Files
CookieBridge/web/src/views/SettingsView.vue
徐枫 e3a9d9f63c feat: scaffold Vue 3 + TypeScript + Vite frontend admin panel
Set up web/ directory with complete frontend scaffolding:
- Vue 3 + TypeScript + Vite with Tailwind CSS v4
- Vue Router with auth guard (redirects to /login when unauthenticated)
- Pinia stores: auth, cookies, devices, settings
- Axios HTTP client with token interceptor
- Views: Login, Dashboard, Cookies, Devices, Settings
- Vite dev server proxy to relay API on port 8100
- Headless UI and Heroicons dependencies

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-17 20:22:35 +08:00

93 lines
3.2 KiB
Vue

<script setup lang="ts">
import { onMounted } from "vue";
import { useSettingsStore } from "@/stores/settings";
const store = useSettingsStore();
onMounted(() => store.fetchSettings());
async function save() {
await store.updateSettings(store.settings);
}
</script>
<template>
<div class="p-8">
<h2 class="text-2xl font-semibold text-gray-900">Settings</h2>
<p class="mt-1 text-sm text-gray-500">Configure sync and security settings</p>
<div class="mt-6 max-w-lg space-y-6">
<!-- Sync Settings -->
<section class="rounded-xl bg-white p-6 ring-1 ring-gray-200">
<h3 class="font-medium text-gray-900">Sync</h3>
<div class="mt-4 space-y-4">
<div class="flex items-center justify-between">
<label class="text-sm text-gray-700">Auto-sync</label>
<button
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors"
:class="store.settings.autoSync ? 'bg-blue-600' : 'bg-gray-200'"
@click="store.settings.autoSync = !store.settings.autoSync"
>
<span
class="inline-block h-4 w-4 rounded-full bg-white transition-transform"
:class="store.settings.autoSync ? 'translate-x-6' : 'translate-x-1'"
/>
</button>
</div>
<div>
<label class="block text-sm text-gray-700">Sync interval (seconds)</label>
<input
:value="store.settings.syncIntervalMs / 1000"
type="number"
min="5"
max="300"
class="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm"
@input="store.settings.syncIntervalMs = Number(($event.target as HTMLInputElement).value) * 1000"
/>
</div>
</div>
</section>
<!-- Security Settings -->
<section class="rounded-xl bg-white p-6 ring-1 ring-gray-200">
<h3 class="font-medium text-gray-900">Security</h3>
<div class="mt-4 space-y-4">
<div>
<label class="block text-sm text-gray-700">Max devices</label>
<input
v-model.number="store.settings.maxDevices"
type="number"
min="1"
max="50"
class="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm"
/>
</div>
</div>
</section>
<!-- Appearance -->
<section class="rounded-xl bg-white p-6 ring-1 ring-gray-200">
<h3 class="font-medium text-gray-900">Appearance</h3>
<div class="mt-4">
<label class="block text-sm text-gray-700">Theme</label>
<select
v-model="store.settings.theme"
class="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm"
>
<option value="system">System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
</section>
<button
class="w-full rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700"
@click="save"
>
Save Settings
</button>
</div>
</div>
</template>