phase 0
This commit is contained in:
commit
41573b3c4f
54 changed files with 32839 additions and 0 deletions
23
web/app/app.vue
Normal file
23
web/app/app.vue
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<script setup lang="ts">
|
||||
const { initTheme, toggle, isDark } = useTheme()
|
||||
|
||||
onMounted(() => initTheme())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-slate-50 text-slate-900 dark:bg-slate-900 dark:text-slate-100">
|
||||
<header class="flex items-center justify-between border-b border-slate-200 px-6 py-4 dark:border-slate-700">
|
||||
<NuxtLink to="/" class="text-lg font-semibold">Word Versioning</NuxtLink>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-md border border-slate-300 px-3 py-1.5 text-sm hover:bg-slate-100 dark:border-slate-600 dark:hover:bg-slate-800"
|
||||
@click="toggle"
|
||||
>
|
||||
{{ isDark ? '☀️ Light' : '🌙 Dark' }}
|
||||
</button>
|
||||
</header>
|
||||
<main class="mx-auto max-w-3xl p-6">
|
||||
<NuxtPage />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
3
web/app/assets/css/tailwind.css
Normal file
3
web/app/assets/css/tailwind.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
36
web/app/composables/useTheme.ts
Normal file
36
web/app/composables/useTheme.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
export type Theme = 'light' | 'dark'
|
||||
|
||||
// ต้องตรงกับ inline script กัน FOUC ใน nuxt.config.ts
|
||||
const STORAGE_KEY = 'theme-preference'
|
||||
|
||||
export function useTheme() {
|
||||
const theme = useState<Theme>('theme', () => 'light')
|
||||
const isDark = computed(() => theme.value === 'dark')
|
||||
|
||||
function apply(next: Theme) {
|
||||
theme.value = next
|
||||
if (import.meta.client) {
|
||||
document.documentElement.classList.toggle('dark', next === 'dark')
|
||||
// ข้อยกเว้นเดียวที่ localStorage อนุญาต: theme preference ไม่ใช่ credential (กติกา #4)
|
||||
localStorage.setItem(STORAGE_KEY, next)
|
||||
}
|
||||
}
|
||||
|
||||
/** Sync state กับที่ inline script ตั้งไว้ตอนโหลดหน้า (client เท่านั้น) */
|
||||
function initTheme() {
|
||||
if (!import.meta.client) return
|
||||
const stored = localStorage.getItem(STORAGE_KEY)
|
||||
if (stored === 'light' || stored === 'dark') {
|
||||
theme.value = stored
|
||||
} else {
|
||||
theme.value = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
document.documentElement.classList.toggle('dark', theme.value === 'dark')
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
apply(theme.value === 'dark' ? 'light' : 'dark')
|
||||
}
|
||||
|
||||
return { theme, isDark, initTheme, toggle }
|
||||
}
|
||||
15
web/app/pages/index.vue
Normal file
15
web/app/pages/index.vue
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<section class="space-y-4">
|
||||
<h1 class="text-2xl font-bold">สร้างเอกสารจาก template</h1>
|
||||
<p class="text-slate-600 dark:text-slate-300">
|
||||
เลือก template กรอกค่า fields แล้วดาวน์โหลด .docx ที่เป็น version 1 พร้อม metadata
|
||||
ไปเปิดต่อใน Word พร้อม add-in
|
||||
</p>
|
||||
<!-- Phase 6: รายการ template ที่ active + ลิงก์เข้าหน้า documents/create/[templateId] -->
|
||||
<div
|
||||
class="rounded-lg border border-dashed border-slate-300 p-8 text-center text-sm text-slate-500 dark:border-slate-600 dark:text-slate-400"
|
||||
>
|
||||
รายการ template จะแสดงที่นี่ (Phase 6)
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Loading…
Add table
Add a link
Reference in a new issue