qorzen_oxide/ui/pages/
settings.rs

1// src/ui/pages/settings.rs - Application settings and configuration
2
3use dioxus::prelude::*;
4
5use crate::ui::pages::PageWrapper;
6
7/// Main settings page component
8#[component]
9pub fn Settings() -> Element {
10    let mut active_section = use_signal(|| "general".to_string());
11
12    rsx! {
13        PageWrapper {
14            title: "Settings".to_string(),
15            subtitle: Some("Configure your application preferences".to_string()),
16
17            div {
18                class: "lg:grid lg:grid-cols-12 lg:gap-x-8",
19
20                // Settings navigation
21                aside {
22                    class: "py-6 px-2 sm:px-6 lg:py-0 lg:px-0 lg:col-span-3",
23                    nav {
24                        class: "space-y-1",
25
26                        // General
27                        button {
28                            r#type: "button",
29                            class: format!(
30                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
31                                if active_section() == "general" {
32                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
33                                } else {
34                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
35                                }
36                            ),
37                            onclick: move |_| active_section.set("general".to_string()),
38                            span {
39                                class: "text-lg mr-3",
40                                "⚙️"
41                            }
42                            "General"
43                        }
44
45                        // Appearance
46                        button {
47                            r#type: "button",
48                            class: format!(
49                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
50                                if active_section() == "appearance" {
51                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
52                                } else {
53                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
54                                }
55                            ),
56                            onclick: move |_| active_section.set("appearance".to_string()),
57                            span {
58                                class: "text-lg mr-3",
59                                "🎨"
60                            }
61                            "Appearance"
62                        }
63
64                        // Notifications
65                        button {
66                            r#type: "button",
67                            class: format!(
68                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
69                                if active_section() == "notifications" {
70                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
71                                } else {
72                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
73                                }
74                            ),
75                            onclick: move |_| active_section.set("notifications".to_string()),
76                            span {
77                                class: "text-lg mr-3",
78                                "🔔"
79                            }
80                            "Notifications"
81                        }
82
83                        // Security
84                        button {
85                            r#type: "button",
86                            class: format!(
87                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
88                                if active_section() == "security" {
89                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
90                                } else {
91                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
92                                }
93                            ),
94                            onclick: move |_| active_section.set("security".to_string()),
95                            span {
96                                class: "text-lg mr-3",
97                                "🔒"
98                            }
99                            "Security"
100                        }
101
102                        // System
103                        button {
104                            r#type: "button",
105                            class: format!(
106                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
107                                if active_section() == "system" {
108                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
109                                } else {
110                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
111                                }
112                            ),
113                            onclick: move |_| active_section.set("system".to_string()),
114                            span {
115                                class: "text-lg mr-3",
116                                "🖥️"
117                            }
118                            "System"
119                        }
120
121                        // About
122                        button {
123                            r#type: "button",
124                            class: format!(
125                                "group rounded-md px-3 py-2 flex items-center text-sm font-medium w-full text-left {}",
126                                if active_section() == "about" {
127                                    "bg-blue-50 text-blue-700 hover:text-blue-700 hover:bg-blue-50"
128                                } else {
129                                    "text-gray-900 hover:text-gray-900 hover:bg-gray-50"
130                                }
131                            ),
132                            onclick: move |_| active_section.set("about".to_string()),
133                            span {
134                                class: "text-lg mr-3",
135                                "ℹ️"
136                            }
137                            "About"
138                        }
139                    }
140                }
141
142                // Settings content
143                main {
144                    class: "lg:col-span-9",
145                    match active_section().as_str() {
146                        "general" => rsx! { GeneralSettings {} },
147                        "appearance" => rsx! { AppearanceSettings {} },
148                        "notifications" => rsx! { NotificationSettings {} },
149                        "security" => rsx! { SecuritySettings {} },
150                        "system" => rsx! { SystemSettings {} },
151                        "about" => rsx! { AboutSettings {} },
152                        _ => rsx! { div { "Unknown section" } }
153                    }
154                }
155            }
156        }
157    }
158}
159
160/// General settings section
161#[component]
162fn GeneralSettings() -> Element {
163    let mut language = use_signal(|| "en".to_string());
164    let mut timezone = use_signal(|| "UTC".to_string());
165    let mut date_format = use_signal(|| "MM/DD/YYYY".to_string());
166    let mut time_format = use_signal(|| "12h".to_string());
167    let mut auto_save = use_signal(|| true);
168    let mut saving = use_signal(|| false);
169
170    let handle_save = {
171        move |_| {
172            saving.set(true);
173            spawn(async move {
174                #[cfg(not(target_arch = "wasm32"))]
175                tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
176                #[cfg(target_arch = "wasm32")]
177                gloo_timers::future::TimeoutFuture::new(1000).await;
178                saving.set(false);
179            });
180        }
181    };
182
183    rsx! {
184        div {
185            class: "space-y-6",
186
187            // Section header
188            div {
189                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
190                div {
191                    class: "md:grid md:grid-cols-3 md:gap-6",
192                    div {
193                        class: "md:col-span-1",
194                        h3 {
195                            class: "text-lg font-medium leading-6 text-gray-900",
196                            "General Settings"
197                        }
198                        p {
199                            class: "mt-1 text-sm text-gray-500",
200                            "Configure basic application preferences and regional settings."
201                        }
202                    }
203                    div {
204                        class: "mt-5 md:mt-0 md:col-span-2",
205                        form {
206                            class: "space-y-6",
207                            onsubmit: handle_save,
208
209                            // Language selection
210                            div {
211                                label {
212                                    r#for: "language",
213                                    class: "block text-sm font-medium text-gray-700",
214                                    "Language"
215                                }
216                                select {
217                                    id: "language",
218                                    name: "language",
219                                    class: "mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md",
220                                    value: "{language}",
221                                    onchange: move |e| language.set(e.value()),
222                                    option { value: "en", "English" }
223                                    option { value: "es", "Español" }
224                                    option { value: "fr", "Français" }
225                                    option { value: "de", "Deutsch" }
226                                    option { value: "ja", "日本語" }
227                                    option { value: "zh", "中文" }
228                                }
229                            }
230
231                            // Timezone selection
232                            div {
233                                label {
234                                    r#for: "timezone",
235                                    class: "block text-sm font-medium text-gray-700",
236                                    "Timezone"
237                                }
238                                select {
239                                    id: "timezone",
240                                    name: "timezone",
241                                    class: "mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md",
242                                    value: "{timezone}",
243                                    onchange: move |e| timezone.set(e.value()),
244                                    option { value: "UTC", "UTC (Coordinated Universal Time)" }
245                                    option { value: "America/New_York", "Eastern Time (ET)" }
246                                    option { value: "America/Chicago", "Central Time (CT)" }
247                                    option { value: "America/Denver", "Mountain Time (MT)" }
248                                    option { value: "America/Los_Angeles", "Pacific Time (PT)" }
249                                    option { value: "Europe/London", "London (GMT)" }
250                                    option { value: "Europe/Paris", "Paris (CET)" }
251                                    option { value: "Asia/Tokyo", "Tokyo (JST)" }
252                                }
253                            }
254
255                            // Date format
256                            div {
257                                label {
258                                    r#for: "date_format",
259                                    class: "block text-sm font-medium text-gray-700",
260                                    "Date Format"
261                                }
262                                select {
263                                    id: "date_format",
264                                    name: "date_format",
265                                    class: "mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md",
266                                    value: "{date_format}",
267                                    onchange: move |e| date_format.set(e.value()),
268                                    option { value: "MM/DD/YYYY", "MM/DD/YYYY (12/31/2024)" }
269                                    option { value: "DD/MM/YYYY", "DD/MM/YYYY (31/12/2024)" }
270                                    option { value: "YYYY-MM-DD", "YYYY-MM-DD (2024-12-31)" }
271                                    option { value: "DD.MM.YYYY", "DD.MM.YYYY (31.12.2024)" }
272                                }
273                            }
274
275                            // Time format
276                            div {
277                                label {
278                                    r#for: "time_format",
279                                    class: "block text-sm font-medium text-gray-700",
280                                    "Time Format"
281                                }
282                                select {
283                                    id: "time_format",
284                                    name: "time_format",
285                                    class: "mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md",
286                                    value: "{time_format}",
287                                    onchange: move |e| time_format.set(e.value()),
288                                    option { value: "12h", "12-hour (2:30 PM)" }
289                                    option { value: "24h", "24-hour (14:30)" }
290                                }
291                            }
292
293                            // Auto-save toggle
294                            div {
295                                class: "flex items-center justify-between",
296                                div {
297                                    class: "flex flex-col",
298                                    label {
299                                        r#for: "auto_save",
300                                        class: "text-sm font-medium text-gray-700",
301                                        "Auto-save"
302                                    }
303                                    p {
304                                        class: "text-sm text-gray-500",
305                                        "Automatically save changes as you work"
306                                    }
307                                }
308                                button {
309                                    r#type: "button",
310                                    class: format!(
311                                        "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
312                                        if auto_save() { "bg-blue-600" } else { "bg-gray-200" }
313                                    ),
314                                    onclick: move |_| auto_save.set(!auto_save()),
315                                    span {
316                                        class: format!(
317                                            "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
318                                            if auto_save() { "translate-x-5" } else { "translate-x-0" }
319                                        )
320                                    }
321                                }
322                            }
323
324                            // Save button
325                            div {
326                                class: "flex justify-end",
327                                button {
328                                    r#type: "submit",
329                                    class: "bg-blue-600 border border-transparent rounded-md shadow-sm py-2 px-4 inline-flex justify-center text-sm font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50",
330                                    disabled: saving(),
331                                    if saving() { "Saving..." } else { "Save Changes" }
332                                }
333                            }
334                        }
335                    }
336                }
337            }
338        }
339    }
340}
341
342/// Appearance settings section
343#[component]
344fn AppearanceSettings() -> Element {
345    let mut theme = use_signal(|| "light".to_string());
346    let mut sidebar_collapsed = use_signal(|| false);
347    let mut compact_mode = use_signal(|| false);
348    let mut animations = use_signal(|| true);
349
350    rsx! {
351        div {
352            class: "space-y-6",
353
354            div {
355                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
356                div {
357                    class: "md:grid md:grid-cols-3 md:gap-6",
358                    div {
359                        class: "md:col-span-1",
360                        h3 {
361                            class: "text-lg font-medium leading-6 text-gray-900",
362                            "Appearance"
363                        }
364                        p {
365                            class: "mt-1 text-sm text-gray-500",
366                            "Customize the look and feel of your application."
367                        }
368                    }
369                    div {
370                        class: "mt-5 md:mt-0 md:col-span-2",
371                        div {
372                            class: "space-y-6",
373
374                            // Theme selection
375                            div {
376                                label {
377                                    class: "block text-sm font-medium text-gray-700",
378                                    "Theme"
379                                }
380                                div {
381                                    class: "mt-2 grid grid-cols-3 gap-3 sm:grid-cols-3",
382
383                                    // Light theme
384                                    label {
385                                        class: format!(
386                                            "cursor-pointer relative flex items-center justify-center rounded-md border py-3 px-3 text-sm font-medium uppercase hover:bg-gray-50 focus:outline-none {}",
387                                            if theme() == "light" {
388                                                "bg-blue-50 border-blue-200 text-blue-900"
389                                            } else {
390                                                "bg-white border-gray-200 text-gray-900"
391                                            }
392                                        ),
393                                        input {
394                                            r#type: "radio",
395                                            name: "theme",
396                                            value: "light",
397                                            class: "sr-only",
398                                            checked: theme() == "light",
399                                            onchange: move |_| theme.set("light".to_string())
400                                        }
401                                        span { "☀️ Light" }
402                                    }
403
404                                    // Dark theme
405                                    label {
406                                        class: format!(
407                                            "cursor-pointer relative flex items-center justify-center rounded-md border py-3 px-3 text-sm font-medium uppercase hover:bg-gray-50 focus:outline-none {}",
408                                            if theme() == "dark" {
409                                                "bg-blue-50 border-blue-200 text-blue-900"
410                                            } else {
411                                                "bg-white border-gray-200 text-gray-900"
412                                            }
413                                        ),
414                                        input {
415                                            r#type: "radio",
416                                            name: "theme",
417                                            value: "dark",
418                                            class: "sr-only",
419                                            checked: theme() == "dark",
420                                            onchange: move |_| theme.set("dark".to_string())
421                                        }
422                                        span { "🌙 Dark" }
423                                    }
424
425                                    // Auto theme
426                                    label {
427                                        class: format!(
428                                            "cursor-pointer relative flex items-center justify-center rounded-md border py-3 px-3 text-sm font-medium uppercase hover:bg-gray-50 focus:outline-none {}",
429                                            if theme() == "auto" {
430                                                "bg-blue-50 border-blue-200 text-blue-900"
431                                            } else {
432                                                "bg-white border-gray-200 text-gray-900"
433                                            }
434                                        ),
435                                        input {
436                                            r#type: "radio",
437                                            name: "theme",
438                                            value: "auto",
439                                            class: "sr-only",
440                                            checked: theme() == "auto",
441                                            onchange: move |_| theme.set("auto".to_string())
442                                        }
443                                        span { "🔄 Auto" }
444                                    }
445                                }
446                            }
447
448                            // Interface options
449                            div {
450                                class: "space-y-4",
451
452                                // Sidebar collapsed by default
453                                div {
454                                    class: "flex items-center justify-between",
455                                    div {
456                                        label {
457                                            class: "text-sm font-medium text-gray-700",
458                                            "Collapse sidebar by default"
459                                        }
460                                        p {
461                                            class: "text-sm text-gray-500",
462                                            "Start with a collapsed sidebar for more screen space"
463                                        }
464                                    }
465                                    button {
466                                        r#type: "button",
467                                        class: format!(
468                                            "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
469                                            if sidebar_collapsed() { "bg-blue-600" } else { "bg-gray-200" }
470                                        ),
471                                        onclick: move |_| sidebar_collapsed.set(!sidebar_collapsed()),
472                                        span {
473                                            class: format!(
474                                                "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
475                                                if sidebar_collapsed() { "translate-x-5" } else { "translate-x-0" }
476                                            )
477                                        }
478                                    }
479                                }
480
481                                // Compact mode
482                                div {
483                                    class: "flex items-center justify-between",
484                                    div {
485                                        label {
486                                            class: "text-sm font-medium text-gray-700",
487                                            "Compact mode"
488                                        }
489                                        p {
490                                            class: "text-sm text-gray-500",
491                                            "Reduce spacing and padding for denser layouts"
492                                        }
493                                    }
494                                    button {
495                                        r#type: "button",
496                                        class: format!(
497                                            "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
498                                            if compact_mode() { "bg-blue-600" } else { "bg-gray-200" }
499                                        ),
500                                        onclick: move |_| compact_mode.set(!compact_mode()),
501                                        span {
502                                            class: format!(
503                                                "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
504                                                if compact_mode() { "translate-x-5" } else { "translate-x-0" }
505                                            )
506                                        }
507                                    }
508                                }
509
510                                // Animations
511                                div {
512                                    class: "flex items-center justify-between",
513                                    div {
514                                        label {
515                                            class: "text-sm font-medium text-gray-700",
516                                            "Enable animations"
517                                        }
518                                        p {
519                                            class: "text-sm text-gray-500",
520                                            "Use animations and transitions for smoother interactions"
521                                        }
522                                    }
523                                    button {
524                                        r#type: "button",
525                                        class: format!(
526                                            "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
527                                            if animations() { "bg-blue-600" } else { "bg-gray-200" }
528                                        ),
529                                        onclick: move |_| animations.set(!animations()),
530                                        span {
531                                            class: format!(
532                                                "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
533                                                if animations() { "translate-x-5" } else { "translate-x-0" }
534                                            )
535                                        }
536                                    }
537                                }
538                            }
539                        }
540                    }
541                }
542            }
543        }
544    }
545}
546
547/// Notification settings section
548#[component]
549fn NotificationSettings() -> Element {
550    let mut email_notifications = use_signal(|| true);
551    let mut push_notifications = use_signal(|| false);
552    let mut desktop_notifications = use_signal(|| true);
553    let mut sound_enabled = use_signal(|| false);
554
555    rsx! {
556        div {
557            class: "space-y-6",
558
559            div {
560                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
561                div {
562                    class: "md:grid md:grid-cols-3 md:gap-6",
563                    div {
564                        class: "md:col-span-1",
565                        h3 {
566                            class: "text-lg font-medium leading-6 text-gray-900",
567                            "Notifications"
568                        }
569                        p {
570                            class: "mt-1 text-sm text-gray-500",
571                            "Choose how you want to be notified about updates and events."
572                        }
573                    }
574                    div {
575                        class: "mt-5 md:mt-0 md:col-span-2",
576                        div {
577                            class: "space-y-6",
578
579                            // Email notifications
580                            div {
581                                class: "flex items-center justify-between",
582                                div {
583                                    label {
584                                        class: "text-sm font-medium text-gray-700",
585                                        "Email notifications"
586                                    }
587                                    p {
588                                        class: "text-sm text-gray-500",
589                                        "Receive important updates via email"
590                                    }
591                                }
592                                button {
593                                    r#type: "button",
594                                    class: format!(
595                                        "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
596                                        if email_notifications() { "bg-blue-600" } else { "bg-gray-200" }
597                                    ),
598                                    onclick: move |_| email_notifications.set(!email_notifications()),
599                                    span {
600                                        class: format!(
601                                            "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
602                                            if email_notifications() { "translate-x-5" } else { "translate-x-0" }
603                                        )
604                                    }
605                                }
606                            }
607
608                            // Push notifications
609                            div {
610                                class: "flex items-center justify-between",
611                                div {
612                                    label {
613                                        class: "text-sm font-medium text-gray-700",
614                                        "Push notifications"
615                                    }
616                                    p {
617                                        class: "text-sm text-gray-500",
618                                        "Show notifications in your browser"
619                                    }
620                                }
621                                button {
622                                    r#type: "button",
623                                    class: format!(
624                                        "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
625                                        if push_notifications() { "bg-blue-600" } else { "bg-gray-200" }
626                                    ),
627                                    onclick: move |_| push_notifications.set(!push_notifications()),
628                                    span {
629                                        class: format!(
630                                            "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
631                                            if push_notifications() { "translate-x-5" } else { "translate-x-0" }
632                                        )
633                                    }
634                                }
635                            }
636
637                            // Desktop notifications
638                            div {
639                                class: "flex items-center justify-between",
640                                div {
641                                    label {
642                                        class: "text-sm font-medium text-gray-700",
643                                        "Desktop notifications"
644                                    }
645                                    p {
646                                        class: "text-sm text-gray-500",
647                                        "Show system notifications on your desktop"
648                                    }
649                                }
650                                button {
651                                    r#type: "button",
652                                    class: format!(
653                                        "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
654                                        if desktop_notifications() { "bg-blue-600" } else { "bg-gray-200" }
655                                    ),
656                                    onclick: move |_| desktop_notifications.set(!desktop_notifications()),
657                                    span {
658                                        class: format!(
659                                            "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
660                                            if desktop_notifications() { "translate-x-5" } else { "translate-x-0" }
661                                        )
662                                    }
663                                }
664                            }
665
666                            // Sound notifications
667                            div {
668                                class: "flex items-center justify-between",
669                                div {
670                                    label {
671                                        class: "text-sm font-medium text-gray-700",
672                                        "Sound notifications"
673                                    }
674                                    p {
675                                        class: "text-sm text-gray-500",
676                                        "Play sounds for notifications"
677                                    }
678                                }
679                                button {
680                                    r#type: "button",
681                                    class: format!(
682                                        "relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 {}",
683                                        if sound_enabled() { "bg-blue-600" } else { "bg-gray-200" }
684                                    ),
685                                    onclick: move |_| sound_enabled.set(!sound_enabled()),
686                                    span {
687                                        class: format!(
688                                            "pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200 {}",
689                                            if sound_enabled() { "translate-x-5" } else { "translate-x-0" }
690                                        )
691                                    }
692                                }
693                            }
694                        }
695                    }
696                }
697            }
698        }
699    }
700}
701
702/// Security settings section
703#[component]
704fn SecuritySettings() -> Element {
705    rsx! {
706        div {
707            class: "space-y-6",
708
709            div {
710                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
711                div {
712                    class: "md:grid md:grid-cols-3 md:gap-6",
713                    div {
714                        class: "md:col-span-1",
715                        h3 {
716                            class: "text-lg font-medium leading-6 text-gray-900",
717                            "Security"
718                        }
719                        p {
720                            class: "mt-1 text-sm text-gray-500",
721                            "Manage your account security settings and preferences."
722                        }
723                    }
724                    div {
725                        class: "mt-5 md:mt-0 md:col-span-2",
726                        div {
727                            class: "space-y-6",
728
729                            // Change password
730                            div {
731                                class: "flex items-center justify-between py-4 border-b border-gray-200",
732                                div {
733                                    h4 {
734                                        class: "text-sm font-medium text-gray-900",
735                                        "Password"
736                                    }
737                                    p {
738                                        class: "text-sm text-gray-500",
739                                        "Last changed 3 months ago"
740                                    }
741                                }
742                                button {
743                                    r#type: "button",
744                                    class: "bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
745                                    "Change Password"
746                                }
747                            }
748
749                            // Two-factor authentication
750                            div {
751                                class: "flex items-center justify-between py-4 border-b border-gray-200",
752                                div {
753                                    h4 {
754                                        class: "text-sm font-medium text-gray-900",
755                                        "Two-Factor Authentication"
756                                    }
757                                    p {
758                                        class: "text-sm text-gray-500",
759                                        "Add an extra layer of security to your account"
760                                    }
761                                }
762                                button {
763                                    r#type: "button",
764                                    class: "bg-blue-600 border border-transparent rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
765                                    "Enable 2FA"
766                                }
767                            }
768
769                            // Session management
770                            div {
771                                class: "flex items-center justify-between py-4 border-b border-gray-200",
772                                div {
773                                    h4 {
774                                        class: "text-sm font-medium text-gray-900",
775                                        "Active Sessions"
776                                    }
777                                    p {
778                                        class: "text-sm text-gray-500",
779                                        "Manage devices where you're signed in"
780                                    }
781                                }
782                                button {
783                                    r#type: "button",
784                                    class: "bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
785                                    "Manage Sessions"
786                                }
787                            }
788
789                            // Account deletion
790                            div {
791                                class: "pt-4",
792                                div {
793                                    h4 {
794                                        class: "text-sm font-medium text-red-900",
795                                        "Danger Zone"
796                                    }
797                                    p {
798                                        class: "text-sm text-red-600 mt-1",
799                                        "Permanently delete your account and all associated data. This action cannot be undone."
800                                    }
801                                    button {
802                                        r#type: "button",
803                                        class: "mt-3 bg-red-600 border border-transparent rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",
804                                        "Delete Account"
805                                    }
806                                }
807                            }
808                        }
809                    }
810                }
811            }
812        }
813    }
814}
815
816/// System settings section
817#[component]
818fn SystemSettings() -> Element {
819    let build = option_env!("BUILD_HASH").unwrap_or("dev");
820
821    rsx! {
822        div {
823            class: "space-y-6",
824
825            div {
826                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
827                div {
828                    class: "md:grid md:grid-cols-3 md:gap-6",
829                    div {
830                        class: "md:col-span-1",
831                        h3 {
832                            class: "text-lg font-medium leading-6 text-gray-900",
833                            "System"
834                        }
835                        p {
836                            class: "mt-1 text-sm text-gray-500",
837                            "System-level settings and maintenance options."
838                        }
839                    }
840                    div {
841                        class: "mt-5 md:mt-0 md:col-span-2",
842                        div {
843                            class: "space-y-6",
844
845                            // Cache management
846                            div {
847                                class: "flex items-center justify-between py-4 border-b border-gray-200",
848                                div {
849                                    h4 {
850                                        class: "text-sm font-medium text-gray-900",
851                                        "Cache"
852                                    }
853                                    p {
854                                        class: "text-sm text-gray-500",
855                                        "Clear application cache to free up space"
856                                    }
857                                }
858                                button {
859                                    r#type: "button",
860                                    class: "bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
861                                    "Clear Cache"
862                                }
863                            }
864
865                            // Data export
866                            div {
867                                class: "flex items-center justify-between py-4 border-b border-gray-200",
868                                div {
869                                    h4 {
870                                        class: "text-sm font-medium text-gray-900",
871                                        "Data Export"
872                                    }
873                                    p {
874                                        class: "text-sm text-gray-500",
875                                        "Download a copy of your data"
876                                    }
877                                }
878                                button {
879                                    r#type: "button",
880                                    class: "bg-blue-600 border border-transparent rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
881                                    "Export Data"
882                                }
883                            }
884
885                            // System logs
886                            div {
887                                class: "flex items-center justify-between py-4 border-b border-gray-200",
888                                div {
889                                    h4 {
890                                        class: "text-sm font-medium text-gray-900",
891                                        "System Logs"
892                                    }
893                                    p {
894                                        class: "text-sm text-gray-500",
895                                        "View and download system log files"
896                                    }
897                                }
898                                button {
899                                    r#type: "button",
900                                    class: "bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",
901                                    "View Logs"
902                                }
903                            }
904
905                            // System information
906                            div {
907                                class: "pt-4",
908                                div {
909                                    class: "bg-gray-50 rounded-lg p-4",
910                                    h4 {
911                                        class: "text-sm font-medium text-gray-900 mb-3",
912                                        "System Information"
913                                    }
914                                    dl {
915                                        class: "grid grid-cols-1 gap-x-4 gap-y-2 sm:grid-cols-2",
916                                        div {
917                                            dt {
918                                                class: "text-sm font-medium text-gray-500",
919                                                "Version"
920                                            }
921                                            dd {
922                                                class: "text-sm text-gray-900",
923                                                "{crate::VERSION}"
924                                            }
925                                        }
926                                        div {
927                                            dt {
928                                                class: "text-sm font-medium text-gray-500",
929                                                "Platform"
930                                            }
931                                            dd {
932                                                class: "text-sm text-gray-900",
933                                                "Web (WASM)"
934                                            }
935                                        }
936                                        div {
937                                            dt {
938                                                class: "text-sm font-medium text-gray-500",
939                                                "Build"
940                                            }
941                                            dd {
942                                                class: "text-sm text-gray-900",
943                                                "{build}"
944                                            }
945                                        }
946                                        div {
947                                            dt {
948                                                class: "text-sm font-medium text-gray-500",
949                                                "User Agent"
950                                            }
951                                            dd {
952                                                class: "text-sm text-gray-900",
953                                                "Qorzen Application"
954                                            }
955                                        }
956                                    }
957                                }
958                            }
959                        }
960                    }
961                }
962            }
963        }
964    }
965}
966
967/// About section
968#[component]
969fn AboutSettings() -> Element {
970    rsx! {
971        div {
972            class: "space-y-6",
973
974            div {
975                class: "bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6",
976                div {
977                    class: "text-center",
978                    div {
979                        class: "mx-auto h-16 w-16 bg-blue-600 rounded-xl flex items-center justify-center mb-4",
980                        span {
981                            class: "text-white font-bold text-2xl",
982                            "Q"
983                        }
984                    }
985                    h2 {
986                        class: "text-2xl font-bold text-gray-900",
987                        "Qorzen"
988                    }
989                    p {
990                        class: "text-sm text-gray-500 mt-1",
991                        "Version {crate::VERSION}"
992                    }
993                    p {
994                        class: "text-gray-600 mt-4 max-w-2xl mx-auto",
995                        "A modular, cross-platform application framework built with Rust and Dioxus.
996                         Designed for modern development workflows with extensibility through plugins."
997                    }
998
999                    div {
1000                        class: "mt-8 flex justify-center space-x-6",
1001                        a {
1002                            href: "https://github.com/qorzen/qorzen-oxide",
1003                            target: "_blank",
1004                            rel: "noopener noreferrer",
1005                            class: "text-gray-400 hover:text-gray-500",
1006                            span {
1007                                class: "sr-only",
1008                                "GitHub"
1009                            }
1010                            "🐙 GitHub"
1011                        }
1012                        a {
1013                            href: "https://docs.qorzen.com",
1014                            target: "_blank",
1015                            rel: "noopener noreferrer",
1016                            class: "text-gray-400 hover:text-gray-500",
1017                            "📚 Documentation"
1018                        }
1019                        a {
1020                            href: "mailto:support@qorzen.com",
1021                            class: "text-gray-400 hover:text-gray-500",
1022                            "📧 Support"
1023                        }
1024                    }
1025
1026                    div {
1027                        class: "mt-8 pt-8 border-t border-gray-200",
1028                        p {
1029                            class: "text-sm text-gray-500",
1030                            "© 2024 Qorzen. Built with ❤️ and 🦀"
1031                        }
1032                        p {
1033                            class: "text-xs text-gray-400 mt-2",
1034                            "Licensed under the MIT License"
1035                        }
1036                    }
1037                }
1038            }
1039        }
1040    }
1041}
1042
1043#[cfg(test)]
1044mod tests {
1045    use super::*;
1046
1047    #[test]
1048    fn test_settings_component_creation() {
1049        let _settings = rsx! { Settings {} };
1050    }
1051
1052    #[test]
1053    fn test_general_settings_creation() {
1054        let _general = rsx! { GeneralSettings {} };
1055    }
1056
1057    #[test]
1058    fn test_appearance_settings_creation() {
1059        let _appearance = rsx! { AppearanceSettings {} };
1060    }
1061}