feat: make toasts available on all routes
This commit is contained in:
1 parent
865410b6f2
commit
de7b8633ff
4 files changed
+121
-96
No files matched your search
+20
-17
@@ -3,6 +3,7 @@ use leptos::prelude::*;
|
|||||||
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
||||||
use leptos_oidc::{Auth, AuthParameters, AuthSignal, Challenge};
|
use leptos_oidc::{Auth, AuthParameters, AuthSignal, Challenge};
|
||||||
use leptos_router::{components::{Route, Router, Routes, ParentRoute}, path};
|
use leptos_router::{components::{Route, Router, Routes, ParentRoute}, path};
|
||||||
|
use crate::components::ToastList;
|
||||||
|
|
||||||
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
@@ -94,23 +95,25 @@ pub fn AppWithRoutes() -> impl IntoView {
|
|||||||
<Title text="R15 Scholarship App DEV" />
|
<Title text="R15 Scholarship App DEV" />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
// TODO Create a 404 page
|
<ToastList>
|
||||||
<Routes fallback=|| "Page not found.".into_view()>
|
// TODO Create a 404 page
|
||||||
<Route path=path!("") view=HomePage/>
|
<Routes fallback=|| "Page not found.".into_view()>
|
||||||
<Route path=path!("/about") view=AboutPage/>
|
<Route path=path!("") view=HomePage/>
|
||||||
<Route path=path!("/test_page") view=TestPage/>
|
<Route path=path!("/about") view=AboutPage/>
|
||||||
<Route path=path!("/comparison") view=ComparisonTestPage />
|
<Route path=path!("/test_page") view=TestPage/>
|
||||||
<Route path=path!("/providers") view=ProviderPortal/>
|
<Route path=path!("/comparison") view=ComparisonTestPage />
|
||||||
<Route path=path!("/providers/profile") view=ProviderContactPage />
|
<Route path=path!("/providers") view=ProviderPortal/>
|
||||||
<ParentRoute path=path!("/providers/scholarships") view=ScholarshipInfoPage>
|
<Route path=path!("/providers/profile") view=ProviderContactPage />
|
||||||
<Route path=path!(":id") view=ScholarshipInfoPage/>
|
<ParentRoute path=path!("/providers/scholarships") view=ScholarshipInfoPage>
|
||||||
<Route path=path!("") view=ScholarshipInfoPage/>
|
<Route path=path!(":id") view=ScholarshipInfoPage/>
|
||||||
</ParentRoute>
|
<Route path=path!("") view=ScholarshipInfoPage/>
|
||||||
<ParentRoute path=path!("loaners") view=LoanerPage>
|
</ParentRoute>
|
||||||
<Route path=path!("") view=LoanerPage />
|
<ParentRoute path=path!("loaners") view=LoanerPage>
|
||||||
<Route path=path!(":form_name") view=LoanerPage />
|
<Route path=path!("") view=LoanerPage />
|
||||||
</ParentRoute>
|
<Route path=path!(":form_name") view=LoanerPage />
|
||||||
</Routes>
|
</ParentRoute>
|
||||||
|
</Routes>
|
||||||
|
</ToastList>
|
||||||
</main>
|
</main>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::components::toasts::toast::Toast;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Toast {
|
pub struct Toast {
|
||||||
id: String,
|
id: String,
|
||||||
|
header: String,
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,10 +12,16 @@ impl Toast {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Toast {
|
Toast {
|
||||||
id: "".to_owned(),
|
id: "".to_owned(),
|
||||||
|
header: "".to_owned(),
|
||||||
message: "".to_owned(),
|
message: "".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(mut self, header: impl Into<String>) -> Self {
|
||||||
|
self.header = header.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn msg(mut self, msg: impl Into<String>) -> Self {
|
pub fn msg(mut self, msg: impl Into<String>) -> Self {
|
||||||
self.message = msg.into();
|
self.message = msg.into();
|
||||||
self
|
self
|
||||||
@@ -61,11 +68,11 @@ pub fn ToastList(
|
|||||||
<For
|
<For
|
||||||
each=move || context.messages.get()
|
each=move || context.messages.get()
|
||||||
key=|toast| toast.id.clone()
|
key=|toast| toast.id.clone()
|
||||||
let(Toast { id, message })
|
let(Toast { id, header, message })
|
||||||
>
|
>
|
||||||
<Toast
|
<Toast
|
||||||
message=message
|
message=message
|
||||||
title="Testing Toast"
|
title=header
|
||||||
on_close=move || {
|
on_close=move || {
|
||||||
context.messages.update(|list|
|
context.messages.update(|list|
|
||||||
list.retain(|v| v.id != id)
|
list.retain(|v| v.id != id)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ pub fn ValidatedForm(
|
|||||||
}
|
}
|
||||||
button_type="submit"
|
button_type="submit"
|
||||||
>
|
>
|
||||||
"Submit form (but actually)"
|
"Submit"
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use leptos::logging::log;
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos_oidc::{AuthLoaded, Authenticated};
|
use leptos_oidc::{AuthLoaded, Authenticated};
|
||||||
use crate::common::ValueType;
|
use crate::common::ValueType;
|
||||||
use crate::components::{Banner, Loading, OutlinedTextField, Panel, Row, TextFieldType, ValidatedForm};
|
use crate::components::{Banner, Loading, OutlinedTextField, Panel, Row, TextFieldType, Toast, ToastContext, ToastList, ValidatedForm};
|
||||||
use crate::pages::UnauthenticatedPage;
|
use crate::pages::UnauthenticatedPage;
|
||||||
use crate::pages::utils::get_user_claims;
|
use crate::pages::utils::get_user_claims;
|
||||||
|
|
||||||
@@ -120,86 +120,101 @@ pub fn ProviderContactPage() -> impl IntoView {
|
|||||||
submit_action.pending().get()
|
submit_action.pending().get()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut toasts_context = expect_context::<ToastContext>();
|
||||||
|
Effect::new(move || {
|
||||||
|
submit_action.value().get().is_some()
|
||||||
|
.then(|| {
|
||||||
|
toasts_context.toast(
|
||||||
|
Toast::new()
|
||||||
|
.id(uuid::Uuid::new_v4())
|
||||||
|
.header("Submission Successful")
|
||||||
|
.msg("You can go back or continue editing your responses.")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Display contact form.
|
// Display contact form.
|
||||||
view! {
|
view! {
|
||||||
<Banner
|
<Banner title="R15 Scholarships" logo="/PHS_Stacked_Acronym.png" path="/" />
|
||||||
title="R15 Scholarships"
|
|
||||||
logo="/PHS_Stacked_Acronym.png"
|
|
||||||
path="/"
|
|
||||||
/>
|
|
||||||
<AuthLoaded fallback=Loading>
|
<AuthLoaded fallback=Loading>
|
||||||
<Authenticated unauthenticated=UnauthenticatedPage>
|
<Authenticated unauthenticated=UnauthenticatedPage>
|
||||||
<Suspense fallback=Loading>
|
<Suspense fallback=Loading>
|
||||||
<Panel>
|
<div class="flex flex-row">
|
||||||
<ValidatedForm on_submit=on_submit>
|
<div class="flex flex-col flex-1" />
|
||||||
{move || contact_resource.get()
|
<Panel>
|
||||||
.map(|_| {
|
<ValidatedForm on_submit=on_submit>
|
||||||
view! {
|
{move || {
|
||||||
<Row>
|
contact_resource
|
||||||
<OutlinedTextField
|
.get()
|
||||||
label="First Name:"
|
.map(|_| {
|
||||||
placeholder="John"
|
view! {
|
||||||
disabled=elements_disabled
|
<Row>
|
||||||
data_member="first_name"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="First Name:"
|
||||||
required=true
|
placeholder="John"
|
||||||
/>
|
disabled=elements_disabled
|
||||||
<OutlinedTextField
|
data_member="first_name"
|
||||||
label="Last Name:"
|
data_map=contact_info
|
||||||
placeholder="Smith"
|
required=true
|
||||||
disabled=elements_disabled
|
/>
|
||||||
data_member="last_name"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="Last Name:"
|
||||||
required=true
|
placeholder="Smith"
|
||||||
/>
|
disabled=elements_disabled
|
||||||
</Row>
|
data_member="last_name"
|
||||||
<Row>
|
data_map=contact_info
|
||||||
<OutlinedTextField
|
required=true
|
||||||
label="Contact Email:"
|
/>
|
||||||
placeholder="student@region15.org"
|
</Row>
|
||||||
disabled=elements_disabled
|
<Row>
|
||||||
data_member="contact_email"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="Contact Email:"
|
||||||
input_type=TextFieldType::Email
|
placeholder="student@region15.org"
|
||||||
required=true
|
disabled=elements_disabled
|
||||||
/>
|
data_member="contact_email"
|
||||||
</Row>
|
data_map=contact_info
|
||||||
<Row>
|
input_type=TextFieldType::Email
|
||||||
<OutlinedTextField
|
required=true
|
||||||
label="Phone Number:"
|
/>
|
||||||
placeholder="123-456-7890"
|
</Row>
|
||||||
disabled=elements_disabled
|
<Row>
|
||||||
data_member="phone_number"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="Phone Number:"
|
||||||
required=true
|
placeholder="123-456-7890"
|
||||||
/>
|
disabled=elements_disabled
|
||||||
</Row>
|
data_member="phone_number"
|
||||||
<Row>
|
data_map=contact_info
|
||||||
<OutlinedTextField
|
required=true
|
||||||
label="Street Address:"
|
/>
|
||||||
placeholder="123 Fake Street"
|
</Row>
|
||||||
disabled=elements_disabled
|
<Row>
|
||||||
data_member="address"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="Street Address:"
|
||||||
required=true
|
placeholder="123 Fake Street"
|
||||||
/>
|
disabled=elements_disabled
|
||||||
</Row>
|
data_member="address"
|
||||||
<Row>
|
data_map=contact_info
|
||||||
<OutlinedTextField
|
required=true
|
||||||
label="Testing Number"
|
/>
|
||||||
placeholder="Just put a number"
|
</Row>
|
||||||
disabled=elements_disabled
|
<Row>
|
||||||
data_member="testing_number"
|
<OutlinedTextField
|
||||||
data_map=contact_info
|
label="Testing Number"
|
||||||
input_type=TextFieldType::Number
|
placeholder="Just put a number"
|
||||||
required=true
|
disabled=elements_disabled
|
||||||
/>
|
data_member="testing_number"
|
||||||
</Row>
|
data_map=contact_info
|
||||||
}
|
input_type=TextFieldType::Number
|
||||||
})
|
required=true
|
||||||
}
|
/>
|
||||||
</ValidatedForm>
|
</Row>
|
||||||
</Panel>
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</ValidatedForm>
|
||||||
|
</Panel>
|
||||||
|
<div class="flex flex-col flex-1" />
|
||||||
|
</div>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Authenticated>
|
</Authenticated>
|
||||||
</AuthLoaded>
|
</AuthLoaded>
|
||||||
|
|||||||
Reference in new issue
Block a user