maud_ui/primitives/
alert.rs1use maud::{html, Markup};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Variant {
7 Default,
8 Info,
9 Success,
10 Warning,
11 Danger,
12}
13
14impl Variant {
15 fn class(&self) -> &'static str {
16 match self {
17 Self::Default => "mui-alert--default",
18 Self::Info => "mui-alert--info",
19 Self::Success => "mui-alert--success",
20 Self::Warning => "mui-alert--warning",
21 Self::Danger => "mui-alert--danger",
22 }
23 }
24
25 fn icon_char(&self) -> &'static str {
26 match self {
27 Self::Default => "\u{25cb}", Self::Info => "\u{24d8}", Self::Success => "\u{2713}", Self::Warning => "\u{26a0}", Self::Danger => "\u{26a0}", }
33 }
34}
35
36#[derive(Debug, Clone)]
38pub struct Props {
39 pub title: String,
41 pub description: Option<String>,
43 pub variant: Variant,
45 pub icon: bool,
47}
48
49impl Default for Props {
50 fn default() -> Self {
51 Self {
52 title: String::new(),
53 description: None,
54 variant: Variant::Default,
55 icon: true,
56 }
57 }
58}
59
60pub fn render(props: Props) -> Markup {
62 html! {
63 div class={"mui-alert " (props.variant.class())} role="alert" {
64 @if props.icon {
65 div class="mui-alert__icon" aria-hidden="true" {
66 (props.variant.icon_char())
67 }
68 }
69 div class="mui-alert__content" {
70 div class="mui-alert__title" {
71 (props.title)
72 }
73 @if let Some(desc) = props.description {
74 p class="mui-alert__description" {
75 (desc)
76 }
77 }
78 }
79 }
80 }
81}
82
83pub fn showcase() -> Markup {
85 html! {
86 div.mui-showcase__grid {
87 div {
88 p.mui-showcase__caption { "Subscription expiring" }
89 div.mui-showcase__column {
90 (render(Props {
91 title: "Your Pro plan expires in 3 days".into(),
92 description: Some("Renew by Apr 19 to keep unlimited builds and priority support. After expiry your workspace drops to the Free tier and projects over 3 will be archived.".into()),
93 variant: Variant::Warning,
94 icon: true,
95 }))
96 }
97 }
98
99 div {
100 p.mui-showcase__caption { "Two-factor enabled" }
101 div.mui-showcase__column {
102 (render(Props {
103 title: "Two-factor authentication is on".into(),
104 description: Some("Backup codes were emailed to invoice@geldentech.ca. Store them somewhere safe — you'll need one if you lose access to your authenticator.".into()),
105 variant: Variant::Success,
106 icon: true,
107 }))
108 }
109 }
110
111 div {
112 p.mui-showcase__caption { "Destructive — API key revocation" }
113 div.mui-showcase__column {
114 (render(Props {
115 title: "Revoke key sk_live_\u{2026}A9f2?".into(),
116 description: Some("Any services using this key will stop working immediately. This action cannot be undone — you'll need to issue a new key and redeploy.".into()),
117 variant: Variant::Danger,
118 icon: true,
119 }))
120 }
121 }
122
123 div {
124 p.mui-showcase__caption { "Informational" }
125 div.mui-showcase__column {
126 (render(Props {
127 title: "Scheduled maintenance Sunday 02:00 UTC".into(),
128 description: Some("The build pipeline will be paused for roughly 20 minutes. In-flight deploys will resume automatically once maintenance completes.".into()),
129 variant: Variant::Info,
130 icon: true,
131 }))
132 }
133 }
134 }
135 }
136}