diff --git a/services/frontend-leptos/frontend/src/ui/empty_state.rs b/services/frontend-leptos/frontend/src/ui/empty_state.rs new file mode 100644 index 0000000..662f5d5 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/empty_state.rs @@ -0,0 +1,19 @@ +// services/frontend-leptos/frontend/src/ui/empty_state.rs +use leptos::prelude::*; + +#[component] +pub fn EmptyState( + #[prop(optional)] icon: Option, + title: &'static str, + #[prop(optional)] description: Option<&'static str>, + #[prop(optional)] children: Option, +) -> impl IntoView { + view! { +
+ {icon.map(|i| view! {
{i}
})} +
{title}
+ {description.map(|d| view! {

{d}

})} + {children.map(|c| c())} +
+ } +} diff --git a/services/frontend-leptos/frontend/src/ui/mod.rs b/services/frontend-leptos/frontend/src/ui/mod.rs index d67bd50..7ee2c6f 100644 --- a/services/frontend-leptos/frontend/src/ui/mod.rs +++ b/services/frontend-leptos/frontend/src/ui/mod.rs @@ -7,3 +7,7 @@ pub mod scroll_area; pub mod select; pub mod tabs; pub mod toast; +pub mod skeleton; +pub mod status_badge; +pub mod empty_state; +pub mod modal; diff --git a/services/frontend-leptos/frontend/src/ui/modal.rs b/services/frontend-leptos/frontend/src/ui/modal.rs new file mode 100644 index 0000000..866f9a9 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/modal.rs @@ -0,0 +1,46 @@ +// services/frontend-leptos/frontend/src/ui/modal.rs +use std::sync::Arc; +use leptos::prelude::*; + +#[component] +pub fn Modal( + is_open: RwSignal, + #[prop(optional)] title: Option<&'static str>, + #[prop(optional)] on_close: Option>, + children: Children, +) -> impl IntoView { + let oc1 = on_close.clone(); + let oc2 = on_close; + + view! { + + } +} diff --git a/services/frontend-leptos/frontend/src/ui/skeleton.rs b/services/frontend-leptos/frontend/src/ui/skeleton.rs new file mode 100644 index 0000000..5cb9f49 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/skeleton.rs @@ -0,0 +1,30 @@ +// services/frontend-leptos/frontend/src/ui/skeleton.rs +use leptos::prelude::*; + +#[derive(Clone, Default)] +pub enum SkeletonShape { + #[default] + Rounded, + Circular, + Rectangular, +} + +#[component] +pub fn Skeleton( + #[prop(optional)] width: &'static str, + #[prop(optional)] height: &'static str, + #[prop(optional)] shape: SkeletonShape, +) -> impl IntoView { + let shape_class = match shape { + SkeletonShape::Rounded => "", + SkeletonShape::Circular => "skeleton-circular", + SkeletonShape::Rectangular => "skeleton-rectangular", + }; + let combined = format!("skeleton {}", shape_class); + view! { +
+ } +} diff --git a/services/frontend-leptos/frontend/src/ui/status_badge.rs b/services/frontend-leptos/frontend/src/ui/status_badge.rs new file mode 100644 index 0000000..5dfb59d --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/status_badge.rs @@ -0,0 +1,21 @@ +// services/frontend-leptos/frontend/src/ui/status_badge.rs +use leptos::prelude::*; +use shared_types::message::AiStatus; + +#[component] +pub fn StatusBadge(status: AiStatus) -> impl IntoView { + let (class, label) = match status { + AiStatus::Flagged => ("status-badge-flagged", "Flagged"), + AiStatus::Clean => ("status-badge-clean", "Clean"), + AiStatus::Warn => ("status-badge-warn", "Warned"), + AiStatus::Pending => ("status-badge-pending", "Pending"), + AiStatus::Processing => ("status-badge-processing", "Processing"), + AiStatus::Error => ("status-badge-error", "Error"), + }; + let combined = format!("status-badge {}", class); + view! { + + {label} + + } +}