feat: implement applicant page shell
This commit is contained in:
1 parent
2e134fb693
commit
05b865c608
2 files changed
+83
-31
No files matched your search
+4
-2
@@ -1,11 +1,11 @@
|
|||||||
use crate::components::ToastList;
|
use crate::components::ToastList;
|
||||||
use crate::components::login::ProviderLoginContext;
|
use crate::components::login::ProviderLoginContext;
|
||||||
use crate::pages::student;
|
|
||||||
use crate::pages::{
|
use crate::pages::{
|
||||||
AdminHomePage, AdminProviderPage, AdminScholarshipPage, AdminShell, AdminUtilsPage,
|
AdminHomePage, AdminProviderPage, AdminScholarshipPage, AdminShell, AdminUtilsPage,
|
||||||
ApplicantsPageFallback, AuthCallbackPage, LoanerBorrowForm, LoanerFallback, LoanerReturnForm,
|
ApplicantsPageFallback, AuthCallbackPage, LoanerBorrowForm, LoanerFallback, LoanerReturnForm,
|
||||||
LoanerShell, ProviderContactPage, ProviderPortal, ScholarshipInfoPage,
|
LoanerShell, ProviderContactPage, ProviderPortal, ScholarshipInfoPage,
|
||||||
};
|
};
|
||||||
|
use crate::pages::{ApplicantsPageShell, student};
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
||||||
use leptos_oidc::AuthSignal;
|
use leptos_oidc::AuthSignal;
|
||||||
@@ -86,7 +86,9 @@ fn ProviderRoutes() -> impl MatchNestedRoutes + Clone {
|
|||||||
view! {
|
view! {
|
||||||
<ParentRoute path=path!("/providers") view=ProviderLoginContext>
|
<ParentRoute path=path!("/providers") view=ProviderLoginContext>
|
||||||
<Route path=path!("") view=ProviderPortal />
|
<Route path=path!("") view=ProviderPortal />
|
||||||
<Route path=path!("/applicants") view=ApplicantsPageFallback />
|
<ParentRoute path=path!("/applicants") view=ApplicantsPageShell>
|
||||||
|
<Route path=path!("") view=ApplicantsPageFallback />
|
||||||
|
</ParentRoute>
|
||||||
<Route path=path!("/callback") view=AuthCallbackPage />
|
<Route path=path!("/callback") view=AuthCallbackPage />
|
||||||
<Route path=path!("/profile") view=ProviderContactPage />
|
<Route path=path!("/profile") view=ProviderContactPage />
|
||||||
// <Route path=path!("/scholarships") view=FormClosedPage />
|
// <Route path=path!("/scholarships") view=FormClosedPage />
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
use crate::common::ValueType;
|
use crate::common::{ExpandableInfo, ValueType};
|
||||||
use crate::components::{Banner, Loading};
|
use crate::components::{Banner, Loading};
|
||||||
use leptos::either::Either;
|
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos_oidc::AuthSignal;
|
use leptos_oidc::AuthSignal;
|
||||||
|
use leptos_router::components::Outlet;
|
||||||
|
use leptos_router::hooks::use_navigate;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ApplicantsPageFallback() -> impl IntoView {
|
pub fn ApplicantsPageFallback() -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
<Banner title="R15 Scholarships" logo="/PHS_Stacked_Acronym.png" path="/providers" />
|
<div class="flex flex-col flex-1 gap-2">
|
||||||
<div class="flex flex-col gap-4 mt-3 items-center justify-center">
|
<h1 class="flex-1 text-center font-bold text-2xl">"Scholarship Applicants"</h1>
|
||||||
<h1 class="text-3xl font-bold">"Applicants Page"</h1>
|
<p class="text-center text-lg">
|
||||||
|
"Please select a scholarship from the left to view the eligible applicants."
|
||||||
<p>
|
|
||||||
"This page is under construction! It will show all the students that are eligible for your scholarship(s)."
|
|
||||||
</p>
|
</p>
|
||||||
<p>"Come back soon!"</p>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,7 +27,19 @@ pub fn ApplicantsPageShell() -> impl IntoView {
|
|||||||
// The content will be shown within the right side, but only as a result of some subroutes,
|
// The content will be shown within the right side, but only as a result of some subroutes,
|
||||||
// each of which is still considered a single page.
|
// each of which is still considered a single page.
|
||||||
|
|
||||||
view! { <div></div> }
|
view! {
|
||||||
|
<Banner title="R15 Scholarships" logo="/PHS_Stacked_Acronym.png" path="/providers" />
|
||||||
|
<div class="flex flex-row mt-5">
|
||||||
|
<div class="flex-1" />
|
||||||
|
<div class="flex-3 flex flex-row">
|
||||||
|
<ApplicantsScholarshipList />
|
||||||
|
<div class="flex-3 text-center">
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
@@ -82,8 +92,17 @@ fn ApplicantsScholarshipList() -> impl IntoView {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let navigate = use_navigate();
|
||||||
|
|
||||||
|
// This closure returns another closure that's using the correct scholarship ID.
|
||||||
|
// It avoids having to define it within the Transition component. It's wrapped in a Callback
|
||||||
|
// because this makes it Send + Sync.
|
||||||
|
let on_view_click = Callback::new(move |scholarship_id: String| {
|
||||||
|
navigate(&*scholarship_id, Default::default());
|
||||||
|
});
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="flex flex-col rounded-md shadow-lg/33 p-2">
|
<div class="flex flex-col flex-1 rounded-md shadow-lg/33 p-2 gap-3">
|
||||||
<h2 class="text-xl font-bold flex-1 text-center">"Scholarships"</h2>
|
<h2 class="text-xl font-bold flex-1 text-center">"Scholarships"</h2>
|
||||||
<Transition fallback=Loading>
|
<Transition fallback=Loading>
|
||||||
{move || {
|
{move || {
|
||||||
@@ -93,26 +112,28 @@ fn ApplicantsScholarshipList() -> impl IntoView {
|
|||||||
let items = match items_res {
|
let items = match items_res {
|
||||||
Ok(items) => items,
|
Ok(items) => items,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Either::Left(
|
return view! {
|
||||||
view! {
|
<div>
|
||||||
<div>
|
{format!("Couldn't get scholarships: {}", e.to_string())}
|
||||||
{format!("Couldn't get scholarships: {}", e.to_string())}
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
.into_any();
|
||||||
.into_any(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Either::Right(
|
|
||||||
items
|
|
||||||
.into_iter()
|
|
||||||
.map(|item| {
|
|
||||||
|
|
||||||
view! { <ApplicantsScholarshipEntry /> }
|
view! {
|
||||||
.into_any()
|
<For
|
||||||
})
|
each=move || items.clone()
|
||||||
.collect_view(),
|
key=|item| item.subject.clone()
|
||||||
)
|
let(item)
|
||||||
|
>
|
||||||
|
<ApplicantsScholarshipEntry
|
||||||
|
item=item
|
||||||
|
on_view_click=on_view_click
|
||||||
|
/>
|
||||||
|
</For>
|
||||||
|
}
|
||||||
|
.into_any()
|
||||||
})
|
})
|
||||||
.collect_view()
|
.collect_view()
|
||||||
}}
|
}}
|
||||||
@@ -122,7 +143,36 @@ fn ApplicantsScholarshipList() -> impl IntoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn ApplicantsScholarshipEntry() -> impl IntoView {}
|
fn ApplicantsScholarshipEntry(
|
||||||
|
#[prop()] item: ExpandableInfo,
|
||||||
|
#[prop(into)] on_view_click: Callback<String, ()>,
|
||||||
|
) -> impl IntoView {
|
||||||
|
// Store the item's subject.
|
||||||
|
let subject = StoredValue::new(item.subject);
|
||||||
|
let scholarship_name = Memo::new(move |_| {
|
||||||
|
item.data
|
||||||
|
.get("name")
|
||||||
|
.map(|name| name.as_string().ok().flatten())
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or("<unnamed scholarship>".to_string())
|
||||||
|
});
|
||||||
|
|
||||||
|
let on_click = move |_| {
|
||||||
|
on_view_click.run(subject.get_value());
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class="flex flex-col rounded-md shadow-md hover:shadow-lg/33 transition-shadow">
|
||||||
|
<div class="text-center p-2">{scholarship_name}</div>
|
||||||
|
<div
|
||||||
|
class="flex-1 font-bold text-white rounded-b-md text-center cursor-pointer bg-red-800 hover:bg-red-900 p-2 transition-bg"
|
||||||
|
on:click=on_click
|
||||||
|
>
|
||||||
|
"View Applicants"
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn ApplicantsStudentList() -> impl IntoView {}
|
fn ApplicantsStudentList() -> impl IntoView {}
|
||||||
Reference in new issue
Block a user