92 lines
2.4 KiB
Vue
92 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, reactive, ref } from 'vue'
|
|
import type { NotificationPrefs } from '../types'
|
|
import * as api from '../services/api'
|
|
import { t } from '../i18n'
|
|
import { useToast } from '../composables/useToast'
|
|
|
|
const { success, error } = useToast()
|
|
const loading = ref(false)
|
|
|
|
const form = reactive<NotificationPrefs>({
|
|
subscribed: true,
|
|
dnd_start: '',
|
|
dnd_end: '',
|
|
locale: 'zh',
|
|
timezone: 'Asia/Shanghai',
|
|
daily_summary_enabled: true,
|
|
daily_summary_time: '09:30',
|
|
})
|
|
|
|
async function loadPrefs() {
|
|
loading.value = true
|
|
try {
|
|
const prefs = await api.getNotificationPrefs()
|
|
Object.assign(form, prefs)
|
|
} catch {
|
|
error(t('load_settings_failed'))
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function savePrefs() {
|
|
loading.value = true
|
|
try {
|
|
const updated = await api.updateNotificationPrefs(form)
|
|
Object.assign(form, updated)
|
|
success(t('save_settings_success'))
|
|
} catch {
|
|
error(t('save_settings_failed'))
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(loadPrefs)
|
|
</script>
|
|
|
|
<template>
|
|
<section class="page">
|
|
<header class="page-head">
|
|
<h2>{{ t('user_settings_title') }}</h2>
|
|
<p>{{ t('user_settings_subtitle') }}</p>
|
|
</header>
|
|
|
|
<form class="card settings-form" @submit.prevent="savePrefs">
|
|
<label class="inline">
|
|
<input v-model="form.subscribed" type="checkbox" />
|
|
{{ t('reminders') }}
|
|
</label>
|
|
<label>
|
|
{{ t('timezone') }}
|
|
<input v-model="form.timezone" type="text" placeholder="Asia/Shanghai" />
|
|
</label>
|
|
<label>
|
|
{{ t('locale') }}
|
|
<select v-model="form.locale">
|
|
<option value="zh">中文</option>
|
|
<option value="en">English</option>
|
|
</select>
|
|
</label>
|
|
<label>
|
|
{{ t('dnd_start') }}
|
|
<input v-model="form.dnd_start" type="time" />
|
|
</label>
|
|
<label>
|
|
{{ t('dnd_end') }}
|
|
<input v-model="form.dnd_end" type="time" />
|
|
</label>
|
|
<label class="inline">
|
|
<input v-model="form.daily_summary_enabled" type="checkbox" />
|
|
{{ t('daily_summary_enabled') }}
|
|
</label>
|
|
<label>
|
|
{{ t('daily_summary_time') }}
|
|
<input v-model="form.daily_summary_time" type="time" />
|
|
</label>
|
|
<button class="btn primary" type="submit" :disabled="loading">{{ loading ? t('loading_wait') : t('save_settings') }}</button>
|
|
</form>
|
|
</section>
|
|
</template>
|