feat: migrate website-creator from Next.js+Payload to Astro+Tina CMS

Major changes:
- Replace Payload CMS with Tina CMS (self-hosted)
- Add Astro DB for consent logging (PDPA compliant)
- Update Tailwind v3 to v4 (@tailwindcss/vite plugin)
- Add astro-tina-starter template
- Rewrite consent template for Astro (ConsentBanner.astro, Astro DB, Nano Stores)
- Add install-tina-backend.sh for self-hosted Tina per customer
- Rename convert-astro.sh to migrate-tina.sh
- Add AGENTS.md template for generated websites
- Delete all Payload/Next.js files

Technical updates:
- Astro DB using defineDb with eq operators for queries
- Tailwind v4 with @theme block
- Tina CMS local development mode
- Proper Astro API routes for consent

Research-verified with official documentation (April 2026)
This commit is contained in:
2026-04-17 14:52:59 +07:00
parent ce8483e546
commit 628298183a
74 changed files with 3536 additions and 11431 deletions

View File

@@ -1,61 +1,70 @@
# PDPA Consent Logging Template
Template สำหรับเพิ่ม PDPA consent logging ใน Next.js + Payload CMS (MongoDB)
Template สำหรับเพิ่ม PDPA consent logging ใน Astro + Tina (Astro DB)
## Files
```
consent/
├── collections/
│ └── ConsentLogs.ts # Payload collection สำหรับ consent logs
├── ConsentBanner.astro # Consent banner component
├── api/
│ └── route.ts # API endpoint สำหรับบันทึก consent
├── cookie-banner.tsx # CookieBanner component
└── README.md
│ └── consent.ts # API endpoints (GET, POST, DELETE)
├── db/
│ └── config.ts # Astro DB schema (defineTable)
├── stores/
│ └── consent.ts # Nano Stores for client state
└── README.md # This file
```
## วิธีใช้
## วิธีใช้ (Astro)
### 1. เพิ่ม ConsentLogs Collection
### 1. เพิ่ม Astro DB Schema
Copy `collections/ConsentLogs.ts` ไปที่ `src/collections/` ของ project
Copy `db/config.ts` ไปที่ `src/db/config.ts`:
```ts
// src/db/config.ts
import { defineTable, column } from 'astro:db';
export const ConsentLog = defineTable({
columns: {
id: column.number({ primaryKey: true }),
action: column.text(),
purpose: column.text(),
analytics: column.boolean({ default: false }),
marketing: column.boolean({ default: false }),
functional: column.boolean({ default: false }),
userAgent: column.text({ optional: true }),
ip: column.text({ optional: true }),
timestamp: column.date(),
sessionId: column.text({ optional: true }),
},
});
```
### 2. สร้าง API Endpoint
Copy `api/route.ts` ไปที่ `src/app/api/consent/route.ts`
Copy `api/consent.ts` ไปที่ `src/pages/api/consent.ts`
### 3. เพิ่ม CookieBanner Component
### 3. เพิ่ม ConsentBanner Component
Copy `cookie-banner.tsx` ไปที่ `src/components/`
Copy `ConsentBanner.astro` ไปที่ `src/components/consent/ConsentBanner.astro`
### 4. เพิ่มใน Layout
เพิ่ม `<CookieBanner />` ใน `src/app/(frontend)/layout.tsx`:
เพิ่ม `<ConsentBanner />` ใน `src/layouts/Layout.astro`:
```tsx
import { CookieBanner } from '@/components/cookie-banner'
```astro
---
import ConsentBanner from '../components/consent/ConsentBanner.astro';
---
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<CookieBanner />
</body>
</html>
)
}
```
### 5. เพิ่ม Collection ใน payload.config.ts
```ts
import ConsentLogs from './collections/ConsentLogs'
export default buildConfig({
collections: [Users, Media, Snacks, Orders, ConsentLogs],
// ...
})
<html lang="th">
<body>
<slot />
<ConsentBanner />
</body>
</html>
```
## API
@@ -80,7 +89,7 @@ export default buildConfig({
{
"success": true,
"doc": {
"id": "...",
"id": 1,
"action": "accept",
"purpose": "all",
"analytics": true,
@@ -93,7 +102,46 @@ export default buildConfig({
}
```
### GET /api/consent
ดึง consent logs
```bash
curl "http://localhost:4321/api/consent"
```
### DELETE /api/consent
Right to be forgotten (ลบข้อมูลตาม พ.ร.บ.)
```bash
curl -X DELETE "http://localhost:4321/api/consent?sessionId=xxx"
```
## Nano Stores Usage
```ts
import { consentStore, hasAnalyticsConsent, hasMarketingConsent } from './stores/consent';
// Subscribe to changes
consentStore.subscribe((state) => {
console.log('Consent changed:', state);
});
// Check consent
if (hasAnalyticsConsent()) {
// Load analytics
}
```
## UX
- **ยอมรับทั้งหมด** - เปิดทุกคุกกี้
- **ปฏิเสธทั้งหมด** - ปิดทุกคุกกี้ (ยกเว้น functional)
- **ตั้งค่าคุกกี้** - แผงปรับแต่งเอง
## ⚠️ Pitfalls สำคัญ
1. **ใช้ `mongooseAdapter` ไม่ใช่ `mongodbAdapter`**
2. **ConsentLogs ต้องใช้ `export default`** ไม่ใช่ named export
1. **Astro DB ต้องรันบน server-side** - ใช้ `APIRoute` import
2. **Nano Stores รันบน client-side** - ใช้ `<script>` tag ใน Astro
3. **import ถูกต้อง** - ใช้ `import { db } from 'astro:db'` ไม่ใช่ `defineDb`