Skip to content

Commit

Permalink
Cleanup Navbars
Browse files Browse the repository at this point in the history
  • Loading branch information
gigincg committed Jan 8, 2025
1 parent b7d8b6b commit adac786
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 137 deletions.
8 changes: 2 additions & 6 deletions src/Routers/PatientRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import careConfig from "@careConfig";
import { useRoutes } from "raviger";

import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { AppSidebar } from "@/components/ui/sidebar/app-sidebar";
import { AppSidebar, SidebarFor } from "@/components/ui/sidebar/app-sidebar";

import ErrorBoundary from "@/components/Common/ErrorBoundary";
import ErrorPage from "@/components/ErrorPages/DefaultErrorPage";
import { patientTabs } from "@/components/Patient/PatientDetailsTab";
import { PatientHome } from "@/components/Patient/PatientHome";

import { usePatientContext } from "@/hooks/usePatientUser";

import PatientUserProvider from "@/Providers/PatientUserProvider";
import { PatientRegistration } from "@/pages/Appoinments/PatientRegistration";
import PatientSelect from "@/pages/Appoinments/PatientSelect";
Expand Down Expand Up @@ -70,8 +68,6 @@ export default function PatientRouter() {

const appointmentPages = useRoutes(AppointmentRoutes);

const patientUserContext = usePatientContext();

if (!pages) {
if (appointmentPages) {
return <PatientUserProvider>{appointmentPages}</PatientUserProvider>;
Expand All @@ -82,7 +78,7 @@ export default function PatientRouter() {
return (
<PatientUserProvider>
<SidebarProvider>
<AppSidebar patientUserContext={patientUserContext} />
<AppSidebar sidebarFor={SidebarFor.PATIENT} />
<main
id="pages"
className="flex-1 overflow-y-auto bg-gray-100 focus:outline-none md:pb-2 md:pr-2"
Expand Down
137 changes: 15 additions & 122 deletions src/components/ui/sidebar/app-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { DashboardIcon } from "@radix-ui/react-icons";
import { TFunction } from "i18next";
import { Link, usePathParams } from "raviger";
import * as React from "react";
import { useTranslation } from "react-i18next";

import {
Sidebar,
Expand All @@ -14,121 +12,32 @@ import {
SidebarMenuItem,
SidebarRail,
} from "@/components/ui/sidebar";
import { FacilityNav } from "@/components/ui/sidebar/facility-nav";
import { FacilitySwitcher } from "@/components/ui/sidebar/facility-switcher";
import { NavMain } from "@/components/ui/sidebar/nav-main";
import {
FacilityNavUser,
PatientNavUser,
} from "@/components/ui/sidebar/nav-user";
import { OrgNav } from "@/components/ui/sidebar/org-nav";
import { OrganizationSwitcher } from "@/components/ui/sidebar/organization-switcher";
import { PatientNav } from "@/components/ui/sidebar/patient-nav";

import { UserFacilityModel, UserModel } from "@/components/Users/models";

import { PatientUserContextType } from "@/Providers/PatientUserProvider";
import { AppointmentPatient } from "@/pages/Patient/Utils";
import { Organization } from "@/types/organization/organization";

import { PatientSwitcher } from "./patient-switcher";

interface NavigationLink {
name: string;
url: string;
icon?: string;
}

interface AppSidebarProps extends React.ComponentProps<typeof Sidebar> {
user?: UserModel;
facilitySidebar?: boolean;
patientUserContext?: PatientUserContextType;
sidebarFor?: SidebarFor;
}

function generateFacilityLinks(
selectedFacility: UserFacilityModel | null,
t: TFunction,
// TODO: switch to UserBase once getcurrentuser serializer is updated
user?: UserModel,
) {
if (!selectedFacility) return [];

const baseUrl = `/facility/${selectedFacility.id}`;
const links: NavigationLink[] = [
{ name: t("facility"), url: baseUrl, icon: "d-hospital" },
{
name: t("appointments"),
url: `${baseUrl}/appointments`,
icon: "d-calendar",
},
{
name: t("search_patients"),
url: `${baseUrl}/patients`,
icon: "d-patient",
},
{ name: t("encounters"), url: `${baseUrl}/encounters`, icon: "d-patient" },
// { name: t("assets"), url: `${baseUrl}/assets`, icon: "d-folder" },
{ name: t("resource"), url: "/resource", icon: "d-book-open" },
{ name: t("users"), url: `${baseUrl}/users`, icon: "d-people" },
{
name: t("organization"),
url: `${baseUrl}/organization`,
icon: "d-book-open",
},
];

if (user) {
links.push({
name: t("schedules"),
url: `${baseUrl}/users/${user.username}/availability`,
icon: "d-calendar",
});
}

return links;
}

function generateOrganizationLinks(
organizations: Organization[],
): NavigationLink[] {
return organizations.map((org) => ({
name: org.name,
url: `/organization/${org.id}`,
}));
}

function generatePatientLinks(
selectedUser: AppointmentPatient | null,
t: TFunction,
): NavigationLink[] {
if (!selectedUser) return [];

const { geo_organization } = selectedUser;
let parentOrganization = geo_organization?.parent;
while (parentOrganization?.parent) {
if (parentOrganization.level_cache === 1) {
break;
}
parentOrganization = parentOrganization.parent;
}

const queryParams = new URLSearchParams();

if (parentOrganization) {
queryParams.set("organization", String(parentOrganization?.id));
}

return [
{ name: t("appointments"), url: "/patient/home", icon: "d-patient" },
{
name: t("nearby_facilities"),
url: `/nearby_facilities/?${queryParams.toString()}`,
icon: "d-patient",
},
];
export enum SidebarFor {
FACILITY = "facility",
PATIENT = "patient",
}

export function AppSidebar({
user,
patientUserContext,
facilitySidebar = true,
sidebarFor = SidebarFor.FACILITY,
...props
}: AppSidebarProps) {
const exactMatch = usePathParams("/facility/:facilityId");
Expand All @@ -139,11 +48,12 @@ export function AppSidebar({
const orgSubpathMatch = usePathParams("/organization/:id/*");
const organizationId = orgMatch?.id || orgSubpathMatch?.id;

const facilitySidebar = sidebarFor === SidebarFor.FACILITY;
const patientSidebar = sidebarFor === SidebarFor.PATIENT;

const [selectedFacility, setSelectedFacility] =
React.useState<UserFacilityModel | null>(null);

const { t } = useTranslation();

const selectedOrganization = React.useMemo(() => {
if (!user?.organizations || !organizationId) return undefined;
return user.organizations.find((org) => org.id === organizationId);
Expand Down Expand Up @@ -207,34 +117,17 @@ export function AppSidebar({

<SidebarContent>
{facilitySidebar && !selectedOrganization && (
<NavMain links={generateFacilityLinks(selectedFacility, t, user)} />
<FacilityNav selectedFacility={selectedFacility} user={user} />
)}
{selectedOrganization && (
<NavMain
links={generateOrganizationLinks(user?.organizations || [])}
/>
)}
{patientUserContext && (
<>
<PatientSwitcher />
<NavMain
links={generatePatientLinks(
patientUserContext.selectedPatient,
t,
)}
/>
</>
<OrgNav organizations={user?.organizations || []} />
)}
{patientSidebar && <PatientNav />}
</SidebarContent>

<SidebarFooter>
{(facilitySidebar || selectedOrganization) && <FacilityNavUser />}
{patientUserContext && (
<PatientNavUser
patient={patientUserContext.selectedPatient}
phoneNumber={patientUserContext.tokenData.phoneNumber}
/>
)}
{patientSidebar && <PatientNavUser />}
</SidebarFooter>

<SidebarRail />
Expand Down
63 changes: 63 additions & 0 deletions src/components/ui/sidebar/facility-nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { TFunction } from "i18next";
import { useTranslation } from "react-i18next";

import { NavMain } from "@/components/ui/sidebar/nav-main";

import { UserFacilityModel, UserModel } from "@/components/Users/models";

interface NavigationLink {
name: string;
url: string;
icon?: string;
}

interface FacilityNavProps {
selectedFacility: UserFacilityModel | null;
user?: UserModel;
}

function generateFacilityLinks(
selectedFacility: UserFacilityModel | null,
t: TFunction,
user?: UserModel,
) {
if (!selectedFacility) return [];

const baseUrl = `/facility/${selectedFacility.id}`;
const links: NavigationLink[] = [
{ name: t("facility"), url: baseUrl, icon: "d-hospital" },
{
name: t("appointments"),
url: `${baseUrl}/appointments`,
icon: "d-calendar",
},
{
name: t("search_patients"),
url: `${baseUrl}/patients`,
icon: "d-patient",
},
{ name: t("encounters"), url: `${baseUrl}/encounters`, icon: "d-patient" },
{ name: t("resource"), url: "/resource", icon: "d-book-open" },
{ name: t("users"), url: `${baseUrl}/users`, icon: "d-people" },
{
name: t("organization"),
url: `${baseUrl}/organization`,
icon: "d-book-open",
},
];

if (user) {
links.push({
name: t("schedules"),
url: `${baseUrl}/users/${user.username}/availability`,
icon: "d-calendar",
});
}

return links;
}

export function FacilityNav({ selectedFacility, user }: FacilityNavProps) {
const { t } = useTranslation();
return <NavMain links={generateFacilityLinks(selectedFacility, t, user)} />;
}
15 changes: 6 additions & 9 deletions src/components/ui/sidebar/nav-user.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import { Avatar } from "@/components/Common/Avatar";

import useAuthUser, { useAuthContext } from "@/hooks/useAuthUser";
import { usePatientSignOut } from "@/hooks/usePatientSignOut";

import { AppointmentPatient } from "@/pages/Patient/Utils";
import { usePatientContext } from "@/hooks/usePatientUser";

export function FacilityNavUser() {
const { t } = useTranslation();
Expand Down Expand Up @@ -117,16 +116,14 @@ export function FacilityNavUser() {
);
}

export function PatientNavUser({
patient,
phoneNumber,
}: {
patient: AppointmentPatient | null;
phoneNumber: string;
}) {
export function PatientNavUser() {
const { t } = useTranslation();
const { isMobile, open } = useSidebar();
const signOut = usePatientSignOut();
const patientUserContext = usePatientContext();

const patient = patientUserContext?.selectedPatient;
const phoneNumber = patientUserContext?.tokenData.phoneNumber;

return (
<SidebarMenu>
Expand Down
26 changes: 26 additions & 0 deletions src/components/ui/sidebar/org-nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { NavMain } from "@/components/ui/sidebar/nav-main";

import { Organization } from "@/types/organization/organization";

interface NavigationLink {
name: string;
url: string;
icon?: string;
}

interface OrgNavProps {
organizations: Organization[];
}

function generateOrganizationLinks(
organizations: Organization[],
): NavigationLink[] {
return organizations.map((org) => ({
name: org.name,
url: `/organization/${org.id}`,
}));
}

export function OrgNav({ organizations }: OrgNavProps) {
return <NavMain links={generateOrganizationLinks(organizations)} />;
}
Loading

0 comments on commit adac786

Please sign in to comment.