feat: add locale and currency settings with searchable dropdowns
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user