feat: sync user preferences (currency, locale) with Directus on login/logout

This commit is contained in:
2026-02-05 17:29:34 +01:00
parent 56cf5a63c3
commit 5c66ca28b9
4 changed files with 86 additions and 6 deletions

View File

@@ -173,6 +173,19 @@ User-Favoriten.
--- ---
## directus_users (Custom Fields)
Zusätzliche Felder für User-Einstellungen.
| Feld | Typ | Beschreibung |
|------|-----|--------------|
| `preferred_currency` | string | Bevorzugte Währung: `USD`, `EUR`, `CHF` (Default: `USD`) |
| `preferred_locale` | string | Bevorzugte Sprache: `de`, `en`, `fr` |
**Hinweis:** Diese Felder müssen in Directus unter Settings → Data Model → directus_users angelegt werden.
---
## reports ## reports
Meldungen von Anzeigen. Meldungen von Anzeigen.

View File

@@ -46,13 +46,17 @@ class PageSettings extends HTMLElement {
}) })
// Language select // Language select
this.querySelector('#lang-select')?.addEventListener('change', (e) => { this.querySelector('#lang-select')?.addEventListener('change', async (e) => {
i18n.setLocale(e.target.value) i18n.setLocale(e.target.value)
// Save to user profile if logged in
if (this.isLoggedIn) {
await auth.updatePreferences({ preferred_locale: e.target.value })
}
}) })
// Currency select // Currency select
this.querySelector('#currency-select')?.addEventListener('change', (e) => { this.querySelector('#currency-select')?.addEventListener('change', async (e) => {
this.setCurrency(e.target.value) await this.setCurrency(e.target.value)
this.showToast(t('settings.currencyChanged')) this.showToast(t('settings.currencyChanged'))
}) })
@@ -103,9 +107,14 @@ class PageSettings extends HTMLElement {
return localStorage.getItem('dgray_currency') || 'USD' return localStorage.getItem('dgray_currency') || 'USD'
} }
setCurrency(currency) { async setCurrency(currency) {
localStorage.setItem('dgray_currency', currency) localStorage.setItem('dgray_currency', currency)
window.dispatchEvent(new CustomEvent('currency-changed', { detail: { currency } })) window.dispatchEvent(new CustomEvent('currency-changed', { detail: { currency } }))
// Save to user profile if logged in
if (auth.isLoggedIn()) {
await auth.updatePreferences({ preferred_currency: currency })
}
} }
showToast(message) { showToast(message) {

View File

@@ -7,6 +7,7 @@
*/ */
import { directus } from './directus.js' import { directus } from './directus.js'
import { i18n } from '../i18n.js'
const AUTH_DOMAIN = 'dgray.io' const AUTH_DOMAIN = 'dgray.io'
@@ -122,7 +123,7 @@ class AuthService {
} }
/** /**
* Logs out the current user * Logs out the current user and resets preferences to defaults
*/ */
async logout() { async logout() {
try { try {
@@ -133,9 +134,24 @@ class AuthService {
this.currentUser = null this.currentUser = null
this.clearStoredUuid() this.clearStoredUuid()
this.resetPreferencesToDefaults()
this.notifyListeners() this.notifyListeners()
} }
/**
* Reset preferences to defaults on logout
*/
resetPreferencesToDefaults() {
const defaultCurrency = 'USD'
const defaultLocale = 'en'
localStorage.setItem('dgray_currency', defaultCurrency)
localStorage.setItem('locale', defaultLocale)
window.dispatchEvent(new CustomEvent('currency-changed', { detail: { currency: defaultCurrency } }))
i18n.setLocale(defaultLocale)
}
/** /**
* Checks if user is logged in * Checks if user is logged in
* @returns {boolean} * @returns {boolean}
@@ -154,6 +170,8 @@ class AuthService {
if (!this.currentUser) { if (!this.currentUser) {
try { try {
this.currentUser = await directus.getCurrentUser() this.currentUser = await directus.getCurrentUser()
// Sync preferences to localStorage
this.syncPreferencesToLocal()
} catch (e) { } catch (e) {
return null return null
} }
@@ -162,6 +180,45 @@ class AuthService {
return this.currentUser return this.currentUser
} }
/**
* Sync user preferences from Directus to localStorage and apply them
*/
syncPreferencesToLocal() {
if (!this.currentUser) return
if (this.currentUser.preferred_currency) {
const currency = this.currentUser.preferred_currency
localStorage.setItem('dgray_currency', currency)
window.dispatchEvent(new CustomEvent('currency-changed', { detail: { currency } }))
}
if (this.currentUser.preferred_locale) {
const locale = this.currentUser.preferred_locale
localStorage.setItem('locale', locale)
i18n.setLocale(locale)
}
}
/**
* Update user preferences in Directus
* @param {Object} prefs - Preferences to update
* @param {string} [prefs.preferred_currency] - Currency code
* @param {string} [prefs.preferred_locale] - Locale code
* @returns {Promise<boolean>} Success
*/
async updatePreferences(prefs) {
if (!this.isLoggedIn()) return false
try {
await directus.updateCurrentUser(prefs)
// Update local cache
this.currentUser = { ...this.currentUser, ...prefs }
return true
} catch (e) {
console.error('Failed to update preferences:', e)
return false
}
}
/** /**
* Stores UUID in localStorage (optional convenience) * Stores UUID in localStorage (optional convenience)
* User should still backup their UUID * User should still backup their UUID
@@ -210,6 +267,7 @@ class AuthService {
if (directus.isAuthenticated()) { if (directus.isAuthenticated()) {
try { try {
this.currentUser = await directus.getCurrentUser() this.currentUser = await directus.getCurrentUser()
this.syncPreferencesToLocal()
this.notifyListeners() this.notifyListeners()
return true return true
} catch (e) { } catch (e) {

View File

@@ -296,7 +296,7 @@ class DirectusService {
async getCurrentUser() { async getCurrentUser() {
const response = await this.get('/users/me', { const response = await this.get('/users/me', {
fields: ['id', 'email', 'first_name', 'last_name', 'avatar', 'role.name', 'status'] fields: ['id', 'email', 'first_name', 'last_name', 'avatar', 'role.name', 'status', 'preferred_currency', 'preferred_locale']
}) })
return response.data return response.data
} }