# 📘 คู่มือสร้างเว็บไซต์สไตล์ mimoth.com
## ฉบับเปิด source code จริง + ดูหน้าเว็บจริง — สอนแบบถูกวิธี

> ผู้เขียน: Hermes Agent (by Nous Research)
> เวอร์ชัน: 1.0 — มิถุนายน 2026

---

## 🧭 สารบัญ

1. [แนะนำโปรเจกต์และแนวคิด](#1-แนะนำโปรเจกต์และแนวคิด)
2. [Setup โปรเจกต์ Next.js + TypeScript + Tailwind](#2-setup-โปรเจกต์-nextjs--typescript--tailwind)
3. [ระบบ Design — ทำ Dark Graphite UI](#3-ระบบ-design--ทำ-dark-graphite-ui)
4. [การ Routing และหน้า Home](#4-การ-routing-และหน้า-home)
5. [ระบบ Component — Card, Pill, CtaLink, SectionHeader](#5-ระบบ-component--card-pill-ctalink-sectionheader)
6. [Data Layer — Content Source Pattern (Local → Supabase)](#6-data-layer--content-source-pattern-local--supabase)
7. [Tools Directory — หน้า Directory + Detail](#7-tools-directory--หน้า-directory--detail)
8. [Guides — หน้ารวม + แบบละเอียด](#8-guides--หน้ารวม--แบบละเอียด)
9. [News Desk — ข่าว + กรองหลายมิติ](#9-news-desk--ข่าว--กรองหลายมิติ)
10. [AI Stacks & Deals — หน้าจัดชุดเครื่องมือ](#10-ai-stacks--deals--หน้าจัดชุดเครื่องมือ)
11. [SEO — Metadata, JSON-LD, OG Images](#11-seo--metadata-json-ld-og-images)
12. [Auth & Dashboard — Supabase Auth + Member Feature](#12-auth--dashboard--supabase-auth--member-feature)
13. [Services & Monetization](#13-services--monetization)
14. [Admin CMS — /mimoadminza](#14-admin-cms--mimoadminza)
15. [Deploy ขึ้น Vercel + Security Headers](#15-deploy-ขึ้น-vercel--security-headers)
16. [บทสรุป — ถอดบทเรียนจากของจริง](#16-บทสรุป--ถอดบทเรียนจากของจริง)

---

## 1. แนะนำโปรเจกต์และแนวคิด

### mimoth.com คืออะไร?

`mimoth.com` (ชื่อเล่น MIMO) คือ **Thai-first AI Tools Discovery Platform** — แพลตฟอร์มรวมรีวิว AI tools, คู่มือ, ข่าว และดีลสำหรับคนทำงานออนไลน์ไทย

### Concept หลัก

| แนวคิด | รายละเอียด |
|--------|-----------|
| **ภาษาไทย 100%** | เขียนเพื่อคนไทย ใช้ภาษาไทยทั้งหมด |
| **Thai-first** | เนื้อหาคำนึงถึง use case ของคนไทย |
| **Decision-focused** | แต่ละหน้า design มาเพื่อช่วยตัดสินใจ |
| **70/30 Content Access** | 70% เปิดให้สาธารณะ, 30% ใช้สมัครสมาชิก |
| **Dark Graphite UI** | Design สีเข้ม สะอาด Professional |

### เปิดดูของจริง

```bash
# URL ที่เปิดดูได้เลย
https://mimoth.com/          # หน้าแรก
https://mimoth.com/tools      # Tools Directory
https://mimoth.com/guides     # คู่มือ
https://mimoth.com/news       # ข่าว AI
https://mimoth.com/deals      # AI Stacks & Deals
https://mimoth.com/services   # บริการ
```

---

## 2. Setup โปรเจกต์ Next.js + TypeScript + Tailwind

### คำสั่งเริ่มต้น

```bash
npx create-next-app@latest my-project --typescript --tailwind --app
cd my-project
```

### package.json (ของจริง)

```json
{
  "dependencies": {
    "next": "16.2.6",
    "react": "19.2.6",
    "react-dom": "19.2.6",
    "@supabase/ssr": "^0.10.3",
    "@supabase/supabase-js": "^2.106.2",
    "@stripe/stripe-js": "^9.7.0",
    "stripe": "^22.2.0"
  },
  "devDependencies": {
    "@types/node": "25.9.1",
    "@types/react": "19.2.15",
    "@types/react-dom": "19.2.3",
    "autoprefixer": "10.5.0",
    "postcss": "8.5.15",
    "tailwindcss": "3.4.19",
    "typescript": "6.0.3"
  },
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "typecheck": "tsc --noEmit",
    "seo:audit": "node scripts/seo-route-audit.mjs"
  }
}
```

> 💡 **ข้อสังเกต:** ของจริงใช้ TypeScript 6.0.3 ที่เพิ่งออกใหม่ กับ Next.js 16 และ React 19 ซึ่งเป็นเวอร์ชันล่าสุด

---

## 3. ระบบ Design — ทำ Dark Graphite UI

### Tailwind Config

```typescript
// tailwind.config.ts
const config: Config = {
  content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
  theme: {
    extend: {
      colors: {
        graphite: {
          bg: "#050505",             // main background
          card: "#0B0B0B",           // card background
          border: "rgba(255,255,255,0.08)",  // border
          soft: "rgba(255,255,255,0.05)",     // subtle overlay
        },
      },
      boxShadow: {
        graphite: "0 24px 80px rgba(0,0,0,0.45)",
      },
    },
  },
  plugins: [],
};
```

### globals.css — สิ่งที่ทำให้รู้สึก "MIMO"

ของจริงใช้ CSS pseudo-elements สร้าง Texture หลายชั้น:

```css
/* 1) Body background — รูปพื้นหลังแบบ luxury */
body {
  background:
    linear-gradient(180deg, rgba(5,5,5,0.82), rgba(5,5,5,0.94)),
    url("/images/home/mimo-luxury-hero.jpg") center top / cover fixed no-repeat,
    #050505;
}

/* 2) Ambient gold light + grid scanline */
body::before {
  background-image:
    linear-gradient(135deg, rgba(245,184,49,0.1), transparent 18%, transparent 82%, rgba(245,184,49,0.08)),
    repeating-linear-gradient(0deg,
      rgba(255,255,255,0.018) 0,
      rgba(255,255,255,0.018) 1px,
      transparent 1px,
      transparent 4px);
  mix-blend-mode: screen;
  opacity: 0.22;
}

/* 3) Radial gold spots + gradient overlay */
body::after {
  background-image:
    radial-gradient(circle at 18% 22%, rgba(245,184,49,0.18), transparent 18%),
    radial-gradient(circle at 82% 72%, rgba(245,184,49,0.16), transparent 16%),
    linear-gradient(115deg, transparent 0 58%, rgba(255,255,255,0.035) 58.1%, transparent 58.35%),
    linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.5) 340px, rgba(0,0,0,0.72));
}

/* 4) Grid pattern สำหรับ section */
.bg-grid {
  background-image:
    linear-gradient(rgba(255,255,255,0.032) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.032) 1px, transparent 1px);
  background-size: 44px 44px;
}
```

> 🔑 **หัวใจของ Design:** ไม่ใช่แค่สีดำเรียบ ๆ แต่มี Texture หลายชั้น — gold ambient light, grid scanline, radial glow — ทำให้รู้สึก Premium

---

## 4. การ Routing และหน้า Home

### โครงสร้าง App Router

```
src/app/
├── layout.tsx          # Root layout — header + main + footer
├── page.tsx            # หน้า Home
├── not-found.tsx       # 404
├── loading.tsx         # Loading state
├── globals.css         # Global styles
├── robots.ts           # robots.txt
├── sitemap.ts          # sitemap.xml
├── icon.tsx            # Favicon
├── apple-icon.tsx      # Apple touch icon
├── opengraph-image.tsx # OG Image
├── tools/              # /tools
│   ├── page.tsx        # listing
│   ├── [slug]/page.tsx # detail
│   └── compare/page.tsx# comparison
├── guides/             # /guides
│   ├── page.tsx
│   └── [slug]/page.tsx
├── news/               # /news
│   ├── page.tsx
│   └── [slug]/page.tsx
├── deals/page.tsx      # /deals
├── services/           # /services
│   ├── page.tsx
│   └── ai-stack-audit-express/page.tsx
├── auth/               # /auth
│   ├── login/page.tsx
│   ├── register/page.tsx
│   ├── forgot-password/page.tsx
│   └── reset-password/page.tsx
├── dashboard/          # /dashboard
│   ├── page.tsx
│   └── prompts/...
├── about/page.tsx, contact/page.tsx, privacy/page.tsx
├── advertise/page.tsx, affiliate-disclosure/page.tsx
├── methodology/page.tsx, upgrade/...
└── mimoadminza/        # /mimoadminza (admin CMS)
    ├── layout.tsx
    ├── page.tsx
    ├── tools/, guides/, news/, deals/
    ├── media/, affiliate-links/, audit-logs/, news-intake/
```

### Root Layout — backbone ของทั้งเว็บ

```tsx
// layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="th">
      <body className="min-h-screen bg-[#050505] antialiased">
        <CompareProvider>
          <SiteHeader />
          <main>{children}</main>
          <SiteFooter />
          <CompareBar />
        </CompareProvider>
      </body>
    </html>
  );
}
```

> ✅ `lang="th"` — บอก search engine ว่าเป็นภาษาไทย
> ✅ `CompareProvider` + `CompareBar` — ระบบเปรียบเทียบเครื่องมือ (global context)

### ตัวอย่าง Hero Section ของ Home

```tsx
<section className="mx-auto max-w-[1500px] px-4 py-8">
  <div className="hero-cinematic mima-frame grid overflow-hidden rounded-[4px] lg:grid-cols-[minmax(0,1fr)_440px]">
    {/* Content column */}
    <div className="p-5 sm:p-10">
      {/* Pill tags */}
      <div className="flex flex-wrap gap-2">
        <Pill>Thai-first AI discovery</Pill>
        <Pill>รีวิวสั้น อ่านง่าย</Pill>
      </div>
      {/* H1 — ใช้ text-8xl บน XL screen */}
      <h1 className="text-4xl sm:text-6xl lg:text-7xl xl:text-8xl font-semibold leading-[0.95]">
        เลือก AI tools
        <span className="block text-zinc-300">ให้ตรงงานจริง</span>
      </h1>
      {/* Metric counters */}
      <div className="grid grid-cols-3 border border-white/[0.08]">
        <div className="bg-[#0B0B0B]/80 p-4">
          <p className="text-3xl font-semibold text-white">{tools.length}+</p>
          <p className="mima-label text-zinc-600">AI TOOLS</p>
        </div>
      </div>
    </div>
    {/* Sidebar — CommandPanel + featured deal */}
    <aside className="p-5">
      <CommandPanel />
    </aside>
  </div>
</section>
```

---

## 5. ระบบ Component — Card, Pill, CtaLink, SectionHeader

ของจริงมี `src/components/ui.tsx` รวม component หลักไว้ในไฟล์เดียว:

### Card
```tsx
export function Card({ children, className = "", id }) {
  return (
    <div id={id} className={`mima-cell scan-hover terminal-shadow min-w-0 rounded-[4px] border p-5 ${className}`}>
      {children}
    </div>
  );
}
```

Class `.mima-cell`, `.scan-hover`, `.terminal-shadow` ถูกนิยามใน globals.css — ทำให้ Card มี border glow + hover effect แบบ scanline

### Pill (Tag)
```tsx
export function Pill({ children, className = "" }) {
  return (
    <span className={`inline-flex items-center rounded-[3px] border border-white/[0.09] bg-white/[0.035] px-3 py-1.5 text-xs font-medium text-zinc-400 ${className}`}>
      {children}
    </span>
  );
}
```

### CtaLink (3 variants)
```tsx
export function CtaLink({ href, children, variant = "primary", className = "" }) {
  const classes = {
    primary: "border-white/[0.16] bg-white/[0.1] text-white hover:bg-white/[0.16]",
    secondary: "border-white/[0.09] bg-white/[0.03] text-zinc-300 hover:bg-white/[0.07]",
    quiet: "border-white/[0.04] bg-transparent text-zinc-400 hover:bg-white/[0.045]",
  }[variant];

  return (
    <Link href={href} className={`inline-flex items-center justify-center rounded-[4px] border px-5 py-3 text-sm font-medium transition ${classes} ${className}`}>
      {children}
    </Link>
  );
}
```

### SectionHeader
```tsx
export function SectionHeader({ eyebrow, title, description }) {
  return (
    <div className="max-w-3xl">
      <p className="mima-label text-zinc-500">{eyebrow}</p>
      <h2 className="mt-4 text-3xl sm:text-4xl font-semibold leading-tight text-white">{title}</h2>
      {description && <p className="mt-4 text-base leading-7 text-zinc-400">{description}</p>}
    </div>
  );
}
```

### SiteHeader (Sticky Top Bar)
```tsx
<header className="sticky top-0 z-50 bg-[#050505]/92 backdrop-blur-xl border-b border-white/[0.1]">
  <div className="mx-auto max-w-[1500px] flex items-stretch border-x border-white/[0.08] lg:grid lg:grid-cols-[280px_minmax(0,1fr)_auto]">
    <Link href="/" className="flex items-center px-6 border-r border-white/[0.08]">
      <BrandLogo />
    </Link>
    <nav className="hidden lg:flex items-stretch">
      <PrimaryNav variant="desktop" />
    </nav>
    <div className="flex items-center gap-2 px-4">
      <HeaderAuthActions variant="desktop" />
      <details className="group relative lg:hidden">
        <summary className="h-9 flex items-center px-3 rounded-[4px] border border-white/[0.1] bg-white/[0.04] text-sm font-medium text-white cursor-pointer">
          เมนู
        </summary>
        {/* Mobile dropdown menu */}
      </details>
    </div>
  </div>
</header>
```

> 💡 **Mobile-first:** ของจริงใช้ `lg:hidden` + details/summary สำหรับ mobile menu
> 💡 **Sticky header** พร้อม `backdrop-blur-xl` — ให้เห็นเนื้อหาเลื่อนใต้ header

---

## 6. Data Layer — Content Source Pattern (Local → Supabase)

นี่คือ **หัวใจของสถาปัตยกรรมข้อมูล** ของ mimoth.com

### Content Source Interface

```typescript
// src/lib/content/types.ts
export type ContentSource = {
  getToolCategories(): ToolCategory[];
  getAllTools(): Tool[];
  getFeaturedTools(limit?: number): Tool[];
  getToolBySlug(slug: string): Tool | undefined;
  getAllGuides(): Guide[];
  getGuideBySlug(slug: string): Guide | undefined;
  getAllNewsPosts(): NewsItem[];
  getAllDeals(): Deal[];
  getRelatedToolsForTool(toolSlug: string): Tool[];
  getRelatedGuidesForTool(toolSlug: string): Guide[];
  getRelatedDealsForTool(toolSlug: string): Deal[];
  getRelatedGuidesForGuide(guideSlug: string): Guide[];
  getSuggestedToolsForGuide(guideSlug: string): Tool[];
};
```

### Dual Source Pattern (Repository)

```typescript
// src/lib/content/repository.ts
async function getAllTools() {
  return withContentFallback(
    () => supabaseContentSource.getAllTools(),
    () => localContentSource.getAllTools()
  );
}

// Fallback logic
async function withContentFallback<T>(
  supabaseRead: () => Promise<T>,
  localRead: () => T
): Promise<T> {
  if (!shouldTrySupabase()) return localRead();
  try {
    const value = await supabaseRead();
    if (hasUsableValue(value)) return value;
  } catch { /* fallback silently */ }
  return localRead();
}
```

### Local Content Files

ข้อมูลจริงเก็บในไฟล์ TypeScript ที่ `/src/data/`:

```
src/data/
├── placeholders.ts        # Main data (2338 lines!) — tools, guides, news, deals
├── prompts.ts             # Prompt templates
├── news-auto.json         # Auto-published news
└── *いろんな guide ไฟล์*    # Individual guide data files
```

### Data Types (ตัวอย่าง)

```typescript
type Tool = {
  slug: string;
  name: string;
  category: string;
  price: string;           // "ฟรี", "Pro $20/เดือน", etc.
  pricingNote: string;
  summary: string;         // English summary
  thaiSummary: string;     // สรุปภาษาไทย
  useCase: string;         // use case จริง
  bestFor: string;         // เหมาะกับใคร
  notFor?: string;         // ไม่เหมาะกับใคร
  tags: string[];
  score: string;
  affiliateCta: string;
  featured?: boolean;
  quickVerdict?: { suitableFor, strength, caution, startPlan };
  pros?: string[];
  cons?: string[];
  internalLinks?: { href, label, description }[];
};
```

> 📌 **ข้อดีของ Local-first:** ไม่ต้องพึ่ง database ในการ dev, deploy บน Vercel เร็ว, SEO friendly, CI ไม่พังเพราะ DB

---

## 7. Tools Directory — หน้า Directory + Detail

### /tools — Directory Page

โครงสร้าง 3 ส่วนหลัก:

1. **Search + Filter Bar** — form action="/tools" พร้อม q + category params
2. **Category Pills** — filter link ที่เปลี่ยน URL
3. **Tool Cards Grid** — 3 columns บน XL screen

```tsx
// Search form
<form action="/tools" className="grid lg:grid-cols-[1fr_260px_auto] gap-3">
  <input name="q" placeholder="ค้นหา เช่น วิดีโอ, SEO, automation" />
  <select name="category">{categories.map(...)}</select>
  <button>ค้นหาเครื่องมือ</button>
</form>

// Tool card structure
<Card>
  <div>
    <p className="text-xs uppercase text-zinc-500">{tool.category}</p>
    <Link href={`/tools/${tool.slug}`}>
      <h3 className="text-2xl font-semibold text-white">{tool.name}</h3>
    </Link>
  </div>
  <p className="mt-5 text-sm text-zinc-400">{tool.thaiSummary}</p>
  <div className="grid gap-3 text-sm">
    <div className="border border-white/[0.08] bg-white/[0.03] p-3">
      <p className="text-xs text-zinc-600">ราคา</p>
      <p className="mt-1 text-zinc-300">{tool.price}</p>
    </div>
    <div className="border border-white/[0.08] bg-white/[0.03] p-3">
      <p className="text-xs text-zinc-600">Use case</p>
      <p className="mt-1 text-zinc-300">{tool.useCase}</p>
    </div>
  </div>
  <p className="mt-5 text-sm text-zinc-500">เหมาะกับ: {tool.bestFor}</p>
  <div className="flex flex-wrap gap-2">{tool.tags.map(tag => <Pill>{tag}</Pill>)}</div>
</Card>
```

### Filter Logic (Server-side)

```tsx
export default async function ToolsPage({ searchParams }) {
  const params = await searchParams;
  const query = params.q?.trim() ?? "";
  const activeCategory = toolCategories.includes(params.category) ? params.category : "ทั้งหมด";

  const filteredTools = tools.filter(tool => {
    const matchesCategory = activeCategory === "ทั้งหมด" || tool.category === activeCategory;
    const searchableText = [tool.name, tool.category, tool.summary, tool.thaiSummary, ...tool.tags]
      .join(" ").toLowerCase();
    return matchesCategory && (!query || searchableText.includes(query.toLowerCase()));
  });
  // ...
}
```

> ✅ **Server Component** — filter ทำงานบน server, SEO crawler เห็น content เต็ม
> ✅ URL-based filter — user แชร์ลิงก์ filter ได้

---

## 8. Guides — หน้ารวม + แบบละเอียด

### /guides — Topic Clusters

ของจริงใช้ **Topic Clusters** เพื่อจัดกลุ่มคู่มือ:

```tsx
const topicClusters = [
  {
    title: "เริ่มใช้ ChatGPT ภาษาไทย",
    description: "ตั้ง prompt, tone ภาษา และ workflow",
    slugs: ["chatgpt-thai-language-setup", "chatgpt-for-work-thai", "chatgpt-vs-claude-thai"],
  },
  {
    title: "ออกแบบภาพด้วย AI",
    description: "แก้ภาพแตก ลบพื้นหลัง แปลง SVG",
    slugs: ["ai-remove-background-product-photo", "ai-image-upscaler-tools", "ai-image-to-vector-svg"],
  },
  // ...
];
```

### Guide Detail — Content Sections

```typescript
type Guide = {
  slug: string;
  title: string;
  summary: string;
  category: string;
  level: string;            // "beginner", "intermediate"
  readingTime: string;      // "8 นาที"
  tags: string[];
  steps: string[];          // ขั้นตอนหลัก
  contentSections?: {
    title: string;
    body: string[];
    bullets?: string[];
  }[];
  comparisonRows?: {
    topic: string;
    primary: string;
    secondary: string;
    note: string;
  }[];
  faq?: { question: string; answer: string }[];
  internalLinks?: { href: string; label: string; description: string }[];
  affiliateCta?: { href: string; label: string };
};
```

---

## 9. News Desk — ข่าว + กรองหลายมิติ

### /news — News Listing

ของจริงมีระบบกรอง 2 มิติ:

```tsx
// 1) Category filter
const VISIBLE_CATEGORIES = [
  "ทั้งหมด", "AI Agents", "Tools Update", "Business / SME",
  "Content / Video", "Automation", "Pricing / Deals",
];

// 2) Type filter
const newsTypes = ["news", "trend-brief", "product-update", "model-update", "business"];

// Category mapping system (raw categories → visible categories)
const categoryToVisible = {
  "AI Agents": "AI Agents",
  "Product Update": "Tools Update",
  "Model Update": "Tools Update",
  "AI Business": "Business / SME",
  Automation: "Automation",
  ราคา: "Pricing / Deals",
  // ...
};
```

> 💡 **NewsType System** — ใช้ badge สีบอกประเภทข่าว เช่น `Trend Brief` `Product Update` เพื่อให้คนอ่านเข้าใจทันที

---

## 10. AI Stacks & Deals — หน้าจัดชุดเครื่องมือ

### /deals — Stack Board

ของจริงใช้ดีลเป็น **Stack แนะนำ** ไม่ใช่แค่ส่วนลด:

```tsx
const dealToolSlugs = {
  "ai-content-stack": ["chatgpt", "claude", "perplexity", "canva-ai"],
  "ai-video-creator-bundle": ["capcut-ai", "runway", "descript"],
  "business-ai-starter-pack": ["chatgpt", "gemini", "notion-ai", "zapier-ai"],
  "designer-ai-visual-pack": ["canva-ai", "adobe-firefly", "midjourney"],
};
```

เชื่อมโยง Deal → Tool slugs → แสดงปุ่มลิงก์ไปหน้ารีวิวแต่ละตัว

### Access Gating (70/30 Pattern)

```tsx
function getDealAccessMeta(position: number) {
  if (position % 5 === 0)  return { accessLevel: "pro" };     // 20% Pro
  if (position % 3 === 0)  return { accessLevel: "member" };  // 33% Member
  return { accessLevel: "public" };                            // 47% Public
}
```

> ✅ Every 5th item = Pro-only (ซ่อนรายละเอียด)
> ✅ Every 3rd item = Member-only (สมัครฟรี)
> ✅ Default = Public (SEO indexable)

---

## 11. SEO — Metadata, JSON-LD, OG Images

### Metadata Builder

ของจริงมี helper function ที่ reuse ได้:

```tsx
// src/lib/seo.ts
export const siteConfig = {
  name: "MIMO",
  url: "https://mimoth.com",
  title: "MIMO | AI Tools Thailand",
  description: "MIMO คือคลังเครื่องมือ AI ภาษาไทยสำหรับค้นหา เปรียบเทียบ...",
  locale: "th_TH",
  language: "th-TH",
};

export function buildMetadata({ title, description, path, image, type, noIndex }) {
  const url = absoluteUrl(path);
  return {
    title,
    description,
    alternates: { canonical: url },
    openGraph: {
      title: `${title} | ${siteConfig.name}`,
      description, url, siteName: siteConfig.name,
      locale: siteConfig.locale, type,
      images: [{ url: image || defaultSocialImage, width: 1200, height: 630 }],
    },
    twitter: { card: "summary_large_image", title, description, images: [image || defaultSocialImage] },
    robots: noIndex ? { index: false, follow: false } : { index: true, follow: true },
  };
}
```

### JSON-LD Helpers

```tsx
createWebsiteJsonLd()        // WebSite schema — หน้า Home
createItemListJsonLd(name, path, items)  // ItemList — Tools, Guides, News listing
createToolJsonLd(tool)       // SoftwareApplication — tool detail
createGuideArticleJsonLd(guide) // Article + FAQ — guide detail
createNewsArticleJsonLd(article) // NewsArticle —ข่าว detail
```

### Usage ในแต่ละหน้า

```tsx
// tools/page.tsx
export const metadata = buildMetadata({
  title: "AI Tools Directory ภาษาไทย",
  description: "ค้นหาและกรองเครื่องมือ AI...",
  path: "/tools",
});

// ใน JSX
<JsonLd data={createItemListJsonLd("MIMO AI Tools Directory", "/tools", toolItems)} />
```

### OG Image (Dynamic)

ของจริงใช้ Next.js OG image generation ที่ `/opengraph-image.tsx` — สร้างภาพ 1200×630 แบบ dynamic

---

## 12. Auth & Dashboard — Supabase Auth + Member Feature

### Auth Pages
```
/auth/login
/auth/register
/auth/forgot-password
/auth/reset-password
```

### Middleware

```typescript
// src/middleware.ts
export { middleware } from "@/lib/auth/session";
// หรือ custom middleware ที่ check session แล้ว redirect
```

### Dashboard
```
/dashboard          — Member dashboard
/dashboard/prompts  — Saved prompts
```

### Content Access Pattern

```typescript
// src/lib/content-access.ts
type ContentAccessMeta = {
  accessLevel: "public" | "member" | "pro";
  contentType: string;
  memberBenefit: string;
  proBenefit: string;
  badges?: string[];
};
```

ใช้ component `ContentAccessBadge` เพื่อแสดง badge ระดับการเข้าถึงบน card:

```tsx
<ContentAccessBadge meta={{ accessLevel: "member", memberBenefit: "สมัครฟรีเพื่อบันทึก", ... }} />
```

---

## 13. Services & Monetization

ของจริงมี 4 Packages:

| Package | ราคา | เหมาะกับ | Timeline |
|---------|------|----------|----------|
| **AI Stack Audit Express** | 1,500 บาท | คนทำเพจ ร้านเล็ก ฟรีแลนซ์ | 24-48 ชม. |
| **AI Stack Audit** | แจ้งราคา | ทีมที่ใช้หลายเครื่องมือ | 3-5 วัน |
| **Workflow Setup** | แจ้งราคา | ร้านค้าออนไลน์, ทีมคอนเทนต์ | 7-14 วัน |
| **Team Playbook** | แจ้งราคา | SME / Agency | 2-3 สัปดาห์ |

ทั้งหมดใช้ **LINE** เป็นช่องทางติดต่อ (`lin.ee/UTqZIGt`) — ไม่มีระบบ checkout อัตโนมัติ

> 💡 **Business Model:** Services → Relationship → Affiliate → Repeat

---

## 14. Admin CMS — /mimoadminza

Admin ซ่อนอยู่ที่ `/mimoadminza` (เปลี่ยน path จาก `/admin` ด้วย redirect ใน next.config.ts):

```
/mimoadminza/
├── page.tsx              # Dashboard หลัก
├── tools/ + tools/new/   # CRUD tools
├── guides/ + guides/new/ # CRUD guides
├── news/ + news/new/     # CRUD news
├── deals/ + deals/new/   # CRUD deals
├── media/                # Media library
├── affiliate-links/      # Affiliate link management
├── audit-logs/           # Activity log
└── news-intake/          # News auto-publish
```

ของจริงมี component ระบบ CMS แยกใน `src/components/admin-*.tsx` และ `src/lib/admin/`:
- `cms-actions.ts` — Server Actions สำหรับ CRUD
- `cms.ts`, `mock.ts`, `records.ts` — data management
- ระบบ mock data ก่อนเชื่อม Supabase จริง

---

## 15. Deploy ขึ้น Vercel + Security Headers

### next.config.ts

```typescript
const nextConfig = {
  poweredByHeader: false,
  async headers() {
    return [
      {
        source: "/:path*",
        headers: [
          // Content Security Policy
          { key: "Content-Security-Policy", value: contentSecurityPolicy },
          // HSTS — 2 years
          { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" },
          { key: "X-Content-Type-Options", value: "nosniff" },
          { key: "X-Frame-Options", value: "DENY" },
          { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
          // Permissions Policy — ปิดทุกอย่างที่ไม่ได้ใช้
          { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=(), payment=()" },
        ],
      },
    ];
  },
};
```

### Content Security Policy (CSP)
```
default-src 'self'
script-src 'self' 'unsafe-inline'     # Next.js hydration
style-src 'self' 'unsafe-inline'      # Tailwind JIT
img-src 'self' data: blob: https://*.supabase.co
connect-src 'self' https://*.supabase.co wss://*.supabase.co
frame-src 'none' / frame-ancestors 'none'   # ป้องกัน clickjacking
upgrade-insecure-requests
```

### Vercel Config
```json
// .vercel/project.json — auto-generated by Vercel CLI
```

### การ Deploy
```bash
# Build
npm run build

# TypeScript check
npm run typecheck

# Vercel CLI
npx vercel --prod
# หรือเชื่อม GitHub auto-deploy
```

---

## 16. บทสรุป — ถอดบทเรียนจากของจริง

### ✅ สิ่งที่ mimoth.com ทำถูก

| เรื่อง | รายละเอียด |
|--------|-----------|
| **ภาษาไทย 100%** | UX เขียนเพื่อคนไทย ใช้ภาษาไทยทุกจุด |
| **Dark Graphite UI** | Design Premium ไม่ซ้ำใคร ด้วย texture หลายชั้น |
| **Content-first** | data อยู่ที่ local TS files → ไม่พึ่ง DB |
| **SEO ทำเต็ม** | JSON-LD ทุกหน้า, metadata builder, sitemap, OG |
| **Server Components** | ทุก filter/search ทำงานบน server |
| **70/30 Gating** | เนื้อหาส่วนใหญ่ public, member/pro เป็น bonus |
| **Shared UI System** | Card, Pill, CtaLink, SectionHeader |
| **Dual Source** | Local → Supabase fallback ไม่เสีย content |

### ❌ ข้อควรระวัง

| ข้อ | คำอธิบาย |
|-----|----------|
| **ไม่ rewrite whole project** | ของจริงเป็นโปรเจกต์ใหญ่ เปลี่ยนทีละน้อย |
| **ไม่ทำ Stripe/payment โดยไม่จำเป็น** | ใช้ LINE manual ก่อน |
| **ไม่ print secrets** | env ปลอดภัย ไม่โชว์ในโค้ด |
| **ไม่ break SEO pages** | content เก่าต้องไม่หาย |
| **Check type/build ก่อน commit** | `npm run typecheck && npm run build` |

### 🚀 เส้นทางเริ่มต้นสำหรับคนอยากสร้างเว็บสไตล์นี้

```
1. Next.js + Tailwind setup → ทำ Design System
2. Data layer (local TS files) → Content types
3. หน้า Home → Hero + Sections
4. หน้า Directory (tools) → Filter + Search
5. Detail page (tool/[slug]) → Full content
6. SEO → Metadata + JSON-LD + OG
7. Auth → Supabase
8. Dashboard → Member features
9. Admin CMS → Content management
10. Deploy → Vercel + Security Headers
```

---

> 📚 **แหล่งข้อมูล**
> - ดูของจริงได้ที่: [https://mimoth.com](https://mimoth.com)
> - Source code: `/root/mir/` (ในเครื่องนี้)
> - Next.js App Router: [nextjs.org/docs](https://nextjs.org/docs)
> - Tailwind CSS: [tailwindcss.com/docs](https://tailwindcss.com/docs)
> - Supabase Auth: [supabase.com/docs/guides/auth](https://supabase.com/docs/guides/auth)
