#[cfg(feature = "ssr")] use crate::utils::server::{create_dynamo_client, into_attr_map}; 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, Toast, ToastContext, ToastList, ValidatedForm}; use crate::pages::UnauthenticatedPage; use crate::utils::get_user_claims; #[cfg(feature = "ssr")] static PROVIDER_CONTACT_TABLE: &str = "leptos-provider-contacts"; #[server] async fn get_provider_contact(id: String) -> Result, 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(PROVIDER_CONTACT_TABLE) .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::>(); 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) -> 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(PROVIDER_CONTACT_TABLE) .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::::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() }); let mut toasts_context = expect_context::(); Effect::watch( move || submit_action.value().get(), move |value, _, _| { log!("Running submit_action effect"); let Some(result) = value else { return; }; let toast = match result { Ok(_) => Toast::new() .id(uuid::Uuid::new_v4()) .header("Submission Successful") .msg("You can go back or continue editing your responses."), Err(err) => Toast::new() .id(uuid::Uuid::new_v4()) .header("Submission Failed") .msg(err.to_string()) }; untrack(move || { submit_action.clear(); toasts_context.toast(toast); }); }, false ); // Display contact form. view! {
{move || { contact_resource .get() .map(|_| { view! { } }) }}
} }