feat: remove former MultiEntry component and unused ProviderEntry page
This commit is contained in:
1 parent
86bd471c1e
commit
208bea2d09
19 files changed
+91
-388
No files matched your search
+1
-2
@@ -7,7 +7,7 @@ use leptos_router::{
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
use crate::pages::{AboutPage, HomePage, ProviderEntry};
|
||||
use crate::pages::{AboutPage, HomePage};
|
||||
|
||||
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||
view! {
|
||||
@@ -67,7 +67,6 @@ pub fn App() -> impl IntoView {
|
||||
<Routes fallback=|| "Page not found.".into_view()>
|
||||
<Route path=StaticSegment("") view=HomePage/>
|
||||
<Route path=StaticSegment("about") view=AboutPage/>
|
||||
<Route path=StaticSegment("providers") view=ProviderEntry/>
|
||||
</Routes>
|
||||
</main>
|
||||
</Router>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::common::ValueType;
|
||||
use macros::Reactive;
|
||||
use crate::components::ValueType;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// This struct allows for completely open-ended data storage.
|
||||
///
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
use leptos::{view, IntoView};
|
||||
use crate::common::ValueType;
|
||||
use crate::components::{CheckboxList, OutlinedTextField, RadioList, Row, Select};
|
||||
use leptos::either::EitherOf5;
|
||||
use leptos::prelude::RwSignal;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::components::{CheckboxList, OutlinedTextField, RadioList, Row, Select, ValueType};
|
||||
use leptos::{IntoView, view};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Defines a series of options that allow a user to define a form.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
@@ -23,7 +24,7 @@ pub enum InputType{
|
||||
Checkbox(String, String, Vec<String>),
|
||||
/// Represents a dropdown input. Requires a `String` key, `String` label, and a series
|
||||
/// of `String` options. The selected value will be returned as a `String`.
|
||||
Select(String, String, Vec<String>)
|
||||
Select(String, String, Vec<String>),
|
||||
}
|
||||
|
||||
impl InputType {
|
||||
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
mod student_info;
|
||||
mod user;
|
||||
mod form_schema;
|
||||
mod expandable_info;
|
||||
mod form_schema;
|
||||
mod user;
|
||||
pub mod value_type;
|
||||
|
||||
pub use self::{expandable_info::*, form_schema::*, student_info::*, user::*};
|
||||
pub use self::{expandable_info::*, form_schema::*, user::*, value_type::*};
|
||||
@@ -1,50 +0,0 @@
|
||||
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, 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.
|
||||
///
|
||||
/// This is the primary key of the table, and should not have a default value.
|
||||
pub Email: String,
|
||||
/// The student's first name.
|
||||
#[serde(default)]
|
||||
pub first_name: ValueType, // String
|
||||
/// The student's last name.
|
||||
#[serde(default)]
|
||||
pub last_name: ValueType, // String
|
||||
/// The student's highest math score on the SAT.
|
||||
#[serde(default = "default_number")]
|
||||
pub math_sat: ValueType, // Number
|
||||
/// The student's desired contact email.
|
||||
#[serde(default)]
|
||||
pub contact_email: ValueType, // String
|
||||
/// The student's address.
|
||||
#[serde(default)]
|
||||
pub address: ValueType, // String
|
||||
/// The student's town of residence.
|
||||
#[serde(default)]
|
||||
pub town: ValueType, // String
|
||||
/// The student's entered phone number.
|
||||
#[serde(default)]
|
||||
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<Utc>,
|
||||
/// The student's gender.
|
||||
#[serde(default)]
|
||||
pub gender: ValueType, // String
|
||||
/// The student's athletic information.
|
||||
#[serde(default)]
|
||||
pub athletic_info: Vec<MultiEntryData>,
|
||||
}
|
||||
|
||||
fn default_number() -> ValueType {
|
||||
ValueType::Number(None)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::fmt::Display;
|
||||
|
||||
/// Defines a set of possible input types. They allow for the type and value of every data member
|
||||
@@ -24,7 +24,11 @@ pub enum ValueType {
|
||||
impl ValueType {
|
||||
/// Returns true if this is a `String`, otherwise false.
|
||||
pub fn is_string(&self) -> bool {
|
||||
if let ValueType::String(_) = self { true } else { false }
|
||||
if let ValueType::String(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to get this value as a `String` type. This is different from the `to_string` method.
|
||||
@@ -38,7 +42,11 @@ impl ValueType {
|
||||
|
||||
/// Returns true if this is a `Number`, otherwise false.
|
||||
pub fn is_number(&self) -> bool {
|
||||
if let ValueType::Number(_) = self { true } else { false }
|
||||
if let ValueType::Number(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to get this value as an `i32`.
|
||||
@@ -52,7 +60,11 @@ impl ValueType {
|
||||
|
||||
/// Returns true if this is a `List`, otherwise false.
|
||||
pub fn is_list(&self) -> bool {
|
||||
if let ValueType::List(_) = self { true } else { false }
|
||||
if let ValueType::List(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to get this value as a `Vec<ValueType>`. Each of the values inside the list must
|
||||
@@ -67,7 +79,11 @@ impl ValueType {
|
||||
|
||||
/// Returns true if this is a `Map`, otherwise false.
|
||||
pub fn is_map(&self) -> bool {
|
||||
if let ValueType::Map(_) = self { true } else { false }
|
||||
if let ValueType::Map(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to get this value as a `HashMap<String, ValueType>`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::common::ValueType;
|
||||
use leptos::prelude::*;
|
||||
use crate::components::ValueType;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[component]
|
||||
pub fn Checkbox(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::common::{InputType, ValueType};
|
||||
use crate::components::ActionButton;
|
||||
use leptos::leptos_dom::logging::console_log;
|
||||
use leptos::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
use crate::common::InputType;
|
||||
use crate::components::{ActionButton, ValueType};
|
||||
|
||||
// region Helper Functions
|
||||
|
||||
@@ -15,9 +15,9 @@ fn get_uuid_from_map(map: &HashMap<String, ValueType>) -> Option<String> {
|
||||
/// Updates an Entry within the given `Vec`.
|
||||
fn update_entry_list(list: &mut Vec<ValueType>, data: &HashMap<String, ValueType>) {
|
||||
if let Some(uuid) = get_uuid_from_map(&data) {
|
||||
if let Some(index) = list.iter()
|
||||
.position(|x| get_uuid_from_map(&x.as_map().unwrap().unwrap_or_default()) == Some(uuid.clone()))
|
||||
{
|
||||
if let Some(index) = list.iter().position(|x| {
|
||||
get_uuid_from_map(&x.as_map().unwrap().unwrap_or_default()) == Some(uuid.clone())
|
||||
}) {
|
||||
list[index] = ValueType::Map(Some(data.clone()));
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,10 @@ fn update_entry_list(list: &mut Vec<ValueType>, data: &HashMap<String, ValueType
|
||||
/// This key can be found by using the `HashMap::get` function.
|
||||
fn new_entry() -> ValueType {
|
||||
let mut entry_map = HashMap::new();
|
||||
entry_map.insert("uuid".into(), ValueType::String(Some(Uuid::new_v4().to_string())));
|
||||
entry_map.insert(
|
||||
"uuid".into(),
|
||||
ValueType::String(Some(Uuid::new_v4().to_string())),
|
||||
);
|
||||
ValueType::Map(Some(entry_map))
|
||||
}
|
||||
|
||||
@@ -62,23 +65,30 @@ fn new_entry() -> ValueType {
|
||||
/// In this example, any time a new `Entry` is created, it will contain two text fields that edit the
|
||||
/// `first_name` and `last_name` keys within that `Entry`.
|
||||
#[component]
|
||||
pub fn MultiEntryRewrite(
|
||||
pub fn MultiEntry(
|
||||
/// The data member that contains the list of entries within the `data_map`.
|
||||
#[prop(into)] data_member: String,
|
||||
#[prop(into)]
|
||||
data_member: String,
|
||||
/// The data map that contains all the information. Data is found within this map using the
|
||||
/// component's `data_member` input.
|
||||
#[prop()] data_map: RwSignal<HashMap<String, ValueType>>,
|
||||
#[prop()]
|
||||
data_map: RwSignal<HashMap<String, ValueType>>,
|
||||
#[prop(into)] name_member: String,
|
||||
/// The type and order of the inputs for each `Entry` component within this `MultiEntry` component.
|
||||
#[prop(optional)] schema: Vec<InputType>,
|
||||
#[prop(optional)]
|
||||
schema: Vec<InputType>,
|
||||
) -> impl IntoView {
|
||||
// Make the values within the list reactive. Each of these values should be a ValueType::Map,
|
||||
// so we can pass these directly to the application.
|
||||
let data_reactive = RwSignal::new(data_map.get_untracked()
|
||||
let data_reactive = RwSignal::new(
|
||||
data_map
|
||||
.get_untracked()
|
||||
.get(&data_member)
|
||||
.unwrap_or(&ValueType::List(None)).as_list()
|
||||
.unwrap_or(&ValueType::List(None))
|
||||
.as_list()
|
||||
.unwrap_or(Some(Vec::<ValueType>::new()))
|
||||
.unwrap_or(Vec::new()));
|
||||
.unwrap_or(Vec::new()),
|
||||
);
|
||||
|
||||
// This effect updates the data_map with any new values from the data_reactive list, every time
|
||||
// the data_reactive list is changed. This allows changes from within the Entry component to
|
||||
@@ -168,16 +178,20 @@ fn Entry(
|
||||
/// The data map that contains all information. Data is found within this map using the `member`
|
||||
/// props. This map should be unique to this entry; in other words, it should be contained and
|
||||
/// passed down from within the entry list in the parent `MultiEntry` component.
|
||||
#[prop()] data_map: RwSignal<HashMap<String, ValueType>>,
|
||||
#[prop()]
|
||||
data_map: RwSignal<HashMap<String, ValueType>>,
|
||||
/// The schema of this entry. Should contain all information about what inputs to use and what
|
||||
/// data members those inputs modify.
|
||||
#[prop()] schema: Vec<InputType>,
|
||||
#[prop()]
|
||||
schema: Vec<InputType>,
|
||||
/// The display name member of this entry. Determines where the component should search for the
|
||||
/// name of the entry within the `data_map`.
|
||||
#[prop(into)] name_member: String,
|
||||
#[prop(into)]
|
||||
name_member: String,
|
||||
/// The info member of this entry. Determines where the component should search for the extra
|
||||
/// information of this entry within the `data_map`.
|
||||
#[prop(optional, into)] info_member: String,
|
||||
#[prop(optional, into)]
|
||||
info_member: String,
|
||||
) -> impl IntoView {
|
||||
view! {
|
||||
<div class="flex flex-col flex-1 p-2 rounded-sm transition-shadow shadow-sm hover:shadow-lg/30">
|
||||
@@ -1,12 +0,0 @@
|
||||
pub mod multi_entry_data;
|
||||
pub mod multi_entry;
|
||||
mod multi_entry_member;
|
||||
mod rewrite;
|
||||
|
||||
pub use crate::common::value_type::*;
|
||||
pub use self::{
|
||||
multi_entry::*,
|
||||
multi_entry_data::*,
|
||||
multi_entry_member::*,
|
||||
rewrite::*,
|
||||
};
|
||||
@@ -1,144 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use leptos::either::either;
|
||||
use crate::components::{ActionButton, OutlinedTextField};
|
||||
use leptos::prelude::*;
|
||||
use crate::common::InputType;
|
||||
use crate::components::ValueType;
|
||||
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().clone());
|
||||
let temp = either!(member_info.input_type,
|
||||
InputType::Text(_, _, _) => view! {
|
||||
<OutlinedTextField
|
||||
label=member_info.display_name
|
||||
data_member=member_info.member_name
|
||||
data_map=RwSignal::new(HashMap::default())
|
||||
placeholder="testing"
|
||||
value=reactive
|
||||
/>
|
||||
},
|
||||
_ => view! {}
|
||||
);
|
||||
|
||||
temp.into_view()
|
||||
}
|
||||
|
||||
/// Represents a single entry in a MultiEntry component.
|
||||
/// These are displayed in a list, and function a little bit like a dropdown.
|
||||
/// When clicked, they expand to show all the inputs, which can be edited.
|
||||
#[component]
|
||||
pub fn Entry(
|
||||
/// The data for this entry.
|
||||
#[prop()]
|
||||
entry_data: MultiEntryData,
|
||||
/// The main display member for this entry.
|
||||
#[prop()]
|
||||
name_member: Signal<MultiEntryMember>,
|
||||
/// The secondary display member for this entry.
|
||||
#[prop()]
|
||||
info_member: Signal<MultiEntryMember>,
|
||||
/// The schema for all inputs that should be used, and what `MultiEntryMember` info is associated
|
||||
/// with them.
|
||||
#[prop()]
|
||||
schema: Arc<Vec<MultiEntryMember>>
|
||||
) -> impl IntoView {
|
||||
let name_data = entry_data.data.get(&name_member.get().member_name).unwrap();
|
||||
let info_data = entry_data.data.get(&info_member.get().member_name).unwrap();
|
||||
|
||||
let schema = Arc::clone(&schema);
|
||||
|
||||
view! {
|
||||
// This div MUST have the same spacing CSS as the second-level header div
|
||||
<div class="flex rounded-sm transition-shadow shadow-sm hover:shadow-lg/30 p-3 m-1">
|
||||
<span class="flex-1">{name_data.to_string()}</span>
|
||||
<span class="flex-1">{info_data.to_string()}</span>
|
||||
</div>
|
||||
{schema
|
||||
.iter()
|
||||
.map(|input_type| {
|
||||
let data = entry_data.clone();
|
||||
let input = input_type.clone();
|
||||
view! {
|
||||
// <div>{render_entry_component(data, input, "test".to_owned())}</div>
|
||||
}
|
||||
}).collect_view()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows users to enter more open-ended information, and generates a `Vec<MultiDataEntry>` filled
|
||||
/// with the user's entered information. The schema for this data must be defined by this component
|
||||
/// such that it is constructable using a series of `String` keys, where each key stores a single
|
||||
/// `ValueType` enum.
|
||||
#[component]
|
||||
pub fn MultiEntry(
|
||||
/// The list of entries to use.
|
||||
#[prop()]
|
||||
entries: RwSignal<Vec<MultiEntryData>>,
|
||||
/// The main display member for each entry object.
|
||||
#[prop()]
|
||||
name_member: Signal<MultiEntryMember>,
|
||||
/// The secondary display member for each entry object.
|
||||
#[prop()]
|
||||
info_member: Signal<MultiEntryMember>,
|
||||
/// The schema of the components. Determines what kind of data is stored and where.
|
||||
/// The `name_member` and `info_member` should be included in this list.
|
||||
#[prop(optional)]
|
||||
schema: Vec<MultiEntryMember>
|
||||
) -> impl IntoView {
|
||||
// Creates an entry in the given entries list.
|
||||
let create_entry = move |_| {
|
||||
let mut new_entry = MultiEntryData::new();
|
||||
new_entry.data.insert(
|
||||
name_member.get().member_name,
|
||||
ValueType::String(Some(String::from("Testing"))),
|
||||
);
|
||||
new_entry.data.insert(
|
||||
info_member.get().member_name,
|
||||
ValueType::String(Some(new_entry.id.to_string())),
|
||||
);
|
||||
entries.update(|entry_vec| entry_vec.push(new_entry));
|
||||
};
|
||||
|
||||
let rc_schema = Arc::new(schema);
|
||||
|
||||
view! {
|
||||
<div class="flex-auto p-2 m-5">
|
||||
// Header section
|
||||
<div class="rounded-md bg-red-700">
|
||||
// This div MUST have the same spacing CSS as the main entry div
|
||||
<div class="flex bg-inherit p-3 m-1">
|
||||
<span class="flex-1 text-white font-bold">
|
||||
{name_member.get().display_name}
|
||||
</span>
|
||||
<span class="flex-1 text-white font-bold">
|
||||
{info_member.get().display_name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
// Entry section
|
||||
<div>
|
||||
<For
|
||||
each=move || entries.get()
|
||||
key=|entry: &MultiEntryData| entry.id
|
||||
children=move |entry| {
|
||||
let schema = Arc::clone(&rc_schema);
|
||||
view! {
|
||||
<Entry
|
||||
entry_data=entry.clone()
|
||||
name_member=name_member
|
||||
info_member=info_member
|
||||
schema=schema
|
||||
/>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ActionButton on:click=create_entry>Add Entry</ActionButton>
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
use macros::Reactive;
|
||||
use crate::components::ValueType;
|
||||
|
||||
/// Stores all data for the `MultiEntry` component.
|
||||
///
|
||||
/// All values are stored within the `HashMap`. These entries only contain the value and
|
||||
/// the type of the value itself. Each piece of data also has a unique ID, which allows for simpler
|
||||
/// dynamic rendering.`data`
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Reactive, Default)]
|
||||
pub struct MultiEntryData {
|
||||
/// The data's unique ID.
|
||||
pub id: Uuid,
|
||||
/// The pertinent data for this struct. This may be variable - each `MultiEntry` component
|
||||
/// may specify its own schema and way of storing this data. The only limitation will be the
|
||||
/// types of data that can be stored - they must be easily parsable by a standard HTML input.
|
||||
pub data: HashMap<String, ValueType>,
|
||||
}
|
||||
|
||||
impl MultiEntryData {
|
||||
/// Creates a new MultiEntryData struct.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
data: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::common::InputType;
|
||||
|
||||
/// Contains all information required to display an entry in the MultiEntry component.
|
||||
///
|
||||
/// NOTE: This does not define a schema for the data stored by the component, only the data that the
|
||||
/// component displays as "identifying information."
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct MultiEntryMember {
|
||||
/// The name of the member, used for display only.
|
||||
pub display_name: String,
|
||||
/// The actual name of the member, used to get the data from an Entry struct.
|
||||
pub member_name: String,
|
||||
/// The type of input that should be used to display this member.
|
||||
pub input_type: InputType
|
||||
}
|
||||
|
||||
impl MultiEntryMember {
|
||||
/// Creates a new MultiEntryMember struct.
|
||||
pub fn _new() -> Self {
|
||||
Self {
|
||||
display_name: String::new(),
|
||||
member_name: String::new(),
|
||||
input_type: InputType::Text("".to_string(), "".to_string(), "".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new MultiEntryMember struct with the specified information.
|
||||
pub fn _new_with_data(display_name: String, member_name: String, input_type: InputType) -> Self {
|
||||
Self {
|
||||
display_name,
|
||||
member_name,
|
||||
input_type
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new MultiEntryMember struct with the specified information. Uses string slices.
|
||||
pub fn from_str(display_name: &str, member_name: &str) -> Self {
|
||||
Self {
|
||||
display_name: display_name.into(),
|
||||
member_name: member_name.into(),
|
||||
input_type: InputType::Text("".to_string(), "".to_string(), "".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ use leptos::prelude::*;
|
||||
#[component]
|
||||
pub fn Panel(
|
||||
#[prop(optional, default = false)] hidden: bool,
|
||||
#[prop(optional)] children: Option<Children>
|
||||
#[prop(optional)] children: Option<Children>,
|
||||
) -> impl IntoView {
|
||||
view! {
|
||||
<div
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::common::ValueType;
|
||||
use leptos::prelude::*;
|
||||
use crate::components::ValueType;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[component]
|
||||
pub fn Radio(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::common::ValueType;
|
||||
use leptos::ev::{Event, Targeted};
|
||||
use leptos::prelude::*;
|
||||
use leptos::web_sys::HtmlSelectElement;
|
||||
use crate::components::ValueType;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// A custom-styled select input.
|
||||
///
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::common::ValueType;
|
||||
use leptos::leptos_dom::logging::console_log;
|
||||
use leptos::prelude::*;
|
||||
use crate::components::ValueType;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[component]
|
||||
pub fn OutlinedTextField(
|
||||
@@ -15,7 +15,7 @@ pub fn OutlinedTextField(
|
||||
#[prop(optional)] error: RwSignal<bool>,
|
||||
#[prop(optional, into)] name: String,
|
||||
#[prop(optional, into)] label: String,
|
||||
#[prop(optional, into)] error_text: RwSignal<String>
|
||||
#[prop(optional, into)] error_text: RwSignal<String>,
|
||||
) -> impl IntoView {
|
||||
// This function parses the input into the correct type. It only accepts numbers or strings as
|
||||
// valid types, and parses them accordingly.
|
||||
@@ -33,26 +33,29 @@ pub fn OutlinedTextField(
|
||||
data_map.update(|map| {
|
||||
map.insert(data_member.clone(), ValueType::String(Some(to_parse)));
|
||||
});
|
||||
},
|
||||
}
|
||||
"number" => {
|
||||
// Define number parse function.
|
||||
// If the number parses, Some(num), else None, but we want to keep the value that's
|
||||
// in the text field at this point, just set the error.
|
||||
console_log(format!("Parsing {to_parse} to a number").as_str());
|
||||
match to_parse.parse::<i32>().map(|n| ValueType::Number(Some(n.to_string()))) {
|
||||
match to_parse
|
||||
.parse::<i32>()
|
||||
.map(|n| ValueType::Number(Some(n.to_string())))
|
||||
{
|
||||
Ok(value_type) => {
|
||||
error.set(false);
|
||||
value.set(value_type.clone());
|
||||
data_map.update(|map| {
|
||||
map.insert(data_member.clone(), value_type);
|
||||
});
|
||||
},
|
||||
}
|
||||
Err(_) => {
|
||||
error.set(true);
|
||||
error_text.set("Value is not a valid number.".to_owned());
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
// Create some custom function that reports failure.
|
||||
let msg = format!("Input {input_type:?} is not a valid type.");
|
||||
|
||||
@@ -7,13 +7,16 @@ use serde_dynamo::{from_item, to_item};
|
||||
|
||||
use crate::app::Unauthenticated;
|
||||
use crate::common::{ExpandableInfo, UserClaims};
|
||||
use crate::components::{ActionButton, CheckboxList, Loading, MultiEntryRewrite, OutlinedTextField, Panel, RadioList, Row, Select};
|
||||
use crate::components::{
|
||||
ActionButton, CheckboxList, Loading, MultiEntry, OutlinedTextField, Panel, RadioList, Row,
|
||||
Select,
|
||||
};
|
||||
use crate::input;
|
||||
use leptos::leptos_dom::logging::console_log;
|
||||
use leptos::prelude::*;
|
||||
use leptos_oidc::{Algorithm, AuthLoaded, AuthSignal, Authenticated};
|
||||
use traits::{AsReactive, ReactiveCapture};
|
||||
use crate::input;
|
||||
use std::collections::HashMap;
|
||||
use traits::{AsReactive, ReactiveCapture};
|
||||
|
||||
/// # Get Student Info
|
||||
/// Gets a student's information given their `subject`.
|
||||
@@ -265,7 +268,7 @@ pub fn HomePage() -> impl IntoView {
|
||||
/>
|
||||
</Row>
|
||||
<Row>
|
||||
<MultiEntryRewrite
|
||||
<MultiEntry
|
||||
data_map = expandable_react.data
|
||||
data_member = "test"
|
||||
name_member = "first_name"
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
mod about_page;
|
||||
mod home_page;
|
||||
mod provider_entry;
|
||||
|
||||
pub use self::{about_page::*, home_page::*, provider_entry::*};
|
||||
pub use self::{about_page::*, home_page::*};
|
||||
@@ -1,50 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::app::Unauthenticated;
|
||||
use crate::common::UserClaims;
|
||||
use crate::components::{Loading, MultiEntry, MultiEntryData, MultiEntryMember, OutlinedTextField, ValueType};
|
||||
use leptos::leptos_dom::logging::console_log;
|
||||
use leptos::prelude::*;
|
||||
use leptos_oidc::{Algorithm, AuthLoaded, AuthSignal, Authenticated, LogoutLink};
|
||||
|
||||
#[component]
|
||||
pub fn ProviderEntry() -> impl IntoView {
|
||||
let auth = use_context::<AuthSignal>().expect("Couldn't find auth signal");
|
||||
let auth_data = auth
|
||||
.get()
|
||||
.authenticated()
|
||||
.and_then(|data| data.decoded_access_token::<UserClaims>(Algorithm::RS256, &["account"]));
|
||||
|
||||
let multi_entries: RwSignal<Vec<MultiEntryData>> = RwSignal::new(vec![]);
|
||||
|
||||
console_log(format!("User claims: {auth_data:?}").as_str());
|
||||
|
||||
view! (
|
||||
<AuthLoaded fallback=Loading>
|
||||
<Authenticated unauthenticated=Unauthenticated>
|
||||
<LogoutLink class="text-logout">"Sign out"</LogoutLink>
|
||||
<h1>This is the provider entry page</h1>
|
||||
<h2>It would usually have a series of questions that we ask the providers</h2>
|
||||
<div>
|
||||
// Much of this is just a placeholder.
|
||||
<OutlinedTextField
|
||||
placeholder = "Testing information..."
|
||||
name = "testing_input"
|
||||
label = "This is a testing question."
|
||||
data_member = "testing"
|
||||
data_map = RwSignal::new(HashMap::new())
|
||||
value = RwSignal::new(ValueType::String(None))
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<p>This is an example of the multientry element.</p>
|
||||
<MultiEntry
|
||||
entries=multi_entries
|
||||
name_member=Signal::from(MultiEntryMember::from_str("Entry Name", "name"))
|
||||
info_member=Signal::from(MultiEntryMember::from_str("Entry Info", "info"))
|
||||
schema=vec![MultiEntryMember::from_str("Entry Name", "name"), MultiEntryMember::from_str("Entry Info", "info")]
|
||||
/>
|
||||
</div>
|
||||
</Authenticated>
|
||||
</AuthLoaded>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user