feat(settings): add timezone field to General tab
- New Timezone section with text input + Detect button - Detect auto-fills from browser Intl API - Save calls PUT /api/settings (which now propagates to scheduler) - Briefing tab firing timezone hint reads stored value instead of live browser API Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,27 @@ const toastStore = useToastStore();
|
||||
const pushStore = usePushStore();
|
||||
const assistantName = ref("");
|
||||
const defaultModel = ref("");
|
||||
const userTimezone = ref("");
|
||||
const savingTimezone = ref(false);
|
||||
const timezoneSaved = ref(false);
|
||||
|
||||
function detectTimezone() {
|
||||
userTimezone.value = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
}
|
||||
|
||||
async function saveTimezone() {
|
||||
savingTimezone.value = true;
|
||||
timezoneSaved.value = false;
|
||||
try {
|
||||
await apiPut('/api/settings', { user_timezone: userTimezone.value });
|
||||
timezoneSaved.value = true;
|
||||
setTimeout(() => (timezoneSaved.value = false), 2000);
|
||||
} catch {
|
||||
toastStore.show('Failed to save timezone', 'error');
|
||||
} finally {
|
||||
savingTimezone.value = false;
|
||||
}
|
||||
}
|
||||
const backgroundModel = ref("");
|
||||
const installedModels = ref<string[]>([]);
|
||||
const defaultChatModel = ref("");
|
||||
@@ -710,6 +731,7 @@ onMounted(async () => {
|
||||
const allSettings = await apiGet<Record<string, string>>("/api/settings");
|
||||
defaultModel.value = allSettings.default_model ?? "";
|
||||
backgroundModel.value = allSettings.background_model ?? "";
|
||||
userTimezone.value = allSettings.user_timezone ?? "";
|
||||
chatRetentionDays.value = allSettings.chat_retention_days !== undefined
|
||||
? Number(allSettings.chat_retention_days)
|
||||
: 90;
|
||||
@@ -1463,6 +1485,32 @@ function formatUserDate(iso: string): string {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Timezone -->
|
||||
<section class="settings-section full-width">
|
||||
<h2>Timezone</h2>
|
||||
<p class="section-desc">Used to schedule briefings and format times in chat. Set this to your local IANA timezone (e.g. America/New_York, Europe/London).</p>
|
||||
<div class="field">
|
||||
<label for="user-timezone">Your timezone</label>
|
||||
<div style="display:flex; gap:0.5rem; align-items:center">
|
||||
<input
|
||||
id="user-timezone"
|
||||
v-model="userTimezone"
|
||||
type="text"
|
||||
class="input"
|
||||
placeholder="e.g. America/New_York"
|
||||
/>
|
||||
<button class="btn-secondary" type="button" @click="detectTimezone">Detect</button>
|
||||
</div>
|
||||
<p class="field-hint">Click Detect to auto-fill from your browser.</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn-save" @click="saveTimezone" :disabled="savingTimezone">
|
||||
{{ savingTimezone ? 'Saving…' : 'Save' }}
|
||||
</button>
|
||||
<span v-if="timezoneSaved" class="saved-msg">Saved!</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Model Management -->
|
||||
<section class="settings-section full-width">
|
||||
<div class="model-mgmt-header">
|
||||
@@ -2104,7 +2152,7 @@ function formatUserDate(iso: string): string {
|
||||
</div>
|
||||
</div>
|
||||
<p class="field-hint" style="margin-top: 0.5rem">
|
||||
Firing in timezone: <strong>{{ Intl.DateTimeFormat().resolvedOptions().timeZone }}</strong>
|
||||
Firing in timezone: <strong>{{ userTimezone || 'UTC (not configured — set in General settings)' }}</strong>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user