From e7446788f24f31fff535dcd88a5795562a62fb07 Mon Sep 17 00:00:00 2001 From: Nathan Panchout Date: Wed, 11 Mar 2026 10:43:20 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(front)=20add=20LeftPanelContext=20for?= =?UTF-8?q?=20mobile=20panel=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a context to manage left panel visibility on mobile, integrate it into SimpleLayout and calendar page. --- .../components/simple/SimpleLayout.tsx | 4 ++ .../layouts/contexts/LeftPanelContext.tsx | 45 +++++++++++++++++++ .../apps/calendars/src/pages/_app.tsx | 7 ++- .../apps/calendars/src/pages/calendar.tsx | 13 +++++- 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 src/frontend/apps/calendars/src/features/layouts/contexts/LeftPanelContext.tsx diff --git a/src/frontend/apps/calendars/src/features/layouts/components/simple/SimpleLayout.tsx b/src/frontend/apps/calendars/src/features/layouts/components/simple/SimpleLayout.tsx index c29d3f8..c2e63b9 100644 --- a/src/frontend/apps/calendars/src/features/layouts/components/simple/SimpleLayout.tsx +++ b/src/frontend/apps/calendars/src/features/layouts/components/simple/SimpleLayout.tsx @@ -3,6 +3,7 @@ import { GlobalLayout } from "../global/GlobalLayout"; import { HeaderRight } from "../header/Header"; import { Toaster } from "@/features/ui/components/toaster/Toaster"; import { LeftPanelMobile } from "@/features/layouts/components/left-panel/LeftPanelMobile"; +import { useLeftPanel } from "../../contexts/LeftPanelContext"; export const getSimpleLayout = (page: React.ReactElement) => { return {page}; @@ -14,12 +15,15 @@ export const getSimpleLayout = (page: React.ReactElement) => { * Auth context to the children. */ export const SimpleLayout = ({ children }: { children: React.ReactNode }) => { + const { isLeftPanelOpen, setIsLeftPanelOpen } = useLeftPanel(); return (
} rightHeaderContent={} > diff --git a/src/frontend/apps/calendars/src/features/layouts/contexts/LeftPanelContext.tsx b/src/frontend/apps/calendars/src/features/layouts/contexts/LeftPanelContext.tsx new file mode 100644 index 0000000..6c18e68 --- /dev/null +++ b/src/frontend/apps/calendars/src/features/layouts/contexts/LeftPanelContext.tsx @@ -0,0 +1,45 @@ +import { + createContext, + useContext, + useMemo, + useState, + type ReactNode, +} from "react"; + +interface LeftPanelContextType { + isLeftPanelOpen: boolean; + setIsLeftPanelOpen: (open: boolean) => void; +} + +const LeftPanelContext = createContext( + undefined, +); + +export const useLeftPanel = () => { + const context = useContext(LeftPanelContext); + if (!context) { + throw new Error( + "useLeftPanel must be used within a LeftPanelProvider", + ); + } + return context; +}; + +interface LeftPanelProviderProps { + children: ReactNode; +} + +export const LeftPanelProvider = ({ children }: LeftPanelProviderProps) => { + const [isLeftPanelOpen, setIsLeftPanelOpen] = useState(false); + + const value = useMemo( + () => ({ isLeftPanelOpen, setIsLeftPanelOpen }), + [isLeftPanelOpen, setIsLeftPanelOpen], + ); + + return ( + + {children} + + ); +}; diff --git a/src/frontend/apps/calendars/src/pages/_app.tsx b/src/frontend/apps/calendars/src/pages/_app.tsx index 451bbc9..f56a847 100644 --- a/src/frontend/apps/calendars/src/pages/_app.tsx +++ b/src/frontend/apps/calendars/src/pages/_app.tsx @@ -33,6 +33,7 @@ import { } from "@/features/ui/cunningham/useCunninghamTheme"; import { FeedbackFooterMobile } from "@/features/feedback/Feedback"; import { useDynamicFavicon } from "@/features/ui/hooks/useDynamicFavicon"; +import { LeftPanelProvider } from "@/features/layouts/contexts/LeftPanelContext"; export type NextPageWithLayout

= NextPage & { getLayout?: (page: ReactElement) => ReactNode; @@ -134,8 +135,10 @@ const MyAppInner = ({ Component, pageProps }: AppPropsWithLayout) => { - {getLayout()} - + + {getLayout()} + + diff --git a/src/frontend/apps/calendars/src/pages/calendar.tsx b/src/frontend/apps/calendars/src/pages/calendar.tsx index 2757810..a0c5810 100644 --- a/src/frontend/apps/calendars/src/pages/calendar.tsx +++ b/src/frontend/apps/calendars/src/pages/calendar.tsx @@ -15,6 +15,7 @@ import { HeaderIcon, HeaderRight, } from "@/features/layouts/components/header/Header"; +import { useLeftPanel } from "@/features/layouts/contexts/LeftPanelContext"; import { SpinnerPage } from "@/features/ui/components/spinner/SpinnerPage"; import { Toaster } from "@/features/ui/components/toaster/Toaster"; import { Scheduler } from "@/features/calendar/components/scheduler/Scheduler"; @@ -56,7 +57,9 @@ export default function CalendarPage() { ); } -CalendarPage.getLayout = function getLayout(page: React.ReactElement) { +const CalendarLayout = ({ children }: { children: React.ReactNode }) => { + const { isLeftPanelOpen, setIsLeftPanelOpen } = useLeftPanel(); + return (

@@ -66,11 +69,17 @@ CalendarPage.getLayout = function getLayout(page: React.ReactElement) { leftPanelContent={} icon={} rightHeaderContent={} + isLeftPanelOpen={isLeftPanelOpen} + setIsLeftPanelOpen={setIsLeftPanelOpen} > - {page} + {children}
); }; + +CalendarPage.getLayout = function getLayout(page: React.ReactElement) { + return {page}; +};