From 4a2a5ca9ff2fa6d4da027dcafbcb28cc5720d5a7 Mon Sep 17 00:00:00 2001 From: Lucas Vas Date: Thu, 22 Jan 2026 01:34:58 -0500 Subject: [PATCH] feat: create sidebar tabs list --- src/app.rs | 15 ++++++++- src/common/mod.rs | 3 +- src/common/tab_info.rs | 5 +++ src/components/banner.rs | 4 +-- src/components/login/admin.rs | 18 +++++++++++ src/components/login/mod.rs | 4 ++- src/components/mod.rs | 3 +- src/components/tabs/mod.rs | 2 ++ src/components/tabs/sidebar.rs | 57 ++++++++++++++++++++++++++++++++++ src/pages/admin/mod.rs | 2 ++ src/pages/admin/shell.rs | 49 +++++++++++++++++++++++++++++ src/pages/mod.rs | 3 +- 12 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/common/tab_info.rs create mode 100644 src/components/login/admin.rs create mode 100644 src/components/tabs/mod.rs create mode 100644 src/components/tabs/sidebar.rs create mode 100644 src/pages/admin/mod.rs create mode 100644 src/pages/admin/shell.rs diff --git a/src/app.rs b/src/app.rs index f502687..ec4ff85 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,4 +1,4 @@ -use crate::pages::{ProviderPortal, ScholarshipInfoPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage, ApplicantsPageFallback, TestPage}; +use crate::pages::{ProviderPortal, ScholarshipInfoPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage, ApplicantsPageFallback, AdminShell, AdminTesting, AdminFallback}; use leptos::prelude::*; use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context}; use leptos_oidc::AuthSignal; @@ -64,6 +64,7 @@ pub fn AppWithRoutes() -> impl IntoView { // + @@ -101,6 +102,18 @@ fn LoanerRoutes() -> impl MatchNestedRoutes + Clone { .into_any_nested_route() } +#[component(transparent)] +fn AdminRoutes() -> impl MatchNestedRoutes + Clone { + view! { + + + + + } + .into_inner() + .into_any_nested_route() +} + #[component] pub fn AuthErrorView() -> impl IntoView { let auth = use_context::().expect("AuthError: RwSignal was not found"); diff --git a/src/common/mod.rs b/src/common/mod.rs index 487f959..cd627ea 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -7,8 +7,9 @@ mod submit_status; mod user; mod value_type; pub mod animations; +mod tab_info; pub use self::{ comparison::*, date_info::*, expandable_info::*, form_params::*, form_schema::*, - submit_status::*, user::*, value_type::*, + submit_status::*, user::*, value_type::*, tab_info::*, }; diff --git a/src/common/tab_info.rs b/src/common/tab_info.rs new file mode 100644 index 0000000..f292629 --- /dev/null +++ b/src/common/tab_info.rs @@ -0,0 +1,5 @@ +#[derive(Debug, Clone)] +pub struct TabInfo { + pub name: String, + pub path: String, +} \ No newline at end of file diff --git a/src/components/banner.rs b/src/components/banner.rs index 8a26ec3..d82b994 100644 --- a/src/components/banner.rs +++ b/src/components/banner.rs @@ -22,7 +22,7 @@ pub fn Banner( title: String, /// The file path or URL of a logo displayed at the top left of the banner. #[prop(into)] - logo: String, + logo: Signal, /// The route that the navigates user to a page (home page). #[prop(into, optional)] path: Signal, @@ -44,7 +44,7 @@ pub fn Banner(
icon impl IntoView { + provide_auth_context( + crate::utils::use_origin(), + "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM", + "56c2bqvl021rv8d5mq36blt7jv", + "/providers/callback" + ); + + view! { + {children()} + } +} \ No newline at end of file diff --git a/src/components/login/mod.rs b/src/components/login/mod.rs index fae50eb..c9911f2 100644 --- a/src/components/login/mod.rs +++ b/src/components/login/mod.rs @@ -1,5 +1,7 @@ +pub(crate) mod setup; mod provider; pub use provider::*; mod student; pub use student::*; -pub(crate) mod setup; \ No newline at end of file +mod admin; +pub use admin::*; \ No newline at end of file diff --git a/src/components/mod.rs b/src/components/mod.rs index 27d6b69..89dc30c 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -13,9 +13,10 @@ mod lists; mod toasts; mod header; pub mod login; +mod tabs; pub use self::{ action_button::*, banner::*, dashboard_button::*, lists::*, loading::*, multi_entry::*, panel::*, row::*, text_field::*, - validated_form::*, toasts::*, header::*, date::* + validated_form::*, toasts::*, header::*, date::*, tabs::* }; diff --git a/src/components/tabs/mod.rs b/src/components/tabs/mod.rs new file mode 100644 index 0000000..2c727dc --- /dev/null +++ b/src/components/tabs/mod.rs @@ -0,0 +1,2 @@ +mod sidebar; +pub use sidebar::*; \ No newline at end of file diff --git a/src/components/tabs/sidebar.rs b/src/components/tabs/sidebar.rs new file mode 100644 index 0000000..166e5db --- /dev/null +++ b/src/components/tabs/sidebar.rs @@ -0,0 +1,57 @@ +use leptos::prelude::*; +use leptos_router::components::{Outlet, A}; +use leptos_router::hooks::use_location; +use crate::common::TabInfo; + +#[component] +fn SidebarTab( + #[prop(into)] name: Signal, + #[prop(into)] path: Signal +) -> impl IntoView { + let location = use_location(); + + let selected = Memo::new(move |_| { + let current_path = location.pathname.get(); + + // There's extra logic here as well, but for now this works. + current_path.starts_with(&path.get()) + }); + + view! { + +
+ {name} +
+
+ } +} + +#[component] +pub fn TabSidebarList( + #[prop(into)] tabs: Signal>, +) -> impl IntoView { + // Create a series of tabs based on a given list of names and paths. + + view! { +
+ + +
+ +
+
+ } +} diff --git a/src/pages/admin/mod.rs b/src/pages/admin/mod.rs new file mode 100644 index 0000000..d805db1 --- /dev/null +++ b/src/pages/admin/mod.rs @@ -0,0 +1,2 @@ +mod shell; +pub use shell::*; \ No newline at end of file diff --git a/src/pages/admin/shell.rs b/src/pages/admin/shell.rs new file mode 100644 index 0000000..786c3b1 --- /dev/null +++ b/src/pages/admin/shell.rs @@ -0,0 +1,49 @@ +use leptos::prelude::*; +use crate::common::TabInfo; +use crate::components::{Banner, TabSidebarList}; +use crate::components::login::AdminLoginContext; + +/// # Admin Shell Component +/// +/// This shell should keep track of pretty much everything that changes across the admin page. It +/// will provide the login context, the banner, and the tabs. +#[component] +pub fn AdminShell() -> impl IntoView { + // Create login context + view! { + + + // We'll put the tabs here. + + + } +} + +#[component] +pub fn AdminFallback() -> impl IntoView { + view! { +
+

"This is a fallback page"

+
+ } +} + +#[component] +pub fn AdminTesting() -> impl IntoView { + view! { +
+

"This is a testing page"

+
+ } +} diff --git a/src/pages/mod.rs b/src/pages/mod.rs index 4cdf400..e1bf618 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -10,9 +10,10 @@ mod unauthenticated_page; mod provider_contact; mod auth_callback; mod provider_applicants; +mod admin; pub use self::{ about_page::*, comparison_test::*, home_page::*, loaner_page::*, provider_portal::*, test_page::*, unauthenticated_page::*, scholarship_info::*, provider_contact::*, - auth_callback::*, provider_applicants::* + auth_callback::*, provider_applicants::*, admin::* };