phase 0
This commit is contained in:
commit
41573b3c4f
54 changed files with 32839 additions and 0 deletions
24
web/.gitignore
vendored
Normal file
24
web/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.fleet
|
||||
.idea
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
75
web/README.md
Normal file
75
web/README.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Nuxt Minimal Starter
|
||||
|
||||
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure to install dependencies:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
```
|
||||
|
||||
## Development Server
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
|
||||
# pnpm
|
||||
pnpm build
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||
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>
|
||||
28
web/nuxt.config.ts
Normal file
28
web/nuxt.config.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
compatibilityDate: '2025-07-15',
|
||||
devtools: { enabled: true },
|
||||
|
||||
// ⚠️ Web portal ต้องใช้ port 5173 เท่านั้น — ห้ามใช้ 3000
|
||||
// (3000 ถูก add-in dev server ใช้อยู่: https://localhost:3000)
|
||||
devServer: {
|
||||
port: 5173,
|
||||
},
|
||||
|
||||
modules: ['@nuxtjs/tailwindcss'],
|
||||
|
||||
// ~/assets/css/tailwind.css ถูก @nuxtjs/tailwindcss pick up อัตโนมัติ
|
||||
|
||||
app: {
|
||||
head: {
|
||||
title: 'Word Versioning',
|
||||
// กัน dark-mode flash (FOUC) ก่อน Vue hydrate — ต้องใช้คีย์/ค่าเดียวกับ useTheme.ts
|
||||
script: [
|
||||
{
|
||||
innerHTML:
|
||||
"(function(){try{var t=localStorage.getItem('theme-preference');if(!t){t=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';}if(t==='dark'){document.documentElement.classList.add('dark');}}catch(e){}})();",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
11259
web/package-lock.json
generated
Normal file
11259
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
18
web/package.json
Normal file
18
web/package.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "web",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/tailwindcss": "^6.14.0",
|
||||
"nuxt": "^4.5.2",
|
||||
"vue": "^3.5.41",
|
||||
"vue-router": "^5.2.0"
|
||||
}
|
||||
}
|
||||
BIN
web/public/favicon.ico
Normal file
BIN
web/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
2
web/public/robots.txt
Normal file
2
web/public/robots.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
User-Agent: *
|
||||
Disallow:
|
||||
6
web/tailwind.config.ts
Normal file
6
web/tailwind.config.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import type { Config } from 'tailwindcss'
|
||||
|
||||
export default {
|
||||
// dark mode คุมด้วย class บน <html> (toggle จาก useTheme)
|
||||
darkMode: 'class',
|
||||
} satisfies Config
|
||||
18
web/tsconfig.json
Normal file
18
web/tsconfig.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./.nuxt/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./.nuxt/tsconfig.server.json"
|
||||
},
|
||||
{
|
||||
"path": "./.nuxt/tsconfig.shared.json"
|
||||
},
|
||||
{
|
||||
"path": "./.nuxt/tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue