use dioxus::prelude::*; use dioxus_free_icons::icons::bs_icons::BsBook; use dioxus_free_icons::icons::fa_solid_icons::{FaChartLine, FaCubes, FaGears}; use dioxus_free_icons::Icon; use crate::components::DashboardCard; use crate::Route; /// Overview dashboard page rendered inside the `AppShell` layout. /// /// Displays a welcome heading and a grid of quick-access cards /// for the main GenAI platform tools. #[component] pub fn OverviewPage() -> Element { // Check authentication status on mount via a server function. let auth_check = use_resource(check_auth); let navigator = use_navigator(); // Once the server responds, redirect unauthenticated users to /auth. use_effect(move || { if let Some(Ok(false)) = auth_check() { navigator.push(NavigationTarget::::External( "/auth?redirect_url=/".into(), )); } }); match auth_check() { // Still waiting for the server to respond. None => rsx! {}, // Not authenticated -- render nothing while the redirect fires. Some(Ok(false)) => rsx! {}, // Authenticated -- render the overview dashboard. Some(Ok(true)) => rsx! { section { class: "overview-page", h1 { class: "overview-heading", "GenAI Dashboard" } div { class: "dashboard-grid", DashboardCard { title: "Documentation".to_string(), description: "Guides & API Reference".to_string(), href: "#".to_string(), icon: rsx! { Icon { icon: BsBook, width: 28, height: 28 } }, } DashboardCard { title: "Langfuse".to_string(), description: "Observability & Analytics".to_string(), href: "#".to_string(), icon: rsx! { Icon { icon: FaChartLine, width: 28, height: 28 } }, } DashboardCard { title: "Langchain".to_string(), description: "Agent Framework".to_string(), href: "#".to_string(), icon: rsx! { Icon { icon: FaGears, width: 28, height: 28 } }, } DashboardCard { title: "Hugging Face".to_string(), description: "Browse Models".to_string(), href: "#".to_string(), icon: rsx! { Icon { icon: FaCubes, width: 28, height: 28 } }, } } } }, // Server error -- surface it so it is not silently swallowed. Some(Err(err)) => rsx! { p { "Error: {err}" } }, } } /// Check whether the current request has an active logged-in session. /// /// # Returns /// /// `true` if the session contains a logged-in user, `false` otherwise. /// /// # Errors /// /// Returns `ServerFnError` if the session cannot be extracted from the request. #[server] async fn check_auth() -> Result { use crate::infrastructure::{UserStateInner, LOGGED_IN_USER_SESS_KEY}; use tower_sessions::Session; // Extract the tower_sessions::Session from the Axum request. let session: Session = FullstackContext::extract().await?; let user: Option = session .get(LOGGED_IN_USER_SESS_KEY) .await .map_err(|e| ServerFnError::new(format!("session read failed: {e}")))?; Ok(user.is_some()) }