feat: implement nested routes for loaner form
We're using this as our testing ground before attempting to refactor all other pages as well.
This commit is contained in:
1 parent
8147ec3e00
commit
c693ed9190
5 files changed
+77
-23
No files matched your search
@@ -6,3 +6,6 @@ rustflags = [
|
||||
|
||||
[target.wasm32-unknown-unknown]
|
||||
rustflags = ["--cfg=web_sys_unstable_apis"]
|
||||
|
||||
[target.'cfg(target_os = "windows")']
|
||||
rustflags = ["--cfg=web_sys_unstable_apis"]
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
use crate::pages::{AboutPage, HomePage, LoanerPage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage};
|
||||
use crate::pages::{AboutPage, HomePage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm};
|
||||
use leptos::prelude::*;
|
||||
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
||||
use leptos_oidc::{Auth, AuthParameters, AuthSignal, Challenge};
|
||||
@@ -108,9 +108,10 @@ pub fn AppWithRoutes() -> impl IntoView {
|
||||
<Route path=path!(":id") view=ScholarshipInfoPage/>
|
||||
<Route path=path!("") view=ScholarshipInfoPage/>
|
||||
</ParentRoute>
|
||||
<ParentRoute path=path!("loaners") view=LoanerPage>
|
||||
<Route path=path!("") view=LoanerPage />
|
||||
<Route path=path!(":form_name") view=LoanerPage />
|
||||
<ParentRoute path=path!("loaners") view=LoanerShell>
|
||||
<Route path=path!("") view=LoanerFallback />
|
||||
<Route path=path!("borrowing") view=LoanerBorrowForm />
|
||||
<Route path=path!("returning") view=LoanerReturnForm />
|
||||
</ParentRoute>
|
||||
</Routes>
|
||||
</ToastList>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
use leptos_animate::animations::classes::{In, Out};
|
||||
|
||||
pub fn pop_in_out() -> (In, Out) {
|
||||
(
|
||||
In::default()
|
||||
.source("opacity-0 -translate-y-2 scale-90")
|
||||
.active("transition-all duration-150 transform-gpu")
|
||||
.target("opacity-100 translate-y-0 scale-100"),
|
||||
Out::default()
|
||||
.source("opacity-100 translate-y-0 scale-100")
|
||||
.active("transition-all duration-150 transform-gpu")
|
||||
.target("opacity-0 -translate-y-2 scale-90"),
|
||||
)
|
||||
}
|
||||
@@ -5,5 +5,6 @@ mod form_schema;
|
||||
mod user;
|
||||
mod value_type;
|
||||
mod submit_status;
|
||||
pub mod animations;
|
||||
|
||||
pub use self::{comparison::*, expandable_info::*, form_schema::*, user::*, value_type::*, form_params::*, submit_status::*};
|
||||
+54
-19
@@ -19,6 +19,13 @@ use leptos_router::hooks::{use_navigate, use_params};
|
||||
use leptos_router::params::Params;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use leptos_router::components::Outlet;
|
||||
use leptos_animate::animate;
|
||||
use crate::common::animations::pop_in_out;
|
||||
// Loaner page creates a single page that contains the borrowing/returning buttons
|
||||
// and a panel for a form. At first, it will show a fallback view. At the borrowing
|
||||
// path it will show the borrow form, and at the returning path it will show the
|
||||
// return form.
|
||||
|
||||
#[derive(Params, PartialEq)]
|
||||
struct LoanerParams {
|
||||
@@ -191,7 +198,7 @@ async fn create_borrow_entry(input: ExpandableInfo) -> Result<(), ServerFnError>
|
||||
/// create a true admin page for this, simply to be able to survey and override/remove information
|
||||
/// from the lists.
|
||||
#[component]
|
||||
pub fn LoanerPage() -> impl IntoView {
|
||||
pub fn LoanerShell() -> impl IntoView {
|
||||
// Check URL params. Depending on what string is visible here, we'll display a different form.
|
||||
let params = use_params::<LoanerParams>();
|
||||
let form_passed = move || {
|
||||
@@ -203,16 +210,9 @@ pub fn LoanerPage() -> impl IntoView {
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
let form_view = move || match form_passed().as_str() {
|
||||
"borrowing" => EitherOf3::A(LoanerBorrowForm),
|
||||
"returning" => EitherOf3::B(LoanerReturnForm),
|
||||
_ => EitherOf3::C("Choose something from the left.".into_view()),
|
||||
};
|
||||
|
||||
// We'll create the page here - the sidebar contains all the buttons, while the form
|
||||
// container either shows forms or shows placeholder text.
|
||||
view! {
|
||||
<ToastList>
|
||||
<Banner
|
||||
title="Chromebook Loaners"
|
||||
logo="/PHS_Stacked_Acronym.png"
|
||||
@@ -235,16 +235,36 @@ pub fn LoanerPage() -> impl IntoView {
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-2">
|
||||
<Panel>{form_view}</Panel>
|
||||
<Panel>
|
||||
<Outlet />
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ToastList>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn LoanerFallback() -> impl IntoView {
|
||||
view! {
|
||||
<div
|
||||
class="flex flex-col items-center justify-center"
|
||||
use:animate=pop_in_out()
|
||||
>
|
||||
<div class="text-3xl font-bold mb-2">
|
||||
"Chromebook Loaner Form"
|
||||
</div>
|
||||
<div class="text-lg">
|
||||
"Select an option from the left to begin."
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn LoanerBorrowForm() -> impl IntoView {
|
||||
let navigate = use_navigate();
|
||||
|
||||
// Register server actions.
|
||||
let create_entry_action = ServerAction::<CreateBorrowEntry>::new();
|
||||
|
||||
@@ -268,14 +288,17 @@ pub fn LoanerBorrowForm() -> impl IntoView {
|
||||
toast_context.toast(
|
||||
Toast::new()
|
||||
.id(uuid::Uuid::new_v4().to_string())
|
||||
.msg("From the form!")
|
||||
.header("Borrower Added!")
|
||||
.msg("You can take your loaner now.")
|
||||
);
|
||||
navigate("/loaners", Default::default());
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
view! {
|
||||
<ValidatedForm
|
||||
use:animate=pop_in_out()
|
||||
on_submit=Callback::new(on_submit)
|
||||
title="Borrower Information"
|
||||
description="Please fill out the form below."
|
||||
@@ -368,12 +391,19 @@ pub fn LoanerReturnForm() -> impl IntoView {
|
||||
|
||||
// Create an effect to run after check-in - refreshes the list with another scan request.
|
||||
// This could be beneficial if we ever decided to make multiple loaner kiosks (think SAT days)
|
||||
let mut toasts = expect_context::<ToastContext>();
|
||||
Effect::new(move || {
|
||||
if let Some(Ok(_)) = check_in_action.value().get() {
|
||||
// Return to the main page.
|
||||
if let Some(dialog) = dialog_ref.get() {
|
||||
dialog.close();
|
||||
}
|
||||
toasts.toast(
|
||||
Toast::new()
|
||||
.id(uuid::Uuid::new_v4())
|
||||
.header("Check in successful!")
|
||||
.msg("Don't forget to take your collateral.")
|
||||
);
|
||||
navigate("/loaners", Default::default());
|
||||
check_in_action.clear();
|
||||
}
|
||||
@@ -399,6 +429,7 @@ pub fn LoanerReturnForm() -> impl IntoView {
|
||||
|
||||
view! {
|
||||
<dialog
|
||||
use:animate=pop_in_out()
|
||||
class="p-3 m-auto rounded-md shadow-lg/33 backdrop:backdrop-blur-xs backdrop:transition-backdrop-filter"
|
||||
node_ref=dialog_ref>
|
||||
<h2 class="text-2xl font-bold">"Confirmation"</h2>
|
||||
@@ -414,12 +445,16 @@ pub fn LoanerReturnForm() -> impl IntoView {
|
||||
<ActionButton on:click=close_dialog disabled=dialog_disabled>"Close"</ActionButton>
|
||||
<ActionButton on:click=dialog_check_in disabled=dialog_disabled>"Check In"</ActionButton>
|
||||
</dialog>
|
||||
<div class="flex flex-col justify-center gap-2 mb-3 py-3 px-2">
|
||||
<h2 class="text-2xl font-bold">"Student List"</h2>
|
||||
<p class="text-lg">"Please select your name from the list."</p>
|
||||
</div>
|
||||
<Suspense fallback=move || "Loading...".into_view()>
|
||||
<div class="flex flex-col gap-2 m-2">
|
||||
|
||||
<div
|
||||
class="flex flex-col gap-2 m-2"
|
||||
use:animate=pop_in_out()
|
||||
>
|
||||
<div class="flex flex-col justify-center gap-2 mb-3 py-3 px-2">
|
||||
<h2 class="text-2xl font-bold">"Student List"</h2>
|
||||
<p class="text-lg">"Please select your name from the list."</p>
|
||||
</div>
|
||||
<Suspense fallback=move || "Loading...".into_view()>
|
||||
{move || {
|
||||
match return_list_resource.get() {
|
||||
Some(loaner_list) => {
|
||||
@@ -461,7 +496,7 @@ pub fn LoanerReturnForm() -> impl IntoView {
|
||||
None => Either::Right("No loaners found.".into_view())
|
||||
}
|
||||
}}
|
||||
</div>
|
||||
</Suspense>
|
||||
</Suspense>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user