Skip to main content

ui/
route.rs

1use api::dto::{GameIdDTO, UserIdDTO};
2use dioxus::prelude::*;
3use dioxus_sdk::storage::*;
4
5use crate::{components::toast::ToastProvider, pages::*};
6
7/// Application routing definitions.
8#[derive(Clone, PartialEq, Routable)]
9#[rustfmt::skip]
10pub enum Route {
11    /// Layout component for all pages.
12    #[layout(Layout)]
13
14    /// The root page of the application.
15    ///
16    /// This displays the primary landing UI.
17    #[route("/")]
18    HomePage {},
19
20    /// The game page.
21    ///
22    /// This route renders the UI for interacting with an existing game.
23    /// The `game_id` parameter is extracted from the path segment and
24    /// passed into the page component as a [`GameIdDTO`].
25    ///
26    /// Path: `/game/:game_id`
27    #[route("/game/:game_id")]
28    GamePage {
29        /// The game_id to be viewed.
30        game_id: GameIdDTO
31    },
32
33    /// Fallback for unknown routes.
34    ///
35    /// Any unmatched or malformed path is captured here. All remaining
36    /// path segments are collected into `segments` for diagnostic or
37    /// display purposes.
38    ///
39    /// Path pattern: `/:..segments`
40    #[route("/:..segments")]
41    NotFoundPage {
42        /// Unused parts of the request path
43        segments: Vec<String>
44    },
45}
46
47#[component]
48fn Layout() -> Element {
49    let version = env!("CARGO_PKG_VERSION");
50
51    let user_id = use_storage::<LocalStorage, _>("user_id".into(), UserIdDTO::new);
52    provide_context(user_id);
53
54    rsx! {
55        document::Stylesheet { href: asset!("/assets/css/dx-components-theme.css") }
56        document::Stylesheet { href: asset!("/assets/css/main.css") }
57        document::Link { rel: "icon", href: asset!("/assets/favicon.ico"), type: "image/x-icon" }
58        document::Script { r#type: "module", src: asset!("/assets/js/listen_unhandled_promises.js") }
59
60        header { h1 { "Cribbage"  } }
61        main {
62            ErrorBoundary {
63                handle_error: |errors| rsx! { UnexpectedErrorPage { errors } },
64                ToastProvider {
65                    Outlet::<Route> {}
66                }
67            }
68        }
69        footer { "Copyright © 2025; Nigel Eke. All rights reserved. v {version}" }
70    }
71}