♻️(front) update pages and app structure

Update calendar page to use new Scheduler and CalendarContext.
Update styles, error pages, and app wrapper for new components.
Minor updates to Header, Toaster and Feedback components.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nathan Panchout
2026-01-25 20:35:43 +01:00
parent 48062a9988
commit afb4e35b1d
12 changed files with 44 additions and 76 deletions

View File

@@ -5,7 +5,7 @@ import {
Modal,
ModalSize,
useModal,
} from "@openfun/cunningham-react";
} from "@gouvfr-lasuite/cunningham-react";
import React, { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useConfig } from "../config/ConfigProvider";

View File

@@ -17,7 +17,6 @@ export const HeaderIcon = () => {
};
export const HeaderRight = () => {
const { user } = useAuth();
const { isTablet } = useResponsive();
return (

View File

@@ -1,4 +1,4 @@
import { Button } from "@openfun/cunningham-react";
import { Button } from "@gouvfr-lasuite/cunningham-react";
import clsx from "clsx";
import { ToastContainer, ToastContentProps, toast } from "react-toastify";

View File

@@ -1,7 +1,7 @@
import { login } from "@/features/auth/Auth";
import { getSimpleLayout } from "@/features/layouts/components/simple/SimpleLayout";
import { GenericDisclaimer } from "@/features/ui/components/generic-disclaimer/GenericDisclaimer";
import { Button } from "@openfun/cunningham-react";
import { Button } from "@gouvfr-lasuite/cunningham-react";
import { useTranslation } from "react-i18next";
export default function UnauthorizedPage() {

View File

@@ -1,7 +1,7 @@
import { getSimpleLayout } from "@/features/layouts/components/simple/SimpleLayout";
import { GenericDisclaimer } from "@/features/ui/components/generic-disclaimer/GenericDisclaimer";
import { Icon } from "@gouvfr-lasuite/ui-kit";
import { Button } from "@openfun/cunningham-react";
import { Button } from "@gouvfr-lasuite/cunningham-react";
import { useTranslation } from "react-i18next";
export default function UnauthorizedPage() {

View File

@@ -1,15 +1,12 @@
import {
createContext,
useContext,
useMemo,
useState,
useContext, useState,
type ReactElement,
type ReactNode,
type ReactNode
} from "react";
import type { NextPage } from "next";
import type { AppProps } from "next/app";
import { CunninghamProvider } from "@gouvfr-lasuite/ui-kit";
import { ModalProvider } from "@openfun/cunningham-react";
import {
MutationCache,
Query,
@@ -34,9 +31,7 @@ import {
removeQuotes,
useCunninghamTheme,
} from "@/features/ui/cunningham/useCunninghamTheme";
import { ResponsiveDivs } from "@/features/ui/components/responsive/ResponsiveDivs";
import { FeedbackFooterMobile } from "@/features/feedback/Feedback";
import { useRouter } from "next/router";
export type NextPageWithLayout<P = object, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
@@ -119,7 +114,6 @@ const MyAppInner = ({ Component, pageProps }: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => page);
const { t, i18n } = useTranslation();
const { theme } = useAppContext();
const router = useRouter();
const themeTokens = useCunninghamTheme();
return (
@@ -137,15 +131,14 @@ const MyAppInner = ({ Component, pageProps }: AppPropsWithLayout) => {
currentLocale={capitalizeRegion(i18n.language)}
theme={theme}
>
<ModalProvider>
<ConfigProvider>
<AnalyticsProvider>
{getLayout(<Component {...pageProps} />)}
<ResponsiveDivs />
<FeedbackFooterMobile />
</AnalyticsProvider>
</ConfigProvider>
</ModalProvider>
</CunninghamProvider>
</QueryClientProvider>
</>

View File

@@ -19,7 +19,7 @@
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
// overflow: hidden;
}
}

View File

@@ -2,53 +2,42 @@
* Calendar page - Main calendar view with sidebar.
*/
import { useCallback, useState } from "react";
import { useCallback } from "react";
import { MainLayout } from "@gouvfr-lasuite/ui-kit";
import Head from "next/head";
import { useTranslation } from "next-i18next";
import { login, useAuth } from "@/features/auth/Auth";
import { CalendarView, LeftPanel } from "@/features/calendar/components";
import { useCreateCalendarModal } from "@/features/calendar/components/CreateCalendarModal";
import { useCreateEventModal } from "@/features/calendar/hooks/useCreateEventModal";
import { LeftPanel } from "@/features/calendar/components";
import { useCalendars } from "@/features/calendar/hooks/useCalendars";
import { GlobalLayout } from "@/features/layouts/components/global/GlobalLayout";
import { HeaderRight } from "@/features/layouts/components/header/Header";
import { SpinnerPage } from "@/features/ui/components/spinner/SpinnerPage";
import { Toaster } from "@/features/ui/components/toaster/Toaster";
import { Scheduler } from "@/features/calendar/components/scheduler/Scheduler";
import { CalendarContextProvider, useCalendarContext } from "@/features/calendar/contexts";
export default function CalendarPage() {
const { t } = useTranslation();
const { user } = useAuth();
// Calendar state
const [selectedDate, setSelectedDate] = useState(new Date());
// Use selectedDate from context (the specific day user has clicked/selected)
// Note: currentDate (for view sync) is used directly by MiniCalendar
const { selectedDate, setSelectedDate } = useCalendarContext();
// Fetch calendars for the sidebar
const { data: calendars = [], isLoading: isLoadingCalendars } = useCalendars();
const { data: calendars = [] } = useCalendars();
// Create calendar modal
const createCalendarModal = useCreateCalendarModal();
// Create event modal
const createEventModal = useCreateEventModal({
calendars: calendars || [],
selectedDate
});
// Handlers
const handleDateSelect = useCallback((date: Date) => {
setSelectedDate(date);
}, []);
}, [setSelectedDate]);
const handleCreateEvent = useCallback(() => {
createEventModal.open();
}, [createEventModal]);
const handleCreateCalendar = useCallback(() => {
createCalendarModal.open();
}, [createCalendarModal]);
console.log("handleCreateEvent");
}, []);
// Redirect to login if not authenticated
if (!user) {
@@ -67,26 +56,24 @@ export default function CalendarPage() {
<link rel="icon" href="/favicon.png" />
</Head>
<div className="calendar-page">
<div className="calendar-page__sidebar">
<LeftPanel
calendars={calendars}
selectedDate={selectedDate}
onDateSelect={handleDateSelect}
onCreateEvent={handleCreateEvent}
onCreateCalendar={handleCreateCalendar}
/>
<div className="calendar-page">
<div className="calendar-page__sidebar">
<LeftPanel
calendars={calendars}
selectedDate={selectedDate}
onDateSelect={handleDateSelect}
onCreateEvent={handleCreateEvent}
/>
</div>
<div className="calendar-page__main">
<Scheduler />
</div>
</div>
<div className="calendar-page__main">
<CalendarView
selectedDate={selectedDate}
onSelectDate={handleDateSelect}
/>
</div>
</div>
{createCalendarModal.Modal}
{createEventModal.Modal}
<Toaster />
</>
);
@@ -94,6 +81,7 @@ export default function CalendarPage() {
CalendarPage.getLayout = function getLayout(page: React.ReactElement) {
return (
<CalendarContextProvider>
<div className="calendars__calendar">
<GlobalLayout>
<MainLayout
@@ -111,5 +99,6 @@ CalendarPage.getLayout = function getLayout(page: React.ReactElement) {
</MainLayout>
</GlobalLayout>
</div>
</CalendarContextProvider>
);
};

View File

@@ -11,7 +11,7 @@ import {
Toaster,
ToasterItem,
} from "@/features/ui/components/toaster/Toaster";
import { Button } from "@openfun/cunningham-react";
import { Button } from "@gouvfr-lasuite/cunningham-react";
import { useConfig } from "@/features/config/ConfigProvider";
import { LeftPanelMobile } from "@/features/layouts/components/left-panel/LeftPanelMobile";
import { SESSION_STORAGE_REDIRECT_AFTER_LOGIN_URL } from "@/features/api/fetchApi";
@@ -77,7 +77,7 @@ export default function HomePage() {
<HomeGutter>
<Hero
logo={<div className="calendars__logo-icon" />}
/* banner={banner.src} */
banner={banner.src}
title={t("home.title")}
subtitle={t("home.subtitle")}
mainButton={

View File

@@ -663,7 +663,7 @@
--c--components--gaufre--widgetpath: 'https://static.suite.anct.gouv.fr/widgets/lagaufre.js';
--c--components--gaufre--apiurl: 'https://lasuite.numerique.gouv.fr/api/services';
--c--components--favicon--src: '/assets/favicon.png';
--c--components--logo--src: url('/assets/logo_alpha.svg');
--c--components--logo--src: url('/assets/logo_beta.svg');
--c--components--logo-icon--src: url('/assets/logo-icon_beta.svg');
}
.cunningham-theme--dark{

View File

@@ -4,20 +4,17 @@
@use "./../features/layouts/components/global/GlobalLayout.scss";
@use "./../features/feedback/Feedback.scss";
@use "./../features/layouts/components/header/index.scss";
@use "./../features/ui/components/breadcrumbs";
@use "./../features/ui/components/toaster";
@use "./../features/ui/components/generic-disclaimer/GenericDisclaimer.scss";
@use "./../features/ui/components/info/InfoRow.scss";
@use "./../features/ui/components/responsive";
@use "./../features/ui/components/spinner/SpinnerPage.scss";
@use "./../features/ui/components/infinite-scroll/InfiniteScroll.scss";
@use "./../features/layouts/components/left-panel/LeftPanelMobile.scss";
@use "./../features/calendar/components/MiniCalendar.scss";
@use "./../features/calendar/components/CalendarList.scss";
@use "./../features/calendar/components/LeftPanel.scss";
@use "./../features/calendar/components/CalendarView.scss";
@use "./../features/calendar/components/EventModal.scss";
@use "./../features/calendar/components/RecurrenceEditor.scss";
@use "./../features/calendar/components/AttendeesInput.scss";
@use "./../features/calendar/components/scheduler/Scheduler.scss";
@use "./../pages/index.scss" as *;
@use "./../pages/calendar.scss" as *;
html,
@@ -77,7 +74,5 @@ body {
.c__datagrid--empty,
.c__datagrid thead {
transition:
background-color 0.3s ease,
box-shadow 0.3s ease;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

View File

@@ -1,12 +1,4 @@
import { UseQueryOptions } from "@tanstack/react-query";
export type HookUseQueryOptions2 = {
enabled?: boolean;
}
export type HookUseQueryOptions<T> = Omit<UseQueryOptions<T>, "queryKey" | "queryFn">;