8 7. Tools Directory — หน้า Directory + Detail
8.0.1 /tools — Directory Page
โครงสร้าง 3 ส่วนหลัก:
- Search + Filter Bar — form action=“/tools” พร้อม q + category params
- Category Pills — filter link ที่เปลี่ยน URL
- Tool Cards Grid — 3 columns บน XL screen
// 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>
8.0.2 Filter Logic (Server-side)
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 ได้