feat: add locale and currency settings with searchable dropdowns

This commit is contained in:
Your Name
2026-02-17 23:35:27 +02:00
parent a13dff96c8
commit 8112fe8fd6

View File

@@ -53,6 +53,44 @@
</button> </button>
</div> </div>
</div> </div>
<div class="flex items-center justify-between mt-5">
<div>
<p class="text-[0.8125rem] text-text-primary">Locale</p>
<p class="text-[0.6875rem] text-text-tertiary mt-0.5">Date and number formatting</p>
</div>
<div class="w-56">
<AppSelect
v-model="locale"
:options="LOCALES"
label-key="name"
value-key="code"
placeholder="System Default"
:placeholder-value="'system'"
:searchable="true"
@update:model-value="saveLocaleSettings"
/>
</div>
</div>
<div class="flex items-center justify-between mt-5">
<div>
<p class="text-[0.8125rem] text-text-primary">Currency</p>
<p class="text-[0.6875rem] text-text-tertiary mt-0.5">Currency symbol and formatting</p>
</div>
<div class="w-56">
<AppSelect
v-model="currency"
:options="currencyOptions"
label-key="name"
value-key="code"
placeholder="US Dollar"
:placeholder-value="'USD'"
:searchable="true"
@update:model-value="saveLocaleSettings"
/>
</div>
</div>
</div> </div>
<!-- Timer --> <!-- Timer -->
@@ -112,18 +150,14 @@
<p class="text-[0.8125rem] text-text-primary">Default Hourly Rate</p> <p class="text-[0.8125rem] text-text-primary">Default Hourly Rate</p>
<p class="text-[0.6875rem] text-text-tertiary mt-0.5">Applied to new projects</p> <p class="text-[0.6875rem] text-text-tertiary mt-0.5">Applied to new projects</p>
</div> </div>
<div class="flex items-center gap-1"> <AppNumberInput
<span class="text-[0.8125rem] text-text-tertiary">$</span> v-model="hourlyRate"
<input :min="0"
v-model.number="hourlyRate" :step="1"
type="number" :precision="2"
min="0" prefix="$"
step="0.01" @update:model-value="saveSettings"
class="w-24 px-3 py-1.5 bg-bg-inset border border-border-subtle rounded-lg text-[0.8125rem] text-text-primary text-right font-mono focus:outline-none focus:border-border-visible" />
placeholder="0.00"
@change="saveSettings"
/>
</div>
</div> </div>
</div> </div>
@@ -205,6 +239,9 @@ import { invoke } from '@tauri-apps/api/core'
import { Settings as SettingsIcon, Clock, Receipt, Database, Plus, Minus } from 'lucide-vue-next' import { Settings as SettingsIcon, Clock, Receipt, Database, Plus, Minus } from 'lucide-vue-next'
import { useSettingsStore } from '../stores/settings' import { useSettingsStore } from '../stores/settings'
import { useToastStore } from '../stores/toast' import { useToastStore } from '../stores/toast'
import AppNumberInput from '../components/AppNumberInput.vue'
import AppSelect from '../components/AppSelect.vue'
import { LOCALES, getCurrencies } from '../utils/locale'
const settingsStore = useSettingsStore() const settingsStore = useSettingsStore()
const toastStore = useToastStore() const toastStore = useToastStore()
@@ -224,6 +261,9 @@ const hourlyRate = ref(0)
const idleDetection = ref(true) const idleDetection = ref(true)
const reminderInterval = ref(15) const reminderInterval = ref(15)
const zoomLevel = ref(100) const zoomLevel = ref(100)
const locale = ref('system')
const currency = ref('USD')
const currencyOptions = getCurrencies()
// Dialog state // Dialog state
const showClearDataDialog = ref(false) const showClearDataDialog = ref(false)
@@ -279,6 +319,12 @@ async function saveSettings() {
} }
} }
// Save locale/currency settings
async function saveLocaleSettings() {
await settingsStore.updateSetting('locale', locale.value)
await settingsStore.updateSetting('currency', currency.value)
}
// Export all data // Export all data
async function exportData() { async function exportData() {
try { try {
@@ -318,5 +364,7 @@ onMounted(async () => {
idleDetection.value = settingsStore.settings.idle_detection !== 'false' idleDetection.value = settingsStore.settings.idle_detection !== 'false'
reminderInterval.value = parseInt(settingsStore.settings.reminder_interval) || 15 reminderInterval.value = parseInt(settingsStore.settings.reminder_interval) || 15
zoomLevel.value = parseInt(settingsStore.settings.ui_zoom) || 100 zoomLevel.value = parseInt(settingsStore.settings.ui_zoom) || 100
locale.value = settingsStore.settings.locale || 'system'
currency.value = settingsStore.settings.currency || 'USD'
}) })
</script> </script>