Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Issue: Frontend-rewrite refactor directory structure #4662

Merged
merged 2 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/tupaia-web/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# @tupaia/tupaia-web

Main [Tupaia](https://tupaia.org/) application.

## App Directory Structure

- `api`: API layer abstractions such as react-query queries and mutations.
- `components`: Reusable components that are used throughout the app such as Button, Table, etc.
- `constants`: App wide constants such as colors, fonts, etc. Some constants are also defined in the components files or directories.
- `features`: Specific one-off react components that relate to features of the app such as maps, charts etc.
- `layout`: App wide layout components such as Header, Footer etc.
- `theme`: @material-ui theme configuration.
- `utils`: App wide utils such as navigation utils etc.
- `views`: Top level templates that map to router paths. These might contain components that are specific to the view but are not substantial enough to be a feature such as a one-off form.

Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
/*
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

import React from 'react';
import { MODAL_ROUTES, URL_SEARCH_PARAMS } from '../constants';
import { MODAL_ROUTES, URL_SEARCH_PARAMS } from './constants';
import {
Projects,
Login,
Register,
VerifyEmailResend,
RequestProjectAccess,
RequestCountryAccess,
ForgotPassword,
ResetPassword,
} from '.';
import { Modal } from '../components';
import { useModal } from '../utils';
ProjectsModal,
LoginModal,
RegisterModal,
VerifyEmailResendModal,
RequestProjectAccessModal,
RequestCountryAccessModal,
ForgotPasswordModal,
ResetPasswordModal,
} from './views';
import { Modal } from './components';
import { useModal } from './utils';

/**
* This is the wrapper to handle any search param routes that should be modals
*/

const modalViews = {
[MODAL_ROUTES.PROJECTS]: Projects,
[MODAL_ROUTES.LOGIN]: Login,
[MODAL_ROUTES.REGISTER]: Register,
[MODAL_ROUTES.REQUEST_COUNTRY_ACCESS]: RequestCountryAccess,
[MODAL_ROUTES.REQUEST_PROJECT_ACCESS]: RequestProjectAccess,
[MODAL_ROUTES.FORGOT_PASSWORD]: ForgotPassword,
[MODAL_ROUTES.RESET_PASSWORD]: ResetPassword,
[MODAL_ROUTES.VERIFY_EMAIL_RESEND]: VerifyEmailResend,
[MODAL_ROUTES.PROJECTS]: ProjectsModal,
[MODAL_ROUTES.LOGIN]: LoginModal,
[MODAL_ROUTES.REGISTER]: RegisterModal,
[MODAL_ROUTES.REQUEST_COUNTRY_ACCESS]: RequestCountryAccessModal,
[MODAL_ROUTES.REQUEST_PROJECT_ACCESS]: RequestProjectAccessModal,
[MODAL_ROUTES.FORGOT_PASSWORD]: ForgotPasswordModal,
[MODAL_ROUTES.RESET_PASSWORD]: ResetPasswordModal,
[MODAL_ROUTES.VERIFY_EMAIL_RESEND]: VerifyEmailResendModal,
};

const modalParams = {
Expand Down
9 changes: 5 additions & 4 deletions packages/tupaia-web/src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/
import React from 'react';
import { Navigate, Route, Routes as RouterRoutes, useLocation } from 'react-router-dom';
import { ModalRoutes, LandingPage, Project } from './pages';
import { LandingPage, ProjectPage } from './views';
import { ModalRoutes } from './ModalRoutes';
import { MODAL_ROUTES, DEFAULT_URL } from './constants';
import { Layout } from './layout';
import { MainLayout } from './layout';

/**
* This Router is using [version 6.3]{@link https://reactrouter.com/en/v6.3.0}, as later versions are not supported by our TS setup. See [this issue here]{@link https://github.com/remix-run/react-router/discussions/8364}
Expand All @@ -22,7 +23,7 @@ export const Routes = () => {
<ModalRoutes />
<RouterRoutes>
{/* This is the layout for the entire app, so needs to be wrapped around the rest of the routes so that we can access params in top bar etc */}
<Route element={<Layout />}>
<Route element={<MainLayout />}>
<Route path="/" element={<Navigate to={`${DEFAULT_URL}`} replace />} />
{/* Email verification links redirect to the login page where the verification happens */}
<Route
Expand Down Expand Up @@ -70,7 +71,7 @@ export const Routes = () => {
/>
<Route path="/:landingPageUrlSegment" element={<LandingPage />} />
{/** Because react-router v 6.3 doesn't support optional url segments, we need to handle dashboardCode with a splat/catch-all instead */}
<Route path="/:projectCode/:entityCode/*" element={<Project />} />
<Route path="/:projectCode/:entityCode/*" element={<ProjectPage />} />
</Route>
</RouterRoutes>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const Chart = styled.div`
padding: 1rem 1rem 75%;
`;

export const Sidebar = () => {
export const Dashboard = () => {
const { projectCode, entityCode, '*': dashboardCode } = useParams();
const [isExpanded, setIsExpanded] = useState(false);
const { data: entityData } = useEntity(entityCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

export { Sidebar } from './Sidebar';
export { Dashboard } from './Dashboard';
2 changes: 2 additions & 0 deletions packages/tupaia-web/src/features/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
export { Map } from './Map';
export { Dashboard } from './Dashboard';
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const Container = styled.div`
}
`;

export const Layout = () => {
export const MainLayout = () => {
return (
<Container>
<EnvBanner />
Expand Down
6 changes: 1 addition & 5 deletions packages/tupaia-web/src/layout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
export { DesktopLayout } from './DesktopLayout';
export { Layout } from './Layout';
export { Map } from './Map';
export { MainLayout } from './MainLayout';
export * from './ProjectCardList';
export { Sidebar } from './Sidebar';
export { MobileTabLayout } from './MobileTabLayout';
16 changes: 0 additions & 16 deletions packages/tupaia-web/src/pages/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Error = styled(Typography)`
color: ${({ theme }) => theme.palette.error.main};
`;

export const EmailVerification = () => {
export const EmailVerificationModal = () => {
const { isSuccess, isError } = useEmailVerification();

if (isSuccess) return <Success>Your e-mail was successfully verified</Success>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const CheckEmailMessage = styled.p`
padding: 0 0.9375rem;
`;

export const ForgotPassword = () => {
export const ForgotPasswordModal = () => {
const formContext = useForm({
mode: 'onChange',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Typography from '@material-ui/core/Typography';
import { useLogin } from '../api/mutations';
import { AuthModalBody, AuthModalButton, TextField, RouterLink, Form } from '../components';
import { FORM_FIELD_VALIDATION, MODAL_ROUTES } from '../constants';
import { EmailVerification } from './EmailVerification';
import { EmailVerificationModal } from './EmailVerificationModal';

const ModalBody = styled(AuthModalBody)`
width: 38rem;
Expand Down Expand Up @@ -42,13 +42,17 @@ const ForgotPasswordText = styled(LinkText)`
text-align: right;
`;

export const Login = () => {
export const LoginModal = () => {
const formContext = useForm();
const { mutate: login, isLoading, isError, error } = useLogin();

return (
<ModalBody title="Log in" subtitle="Enter your details below to log in">
{isError ? <Typography color="error">{error.message}</Typography> : <EmailVerification />}
{isError ? (
<Typography color="error">{error.message}</Typography>
) : (
<EmailVerificationModal />
)}
<StyledForm onSubmit={login as SubmitHandler<any>} formContext={formContext}>
<TextField name="email" label="Email" type="email" options={FORM_FIELD_VALIDATION.EMAIL} />
<TextField
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
import React from 'react';
import styled from 'styled-components';
import { Sidebar, Map } from '.';
import { MOBILE_BREAKPOINT } from '../constants';
import { Dashboard, Map } from '../../features';
import { MOBILE_BREAKPOINT } from '../../constants';

const Container = styled.div`
display: none;
Expand All @@ -24,7 +24,7 @@ export const DesktopLayout = () => {
return (
<Container>
<Map />
<Sidebar />
<Dashboard />
</Container>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import { Typography, Tabs as MuiTabs, Tab as MuiTab } from '@material-ui/core';
import { TabContext, TabPanel as MuiTabPanel } from '@material-ui/lab';
import { useParams } from 'react-router';
import { useSearchParams } from 'react-router-dom';
import { useEntity } from '../../api/queries';
import { MOBILE_BREAKPOINT, TABS, URL_SEARCH_PARAMS } from '../../constants';
import { Map } from '../Map';
import { Sidebar } from '..';
import { useEntity } from '../../../api/queries';
import { MOBILE_BREAKPOINT, TABS, URL_SEARCH_PARAMS } from '../../../constants';
import { Dashboard, Map } from '../../../features';
import { Footer } from './Footer';

const Wrapper = styled.div`
Expand Down Expand Up @@ -72,7 +71,7 @@ export const MobileTabLayout = () => {

const selectedTab = urlSearchParams.get(URL_SEARCH_PARAMS.TAB) || TABS.DASHBOARD;

const setSelectedTab = (e: ChangeEvent<{}>, value: `${TABS}`) => {
const setSelectedTab = (_event: ChangeEvent<{}>, value: `${TABS}`) => {
urlSearchParams.set(URL_SEARCH_PARAMS.TAB, value);
setUrlSearchParams(urlSearchParams);
};
Expand All @@ -86,7 +85,7 @@ export const MobileTabLayout = () => {
</TabWrapper>
{data && <EntityName>{data.name}</EntityName>}
<DashboardPanel value={TABS.DASHBOARD}>
<Sidebar />
<Dashboard />
<Footer />
</DashboardPanel>
<TabPanel value={TABS.MAP}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/*
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
import React from 'react';
import { DesktopLayout, MobileTabLayout } from '../layout';
import { DesktopLayout } from './DesktopLayout';
import { MobileTabLayout } from './MobileTabLayout';

/**
* This is the layout for the project/* view. This contains the map and the sidebar, as well as any overlays that are not auth overlays (i.e. not needed in landing pages)
*/
export const Project = () => {
export const ProjectPage = () => {
// Use these to fetch the project and any other entity info you might need
// const { projectCode, entityCode, '*': dashboardCode } = useParams();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

export { Register } from './Register';
export { ProjectPage } from './ProjectPage';
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const Logo = styled.img`
/**
* This is the projects view that is shown when the projects modal is open
*/
export const Projects = () => {
export const ProjectsModal = () => {
const {
data: { projects },
} = useProjects();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const StyledForm = styled(Form)`
}
`;

export const Register = () => {
export const RegisterModal = () => {
const { mutate: onSubmit, isLoading, isSuccess, isError, error } = useRegister();
const formContext = useForm();

Expand Down
6 changes: 6 additions & 0 deletions packages/tupaia-web/src/views/RegisterModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

export { RegisterModal } from './RegisterModal';
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Title = styled(Typography).attrs({
margin-bottom: 1rem;
`;

export const RequestCountryAccess = () => {
export const RequestCountryAccessModal = () => {
const formContext = useForm();
const { data, isLoading: isLoadingList } = useCountryAccessList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ModalBody = styled.div`
max-width: 100%;
`;

export const RequestProjectAccess = () => {
export const RequestProjectAccessModal = () => {
const [urlSearchParams] = useSearchParams();
const [requestAdditionalCountries, setRequestAdditionalCountries] = useState(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

export { RequestProjectAccess } from './RequestProjectAccess';
export { RequestProjectAccessModal } from './RequestProjectAccessModal';
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ModalBody = styled(AuthModalBody)`
width: 38rem;
`;

export const ResetPassword = () => {
export const ResetPasswordModal = () => {
const [urlSearchParams] = useSearchParams();
const { mutate: attemptLogin, isError, isLoading, isSuccess } = useOneTimeLogin();
const token = urlSearchParams.get(URL_SEARCH_PARAMS.PASSWORD_RESET_TOKEN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/

export { ResetPassword } from './ResetPassword';
export { ResetPasswordModal } from './ResetPasswordModal';
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const StyledForm = styled(Form)`
max-width: 100%;
`;

export const VerifyEmailResend = () => {
export const VerifyEmailResendModal = () => {
const formContext = useForm();
const { mutate: submit, isSuccess, isLoading, isError, error } = useResendVerificationEmail();

Expand Down
15 changes: 15 additions & 0 deletions packages/tupaia-web/src/views/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Tupaia
* Copyright (c) 2017 - 2023 Beyond Essential Systems Pty Ltd
*/
export { LandingPage } from './LandingPage';
export { LoginModal } from './LoginModal';
export { ResetPasswordModal } from './ResetPasswordModal/ResetPasswordModal';
export { ProjectPage } from './ProjectPage';
export { RegisterModal } from './RegisterModal';
export { ProjectsModal } from './ProjectsModal';
export { RequestCountryAccessModal } from './RequestCountryAccessModal';
export { RequestProjectAccessModal } from './RequestProjectAccessModal';
export { ForgotPasswordModal } from './ForgotPasswordModal';
export { EmailVerificationModal } from './EmailVerificationModal';
export { VerifyEmailResendModal } from './VerifyEmailResendModal';