use std::collections::HashMap; use std::sync::OnceLock; use dioxus::prelude::*; use super::button::{ErrorButton, SuccessButton, WarningButton}; use crate::data::datasources::random_svg_generators::{ generate_random_svg_avatar, AvatarConfig, AvatarFeeling, }; include!(concat!(env!("OUT_DIR"), "/style_vars.rs")); use style::{COLOR_CRITICAL_100, COLOR_SUCCESS_100, COLOR_WARNING_100}; turf::style_sheet!("src/components/modal.scss"); #[derive(Clone, Copy, Eq, PartialEq, Hash)] pub enum Severity { Ok, Warning, Critical, } fn avatar_configs() -> &'static HashMap> { static HASHMAP: OnceLock> = OnceLock::new(); HASHMAP.get_or_init(|| { let mut configs = HashMap::new(); configs.insert( Severity::Critical, AvatarConfig::new(AvatarFeeling::Alerting, COLOR_CRITICAL_100), ); configs.insert( Severity::Warning, AvatarConfig::new(AvatarFeeling::Warning, COLOR_WARNING_100), ); configs.insert( Severity::Ok, AvatarConfig::new(AvatarFeeling::Ok, COLOR_SUCCESS_100), ); configs }) } #[derive(Props, Clone, PartialEq)] pub struct ModalProps { pub severity: Severity, #[props(optional)] pub title: Option, pub children: Element, #[props(optional)] pub on_confirm: Option>, } #[component] pub fn Modal(props: ModalProps) -> Element { let avatar_config = avatar_configs().get(&props.severity); let random_figure_future = use_resource(move || async move { generate_random_svg_avatar(avatar_config).await }); let icon = match &*random_figure_future.read_unchecked() { Some(svg) => Some(rsx! { div { class: ClassName::MODAL_CONTENT_ICON_PLACEHOLDER, dangerous_inner_html: svg.as_str(), } }), None => None, }; let button_class = match &props.severity { Severity::Ok => SuccessButton, Severity::Warning => WarningButton, Severity::Critical => ErrorButton, }; icon.as_ref()?; rsx! { style { {STYLE_SHEET} }, div { class: ClassName::MODAL, div { class: ClassName::MODAL_CONTENT, div { class: ClassName::MODAL_CONTENT_ICON, {icon} }, div { class: ClassName::MODAL_CONTENT_TITLE, {props.title}, }, div { class: ClassName::MODAL_CONTENT_MSG, {props.children}, }, div { class: ClassName::MODAL_CONTENT_BUTTONS, button_class { onclick: move |evt| { if let Some(cb) = &props.on_confirm { cb.call(evt); } }, }, }, }, }, } }