Add application codebase: PDF annotation for e-Court

Next.js 14 + Drizzle/PostgreSQL + SSE realtime sync — highlight,
freehand, comment, bookmark + ฟีเจอร์ต่อยอด F1–F19 (edit/move, undo/redo,
shapes, redaction, export PDF/CSV, reply, resolve, search, summary,
textbox, stamp, version history)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2026-09-10 14:29:40 +07:00
parent 6fd0c3174f
commit eddcec28c7
60 changed files with 15055 additions and 0 deletions

52
app/page.tsx Normal file
View file

@ -0,0 +1,52 @@
import Link from "next/link";
import { asc } from "drizzle-orm";
import { FileText } from "lucide-react";
import { db } from "@/db";
import { files } from "@/db/schema";
export const dynamic = "force-dynamic";
export default async function HomePage() {
const rows = await db.select().from(files).orderBy(asc(files.createdAt));
return (
<main className="mx-auto max-w-2xl p-8">
<h1 className="text-2xl font-bold text-primary">Jude&apos;s Note</h1>
<p className="mt-1 text-sm text-slate-500">
ระบบ PDF Annotation สำหรับ e-Court
</p>
{rows.length === 0 ? (
<p className="mt-8 rounded border border-dashed p-6 text-center text-sm text-slate-500">
ยังไม่มีไฟล์ในระบบ — รัน /sync-db เพื่อ seed ไฟล์ตัวอย่าง
</p>
) : (
<ul className="mt-6 space-y-2">
{rows.map((f) => (
<li
key={f.id}
className="flex items-center gap-3 rounded-lg border bg-white p-4 shadow-sm"
>
<FileText className="h-5 w-5 shrink-0 text-slate-400" />
<span className="min-w-0 flex-1">
<span className="block break-all line-clamp-2 text-sm font-medium">
{f.title}
</span>
<span className="block text-xs text-slate-400">
{new Date(f.createdAt).toLocaleString("th-TH")}
</span>
</span>
<Link
href={`/annotate/${f.id}`}
className="shrink-0 rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-white transition hover:opacity-90"
>
Annotate
</Link>
</li>
))}
</ul>
)}
</main>
);
}