feat : update

This commit is contained in:
2026-10-05 18:47:41 +07:00 Unverified
parent d44a2597ba
commit 2f1fe0ab76
14 changed files with 311 additions and 38 deletions
+38 -12
View File
@@ -49,6 +49,14 @@ import {
InputGroupAddon,
InputGroupInput,
} from "@/components/ui/input-group";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Spinner } from "@/components/ui/spinner";
import { useAdminPresence } from "@/hooks/use-presence";
import type { CatalogSyncJob } from "@/lib/catalog/sync";
@@ -78,6 +86,7 @@ export function StructuredDashboard({
const router = useRouter();
const [pending, startTransition] = useTransition();
const [query, setQuery] = useState("");
const [sort, setSort] = useState("default");
const [syncJob, setSyncJob] = useState<CatalogSyncJob | null>(null);
const presence = useAdminPresence(null);
const catalogReady = Boolean(catalogVersion);
@@ -86,7 +95,10 @@ export function StructuredDashboard({
const search = searchItems(guides, query,
(guide) => `${guide.name} ${guide.characterKey} ${guide.overview}`,
(guide) => [guide.name]);
const filteredGuides = search.items;
const filteredGuides = sort === "default" ? search.items : [...search.items].sort((left, right) => {
const order = left.name.localeCompare(right.name, "th", { numeric: true });
return sort === "name-asc" ? order : -order;
});
useEffect(() => {
if (!syncJobId || !syncJobStatus || ["completed", "unchanged", "cancelled", "error"].includes(syncJobStatus)) return;
@@ -186,17 +198,31 @@ export function StructuredDashboard({
</Card>
) : null}
{guides.length ? (
<InputGroup className="h-11 max-w-2xl">
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupInput
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder="ค้นหาตัวละคร…"
aria-label="ค้นหาตัวละคร"
/>
</InputGroup>
<div className="flex flex-col gap-3 sm:flex-row sm:items-center">
<InputGroup className="h-11 max-w-2xl flex-1">
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupInput
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder="ค้นหาตัวละคร…"
aria-label="ค้นหาตัวละคร"
/>
</InputGroup>
<Select value={sort} onValueChange={(value) => value && setSort(value)}>
<SelectTrigger aria-label="เรียง Guide" className="h-11 w-full sm:w-44">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="default">เรียงตามเดิม</SelectItem>
<SelectItem value="name-asc">ชื่อ ก-ฮ</SelectItem>
<SelectItem value="name-desc">ชื่อ ฮ-ก</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
) : null}
{filteredGuides.length ? (