feat: create sidebar tabs list
This commit is contained in:
1 parent
9e418dddf5
commit
4a2a5ca9ff
12 files changed
+158
-7
No files matched your search
+14
-1
@@ -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 {
|
||||
// <Route path=path!("/testing") view=TestPage />
|
||||
<ProviderRoutes />
|
||||
<LoanerRoutes />
|
||||
<AdminRoutes />
|
||||
</Routes>
|
||||
</ToastList>
|
||||
</main>
|
||||
@@ -101,6 +102,18 @@ fn LoanerRoutes() -> impl MatchNestedRoutes + Clone {
|
||||
.into_any_nested_route()
|
||||
}
|
||||
|
||||
#[component(transparent)]
|
||||
fn AdminRoutes() -> impl MatchNestedRoutes + Clone {
|
||||
view! {
|
||||
<ParentRoute path=path!("admin") view=AdminShell>
|
||||
<Route path=path!("home") view=AdminFallback />
|
||||
<Route path=path!("testing") view=AdminTesting />
|
||||
</ParentRoute>
|
||||
}
|
||||
.into_inner()
|
||||
.into_any_nested_route()
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn AuthErrorView() -> impl IntoView {
|
||||
let auth = use_context::<AuthSignal>().expect("AuthError: RwSignal<AuthStore> was not found");
|
||||
|
||||
+2
-1
@@ -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::*,
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TabInfo {
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
}
|
||||
@@ -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<String>,
|
||||
/// The route that the navigates user to a page (home page).
|
||||
#[prop(into, optional)]
|
||||
path: Signal<String>,
|
||||
@@ -44,7 +44,7 @@ pub fn Banner(
|
||||
<div class="flex flex-row items-center gap-4 p-6 pb-2">
|
||||
<div class="flex-shrink-0">
|
||||
<img
|
||||
src=logo.clone()
|
||||
src=logo
|
||||
class="h-10 w-10 cursor-pointer"
|
||||
alt="icon"
|
||||
on:click=on_click
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
use leptos::prelude::*;
|
||||
use crate::components::login::setup::provide_auth_context;
|
||||
|
||||
#[component]
|
||||
pub fn AdminLoginContext(
|
||||
children: Children
|
||||
) -> 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()}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
pub(crate) mod setup;
|
||||
mod provider;
|
||||
pub use provider::*;
|
||||
mod student;
|
||||
pub use student::*;
|
||||
pub(crate) mod setup;
|
||||
mod admin;
|
||||
pub use admin::*;
|
||||
@@ -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::*
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
mod sidebar;
|
||||
pub use sidebar::*;
|
||||
@@ -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<String>,
|
||||
#[prop(into)] path: Signal<String>
|
||||
) -> 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! {
|
||||
<A href={move || path.get()}>
|
||||
<div class="p-3 transition-all font-bold"
|
||||
class=(["bg-transparent", "text-white"], move || !selected.get())
|
||||
class=(["bg-white", "text-black"], move || selected.get())>
|
||||
{name}
|
||||
</div>
|
||||
</A>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn TabSidebarList(
|
||||
#[prop(into)] tabs: Signal<Vec<TabInfo>>,
|
||||
) -> impl IntoView {
|
||||
// Create a series of tabs based on a given list of names and paths.
|
||||
|
||||
view! {
|
||||
<div class="flex flex-row h-full w-full fixed">
|
||||
<nav class="flex flex-col bg-red-900 w-64 h-full overflow-scroll">
|
||||
<For
|
||||
each=move || tabs.get()
|
||||
key=|info| info.name.clone()
|
||||
let(TabInfo {name, path})
|
||||
>
|
||||
<SidebarTab
|
||||
name=name
|
||||
path=path
|
||||
/>
|
||||
</For>
|
||||
</nav>
|
||||
|
||||
<div class="flex flex-1">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
mod shell;
|
||||
pub use shell::*;
|
||||
@@ -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! {
|
||||
<AdminLoginContext>
|
||||
<Banner title="R15 Scholarships Admin" logo="/PHS_Stacked_Acronym.png" />
|
||||
// We'll put the tabs here.
|
||||
<TabSidebarList
|
||||
tabs=vec![
|
||||
TabInfo {
|
||||
name: "Home".to_string(),
|
||||
path: "/admin/home".to_string(),
|
||||
},
|
||||
TabInfo {
|
||||
name: "Test".to_string(),
|
||||
path: "/admin/testing".to_string(),
|
||||
}
|
||||
]
|
||||
/>
|
||||
</AdminLoginContext>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn AdminFallback() -> impl IntoView {
|
||||
view! {
|
||||
<div>
|
||||
<p class="mx-auto">"This is a fallback page"</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn AdminTesting() -> impl IntoView {
|
||||
view! {
|
||||
<div>
|
||||
<p class="mx-auto">"This is a testing page"</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -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::*
|
||||
};
|
||||
Reference in new issue
Block a user