diff --git a/src/common/student_info.rs b/src/common/student_info.rs index 1533782..ca617a4 100644 --- a/src/common/student_info.rs +++ b/src/common/student_info.rs @@ -1,11 +1,12 @@ -use crate::components::MultiEntryData; +use crate::components::{MultiEntryData, ValueType}; use macros::Reactive; use serde::{Deserialize, Serialize}; use std::default::Default; use chrono::{DateTime, Utc}; +use reactive_stores::Store; /// Represents information about a student. -#[derive(Serialize, Deserialize, Debug, Clone, Reactive, Default)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, Store, Reactive)] pub struct StudentInfo { /// The email address of the student. This was used in the previous version of the database, /// and should now be deprecated. @@ -14,32 +15,36 @@ pub struct StudentInfo { pub Email: String, /// The student's first name. #[serde(default)] - pub first_name: String, + pub first_name: ValueType, // String /// The student's last name. #[serde(default)] - pub last_name: String, + pub last_name: ValueType, // String /// The student's highest math score on the SAT. - #[serde(default)] - pub math_sat: i32, + #[serde(default = "default_number")] + pub math_sat: ValueType, // Number /// The student's desired contact email. #[serde(default)] - pub contact_email: String, + pub contact_email: ValueType, // String /// The student's address. #[serde(default)] - pub address: String, + pub address: ValueType, // String /// The student's town of residence. #[serde(default)] - pub town: String, + pub town: ValueType, // String /// The student's entered phone number. #[serde(default)] - pub phone_number: String, // May be stored as a straight number in the future. + pub phone_number: ValueType, // May be stored as a straight number in the future, but String /// The student's birthdate. #[serde(default)] pub birth_date: DateTime, /// The student's gender. #[serde(default)] - pub gender: String, + pub gender: ValueType, // String /// The student's athletic information. #[serde(default)] pub athletic_info: Vec, } + +fn default_number() -> ValueType { + ValueType::Number(0) +} \ No newline at end of file diff --git a/src/components/multi_entry/multi_entry.rs b/src/components/multi_entry/multi_entry.rs index 536f3c9..1e85385 100644 --- a/src/components/multi_entry/multi_entry.rs +++ b/src/components/multi_entry/multi_entry.rs @@ -9,7 +9,7 @@ use super::{multi_entry_data::*, multi_entry_member::*}; fn render_entry_component(entry_data: MultiEntryData, member_info: MultiEntryMember, label: String) -> impl IntoView { // Parse the multientry members into the correct components let data = entry_data.data.get(&member_info.member_name); - let reactive = RwSignal::new(data.unwrap().as_string().unwrap()); + let reactive = RwSignal::new(data.unwrap().clone()); let temp = either!(member_info.input_type, InputType::Text => view! { {render_entry_component(data, input, "test".to_owned())} + //
{render_entry_component(data, input, "test".to_owned())}
} }).collect::>() } diff --git a/src/components/multi_entry/value_type.rs b/src/components/multi_entry/value_type.rs index fbe78d2..8b8d7fb 100644 --- a/src/components/multi_entry/value_type.rs +++ b/src/components/multi_entry/value_type.rs @@ -59,6 +59,12 @@ impl ValueType { } } +impl Default for ValueType { + fn default() -> Self { + ValueType::String(String::new()) + } +} + impl Display for ValueType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let str = match self { diff --git a/src/components/text_field.rs b/src/components/text_field.rs index 46f8c4e..51d2dba 100644 --- a/src/components/text_field.rs +++ b/src/components/text_field.rs @@ -1,32 +1,42 @@ use leptos::prelude::*; -use std::str::FromStr; +use crate::components::ValueType; #[component] -pub fn OutlinedTextField( - #[prop(optional, into)] placeholder: T, - #[prop(optional)] value: RwSignal, +pub fn OutlinedTextField( + #[prop(optional, into)] placeholder: String, + // #[prop()] value: Subfield, + #[prop()] value: RwSignal, #[prop(optional)] disabled: RwSignal, #[prop(optional)] error: RwSignal, #[prop(optional, into)] name: String, #[prop(optional, into)] label: String, #[prop(optional, into)] input_type: String, -) -> impl IntoView -where - T: Default + 'static + FromStr + ToString + PartialEq + Send + Sync + Clone, -{ - // Parsing logic for non-string types which happens on each input. + #[prop(optional, into)] error_text: RwSignal +) -> impl IntoView { + // Check if the type is one of the supported formats. This input will only accept a string + // or a number value. let on_input = move |e| { - let input_value = event_target_value(&e); - let can_parse = T::from_str(&input_value); - if let Ok(parsed_value) = can_parse { - value.set(parsed_value); - } else { - error.set(true); - value.set(T::default()); + match value.get() { + ValueType::String(_) => { + // Define string parse function. + value.set(ValueType::String(event_target_value(&e))); + }, + ValueType::Number(_) => { + // Define number parse function. + let temp = event_target_value(&e); + value.set(ValueType::Number(temp.parse::().unwrap_or(0))); + }, + _ => { + // Create some custom function that reports failure. + let value_type = value.get(); + println!("Input {value_type:?} is not a valid type."); + error.set(true); + error_text.set(format!("InputType {value_type:?} is not a valid type.")); + } } }; - - view! ( + + view! {
- ) + } } diff --git a/src/pages/home_page.rs b/src/pages/home_page.rs index 5e36a68..4b08df1 100644 --- a/src/pages/home_page.rs +++ b/src/pages/home_page.rs @@ -7,10 +7,11 @@ use serde_dynamo::{from_item, to_item}; use crate::app::Unauthenticated; use crate::common::{StudentInfo, UserClaims}; -use crate::components::{ActionButton, Loading, OutlinedTextField, Panel, RadioList, Row, Select}; +use crate::components::{ActionButton, Loading, OutlinedTextField, Panel, Row}; use leptos::leptos_dom::logging::console_log; use leptos::prelude::*; use leptos_oidc::{Algorithm, AuthLoaded, AuthSignal, Authenticated}; +use reactive_stores::Store; use traits::{AsReactive, ReactiveCapture}; /// # Get Student Info @@ -124,6 +125,7 @@ pub fn HomePage() -> impl IntoView { server_resource .get() .map(|submission: StudentInfo| { + let store_info = Store::new(submission.clone()); let reactive_info = submission.as_reactive(); let elements_disabled = RwSignal::new(false); let result_msg = Signal::derive(move || { @@ -197,34 +199,36 @@ pub fn HomePage() -> impl IntoView { value=reactive_info.address /> - - - - - + // impl IntoView { placeholder = "Testing information..." name = "testing_input" label = "This is a testing question." - value = RwSignal::new("".to_owned()) + value = RwSignal::new(ValueType::String("".to_owned())) />