Merge branch 'main' into feat/provider_portal

# Conflicts:
#	src/pages/mod.rs
This commit is contained in:
meraghon committed 2025-12-05 08:38:10 -05:00
commit c3b46f2999
32 files changed
+142 -23

No files matched your search

+2 -1
View File
@@ -7,7 +7,7 @@ use leptos_router::{
};
use url::Url;
use crate::pages::{AboutPage, HomePage, UnauthenticatedPage};
use crate::pages::{AboutPage, HomePage, TestPage, UnauthenticatedPage};
pub fn shell(options: LeptosOptions) -> impl IntoView {
view! {
@@ -67,6 +67,7 @@ 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("test_page") view=TestPage/>
</Routes>
</main>
</Router>
+8 -2
View File
@@ -1,4 +1,5 @@
use crate::common::ValueType;
use crate::components::utils::create_unique_id;
use leptos::prelude::*;
use std::collections::HashMap;
@@ -7,10 +8,13 @@ pub fn Checkbox(
#[prop()] checked: Signal<bool>,
#[prop(into)] on_change: Callback<(), ()>,
#[prop(into)] value: String,
#[prop(into)] name: String,
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
) -> impl IntoView {
let id = create_unique_id(&name, &value);
view! {
<label for=value class="flex items-center">
<label for=id class="flex items-center">
<input
// Using the "peer" class links this input with the div "peer" at the same level.
// By using the "peer-checked" selector this div can toggle states based on this
@@ -19,7 +23,8 @@ pub fn Checkbox(
relative peer shrink-0
hidden"
type="checkbox"
id=value.clone()
id=id.clone()
name=name.clone()
on:change=move |_| on_change.run(())
prop:checked=checked
disabled=disabled
@@ -109,6 +114,7 @@ pub fn CheckboxList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item.clone()
name=data_member.clone()
disabled=disabled
/>
}
+11 -13
View File
@@ -1,13 +1,14 @@
use std::collections::HashMap;
use leptos::prelude::*;
use crate::common::ValueType;
use crate::components::utils::create_unique_id;
use leptos::prelude::*;
use std::collections::HashMap;
/// # Chip Component
///
///
/// This component defines a single chip for use in the `ChipsList` component. It functions almost
/// identically to the `Checkbox` component. It should only be created from within its parent
/// `CheckboxList` component.
///
///
/// Example usage:
/// ```
/// view! {
@@ -31,11 +32,8 @@ pub fn Chip(
) -> impl IntoView {
// Generate a unique id - ensure that the value doesn't contain spaces.
// Without this id, checkbox/radio inputs can interfere with each other.
let value_no_spaces = value.clone().chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
let id = format!("{}-{}", name.clone(), value_no_spaces);
let id = create_unique_id(&name, &value);
view! {
<label for=id>
<input
@@ -62,10 +60,10 @@ pub fn Chip(
}
/// # Chips List Component
///
///
/// This defines a list of `Chip` components. The list of values is created based on the data from the
/// `data_map` prop, which is found using the given `data_member`.
///
///
/// Any values selected from the list are stored within the `data_map` immediately as part of a callback
/// passed to the `on_change` prop for each individual `Chip` component.
#[component]
@@ -97,7 +95,7 @@ pub fn ChipsList(
.contains(&ValueType::String(Some(item_name.clone())))
}
});
let on_change = {
let item_name = value.clone();
let data_member = data_member.clone();
@@ -129,7 +127,7 @@ pub fn ChipsList(
});
}
};
view! {
<Chip
checked=checked_signal
+61
View File
@@ -0,0 +1,61 @@
use leptos::prelude::*;
use leptos_router::hooks::use_navigate;
/// # Dashboard Button Component
///
/// This component displays a large panel-like button that redirects a user to a specified page.
/// It's best used on a user dashboard, where multiple instances of the button are present.
/// It has a title, a description, and icon
///
/// Example usage:
/// ```
/// <div class="p-6 space-y-4 max-w-1/3">
/// <DashboardButton
/// title="Home Page"
/// description="Navigate to Home Page"
/// icon="square-user.svg"
/// path="/"
/// />
/// </div>
/// ```
#[component]
pub fn DashboardButton(
/// The main label displayed on the button.
#[prop(into)]
title: String,
/// A brief explanatory text that describes the destination page.
#[prop(into)]
description: String,
/// The file path or URL of the icon displayed at the top of the button.
#[prop(into)]
icon: String,
/// The route that the user is navigated to when clicking the button.
#[prop(into)]
path: String,
) -> impl IntoView {
let navigate = use_navigate();
let on_click = move |_| navigate(&path, Default::default());
view! {
<button
type="button"
class="dashboard-button flex items-start gap-3 rounded-lg border-grey-300 p-6
hover:bg-gray-100 transition cursor-pointer w-full text-left
shadow-[inset_0_0_6px_rgba(0,0,0,0.12)]"
on:click=on_click>
<div class="flex flex-col">
<img src={icon.clone()} class="h-8 w-8" alt="icon"/>
<h3 class="font-semibold text-base">
{title.clone()}
</h3>
<p class="text-sm text-gray-600 pt-6">
{description.clone()}
</p>
</div>
</button>
}
}
+5 -3
View File
@@ -1,5 +1,7 @@
mod action_button;
mod checkbox;
mod chips;
mod dashboard_button;
mod loading;
mod multi_entry;
mod panel;
@@ -7,9 +9,9 @@ mod radio;
mod row;
mod select;
mod text_field;
mod chips;
mod utils;
pub use self::{
action_button::*, checkbox::*, loading::*, multi_entry::*, panel::*, radio::*, row::*,
select::*, text_field::*, chips::*
action_button::*, checkbox::*, chips::*, dashboard_button::*, loading::*, multi_entry::*,
panel::*, radio::*, row::*, select::*, text_field::*,
};
+9 -3
View File
@@ -1,4 +1,5 @@
use crate::common::ValueType;
use crate::components::utils::create_unique_id;
use leptos::prelude::*;
use std::collections::HashMap;
@@ -7,10 +8,13 @@ pub fn Radio(
#[prop()] checked: Signal<bool>,
#[prop(into)] on_change: Callback<(), ()>,
#[prop(into)] value: String,
#[prop(into)] name: String,
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
) -> impl IntoView {
let id = create_unique_id(&name, &value);
view! {
<label for=value class="flex items-center">
<label for=id class="flex items-center">
<input
// Using the "peer" class links this input with the div "peer" at the same level.
// By using the "peer-checked" selector this div can toggle states based on this
@@ -18,8 +22,9 @@ pub fn Radio(
class="
relative peer shrink-0
hidden"
type="checkbox"
id=value.clone()
type="radio"
id=id.clone()
name=name.clone()
on:change=move |_| on_change.run(())
prop:checked=checked
disabled=disabled
@@ -96,6 +101,7 @@ pub fn RadioList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item.clone()
name=data_member.clone()
disabled=disabled
/>
}
+10
View File
@@ -0,0 +1,10 @@
/// Creates a unique ID for use in components like the [`CheckboxList`],
/// [`RadioList`], and [`ChipsList`].
pub fn create_unique_id(name: &String, value: &String) -> String {
let value_no_spaces = value
.clone()
.chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
format!("{}-{}", name.clone(), value_no_spaces)
}
+4 -1
View File
@@ -1,6 +1,9 @@
mod about_page;
mod home_page;
mod provider_portal;
mod test_page;
mod unauthenticated_page;
pub use self::{about_page::*, home_page::*, provider_portal::*, unauthenticated_page::*};
pub use self::{
about_page::*, home_page::*, provider_portal::*, test_page::*, unauthenticated_page::*,
};
+28
View File
@@ -0,0 +1,28 @@
use crate::components::DashboardButton;
use leptos::prelude::*;
#[component]
pub fn TestPage() -> impl IntoView {
view! {
<div class="p-6 space-y-4 max-w-1/3">
<DashboardButton
title="Home Page"
description="Navigate to Home Page"
icon="Book.png"
path="/"
/>
<DashboardButton
title="Home Page"
description="Navigate to Home Page"
icon="Calendar.png"
path="/"
/>
<DashboardButton
title="Home Page"
description="Navigate to Home Page"
icon="Edit.png"
path="/"
/>
</div>
}
}