feat: add user theme preference

- Add theme field to User model (common)
- Create migration for theme field
- Add theme selection to Account Settings (html-router)
- Implement server-side theme rendering in base template
- Update JS for system/preference theme handling
- Remove header theme toggle for authenticated users
This commit is contained in:
Per Stark
2026-01-16 13:54:07 +01:00
parent 0df2b9810c
commit b25cfb4633
12 changed files with 282 additions and 42 deletions
@@ -18,6 +18,7 @@ pub struct AccountPageData {
user: User,
timezones: Vec<String>,
conversation_archive: Vec<Conversation>,
theme_options: Vec<String>,
}
pub async fn show_account_page(
@@ -28,6 +29,11 @@ pub async fn show_account_page(
.iter()
.map(std::string::ToString::to_string)
.collect();
let theme_options = vec![
"light".to_string(),
"dark".to_string(),
"system".to_string(),
];
let conversation_archive = User::get_user_conversations(&user.id, &state.db).await?;
Ok(TemplateResponse::new_template(
@@ -36,6 +42,7 @@ pub async fn show_account_page(
user,
timezones,
conversation_archive,
theme_options,
},
))
}
@@ -65,6 +72,7 @@ pub async fn set_api_key(
user: updated_user,
timezones: vec![],
conversation_archive: vec![],
theme_options: vec![],
},
))
}
@@ -118,6 +126,47 @@ pub async fn update_timezone(
user: updated_user,
timezones,
conversation_archive: vec![],
theme_options: vec![],
},
))
}
#[derive(Deserialize)]
pub struct UpdateThemeForm {
theme: String,
}
pub async fn update_theme(
State(state): State<HtmlState>,
RequireUser(user): RequireUser,
auth: AuthSessionType,
Form(form): Form<UpdateThemeForm>,
) -> Result<impl IntoResponse, HtmlError> {
User::update_theme(&user.id, &form.theme, &state.db).await?;
// Clear the cache
auth.cache_clear_user(user.id.to_string());
// Update the user's theme
let updated_user = User {
theme: form.theme,
..user.clone()
};
let theme_options = vec![
"light".to_string(),
"dark".to_string(),
"system".to_string(),
];
Ok(TemplateResponse::new_partial(
"auth/account_settings.html",
"theme_section",
AccountPageData {
user: updated_user,
timezones: vec![],
conversation_archive: vec![],
theme_options,
},
))
}
+1
View File
@@ -16,6 +16,7 @@ where
.route("/account", get(handlers::show_account_page))
.route("/set-api-key", post(handlers::set_api_key))
.route("/update-timezone", patch(handlers::update_timezone))
.route("/update-theme", patch(handlers::update_theme))
.route(
"/change-password",
get(handlers::show_change_password).patch(handlers::change_password),