From 7af38b96c3cf2b25b540b5beacd0ab71a9629741 Mon Sep 17 00:00:00 2001 From: Rudra Patel Date: Sat, 28 Dec 2024 15:30:16 -0600 Subject: [PATCH 1/2] feat: Update sidebar styles --- next.config.mjs | 1 + src/app/dashboard/admin/programs/page.tsx | 2 +- src/components/AdminDashboard/Sidebar.tsx | 103 -------- .../AdminDashboard/Sidebar/index.tsx | 221 ++++++++++++++++++ 4 files changed, 223 insertions(+), 104 deletions(-) delete mode 100644 src/components/AdminDashboard/Sidebar.tsx create mode 100644 src/components/AdminDashboard/Sidebar/index.tsx diff --git a/next.config.mjs b/next.config.mjs index 26c10c7..c8cefe4 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -8,6 +8,7 @@ const nextConfig = { * To fix this, we disable the router cache for dynamic routes. * https://github.com/vercel/next.js/discussions/65487 * https://nextjs.org/docs/14/app/api-reference/next-config-js/staleTimes + * This is the default behavior for Next.js 15. */ experimental: { staleTimes: { diff --git a/src/app/dashboard/admin/programs/page.tsx b/src/app/dashboard/admin/programs/page.tsx index 6226e19..6722559 100644 --- a/src/app/dashboard/admin/programs/page.tsx +++ b/src/app/dashboard/admin/programs/page.tsx @@ -10,7 +10,7 @@ export default function AdminProgramsPage() { alignItems: "center", }} > - Admin Programs Page + Please select a program on the left sidebar. ); } diff --git a/src/components/AdminDashboard/Sidebar.tsx b/src/components/AdminDashboard/Sidebar.tsx deleted file mode 100644 index 213810f..0000000 --- a/src/components/AdminDashboard/Sidebar.tsx +++ /dev/null @@ -1,103 +0,0 @@ -"use client"; - -import { Apps, Home, Notifications, People } from "@mui/icons-material"; -import { - Drawer, - List, - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, - Toolbar, - useTheme, -} from "@mui/material"; -import Link from "next/link"; -import { usePathname } from "next/navigation"; -import React from "react"; - -const drawerWidth = 200; - -export default function Sidebar() { - const theme = useTheme(); - const pathname = usePathname(); - - const links = [ - { href: "/dashboard/admin/programs", label: "Programs", icon: }, - { href: "/dashboard/admin/clients", label: "Clients", icon: }, - { - href: "/dashboard/admin/notifications", - label: "Notifications", - icon: , - }, - { - href: "/dashboard/admin/applications", - label: "Applications", - icon: , - }, - ]; - - return ( - - - - {links.map((link) => ( - - - - - {link.icon} - - - - - - ))} - - - ); -} diff --git a/src/components/AdminDashboard/Sidebar/index.tsx b/src/components/AdminDashboard/Sidebar/index.tsx new file mode 100644 index 0000000..d1dc2ee --- /dev/null +++ b/src/components/AdminDashboard/Sidebar/index.tsx @@ -0,0 +1,221 @@ +"use client"; + +import Apps from "@mui/icons-material/Apps"; +import ExpandLess from "@mui/icons-material/ExpandLess"; +import ExpandMore from "@mui/icons-material/ExpandMore"; +import Home from "@mui/icons-material/Home"; +import Insights from "@mui/icons-material/Insights"; +import MedicationIcon from "@mui/icons-material/Medication"; +import Notifications from "@mui/icons-material/Notifications"; +import People from "@mui/icons-material/People"; +import SmokeFreeIcon from "@mui/icons-material/SmokeFree"; +import TroubleshootIcon from "@mui/icons-material/Troubleshoot"; +import VaccinesIcon from "@mui/icons-material/Vaccines"; +import { + Collapse, + Drawer, + List, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Toolbar, + useTheme, +} from "@mui/material"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { ReactNode, useState } from "react"; + +const drawerWidth = 200; + +type SidebarButtonProps = { + href: string; + icon: ReactNode; + label: string; + padLeft?: boolean; +}; + +type CollapsibleSidebarButtonProps = SidebarButtonProps & { + onClick: () => void; +}; + +export default function Sidebar() { + const theme = useTheme(); + const pathname = usePathname(); + const [open, setOpen] = useState(false); + + function SidebarButton({ href, icon, label, padLeft }: SidebarButtonProps) { + return ( + + + + + {icon} + + + + + + ); + } + + function CollapsibleSidebarButton({ + href, + icon, + label, + onClick, + }: CollapsibleSidebarButtonProps) { + return ( + + + + {icon} + + + {open ? ( + + ) : ( + + )} + + + ); + } + + return ( + + + + } + label="Programs" + onClick={() => setOpen(!open)} + /> + + } + label="Healthy Habits" + padLeft + /> + } + label="Diabetes Prevention" + padLeft + /> + } + label="Rigs Without Cigs" + padLeft + /> + } + label="Vaccine Voucher" + padLeft + /> + } + label="Get Preventative Screenings" + padLeft + /> + + + } + label="Clients" + /> + } + label="Notifications" + /> + } + label="Applications" + /> + + + ); +} From 7c1f07c69fd3df13fb55f0d64a9b72d76b35c4c9 Mon Sep 17 00:00:00 2001 From: Rudra Patel Date: Sat, 28 Dec 2024 20:01:02 -0600 Subject: [PATCH 2/2] feat: Refactor sidebar into multiple components --- .../programs/diabetes-prevention/page.tsx | 16 + .../get-preventative-screenings/page.tsx | 16 + .../admin/programs/healthy-habits/page.tsx | 16 + .../admin/programs/rigs-without-cigs/page.tsx | 16 + .../admin/programs/vaccine-voucher/page.tsx | 16 + .../Sidebar/CollapsibleSidebarButton.tsx | 58 ++++ .../AdminDashboard/Sidebar/SidebarButton.tsx | 54 +++ .../AdminDashboard/Sidebar/getButtonStyles.ts | 17 + .../AdminDashboard/Sidebar/index.tsx | 315 ++++++++---------- 9 files changed, 347 insertions(+), 177 deletions(-) create mode 100644 src/app/dashboard/admin/programs/diabetes-prevention/page.tsx create mode 100644 src/app/dashboard/admin/programs/get-preventative-screenings/page.tsx create mode 100644 src/app/dashboard/admin/programs/healthy-habits/page.tsx create mode 100644 src/app/dashboard/admin/programs/rigs-without-cigs/page.tsx create mode 100644 src/app/dashboard/admin/programs/vaccine-voucher/page.tsx create mode 100644 src/components/AdminDashboard/Sidebar/CollapsibleSidebarButton.tsx create mode 100644 src/components/AdminDashboard/Sidebar/SidebarButton.tsx create mode 100644 src/components/AdminDashboard/Sidebar/getButtonStyles.ts diff --git a/src/app/dashboard/admin/programs/diabetes-prevention/page.tsx b/src/app/dashboard/admin/programs/diabetes-prevention/page.tsx new file mode 100644 index 0000000..93911a0 --- /dev/null +++ b/src/app/dashboard/admin/programs/diabetes-prevention/page.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from "@mui/material"; + +export default function DiabetesPreventionProgramPage() { + return ( + + Diabetes Prevention Program + + ); +} diff --git a/src/app/dashboard/admin/programs/get-preventative-screenings/page.tsx b/src/app/dashboard/admin/programs/get-preventative-screenings/page.tsx new file mode 100644 index 0000000..9a08710 --- /dev/null +++ b/src/app/dashboard/admin/programs/get-preventative-screenings/page.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from "@mui/material"; + +export default function GetPreventativeScreeningsProgramPage() { + return ( + + Get Preventative Screenings Program + + ); +} diff --git a/src/app/dashboard/admin/programs/healthy-habits/page.tsx b/src/app/dashboard/admin/programs/healthy-habits/page.tsx new file mode 100644 index 0000000..fc7e5f6 --- /dev/null +++ b/src/app/dashboard/admin/programs/healthy-habits/page.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from "@mui/material"; + +export default function HealthyHabitsProgramPage() { + return ( + + Healthy Habits Program + + ); +} diff --git a/src/app/dashboard/admin/programs/rigs-without-cigs/page.tsx b/src/app/dashboard/admin/programs/rigs-without-cigs/page.tsx new file mode 100644 index 0000000..5874068 --- /dev/null +++ b/src/app/dashboard/admin/programs/rigs-without-cigs/page.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from "@mui/material"; + +export default function RigsWithoutCigsProgramPage() { + return ( + + Rigs Without Cigs Program + + ); +} diff --git a/src/app/dashboard/admin/programs/vaccine-voucher/page.tsx b/src/app/dashboard/admin/programs/vaccine-voucher/page.tsx new file mode 100644 index 0000000..7206877 --- /dev/null +++ b/src/app/dashboard/admin/programs/vaccine-voucher/page.tsx @@ -0,0 +1,16 @@ +import { Box, Typography } from "@mui/material"; + +export default function VaccineVoucherProgramPage() { + return ( + + Vaccine Voucher Program + + ); +} diff --git a/src/components/AdminDashboard/Sidebar/CollapsibleSidebarButton.tsx b/src/components/AdminDashboard/Sidebar/CollapsibleSidebarButton.tsx new file mode 100644 index 0000000..4dd4755 --- /dev/null +++ b/src/components/AdminDashboard/Sidebar/CollapsibleSidebarButton.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { ExpandLess, ExpandMore } from "@mui/icons-material"; +import { + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Theme, +} from "@mui/material"; +import { ReactNode } from "react"; + +import getButtonStyles from "@/components/AdminDashboard/Sidebar/getButtonStyles"; + +type CollapsibleSidebarButtonProps = { + pathname: string; + theme: Theme; + href: string; + icon: ReactNode; + label: string; + onClick: () => void; + open?: boolean; +}; + +export default function CollapsibleSidebarButton({ + pathname, + theme, + href, + icon, + label, + onClick, + open = false, +}: CollapsibleSidebarButtonProps) { + const { color, backgroundColor, hoverBackgroundColor } = getButtonStyles( + theme, + pathname, + href, + ); + + return ( + + + {icon} + + {open ? ( + + ) : ( + + )} + + + ); +} diff --git a/src/components/AdminDashboard/Sidebar/SidebarButton.tsx b/src/components/AdminDashboard/Sidebar/SidebarButton.tsx new file mode 100644 index 0000000..ed5f6f9 --- /dev/null +++ b/src/components/AdminDashboard/Sidebar/SidebarButton.tsx @@ -0,0 +1,54 @@ +"use client"; + +import { + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + Theme, +} from "@mui/material"; +import Link from "next/link"; +import { ReactNode } from "react"; + +import getButtonStyles from "@/components/AdminDashboard/Sidebar/getButtonStyles"; + +type SidebarButtonProps = { + pathname: string; + theme: Theme; + href: string; + icon: ReactNode; + label: string; + padLeft?: boolean; +}; + +export default function SidebarButton({ + pathname, + theme, + href, + icon, + label, + padLeft, +}: SidebarButtonProps) { + const { color, backgroundColor, hoverBackgroundColor } = getButtonStyles( + theme, + pathname, + href, + ); + + return ( + + + + {icon} + + + + + ); +} diff --git a/src/components/AdminDashboard/Sidebar/getButtonStyles.ts b/src/components/AdminDashboard/Sidebar/getButtonStyles.ts new file mode 100644 index 0000000..63e6aac --- /dev/null +++ b/src/components/AdminDashboard/Sidebar/getButtonStyles.ts @@ -0,0 +1,17 @@ +import { Theme } from "@mui/material"; + +export default function getButtonStyles( + theme: Theme, + pathname: string, + href: string, +) { + const isCurrentPage = pathname === href; + + return { + backgroundColor: isCurrentPage ? theme.palette.primary.main : "inherit", + hoverBackgroundColor: isCurrentPage + ? theme.palette.primary.light + : "lightgray", + color: isCurrentPage ? theme.palette.primary.contrastText : "black", + }; +} diff --git a/src/components/AdminDashboard/Sidebar/index.tsx b/src/components/AdminDashboard/Sidebar/index.tsx index d1dc2ee..66dd68a 100644 --- a/src/components/AdminDashboard/Sidebar/index.tsx +++ b/src/components/AdminDashboard/Sidebar/index.tsx @@ -1,9 +1,7 @@ "use client"; import Apps from "@mui/icons-material/Apps"; -import ExpandLess from "@mui/icons-material/ExpandLess"; -import ExpandMore from "@mui/icons-material/ExpandMore"; -import Home from "@mui/icons-material/Home"; +import Description from "@mui/icons-material/Description"; import Insights from "@mui/icons-material/Insights"; import MedicationIcon from "@mui/icons-material/Medication"; import Notifications from "@mui/icons-material/Notifications"; @@ -11,139 +9,97 @@ import People from "@mui/icons-material/People"; import SmokeFreeIcon from "@mui/icons-material/SmokeFree"; import TroubleshootIcon from "@mui/icons-material/Troubleshoot"; import VaccinesIcon from "@mui/icons-material/Vaccines"; -import { - Collapse, - Drawer, - List, - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, - Toolbar, - useTheme, -} from "@mui/material"; -import Link from "next/link"; +import { Box, Collapse, Drawer, List, Toolbar, useTheme } from "@mui/material"; import { usePathname } from "next/navigation"; -import { ReactNode, useState } from "react"; +import { useState } from "react"; + +import CollapsibleSidebarButton from "@/components/AdminDashboard/Sidebar/CollapsibleSidebarButton"; +import SidebarButton from "@/components/AdminDashboard/Sidebar/SidebarButton"; const drawerWidth = 200; -type SidebarButtonProps = { - href: string; - icon: ReactNode; +type SidebarChildItem = { label: string; - padLeft?: boolean; + icon: React.ReactNode; + href: string; }; -type CollapsibleSidebarButtonProps = SidebarButtonProps & { - onClick: () => void; -}; +type SidebarItem = + | { + type: "standard"; + label: string; + icon: React.ReactNode; + href: string; + } + | { + type: "collapsible"; + label: string; + icon: React.ReactNode; + href: string; + children: SidebarChildItem[]; + }; + +const sidebarItems: SidebarItem[] = [ + { + type: "collapsible", + label: "Programs", + icon: , + href: "/dashboard/admin/programs", + children: [ + { + label: "Healthy Habits", + icon: , + href: "/dashboard/admin/programs/healthy-habits", + }, + { + label: "Diabetes Prevention", + icon: , + href: "/dashboard/admin/programs/diabetes-prevention", + }, + { + label: "Rigs Without Cigs", + icon: , + href: "/dashboard/admin/programs/rigs-without-cigs", + }, + { + label: "Vaccine Voucher", + icon: , + href: "/dashboard/admin/programs/vaccine-voucher", + }, + { + label: "Get Preventative Screenings", + icon: , + href: "/dashboard/admin/programs/get-preventative-screenings", + }, + ], + }, + { + type: "standard", + label: "Clients", + icon: , + href: "/dashboard/admin/clients", + }, + { + type: "standard", + label: "Notifications", + icon: , + href: "/dashboard/admin/notifications", + }, + { + type: "standard", + label: "Applications", + icon: , + href: "/dashboard/admin/applications", + }, +]; export default function Sidebar() { const theme = useTheme(); const pathname = usePathname(); - const [open, setOpen] = useState(false); - function SidebarButton({ href, icon, label, padLeft }: SidebarButtonProps) { - return ( - - - - - {icon} - - - - - - ); - } + const isOnProgramsSubpage = pathname.startsWith("/dashboard/admin/programs"); - function CollapsibleSidebarButton({ - href, - icon, - label, - onClick, - }: CollapsibleSidebarButtonProps) { - return ( - - - - {icon} - - - {open ? ( - - ) : ( - - )} - - - ); - } + const [open, setOpen] = useState(isOnProgramsSubpage); return ( - - } - label="Programs" - onClick={() => setOpen(!open)} - /> - - } - label="Healthy Habits" - padLeft - /> - } - label="Diabetes Prevention" - padLeft - /> - } - label="Rigs Without Cigs" - padLeft - /> - } - label="Vaccine Voucher" - padLeft - /> - } - label="Get Preventative Screenings" - padLeft - /> - + + {sidebarItems.map((item) => { + if (item.type === "collapsible") { + return ( + + setOpen((prev) => !prev)} + /> + + {item.children.map((child) => ( + + ))} + + + ); + } - } - label="Clients" - /> - } - label="Notifications" - /> - } - label="Applications" - /> + return ( + + ); + })} );