feat: implement new provider contact form
This commit is contained in:
1 parent
97ad9ceee7
commit
0401027e7d
3 files changed
+211
-2
No files matched your search
+2
-1
@@ -1,4 +1,4 @@
|
||||
use crate::pages::{AboutPage, HomePage, LoanerPage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage};
|
||||
use crate::pages::{AboutPage, HomePage, LoanerPage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage};
|
||||
use leptos::leptos_dom::log;
|
||||
use leptos::prelude::*;
|
||||
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
|
||||
@@ -105,6 +105,7 @@ pub fn AppWithRoutes() -> impl IntoView {
|
||||
<Route path=path!("/test_page") view=TestPage/>
|
||||
<Route path=path!("/comparison") view=ComparisonTestPage />
|
||||
<Route path=path!("/providers") view=ProviderPortal/>
|
||||
<Route path=path!("/providers/contact") view=ProviderContactPage />
|
||||
<ParentRoute path=path!("/providers/scholarships") view=ScholarshipInfoPage>
|
||||
<Route path=path!(":id") view=ScholarshipInfoPage/>
|
||||
<Route path=path!("") view=ScholarshipInfoPage/>
|
||||
|
||||
+2
-1
@@ -8,8 +8,9 @@ mod scholarship_info;
|
||||
mod test_page;
|
||||
mod unauthenticated_page;
|
||||
mod utils;
|
||||
mod provider_contact;
|
||||
|
||||
pub use self::{
|
||||
about_page::*, comparison_test::*, home_page::*, loaner_page::*, provider_portal::*,
|
||||
test_page::*, unauthenticated_page::*, scholarship_info::*
|
||||
test_page::*, unauthenticated_page::*, scholarship_info::*, provider_contact::*
|
||||
};
|
||||
@@ -0,0 +1,207 @@
|
||||
use std::collections::HashMap;
|
||||
use leptos::logging::log;
|
||||
use leptos::prelude::*;
|
||||
use leptos_oidc::{AuthLoaded, Authenticated};
|
||||
use crate::common::ValueType;
|
||||
use crate::components::{Banner, Loading, OutlinedTextField, Panel, Row, TextFieldType, ValidatedForm};
|
||||
use crate::pages::UnauthenticatedPage;
|
||||
use crate::pages::utils::get_user_claims;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
use crate::pages::utils::server_utils::create_dynamo_client;
|
||||
|
||||
#[cfg(feature = "ssr")]
|
||||
fn into_attr_map(map: HashMap<String, ValueType>) -> HashMap<String, aws_sdk_dynamodb::types::AttributeValue> {
|
||||
map.into_iter().map(|(k, v)| (k, v.into())).collect()
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn get_provider_contact(id: String) -> Result<HashMap<String, ValueType>, ServerFnError> {
|
||||
use aws_sdk_dynamodb::types::AttributeValue;
|
||||
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
|
||||
|
||||
let client = create_dynamo_client().await;
|
||||
|
||||
log!("Getting contact info for provider {}", id);
|
||||
|
||||
match client
|
||||
.get_item()
|
||||
.table_name("leptos-provider-contacts")
|
||||
.key("subject", AttributeValue::S(id))
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(output) => {
|
||||
let Some(item) = output.item else {
|
||||
return Ok(HashMap::new());
|
||||
};
|
||||
|
||||
let map = item.iter().map(|(key, val)| {
|
||||
let val_type = ValueType::from(val);
|
||||
|
||||
(key.clone(), val_type)
|
||||
}).collect::<HashMap<String, ValueType>>();
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
Err(err) => {
|
||||
let msg = err.message().unwrap_or("An unknown error occurred.");
|
||||
Err(ServerFnError::new(msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[server]
|
||||
async fn put_provider_contact(id: String, contact_info: HashMap<String, ValueType>) -> Result<(), ServerFnError> {
|
||||
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
|
||||
|
||||
let client = create_dynamo_client().await;
|
||||
|
||||
let mut item = into_attr_map(contact_info);
|
||||
item.insert("subject".to_owned(), aws_sdk_dynamodb::types::AttributeValue::S(id));
|
||||
|
||||
match client
|
||||
.put_item()
|
||||
.table_name("leptos-provider-contacts")
|
||||
.set_item(Some(item))
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
let msg = err.message().unwrap_or("An unknown error occurred.");
|
||||
Err(ServerFnError::new(msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ProviderContactPage() -> impl IntoView {
|
||||
// Get user claims
|
||||
let user_claims = get_user_claims();
|
||||
let user_id = Memo::new(move |_| {
|
||||
user_claims.get()
|
||||
.map(|info| info.claims.subject.clone())
|
||||
});
|
||||
|
||||
// Get contact information
|
||||
let contact_info = RwSignal::new(HashMap::new());
|
||||
let contact_resource = Resource::new(
|
||||
move || user_id.get(),
|
||||
async move |id| {
|
||||
let Some(id) = id else {
|
||||
return Ok(HashMap::new());
|
||||
};
|
||||
|
||||
get_provider_contact(id).await
|
||||
}
|
||||
);
|
||||
|
||||
Effect::new(move || {
|
||||
match contact_resource.get() {
|
||||
Some(Ok(map)) => contact_info.set(map),
|
||||
Some(Err(e)) => log!("Error getting contact info: {}", e),
|
||||
None => log!("Contact info resource is not ready yet."),
|
||||
}
|
||||
});
|
||||
|
||||
// Set up submit action
|
||||
let submit_action = ServerAction::<PutProviderContact>::new();
|
||||
|
||||
let on_submit = move || {
|
||||
// Submit the form by reading the contact_info.
|
||||
submit_action.dispatch(PutProviderContact {
|
||||
id: user_id.get().unwrap_or_default(),
|
||||
contact_info: contact_info.get()
|
||||
});
|
||||
};
|
||||
|
||||
let elements_disabled = Signal::derive(move || {
|
||||
submit_action.pending().get()
|
||||
});
|
||||
|
||||
// Display contact form.
|
||||
view! {
|
||||
<Banner
|
||||
title="R15 Scholarships"
|
||||
logo="/PHS_Stacked_Acronym.png"
|
||||
path="/"
|
||||
/>
|
||||
<AuthLoaded fallback=Loading>
|
||||
<Authenticated unauthenticated=UnauthenticatedPage>
|
||||
<Suspense fallback=Loading>
|
||||
<Panel>
|
||||
<ValidatedForm on_submit=on_submit>
|
||||
{move || contact_resource.get()
|
||||
.map(|_| {
|
||||
view! {
|
||||
<Row>
|
||||
<OutlinedTextField
|
||||
label="First Name:"
|
||||
placeholder="John"
|
||||
disabled=elements_disabled
|
||||
data_member="first_name"
|
||||
data_map=contact_info
|
||||
required=true
|
||||
/>
|
||||
<OutlinedTextField
|
||||
label="Last Name:"
|
||||
placeholder="Smith"
|
||||
disabled=elements_disabled
|
||||
data_member="last_name"
|
||||
data_map=contact_info
|
||||
required=true
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
<OutlinedTextField
|
||||
label="Contact Email:"
|
||||
placeholder="student@region15.org"
|
||||
disabled=elements_disabled
|
||||
data_member="contact_email"
|
||||
data_map=contact_info
|
||||
input_type=TextFieldType::Email
|
||||
required=true
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
<OutlinedTextField
|
||||
label="Phone Number:"
|
||||
placeholder="123-456-7890"
|
||||
disabled=elements_disabled
|
||||
data_member="phone_number"
|
||||
data_map=contact_info
|
||||
required=true
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
<OutlinedTextField
|
||||
label="Street Address:"
|
||||
placeholder="123 Fake Street"
|
||||
disabled=elements_disabled
|
||||
data_member="address"
|
||||
data_map=contact_info
|
||||
required=true
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
<OutlinedTextField
|
||||
label="Testing Number"
|
||||
placeholder="Just put a number"
|
||||
disabled=elements_disabled
|
||||
data_member="testing_number"
|
||||
data_map=contact_info
|
||||
input_type=TextFieldType::Number
|
||||
required=true
|
||||
/>
|
||||
</Row>
|
||||
}
|
||||
})
|
||||
}
|
||||
</ValidatedForm>
|
||||
</Panel>
|
||||
</Suspense>
|
||||
</Authenticated>
|
||||
</AuthLoaded>
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user