+ "use client"; + import React from "react"; + import { useRouter, usePathname, useSearchParams } from "next/navigation"; + import { apiGet } from "@/lib/api"; + import { Input } from "@/components/ui/input"; + import { Button } from "@/components/ui/button"; + import { Card, CardContent } from "@/components/ui/card"; + + export default function RFAsPage() { + const router = useRouter(); + const pathname = usePathname(); + const sp = useSearchParams(); + + // params from URL + const [q, setQ] = React.useState(sp.get("q") || ""); + const status = sp.get("status") || "All"; + const overdue = sp.get("overdue") === "1"; + const page = Number(sp.get("page") || 1); + const pageSize = Number(sp.get("pageSize") || 20); + const sort = sp.get("sort") || "updated_at:desc"; + + const setParams = (patch) => { + const curr = Object.fromEntries(sp.entries()); + const next = { ...curr, ...patch }; + // normalize + if (!next.q) delete next.q; + if (!next.status || next.status === "All") delete next.status; + if (!next.overdue || next.overdue === "0") delete next.overdue; + if (!next.page || Number(next.page) === 1) delete next.page; + if (!next.pageSize || Number(next.pageSize) === 20) delete next.pageSize; + if (!next.sort || next.sort === "updated_at:desc") delete next.sort; + const usp = new URLSearchParams(next).toString(); + router.replace(`${pathname}${usp ? `?${usp}` : ""}`); + }; + + const [rows, setRows] = React.useState([]); + const [total, setTotal] = React.useState(0); + const [loading, setLoading] = React.useState(true); + const [error, setError] = React.useState(""); + + // fetch whenever URL params change + React.useEffect(() => { + setLoading(true); setError(""); + apiGet("/rfas", { + q, status: status !== "All" ? status : undefined, + overdue: overdue ? 1 : undefined, page, pageSize, sort + }).then((res) => { + // expected: { data: [...], page, pageSize, total } + setRows(res.data || []); + setTotal(res.total || 0); + }).catch((e) => { + setError(e.message || "โหลดข้อมูลไม่สำเร็จ"); + }).finally(() => setLoading(false)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [sp]); + + const pages = Math.max(1, Math.ceil(total / pageSize)); + + return ( +
+
+ setQ(e.target.value)} + onKeyDown={(e) => e.key === "Enter" && setParams({ q, page: 1 })} + /> + + + +
+ + + +
+ + + + + + + + + + + + {loading && } + {error && !loading && } + {!loading && !error && rows.length === 0 && } + {!loading && !error && rows.map((r) => ( + + + + + + + + ))} + +
รหัสชื่อเรื่องสถานะกำหนดส่งผู้รับผิดชอบ
กำลังโหลด…
{error}
ไม่พบข้อมูล
{r.code || r.id}{r.title}{r.status}{r.due_date || "—"}{r.owner_name || "—"}
+
+
+ ทั้งหมด {total} รายการ +
+ + หน้า {page}/{pages} + +
+
+
+
+
+ ); + }