Skip to content

Commit

Permalink
Introduce MenuLayout context
Browse files Browse the repository at this point in the history
  • Loading branch information
ir4y committed Nov 21, 2024
1 parent 2be1f47 commit 128c651
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 48 deletions.
46 changes: 46 additions & 0 deletions src/components/BaseLayout/Sidebar/SidebarTop/context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Role } from 'src/utils/role';
import { EncountersIcon } from 'src/icons/menu/EncountersIcon';
import { InvoicesIcon } from 'src/icons/menu/InvoicesIcon';
import { MedicationsIcon } from 'src/icons/menu/MedicationsIcon';
import { PatientsIcon } from 'src/icons/menu/PatientsIcon';
import { PractitionersIcon } from 'src/icons/menu/PractitionersIcon';
import { PrescriptionsIcon } from 'src/icons/menu/PrescriptionsIcon';
import { QuestionnairesIcon } from 'src/icons/menu/QuestionnairesIcon';
import { ServicesIcon } from 'src/icons/menu/ServicesIcon';
import { t } from '@lingui/macro';
import { createContext } from 'react';

interface Layout {
label: string,
path: string,
icon: React.ReactElement,
}

export type MenuLayoutValue = Record<Role, () => Array<Layout>>;

const defaultMenuLayout:MenuLayoutValue = {
[Role.Admin]: () => [
{ label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon /> },
{ label: t`Services`, path: '/healthcare-services', icon: <ServicesIcon /> },
{ label: t`Encounters`, path: '/encounters', icon: <EncountersIcon /> },
{ label: t`Patients`, path: '/patients', icon: <PatientsIcon /> },
{ label: t`Practitioners`, path: '/practitioners', icon: <PractitionersIcon /> },
{ label: t`Questionnaires`, path: '/questionnaires', icon: <QuestionnairesIcon /> },
],
[Role.Practitioner]: () => [
{ label: t`Encounters`, path: '/encounters', icon: <EncountersIcon /> },
{ label: t`Patients`, path: '/patients', icon: <PatientsIcon /> },
{ label: t`Questionnaires`, path: '/questionnaires', icon: <QuestionnairesIcon /> },
],
[Role.Patient]: () => [{
label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon />
}],
[Role.Receptionist]: () => [
{ label: t`Scheduling`, path: '/scheduling', icon: <EncountersIcon /> },
{ label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon /> },
{ label: t`Medications`, path: '/medications', icon: <MedicationsIcon /> },
{ label: t`Prescriptions`, path: '/prescriptions', icon: <PrescriptionsIcon /> },
],
};

export const MenuLayout = createContext<MenuLayoutValue>(defaultMenuLayout);
37 changes: 5 additions & 32 deletions src/components/BaseLayout/Sidebar/SidebarTop/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { t } from '@lingui/macro';
import { Menu } from 'antd';
import classNames from 'classnames';
import { Link, useLocation, useNavigate } from 'react-router-dom';

import { CompanyName } from 'src/icons/brand/CompanyName';
import { LogoSmall } from 'src/icons/brand/LogoSmall';
import { EncountersIcon } from 'src/icons/menu/EncountersIcon';
import { InvoicesIcon } from 'src/icons/menu/InvoicesIcon';
import { MedicationsIcon } from 'src/icons/menu/MedicationsIcon';
import { PatientsIcon } from 'src/icons/menu/PatientsIcon';
import { PractitionersIcon } from 'src/icons/menu/PractitionersIcon';
import { PrescriptionsIcon } from 'src/icons/menu/PrescriptionsIcon';
import { QuestionnairesIcon } from 'src/icons/menu/QuestionnairesIcon';
import { ServicesIcon } from 'src/icons/menu/ServicesIcon';
import { getToken } from 'src/services/auth';
import { Role, matchCurrentUserRole } from 'src/utils/role';
import { matchCurrentUserRole } from 'src/utils/role';

