diff --git a/src/app.rs b/src/app.rs index 24d92f9..9549173 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,10 +32,10 @@ pub fn App() -> impl IntoView { view! { // injects a stylesheet into the document // id=leptos means cargo-leptos will hot-reload this stylesheet - + // sets the document title - + <Title text="R15 Scholarship App DEV" /> // content for this welcome page <Router> @@ -102,15 +102,15 @@ pub fn AppWithRoutes() -> impl IntoView { <ToastList> // TODO Create a 404 page <Routes fallback=|| "Page not found.".into_view()> - <Route path=path!("") view=HomePage/> - <Route path=path!("/about") view=AboutPage/> - <Route path=path!("/test_page") view=TestPage/> + <Route path=path!("") view=HomePage /> + <Route path=path!("/about") view=AboutPage /> + <Route path=path!("/test_page") view=TestPage /> <Route path=path!("/comparison") view=ComparisonTestPage /> - <Route path=path!("/providers") view=ProviderPortal/> + <Route path=path!("/providers") view=ProviderPortal /> <Route path=path!("/providers/profile") view=ProviderContactPage /> <ParentRoute path=path!("/providers/scholarships") view=ScholarshipInfoPage> - <Route path=path!(":id") view=ScholarshipInfoPage/> - <Route path=path!("") view=ScholarshipInfoPage/> + <Route path=path!(":id") view=ScholarshipInfoPage /> + <Route path=path!("") view=ScholarshipInfoPage /> </ParentRoute> <ParentRoute path=path!("loaners") view=LoanerShell> <Route path=path!("") view=LoanerFallback /> diff --git a/src/components/date.rs b/src/components/date.rs index f2b7fb5..103c8a9 100644 --- a/src/components/date.rs +++ b/src/components/date.rs @@ -8,9 +8,7 @@ fn render_dates(dates: DateRange) -> impl IntoView { format!("{} - {}", start_date, end_date), }; - view! { - <span>{move || date_text.clone()}</span> - } + view! { <span>{move || date_text.clone()}</span> } } fn render_status(status: DateStatus) -> impl IntoView { @@ -33,11 +31,7 @@ fn render_status(status: DateStatus) -> impl IntoView { background_class ); - view! { - <span class=classes> - {move || status_text} - </span> - } + view! { <span class=classes>{move || status_text}</span> } } /// # Date Component @@ -65,26 +59,20 @@ fn Date( ) -> impl IntoView { view! { <div class="flex items-start gap-3 rounded-lg border-grey-300 p-3 - w-full text-left shadow-lg"> + w-full text-left shadow-lg"> // <div class="flex-shrink-0 mt-0.5"> - // <img src={icon} class="h-4 w-4" alt="icon"/> + // <img src={icon} class="h-4 w-4" alt="icon"/> // </div> <div class="flex-1 min-w-0"> <div class="flex items-start justify-between"> <div class="flex-1"> - <h3 class="font-bold text-md text-base"> - {info.get().title} - </h3> + <h3 class="font-bold text-md text-base">{info.get().title}</h3> <h3 class="text-md text-base mt-1"> {move || render_dates(info.get().date)} </h3> - <p class="text-sm text-gray-600"> - {info.get().description} - </p> - </div> - <div class="flex-shrink-0 ml-2"> - {move || render_status(info.get().status)} + <p class="text-sm text-gray-600">{info.get().description}</p> </div> + <div class="flex-shrink-0 ml-2">{move || render_status(info.get().status)}</div> </div> </div> </div> @@ -116,14 +104,12 @@ pub fn DateList( ) -> impl IntoView { view! { {move || { - dates.iter() + dates + .iter() .map(|info| { - view! { - <Date - info=info.clone() - /> - } - }).collect_view() + view! { <Date info=info.clone() /> } + }) + .collect_view() }} } } diff --git a/src/components/lists/multi/checkbox.rs b/src/components/lists/multi/checkbox.rs index 7515b78..252402d 100644 --- a/src/components/lists/multi/checkbox.rs +++ b/src/components/lists/multi/checkbox.rs @@ -134,25 +134,26 @@ pub fn CheckboxList( let cloned = item.clone(); move || cloned.clone() }); - let checked = Signal::derive(move || { controller.selected_list.get().contains(&item.get()) }); - let on_change = move || { - // Update the data list by checking if the value is present in it. If so, - // remove it. If not, add it. - controller.selected_list.update(|list| { - let item = item.get(); - if list.contains(&item) { - list.retain(|val| *val != item); - } else { - list.push(item); - } - }); + controller + .selected_list + .update(|list| { + let item = item.get(); + if list.contains(&item) { + list.retain(|val| *val != item); + } else { + list.push(item); + } + }); controller.dirty.set(true); }; + // Update the data list by checking if the value is present in it. If so, + // remove it. If not, add it. + view! { <Checkbox checked=checked @@ -171,7 +172,7 @@ pub fn CheckboxList( {move || { match controller.error.get() { ValidationState::Invalid(msg) => msg, - _ => "There is no error - should not see this message.".to_string() + _ => "There is no error - should not see this message.".to_string(), } }} </div> diff --git a/src/components/lists/multi/chips.rs b/src/components/lists/multi/chips.rs index d00cd8c..fdd4a22 100644 --- a/src/components/lists/multi/chips.rs +++ b/src/components/lists/multi/chips.rs @@ -45,16 +45,17 @@ pub fn Chip( id=id.clone() prop:checked=checked on:change=move |_| on_change.run(()) - disabled=disabled /> + disabled=disabled + /> <div class="rounded-full p-2.5 - cursor-pointer text-base - bg-transparent border-1 border-gray-300 - shadow-md/50 hover:shadow-md/70 - peer-checked:bg-red-700 peer-checked:border-red-700 peer-checked:text-white - peer-disabled:peer-checked:bg-gray-700 - peer-disabled:peer-checked:border-gray-700 - peer-disabled:cursor-default - transition-all duration-150"> + cursor-pointer text-base + bg-transparent border-1 border-gray-300 + shadow-md/50 hover:shadow-md/70 + peer-checked:bg-red-700 peer-checked:border-red-700 peer-checked:text-white + peer-disabled:peer-checked:bg-gray-700 + peer-disabled:peer-checked:border-gray-700 + peer-disabled:cursor-default + transition-all duration-150"> <span>{display_text.clone()}</span> </div> </label> @@ -98,47 +99,60 @@ pub fn ChipsList( <div class="m-1.5 mt-0 mb-0"> <span class="font-bold">{label}</span> <div class="flex flex-row flex-wrap gap-2 mb-1"> - {move || displayed_text.get().into_iter().zip(values.get()) - .into_iter() - .map(|(text, value)| { - let value = RwSignal::new(value); + {move || { + displayed_text + .get() + .into_iter() + .zip(values.get()) + .into_iter() + .map(|(text, value)| { + let value = RwSignal::new(value); + let checked = Signal::derive(move || { + controller.selected_list.get().contains(&value.get()) + }); + let on_change = move || { + let value = value.get(); + let list = controller.selected_list.get(); + if list.contains(&value) { + allows_multiple + .get() + .then(|| { + controller + .selected_list + .update(|list| list.retain(|v| v != &value)) + }) + .or_else(|| Some(controller.selected_list.set(Vec::new()))); + } else { + allows_multiple + .get() + .then(|| { + controller + .selected_list + .update(|list| list.push(value.clone())) + }) + .or_else(|| Some( + controller.selected_list.set(vec![value.clone()]), + )); + } + controller.dirty.set(true); + }; - let checked = Signal::derive(move || { - controller.selected_list.get().contains(&value.get()) - }); - - let on_change = move || { // Update the data list by checking if the value is present in it. If so, // remove it. If not, add it. - let value = value.get(); - let list = controller.selected_list.get(); - if list.contains(&value) { - allows_multiple.get() - .then(|| controller.selected_list.update(|list| list.retain(|v| v != &value))) - .or_else(|| Some(controller.selected_list.set(Vec::new()))); - } else { - allows_multiple.get() - .then(|| controller.selected_list.update(|list| list.push(value.clone()))) - .or_else(|| Some(controller.selected_list.set(vec![value.clone()]))); + view! { + <Chip + checked=checked + on_change=on_change + value=value + display_text=text + name=data_member + disabled=disabled + /> } - - controller.dirty.set(true); - }; - - view! { - <Chip - checked=checked - on_change=on_change - value=value - display_text=text - name=data_member - disabled=disabled - /> - } - }) - .collect_view() - } + }) + .collect_view() + }} </div> </div> <Show when=move || controller.show_errors.get()> @@ -146,7 +160,7 @@ pub fn ChipsList( {move || { match controller.error.get() { ValidationState::Invalid(msg) => msg, - _ => "There is no error - should not see this message.".to_string() + _ => "There is no error - should not see this message.".to_string(), } }} </div> diff --git a/src/components/lists/single/radio.rs b/src/components/lists/single/radio.rs index 86b4ddf..20619f9 100644 --- a/src/components/lists/single/radio.rs +++ b/src/components/lists/single/radio.rs @@ -121,19 +121,24 @@ pub fn RadioList( .into_iter() .map(|item| { let item = RwSignal::new(item); - let checked_signal = Signal::derive(move || { selected_value.get() == item.get() }); - let on_change = move || { - // on_change only runs when the radio button is checked, not when unchecked. - // Change the selected value to the new one. selected_value.set(item.get()); - error.set(validate(selected_value.get_untracked(), required.get_untracked())); + error + .set( + validate( + selected_value.get_untracked(), + required.get_untracked(), + ), + ); dirty.set(true); }; + // on_change only runs when the radio button is checked, not when unchecked. + // Change the selected value to the new one. + view! { <Radio checked=checked_signal @@ -152,7 +157,7 @@ pub fn RadioList( {move || { match error.get() { ValidationState::Invalid(msg) => msg, - _ => "There is no error - should not see this message.".to_string() + _ => "There is no error - should not see this message.".to_string(), } }} </div> diff --git a/src/components/lists/single/select.rs b/src/components/lists/single/select.rs index 3fd6ab6..b20cddc 100644 --- a/src/components/lists/single/select.rs +++ b/src/components/lists/single/select.rs @@ -93,9 +93,9 @@ pub fn Select( <span class="ml-1.5 mb-0 font-bold">{label}</span> <select class="relative flex-1 border-2 m-1.5 mt-0 p-1.5 rounded-md - transition-border duration-150 - border-red-700 bg-transparent - disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33" + transition-border duration-150 + border-red-700 bg-transparent + disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33" on:change:target=on_change disabled=disabled > @@ -104,15 +104,18 @@ pub fn Select( value="" disabled hidden - selected={move || raw_value.get().is_empty()} - >"Select one..."</option> + selected=move || raw_value.get().is_empty() + > + "Select one..." + </option> {move || { - value_list.iter().map( - move |value| { + value_list + .iter() + .map(move |value| { let display = value.to_owned(); - view! { <option value={display}>{display.clone()}</option> } - } - ).collect::<Vec<_>>() + view! { <option value=display>{display.clone()}</option> } + }) + .collect::<Vec<_>>() }} </select> </label> @@ -122,7 +125,7 @@ pub fn Select( {move || { match error.get() { ValidationState::Invalid(msg) => msg, - _ => "There is no error - should not see this message.".to_string() + _ => "There is no error - should not see this message.".to_string(), } }} </div> diff --git a/src/components/text_field.rs b/src/components/text_field.rs index dee1854..40e9052 100644 --- a/src/components/text_field.rs +++ b/src/components/text_field.rs @@ -144,12 +144,12 @@ pub fn OutlinedTextField( <input node_ref=input_ref class="border-2 m-1.5 p-1.5 mt-0 rounded-md bg-transparent relative flex-1 - transition-all duration-150 - border-red-700 bg-transparent - disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33" - r#type={str_type} - disabled={disabled} - placeholder={placeholder} + transition-all duration-150 + border-red-700 bg-transparent + disabled:border-gray-600 disabled:pointer-events-none disabled:bg-gray-600/33" + r#type=str_type + disabled=disabled + placeholder=placeholder prop:name=name prop:value=raw_value on:input=on_input @@ -160,7 +160,7 @@ pub fn OutlinedTextField( {move || { match error.get() { ValidationState::Invalid(msg) => msg, - _ => "There is no error - should not see this message.".to_string() + _ => "There is no error - should not see this message.".to_string(), } }} </div> diff --git a/src/pages/comparison_test.rs b/src/pages/comparison_test.rs index d01f03e..57afa5a 100644 --- a/src/pages/comparison_test.rs +++ b/src/pages/comparison_test.rs @@ -57,93 +57,84 @@ pub fn ComparisonTestPage() -> impl IntoView { let student_info = student_resource.get(); let comparison_info = comparison_resource.get(); let scholarship_info = scholarship_resource.get(); - match (student_info, comparison_info, scholarship_info) { - (Some(student), Some(comparisons), Some(scholarships)) => Either::Right(view! { - <Panel> - <Row> - <p>{result_msg}</p> - </Row> - <Row> - <ActionButton on:click=move |_| { - // Iterate over all scholarships, get the comparison IDs, - // get ComparisonData from the IDs, then perform the - // comparisons and return a boolean. Alternatively, return - // a list of comparisons that complete and a list that don't. - let comp_member = "requirements".to_string(); - let comparison_results = scholarships.iter().map(|scholarship| { - let list = match scholarship.data.get(&comp_member) { - Some(ValueType::List(Some(list))) => list, - _ => { - log!("Cannot find requirements, assuming none."); - return Ok(Some(scholarship)) // students will always qualify when there are no requirements - } - }; + (Some(student), Some(comparisons), Some(scholarships)) => { + Either::Right( - let mut final_result = Ok(true); - - // The list should exist, and it should contain a series of strings. - for val in list { - let comp_opt = match val { - ValueType::String(Some(comp_id)) => { - // Find the comparison - comparisons.iter().find(|comp| comp.id == *comp_id) - } - _ => None - }; - - let comparison_outcome = match comp_opt { - Some(comp) => { - // Perform the comparison - comp.compare(&student) - } - _ => Err("".to_string()) - }; - - match comparison_outcome { - Ok(true) => {}, - Ok(false) => final_result = Ok(false), - Err(e) => { - final_result = Err(e); - break; + view! { + <Panel> + <Row> + <p>{result_msg}</p> + </Row> + <Row> + <ActionButton on:click=move |_| { + let comp_member = "requirements".to_string(); + let comparison_results = scholarships + .iter() + .map(|scholarship| { + let list = match scholarship.data.get(&comp_member) { + Some(ValueType::List(Some(list))) => list, + _ => { + log!("Cannot find requirements, assuming none."); + return Ok(Some(scholarship)); + } + }; + let mut final_result = Ok(true); + for val in list { + let comp_opt = match val { + ValueType::String(Some(comp_id)) => { + comparisons.iter().find(|comp| comp.id == *comp_id) + } + _ => None, + }; + let comparison_outcome = match comp_opt { + Some(comp) => comp.compare(&student), + _ => Err("".to_string()), + }; + match comparison_outcome { + Ok(true) => {} + Ok(false) => final_result = Ok(false), + Err(e) => { + final_result = Err(e); + break; + } + } + } + match final_result { + Ok(true) => Ok(Some(scholarship)), + Ok(false) => Ok(None), + Err(e) => Err(e), + } + }) + .collect::<Vec<Result<Option<&ExpandableInfo>, String>>>(); + let mut strings = Vec::new(); + strings.push("Scholarship results: \n".to_string()); + for result in comparison_results { + match result { + Ok(Some(scholarship_info)) => { + let name_member = "name".to_string(); + let scl_name = scholarship_info + .data + .get(&name_member) + .unwrap() + .as_string() + .unwrap() + .unwrap(); + strings.push(scl_name); + } + Ok(None) => {} + Err(msg) => strings.push(msg), } } - } - - match final_result { - Ok(true) => Ok(Some(scholarship)), - Ok(false) => Ok(None), - Err(e) => Err(e) - } - }).collect::<Vec<Result<Option<&ExpandableInfo>, String>>>(); - - // Build a display string - let mut strings = Vec::new(); - strings.push("Scholarship results: \n".to_string()); - for result in comparison_results { - match result { - Ok(Some(scholarship_info)) => { - // Get the scholarship name. - let name_member = "name".to_string(); - let scl_name = scholarship_info.data.get(&name_member).unwrap() - .as_string().unwrap().unwrap(); - strings.push(scl_name); - }, - Ok(None) => {}, - Err(msg) => strings.push(msg) - } - } - - let display_text = strings.join("\n").to_string(); - - result_msg.set(display_text); - }>"Test Comparison"</ActionButton> - </Row> - </Panel> - }), - _ => Either::Left(view! { - <p>"Failed API requests."</p> - }) + let display_text = strings.join("\n").to_string(); + result_msg.set(display_text); + }>"Test Comparison"</ActionButton> + </Row> + </Panel> + }, + ) + } + _ => Either::Left(view! { <p>"Failed API requests."</p> }), } }} </Suspense> diff --git a/src/pages/home_page.rs b/src/pages/home_page.rs index 7f58d4d..f303195 100644 --- a/src/pages/home_page.rs +++ b/src/pages/home_page.rs @@ -289,7 +289,7 @@ pub fn HomePage() -> impl IntoView { data_member="contact_email" data_map=form_data input_type=TextFieldType::Email( - vec!["fakeemail.org".to_string(), "gmail.com".to_string()] + vec!["fakeemail.org".to_string(), "gmail.com".to_string()], ) required=true /> @@ -369,8 +369,12 @@ pub fn HomePage() -> impl IntoView { data_map=form_data data_member="community_involvement" schema=vec![ - input!(Text, "service_name", "Activity Name:", true, "Some service activity..."), - input!(Number, "service_hours", "Total Service Hours", true, "20") + input!( + Text, "service_name", "Activity Name:", true, "Some service activity..." + ), + input!( + Number, "service_hours", "Total Service Hours", true, "20" + ), ] /> </Row> @@ -380,8 +384,7 @@ pub fn HomePage() -> impl IntoView { </Row> } }) - }} - <Row> + }} <Row> <ActionButton on:click=pdf_button_click>"Get PDF"</ActionButton> </Row> </Suspense> diff --git a/src/pages/loaner_page.rs b/src/pages/loaner_page.rs index 07b2464..14cd5b0 100644 --- a/src/pages/loaner_page.rs +++ b/src/pages/loaner_page.rs @@ -213,11 +213,7 @@ pub fn LoanerShell() -> impl IntoView { // We'll create the page here - the sidebar contains all the buttons, while the form // container either shows forms or shows placeholder text. view! { - <Banner - title="Chromebook Loaners" - logo="/PHS_Stacked_Acronym.png" - path="/loaners" - /> + <Banner title="Chromebook Loaners" logo="/PHS_Stacked_Acronym.png" path="/loaners" /> <div class="flex m-5"> <div class="flex flex-1 flex-row gap-3"> <div id="sidebar" class="flex flex-1 flex-col gap-2"> @@ -247,16 +243,9 @@ pub fn LoanerShell() -> impl IntoView { #[component] pub fn LoanerFallback() -> impl IntoView { view! { - <div - class="flex flex-col items-center justify-center" - use:animate=pop_in_out() - > - <div class="text-3xl font-bold mb-2"> - "Chromebook Loaner Form" - </div> - <div class="text-lg"> - "Select an option from the left to begin." - </div> + <div class="flex flex-col items-center justify-center" use:animate=pop_in_out()> + <div class="text-3xl font-bold mb-2">"Chromebook Loaner Form"</div> + <div class="text-lg">"Select an option from the left to begin."</div> </div> } } @@ -431,69 +420,85 @@ pub fn LoanerReturnForm() -> impl IntoView { <dialog use:animate=pop_in_out() class="p-3 m-auto rounded-md shadow-lg/33 backdrop:backdrop-blur-xs backdrop:transition-backdrop-filter" - node_ref=dialog_ref> + node_ref=dialog_ref + > <h2 class="text-2xl font-bold">"Confirmation"</h2> <h4 class="text-xl mb-3"> - {move || chosen_student.with(|opt_student| { - if let Some(student) = opt_student.as_ref() { - format!("Are you sure want to check in {} {}?", student.first_name, student.last_name) - } else { - "There is no student selected.".to_string() - } - })} + {move || { + chosen_student + .with(|opt_student| { + if let Some(student) = opt_student.as_ref() { + format!( + "Are you sure want to check in {} {}?", + student.first_name, + student.last_name, + ) + } else { + "There is no student selected.".to_string() + } + }) + }} </h4> - <ActionButton on:click=close_dialog disabled=dialog_disabled>"Close"</ActionButton> - <ActionButton on:click=dialog_check_in disabled=dialog_disabled>"Check In"</ActionButton> + <ActionButton on:click=close_dialog disabled=dialog_disabled> + "Close" + </ActionButton> + <ActionButton on:click=dialog_check_in disabled=dialog_disabled> + "Check In" + </ActionButton> </dialog> - <div - class="flex flex-col gap-2 m-2" - use:animate=pop_in_out() - > + <div class="flex flex-col gap-2 m-2" use:animate=pop_in_out()> <div class="flex flex-col justify-center gap-2 mb-3 py-3 px-2"> <h2 class="text-2xl font-bold">"Student List"</h2> <p class="text-lg">"Please select your name from the list."</p> </div> - <Suspense fallback=move || "Loading...".into_view()> + <Suspense fallback=move || { + "Loading...".into_view() + }> {move || { match return_list_resource.get() { Some(loaner_list) => { - let list_view = loaner_list.iter().map(|student| { - let on_click = { - let student_click = student.clone(); - move |_| { - log!("Running on_click using student {:?}", student_click); - if let Some(dialog) = dialog_ref.get() { - chosen_student.set(Some(student_click.clone())); - dialog.show_modal().expect("Couldn't show modal dialog."); + let list_view = loaner_list + .iter() + .map(|student| { + let on_click = { + let student_click = student.clone(); + move |_| { + log!("Running on_click using student {:?}", student_click); + if let Some(dialog) = dialog_ref.get() { + chosen_student.set(Some(student_click.clone())); + dialog.show_modal().expect("Couldn't show modal dialog."); + } } + }; + let naive_time = chrono::NaiveDateTime::parse_from_str( + &student.date, + "%H:%M, %m/%d/%Y", + ) + .unwrap(); + let time_zone = FixedOffset::west_opt(5 * 3600).unwrap(); + let student_date = time_zone + .from_utc_datetime(&naive_time) + .format("%l:%M %p, %m/%d/%Y") + .to_string(); + log!("Found current date {:?}", student_date); + + view! { + <div + class="flex flex-row p-3 rounded-md cursor-pointer transition-shadow shadow-sm hover:shadow-lg/33" + on:click=on_click + > + <div class="flex-1"> + {student.first_name.clone()}" "{student.last_name.clone()} + </div> + <div class="flex-none">{student_date.clone()}</div> + </div> } - }; - - let naive_time = chrono::NaiveDateTime::parse_from_str(&student.date, "%H:%M, %m/%d/%Y") - .unwrap(); - let time_zone = FixedOffset::west_opt(5 * 3600).unwrap(); - let student_date = time_zone.from_utc_datetime(&naive_time) - .format("%l:%M %p, %m/%d/%Y") - .to_string(); - - log!("Found current date {:?}", student_date); - - view! { - <div class="flex flex-row p-3 rounded-md cursor-pointer transition-shadow shadow-sm hover:shadow-lg/33" on:click=on_click> - <div class="flex-1"> - {student.first_name.clone()}" "{student.last_name.clone()} - </div> - <div class="flex-none"> - {student_date.clone()} - </div> - </div> - } - }).collect_view(); - + }) + .collect_view(); Either::Left(list_view) - }, - None => Either::Right("No loaners found.".into_view()) + } + None => Either::Right("No loaners found.".into_view()), } }} </Suspense> diff --git a/src/pages/provider_contact.rs b/src/pages/provider_contact.rs index 94b8cf7..55a01b4 100644 --- a/src/pages/provider_contact.rs +++ b/src/pages/provider_contact.rs @@ -143,7 +143,7 @@ pub fn ProviderContactPage() -> impl IntoView { <div class="flex flex-row"> <div class="flex flex-col flex-1" /> <Panel> - <ValidatedForm + <ValidatedForm on_submit=on_submit title="Contact Form" description="Enter your contact information and click submit." diff --git a/src/pages/test_page.rs b/src/pages/test_page.rs index f288a7f..92db0f4 100644 --- a/src/pages/test_page.rs +++ b/src/pages/test_page.rs @@ -14,19 +14,19 @@ pub fn TestPage() -> impl IntoView { description="Edit user profile" icon="/Person_Black.png" path="/" - /> + /> <DashboardButton title="Create Scholarship" description="Navigate to Scholarship Creation Page" icon="/Create_Black.png" path="/" - /> + /> <DashboardButton title="Applicants" description="View Scholarship Applicants" icon="/Form_Black.png" path="/" - /> + /> </section> <section class="space-y-2"> <div class="rounded-lg shadow-lg/25 overflow-hidden"> @@ -35,34 +35,35 @@ pub fn TestPage() -> impl IntoView { </div> <div class="p-2"> <div class="flex flex-col p-3 gap-3"> - <DateList - dates=vec![ - DateInfo { - title: "Title".to_string(), - date: DateRange::Range("February 2nd, 2026".to_string(), "February 10th, 2026".to_string()), - description: "This is a test".to_string(), - status: DateStatus::Upcoming - }, - DateInfo { - title: "Scholarships Due".to_string(), - date: DateRange::Single("November 4th, 2025".to_string()), - description: "This is a test".to_string(), - status: DateStatus::Open - }, - DateInfo { - title: "Scholarships Due".to_string(), - date: DateRange::Single("November 4th, 2025".to_string()), - description: "This is a test".to_string(), - status: DateStatus::Deadline - }, - DateInfo { - title: "Scholarships Due".to_string(), - date: DateRange::Single("November 4th, 2025".to_string()), - description: "This is a test".to_string(), - status: DateStatus::Closed - } - ] - /> + <DateList dates=vec![ + DateInfo { + title: "Title".to_string(), + date: DateRange::Range( + "February 2nd, 2026".to_string(), + "February 10th, 2026".to_string(), + ), + description: "This is a test".to_string(), + status: DateStatus::Upcoming, + }, + DateInfo { + title: "Scholarships Due".to_string(), + date: DateRange::Single("November 4th, 2025".to_string()), + description: "This is a test".to_string(), + status: DateStatus::Open, + }, + DateInfo { + title: "Scholarships Due".to_string(), + date: DateRange::Single("November 4th, 2025".to_string()), + description: "This is a test".to_string(), + status: DateStatus::Deadline, + }, + DateInfo { + title: "Scholarships Due".to_string(), + date: DateRange::Single("November 4th, 2025".to_string()), + description: "This is a test".to_string(), + status: DateStatus::Closed, + }, + ] /> </div> </div> </div>