diff --git a/README.md b/README.md index 89da194..c8f7b04 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,10 @@ classDiagram class SidebarShellProps { +children: Children } + class SidebarComponentProps { + +is_open: bool + +on_close: Callback~()~ + } class AdminCheckWrapperProps { +children: Children } @@ -255,6 +259,7 @@ classDiagram RoomTotalsProps --> TicketPartial UserTotalProps --> UserPartial UserTotalProps --> TicketPartial + SidebarShellProps ..> SidebarComponentProps ``` @@ -306,7 +311,7 @@ sequenceDiagram BE-->>FE: HTTP 200 OK {"status": "success", "token": "...", "user": {...}} Note over BE,FE: Header: Set-Cookie: token=...#59; Path=/#59; HttpOnly#59; SameSite=Lax - + Note over FE: Save auth state to global context FE-->>User: Redirect to Dashboard / Home else Password Invalid @@ -351,6 +356,15 @@ sequenceDiagram DB-->>BE: Success BE-->>FE: HTTP 200 OK {"status": "success"} FE-->>Admin: Update ticket status in UI + + Note over Admin, DB: Ticket Archiving Flow (Admin Only Route) + Admin->>FE: Open Archived Tickets page + FE->>BE: GET /api/tickets/archive (Includes 'token' cookie) + Note over BE: validate_admin middleware verifies token & admin role + BE->>DB: SELECT * FROM tickets WHERE status = 'Archived' + DB-->>BE: Return archived tickets + BE-->>FE: HTTP 200 OK [Archived Tickets] + FE-->>Admin: Render historical archive board ``` ## Usage of AI diff --git a/frontend/src/dark_mode.rs b/frontend/src/dark_mode.rs index 6e16770..7d41d92 100644 --- a/frontend/src/dark_mode.rs +++ b/frontend/src/dark_mode.rs @@ -2,6 +2,15 @@ use gloo_storage::{LocalStorage, Storage}; use web_sys::window; use yew::prelude::*; +/// A persistent, floating toggle button to switch the user interface theme between Dark Mode and Light Mode. +/// +/// # Functionality +/// 1. **System Preference Check**: If the user hasn't explicitly set a preference, detects the operating system theme +/// preference using browser `match_media("(prefers-color-scheme: dark)")` query. +/// 2. **Session Persistence**: Caches the selected theme choice under the `"dark-mode"` key in the browser's `LocalStorage` +/// so that user preferences persist across page reloads. +/// 3. **Dynamic Style Swapping**: Injects or removes the `.theme-dark` / `.theme-light` classes directly on the document +/// `body` element, triggering the theme change via globally defined CSS variables. #[function_component(DarkModeToggle)] pub fn dark_mode_toggle() -> Html { // 1. Initialize state from LocalStorage or system preference diff --git a/frontend/src/lib.rs b/frontend/src/lib.rs index 1f9d06d..33a5782 100644 --- a/frontend/src/lib.rs +++ b/frontend/src/lib.rs @@ -70,8 +70,15 @@ pub struct SidebarShellProps { /// This component is designed to wrap page-specific content, ensuring that the sidebar /// is always present for navigation. Integrates with [`crate::pages::sidebar::Sidebar`] for navigation. /// +/// # Mobile Support +/// On mobile displays, the sidebar is hidden by default and can be toggled: +/// - **Menu Toggle Button**: Renders a floating menu button to slide the sidebar open. +/// - **Dark Mode Toggle**: Floating button to change theme. +/// - **Overlay Backdrop**: Dims the screen when the sidebar is open. Clicking it closes the sidebar. +/// - **Auto-Close on Navigation**: Automatically closes the sidebar when navigating to a new route. +/// /// # Components -/// - [`crate::pages::sidebar::Sidebar`]: The navigation sidebar component. +/// - [`crate::pages::sidebar::Sidebar`]: The navigation sidebar component, accepting mobile open state. /// - Main content area: Renders the `children` passed to this component. /// /// # Example diff --git a/frontend/src/pages/sidebar.rs b/frontend/src/pages/sidebar.rs index 902627d..e2a29cc 100644 --- a/frontend/src/pages/sidebar.rs +++ b/frontend/src/pages/sidebar.rs @@ -319,6 +319,11 @@ pub fn users_menu() -> Html { /// and administrative status. It fetches the current user's details via `/api/users/current` /// to determine what menu items to display. /// +/// # Mobile Support +/// On small screens: +/// - Slides into view from the left when `props.is_open` is `true`. +/// - Renders a close button (`✕`) in the header that emits `props.on_close`. +/// /// # Structure /// - Wraps its content in a [`SidebarStateProvider`] to allow nested menus to manage their state. /// - Contains a navigation (`