import s from './SidebarTop.module.scss';
import { S } from './SidebarTop.styles';
import { useContext } from 'react';
import { MenuLayout } from './context';

export interface RouteItem {
path: string;
Expand All @@ -39,30 +32,10 @@ export function SidebarTop(props: Props) {
const isAnonymousUser = !appToken;
const { collapsed, onItemClick, ...other } = props;
const navigate = useNavigate();
const layout = useContext(MenuLayout);

const menuItems: RouteItem[] = !isAnonymousUser
? matchCurrentUserRole({
[Role.Admin]: () => [
{ label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon /> },
{ label: t`Services`, path: '/healthcare-services', icon: <ServicesIcon /> },
{ label: t`Encounters`, path: '/encounters', icon: <EncountersIcon /> },
{ label: t`Patients`, path: '/patients', icon: <PatientsIcon /> },
{ label: t`Practitioners`, path: '/practitioners', icon: <PractitionersIcon /> },
{ label: t`Questionnaires`, path: '/questionnaires', icon: <QuestionnairesIcon /> },
],
[Role.Practitioner]: () => [
{ label: t`Encounters`, path: '/encounters', icon: <EncountersIcon /> },
{ label: t`Patients`, path: '/patients', icon: <PatientsIcon /> },
{ label: t`Questionnaires`, path: '/questionnaires', icon: <QuestionnairesIcon /> },
],
[Role.Patient]: () => [{ label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon /> }],
[Role.Receptionist]: () => [
{ label: t`Scheduling`, path: '/scheduling', icon: <EncountersIcon /> },
{ label: t`Invoices`, path: '/invoices', icon: <InvoicesIcon /> },
{ label: t`Medications`, path: '/medications', icon: <MedicationsIcon /> },
{ label: t`Prescriptions`, path: '/prescriptions', icon: <PrescriptionsIcon /> },
],
})
? matchCurrentUserRole(layout)
: [];

const activeMenu = `/${location.pathname.split('/')[1]}`;
Expand Down
37 changes: 21 additions & 16 deletions src/containers/App/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { t } from '@lingui/macro';
import queryString from 'query-string';
import { useEffect, useRef } from 'react';
import { useContext, useEffect, useRef } from 'react';
import { Route, BrowserRouter, Routes, Navigate, useLocation, useNavigate } from 'react-router-dom';

import { RenderRemoteData } from 'aidbox-react/lib/components/RenderRemoteData';
Expand All @@ -23,7 +23,6 @@ import { QuestionnaireList } from 'src/containers/QuestionnaireList';
import { SignIn } from 'src/containers/SignIn';
import { VideoCall } from 'src/containers/VideoCall';
import { getToken, parseOAuthState, setToken } from 'src/services/auth';
import { sharedAuthorizedPatient } from 'src/sharedState';
import { Role, matchCurrentUserRole } from 'src/utils/role';

import { restoreUserSession } from './utils';
Expand All @@ -37,20 +36,24 @@ import { OrganizationScheduling } from '../OrganizationScheduling';
import { DocumentPrint } from '../PatientDetails/DocumentPrint';
import { Prescriptions } from '../Prescriptions';
import { SetPassword } from '../SetPassword';
import { MenuLayout } from 'src/components/BaseLayout/Sidebar/SidebarTop/context';

export function App() {
const menuLayout = useContext(MenuLayout);
const [userResponse] = useService(async () => {
const appToken = getToken();
return appToken ? restoreUserSession(appToken) : success(null);
});

const renderRoutes = (user: User | null) => {
if (user) {
const layout = matchCurrentUserRole(menuLayout);
const defaultRoute = layout[0]?.path ?? '/encounters'
return matchCurrentUserRole({
[Role.Admin]: () => <AuthenticatedAdminUserApp />,
[Role.Patient]: () => <AuthenticatedPatientUserApp />,
[Role.Practitioner]: () => <AuthenticatedPractitionerUserApp />,
[Role.Receptionist]: () => <AuthenticatedReceptionistUserApp />,
[Role.Admin]: () => <AuthenticatedAdminUserApp defaultRoute={defaultRoute} />,
[Role.Patient]: (patient) => <AuthenticatedPatientUserApp defaultRoute={`/patients/${patient!.id}`} />,
[Role.Practitioner]: () => <AuthenticatedPractitionerUserApp defaultRoute={defaultRoute} />,
[Role.Receptionist]: () => <AuthenticatedReceptionistUserApp defaultRoute={defaultRoute} />,
});
}

Expand Down Expand Up @@ -130,7 +133,11 @@ function AnonymousUserApp() {
);
}

function AuthenticatedAdminUserApp() {
interface RouteProps {
defaultRoute: string;
}

function AuthenticatedAdminUserApp({ defaultRoute }:RouteProps) {
return (
<Routes>
<Route path={`/print-patient-document/:id/:qrId`} element={<DocumentPrint />} />
Expand Down Expand Up @@ -160,7 +167,7 @@ function AuthenticatedAdminUserApp() {
/>
<Route path="/questionnaires/:id" element={<div>questionnaires/:id</div>} />
<Route path="/healthcare-services" element={<HealthcareServiceList />} />
<Route path="*" element={<Navigate to="/encounters" />} />
<Route path="*" element={<Navigate to={defaultRoute} />} />
</Routes>
</BaseLayout>
}
Expand All @@ -169,7 +176,7 @@ function AuthenticatedAdminUserApp() {
);
}

function AuthenticatedPractitionerUserApp() {
function AuthenticatedPractitionerUserApp({ defaultRoute }: RouteProps) {
return (
<Routes>
<Route path={`/print-patient-document/:id/:qrId`} element={<DocumentPrint />} />
Expand All @@ -195,7 +202,7 @@ function AuthenticatedPractitionerUserApp() {
element={<AidboxFormsBuilder />}
/>
<Route path="/questionnaires/:id" element={<div>questionnaires/:id</div>} />
<Route path="*" element={<Navigate to="/encounters" />} />
<Route path="*" element={<Navigate to={defaultRoute} />} />
</Routes>
</BaseLayout>
}
Expand All @@ -204,7 +211,7 @@ function AuthenticatedPractitionerUserApp() {
);
}

function AuthenticatedReceptionistUserApp() {
function AuthenticatedReceptionistUserApp({ defaultRoute }: RouteProps) {
return (
<Routes>
<Route path={`/print-patient-document/:id/:qrId`} element={<DocumentPrint />} />
Expand All @@ -218,7 +225,7 @@ function AuthenticatedReceptionistUserApp() {
<Route path="/invoices/:id" element={<InvoiceDetails />} />
<Route path="/medications" element={<MedicationManagement />} />
<Route path="/prescriptions" element={<Prescriptions />} />
<Route path="*" element={<Navigate to="/scheduling" />} />
<Route path="*" element={<Navigate to={defaultRoute} />} />
</Routes>
</BaseLayout>
}
Expand All @@ -227,9 +234,7 @@ function AuthenticatedReceptionistUserApp() {
);
}

function AuthenticatedPatientUserApp() {
const [patient] = sharedAuthorizedPatient.useSharedState();

function AuthenticatedPatientUserApp({ defaultRoute }: RouteProps) {
return (
<Routes>
<Route path={`/print-patient-document/:id/:qrId`} element={<DocumentPrint />} />
Expand All @@ -241,7 +246,7 @@ function AuthenticatedPatientUserApp() {
<Route path="/invoices" element={<InvoiceList />} />
<Route path="/invoices/:id" element={<InvoiceDetails />} />
<Route path={`/patients/:id/*`} element={<PatientDetails />} />
<Route path="*" element={<Navigate to={`/patients/${patient!.id}`} />} />
<Route path="*" element={<Navigate to={defaultRoute} />} />
</Routes>
</BaseLayout>
}
Expand Down

0 comments on commit 128c651

Please sign in to comment.