diff --git a/src/pages/api/mod.rs b/src/pages/api/mod.rs index a34655e..fb8c5e8 100644 --- a/src/pages/api/mod.rs +++ b/src/pages/api/mod.rs @@ -3,6 +3,7 @@ mod scholarships; mod dates; mod admin; mod providers; +pub mod students; pub use comparisons::*; pub use scholarships::*; @@ -21,3 +22,6 @@ pub static SCHOLARSHIPS_TABLE: &str = "leptos-scholarships"; #[cfg(feature = "ssr")] pub static PROVIDER_CONTACT_TABLE: &str = "leptos-provider-contacts"; + +#[cfg(feature = "ssr")] +pub static MAIN_TABLE_NAME: &str = "scholarships-main"; diff --git a/src/pages/api/students.rs b/src/pages/api/students.rs new file mode 100644 index 0000000..c965d56 --- /dev/null +++ b/src/pages/api/students.rs @@ -0,0 +1,77 @@ +use leptos::prelude::*; + +#[server] +pub async fn put_student_data( + subject: String, + data_type: String, + data_map: std::collections::HashMap +) -> Result<(), ServerFnError> { + use leptos::logging::log; + use crate::utils::server::{create_dynamo_client, into_attr_map}; + use aws_sdk_dynamodb::types::AttributeValue; + use super::MAIN_TABLE_NAME; + + let client = create_dynamo_client().await; + + let mut data_map_attr = into_attr_map(data_map); + data_map_attr.insert( + "HK".into(), + AttributeValue::S(format!("STUDENT#{}", subject)) + ); + data_map_attr.insert( + "SK".into(), + AttributeValue::S(data_type.to_uppercase()) + ); + + log!("Inserting this item: {:?}", data_map_attr); + + client + .put_item() + .table_name(MAIN_TABLE_NAME) + .set_item(Some(data_map_attr)) + .send() + .await + .map(|_| ()) + .map_err(ServerFnError::from) +} + +#[server] +pub async fn get_student_data( + subject: String, + data_type: String, +) -> Result, ServerFnError> { + use crate::utils::server::create_dynamo_client; + use std::collections::HashMap; + use crate::common::ValueType; + use aws_sdk_dynamodb::types::AttributeValue; + use super::MAIN_TABLE_NAME; + + let client = create_dynamo_client().await; + + client + .query() + .table_name(MAIN_TABLE_NAME) + .key_condition_expression("HK = :hk AND SK = :sk") + .expression_attribute_values(":hk", AttributeValue::S(format!("STUDENT#{}", subject))) + .expression_attribute_values(":sk", AttributeValue::S(data_type.to_uppercase())) + .send() + .await + .map(|output| { + // Map the output to a HashMap + let Some(list) = output.items else { + return HashMap::new(); + }; + + let mut map = HashMap::new(); + + let _ = list + .into_iter() + .flatten() + .for_each(|(k, v)| { + map.insert(k, ValueType::from(&v)); + }); + + map + }) + .map_err(ServerFnError::from) +} diff --git a/src/pages/student/academics_page.rs b/src/pages/student/academics_page.rs index dc67bbe..559aa7b 100644 --- a/src/pages/student/academics_page.rs +++ b/src/pages/student/academics_page.rs @@ -1,18 +1,18 @@ -use std::collections::HashMap; -use leptos::prelude::*; +use leptos::prelude::*; use crate::components::{OutlinedTextField, TextFieldType, ValidatedForm}; +use crate::pages::student::form_setup::use_student_form; #[component] pub fn StudentAcademicsPage() -> impl IntoView { - let data_map = RwSignal::new(HashMap::new()); + let controller = use_student_form("academics"); view! {
- + impl IntoView { /> impl IntoView { /> impl IntoView { /> impl IntoView { /> impl IntoView { - let data_map = RwSignal::new(HashMap::new()); + let controller = use_student_form("athletics"); view! {
- + >, + pub user_id: Memo>, + pub submit_action: Callback<()>, + pub refresh_trigger: Trigger, + pub data_resource: Resource, ServerFnError>> +} + +pub fn use_student_form( + form_type: impl Into> +) -> StudentFormInfo { + let form_type = form_type.into(); + + let user_claims = get_user_claims(); + let user_id = Memo::new(move |_| { + user_claims.get() + .map(|info| info.claims.subject.clone()) + }); + + let data_map = RwSignal::new(HashMap::new()); + + let refresh_trigger = Trigger::new(); + let data_resource = Resource::new( + move || (user_id.get().unwrap_or_default(), form_type.get(), refresh_trigger.track()), + async move |(id, form_type, _)| get_student_data( + id, + form_type, + ).await + ); + + Effect::new(move || { + data_resource.with(|map_opt| { + let Some(Ok(map)) = map_opt else { + return; + }; + + data_map.set(map.to_owned()); + }); + }); + + let submit_action = ServerAction::::new(); + let on_submit = move || { + submit_action.dispatch(PutStudentData { + subject: user_id.get().unwrap_or_default(), + data_type: form_type.get(), + data_map: data_map.get() + }); + }; + + StudentFormInfo { + data_map, + refresh_trigger, + data_resource, + user_id, + submit_action: on_submit.into(), + } +} \ No newline at end of file diff --git a/src/pages/student/home_page.rs b/src/pages/student/home_page.rs index 3b5bf0e..f370932 100644 --- a/src/pages/student/home_page.rs +++ b/src/pages/student/home_page.rs @@ -1,13 +1,55 @@ +use std::collections::HashMap; +use leptos::logging::log; use leptos::prelude::*; +use crate::common::ValueType; +use crate::components::ActionButton; +use crate::pages::api::students::{GetStudentData, PutStudentData}; +use crate::utils::get_user_claims; #[component] pub fn StudentHomePage() -> impl IntoView { + let user_claims = get_user_claims(); + let user_id = Memo::new(move |_| { + user_claims.get() + .map(|info| info.claims.subject.clone()) + }); + + let create_student_data = ServerAction::::new(); + let get_student_data = ServerAction::::new(); + + let on_click_student_test = move |_| { + create_student_data.dispatch(PutStudentData { + subject: user_id.get().unwrap_or_default(), + data_type: "TESTING".into(), + data_map: HashMap::from([ + ("testing_info".into(), ValueType::String(Some("hello!".to_string()))) + ]), + }); + }; + + let on_click_get_student = move |_| { + get_student_data.dispatch(GetStudentData { + subject: user_id.get().unwrap_or_default(), + data_type: "TESTING".into() + }); + }; + + Effect::new(move || { + let Some(value) = get_student_data.value().get() else { + return; + }; + + log!("{:?}", value); + }); + view! {
"Student Home Page"
"This is just a placeholder for now. We'll show some redirect buttons."
+ "Test Put Student Function" + "Test Get Student Function"
} } diff --git a/src/pages/student/mod.rs b/src/pages/student/mod.rs index e24b8b2..61275ce 100644 --- a/src/pages/student/mod.rs +++ b/src/pages/student/mod.rs @@ -8,6 +8,7 @@ mod extracurriculars_page; mod work_experience_page; mod university_page; mod family_info_page; +mod form_setup; pub use shell::*; pub use home_page::*;