commit f28c18b00f595f7f6bc6b2ddbbb19ea195b030ab
parent 53910f99f8219ba117b1ce33944cb12b1c0a16b4
Author: triesap <triesap@radroots.dev>
Date: Thu, 22 Jan 2026 11:29:45 +0000
app: add settings route
- create settings page with appearance and actions lists
- wire noop callbacks that log action names
- add settings module export for routing
- register /settings in nav and routes
Diffstat:
3 files changed, 189 insertions(+), 0 deletions(-)
diff --git a/app/src/app.rs b/app/src/app.rs
@@ -40,6 +40,7 @@ use crate::{
RadrootsAppInitStage,
RadrootsAppNotifications,
RadrootsAppLogsPage,
+ RadrootsAppSettingsPage,
RadrootsAppUiDemoPage,
RadrootsAppTangleClientStub,
};
@@ -702,12 +703,14 @@ fn AppShell() -> impl IntoView {
<A href="/" exact=true>"home"</A>
<A href="/logs">"logs"</A>
<A href="/ui">"ui"</A>
+ <A href="/settings">"settings"</A>
<A href="/setup">"setup"</A>
</nav>
<Routes fallback=|| view! { <div>"not_found"</div> }>
<Route path=path!("") view=HomePage />
<Route path=path!("logs") view=RadrootsAppLogsPage />
<Route path=path!("ui") view=RadrootsAppUiDemoPage />
+ <Route path=path!("settings") view=RadrootsAppSettingsPage />
<Route path=path!("setup") view=SetupPage />
</Routes>
</Show>
diff --git a/app/src/lib.rs b/app/src/lib.rs
@@ -11,6 +11,7 @@ mod keystore;
mod logging;
mod logs;
mod notifications;
+mod settings;
mod setup;
mod tangle;
mod ui_demo;
@@ -62,6 +63,7 @@ pub use keystore::{
RadrootsAppKeystoreResult,
};
pub use logs::RadrootsAppLogsPage;
+pub use settings::RadrootsAppSettingsPage;
pub use ui_demo::RadrootsAppUiDemoPage;
pub use logging::{
app_log_entry_error,
diff --git a/app/src/settings.rs b/app/src/settings.rs
@@ -0,0 +1,184 @@
+#![forbid(unsafe_code)]
+
+use leptos::ev::MouseEvent;
+use leptos::prelude::*;
+
+use radroots_app_ui_components::{
+ RadrootsAppUiList,
+ RadrootsAppUiListIcon,
+ RadrootsAppUiListItem,
+ RadrootsAppUiListItemKind,
+ RadrootsAppUiListLabel,
+ RadrootsAppUiListLabelText,
+ RadrootsAppUiListLabelValue,
+ RadrootsAppUiListLabelValueKind,
+ RadrootsAppUiListSelect,
+ RadrootsAppUiListSelectField,
+ RadrootsAppUiListSelectOption,
+ RadrootsAppUiListStyles,
+ RadrootsAppUiListTitle,
+ RadrootsAppUiListTitleValue,
+ RadrootsAppUiListTouch,
+ RadrootsAppUiListTouchEnd,
+ RadrootsAppUiListView,
+};
+
+fn log_settings_action(action: &str) {
+ #[cfg(target_arch = "wasm32")]
+ {
+ web_sys::console::log_1(&action.into());
+ }
+ #[cfg(not(target_arch = "wasm32"))]
+ {
+ println!("{action}");
+ }
+}
+
+fn settings_touch_callback(action: &'static str) -> Callback<MouseEvent> {
+ Callback::new(move |_| log_settings_action(action))
+}
+
+fn settings_label(value: &str, classes: Option<&str>) -> RadrootsAppUiListLabelValue {
+ RadrootsAppUiListLabelValue {
+ classes_wrap: None,
+ hide_truncate: false,
+ value: RadrootsAppUiListLabelValueKind::Text(RadrootsAppUiListLabelText {
+ value: value.to_string(),
+ classes: classes.map(str::to_string),
+ }),
+ }
+}
+
+#[component]
+pub fn RadrootsAppSettingsPage() -> impl IntoView {
+ let color_mode_callback = Callback::new(move |_value: String| {
+ log_settings_action("settings_color_mode");
+ });
+ let appearance_list = RadrootsAppUiList {
+ id: Some("settings-appearance".to_string()),
+ view: Some("settings".to_string()),
+ classes: None,
+ title: Some(RadrootsAppUiListTitle {
+ value: RadrootsAppUiListTitleValue::Text("Appearance".to_string()),
+ classes: None,
+ mod_value: None,
+ link: None,
+ on_click: None,
+ }),
+ default_state: None,
+ list: Some(vec![Some(RadrootsAppUiListItem {
+ kind: RadrootsAppUiListItemKind::Select(RadrootsAppUiListSelect {
+ field: RadrootsAppUiListSelectField {
+ value: "light".to_string(),
+ options: vec![
+ RadrootsAppUiListSelectOption {
+ label: "Light".to_string(),
+ value: "light".to_string(),
+ classes: None,
+ },
+ RadrootsAppUiListSelectOption {
+ label: "Dark".to_string(),
+ value: "dark".to_string(),
+ classes: None,
+ },
+ ],
+ disabled: false,
+ classes: None,
+ id: Some("settings-color-mode".to_string()),
+ on_change: Some(color_mode_callback),
+ },
+ label: RadrootsAppUiListLabel {
+ left: vec![settings_label("color mode", Some("capitalize"))],
+ right: Vec::new(),
+ },
+ display: None,
+ end: Some(RadrootsAppUiListTouchEnd {
+ icon: RadrootsAppUiListIcon {
+ key: "chevrons-up-down".to_string(),
+ class: None,
+ },
+ on_click: None,
+ }),
+ loading: false,
+ on_click: None,
+ }),
+ loading: false,
+ hide_active: true,
+ hide_field: false,
+ full_rounded: false,
+ offset: None,
+ })]),
+ hide_offset: false,
+ styles: Some(RadrootsAppUiListStyles {
+ hide_border_top: None,
+ hide_border_bottom: None,
+ hide_rounded: None,
+ set_title_background: Some(true),
+ set_default_background: None,
+ }),
+ };
+ let actions_list = RadrootsAppUiList {
+ id: Some("settings-actions".to_string()),
+ view: Some("settings".to_string()),
+ classes: None,
+ title: None,
+ default_state: None,
+ list: Some(vec![
+ Some(RadrootsAppUiListItem {
+ kind: RadrootsAppUiListItemKind::Touch(RadrootsAppUiListTouch {
+ label: RadrootsAppUiListLabel {
+ left: vec![settings_label("export database", Some("capitalize"))],
+ right: Vec::new(),
+ },
+ display: None,
+ end: Some(RadrootsAppUiListTouchEnd {
+ icon: RadrootsAppUiListIcon {
+ key: "caret-right".to_string(),
+ class: None,
+ },
+ on_click: None,
+ }),
+ on_click: Some(settings_touch_callback("settings_export_database")),
+ }),
+ loading: false,
+ hide_active: true,
+ hide_field: false,
+ full_rounded: false,
+ offset: None,
+ }),
+ Some(RadrootsAppUiListItem {
+ kind: RadrootsAppUiListItemKind::Touch(RadrootsAppUiListTouch {
+ label: RadrootsAppUiListLabel {
+ left: vec![settings_label("logout", Some("capitalize"))],
+ right: Vec::new(),
+ },
+ display: None,
+ end: Some(RadrootsAppUiListTouchEnd {
+ icon: RadrootsAppUiListIcon {
+ key: "caret-right".to_string(),
+ class: None,
+ },
+ on_click: None,
+ }),
+ on_click: Some(settings_touch_callback("settings_logout")),
+ }),
+ loading: false,
+ hide_active: true,
+ hide_field: false,
+ full_rounded: false,
+ offset: None,
+ }),
+ ]),
+ hide_offset: false,
+ styles: None,
+ };
+ view! {
+ <main style="padding: 16px;">
+ <div style="font: var(--type-title2); margin-bottom: 12px;">"settings"</div>
+ <div style="display:flex;flex-direction:column;gap:16px;">
+ <RadrootsAppUiListView basis=appearance_list />
+ <RadrootsAppUiListView basis=actions_list />
+ </div>
+ </main>
+ }
+}