chore: PC change (create multientry)

This commit is contained in:
alphafetus committed 2025-07-27 17:53:45 -04:00
1 parent 127cf17c90
commit 9d18eb0810
8 files changed
+302 -5

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct FormDefinition {
sections: Vec<Section>
}
#[derive(Serialize, Deserialize)]
struct Section {
questions: Vec<QuestionType>
}
#[derive(Serialize, Deserialize)]
enum QuestionType {
Text,
Email,
Number,
Dropdown,
Checkbox,
Radio,
Multi
}
struct TextInput {
}
#[derive(Serialize, Deserialize)]
struct QuestionComponent {
question_type: QuestionType,
label: Option<String>,
placeholder: Option<String>,
// Used in <select> and <checkbox> elements
options: Option<HashMap<String, String>>
}
+3 -1
View File
@@ -1,7 +1,9 @@
mod loaner_user;
mod student_info;
mod form_definition;
pub use self::{
loaner_user::*,
student_info::*
student_info::*,
form_definition::*
};
+6 -1
View File
@@ -1,4 +1,9 @@
mod action_button;
mod text_field;
mod multi_entry;
pub use self::{action_button::ActionButton, text_field::OutlinedTextField};
pub use self::{
action_button::*,
text_field::*,
multi_entry::*
};
+105
View File
@@ -0,0 +1,105 @@
use std::collections::HashMap;
use leptos::{leptos_dom::logging::console_log, prelude::*};
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct MultiEntryData {
pub id: usize,
pub data: HashMap<String, ValueType>,
}
impl MultiEntryData {
pub fn new() -> Self {
Self {
id: 0,
data: HashMap::new(),
}
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum ValueType {
String(String),
Number(i32),
}
impl ValueType {
pub fn as_string(&self) -> String {
match self {
ValueType::String(s) => s.clone(),
ValueType::Number(n) => n.to_string(),
}
}
}
/// 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()]
entryData: MultiEntryData,
/// The main display member for this entry.
#[prop()]
nameMember: String,
/// The secondary display member for this entry.
#[prop()]
infoMember: String,
) -> impl IntoView {
let nameData = entryData.data.get(&nameMember).unwrap();
let infoData = entryData.data.get(&infoMember).unwrap();
view! {
<div>
<p>{nameData.as_string()}</p>
<p>{infoData.as_string()}</p>
</div>
}
}
#[component]
pub fn MultiEntry(
/// the main display member for each entry object.
#[prop()]
nameMember: String,
/// The secondary display member for each entry object.
#[prop()]
infoMember: String,
) -> impl IntoView {
let entries: Signal<Vec<MultiEntryData>> = Signal::from(vec![]);
let nameKey = nameMember.clone();
let infoKey = infoMember.clone();
let create_entry = move |_| {
console_log("Found button click");
let mut new_entry = MultiEntryData::new();
new_entry.id = entries.get().len() as usize;
new_entry
.data
.insert(nameKey.clone(), ValueType::String(String::from("Testing")));
new_entry
.data
.insert(infoKey.clone(), ValueType::Number(new_entry.id as i32));
entries.get().push(new_entry);
console_log(format!("{:?}", entries.get()).as_str());
};
view! {
<div>
// Entries will go here for right now.
<For
each = move || entries.get()
key = |entry: &MultiEntryData| entry.id
children = move |entry| view! {
<Entry entryData=entry.clone() nameMember=nameMember.clone() infoMember=infoMember.clone()/>
}
/>
</div>
<button on:click=create_entry>
Add Entry
</button>
}
}
+3 -2
View File
@@ -7,6 +7,7 @@ pub fn OutlinedTextField(
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
#[prop(default = String::from(""))] name: String,
#[prop(default = String::from(""))] label: String,
#[prop(default = String::from(""))] input_type: String,
) -> impl IntoView {
view! (
<label>
@@ -15,8 +16,8 @@ pub fn OutlinedTextField(
class="border-2 m-1.5 p-1.5 rounded-md bg-transparent mt-6 relative transition-all duration-400"
class=(["border-red-700"], move || !disabled.get())
class=(["border-gray-600", "pointer-events-none"], move || disabled.get())
r#type="text"
disabled={move || disabled.get()}
r#type={input_type}
disabled={disabled}
placeholder={placeholder}
prop:name=name
bind:value=value // This is a two-way binding - it is allowed to read *and* write.
+8 -1
View File
@@ -1,5 +1,5 @@
use crate::components::{MultiEntry, OutlinedTextField};
use leptos::prelude::*;
use crate::components::OutlinedTextField;
#[component]
pub fn ProviderEntry() -> impl IntoView {
@@ -13,5 +13,12 @@ pub fn ProviderEntry() -> impl IntoView {
label = "This is a testing question.".into()
/>
</div>
<div>
<p>This is an example of the multientry element.</p>
<MultiEntry
nameMember="name".into()
infoMember="info".into()
/>
</div>
)
}