feat : add searchbar to admin
CI / Verify (push) Successful in 1m13s
CI / Build immutable images and deploy (push) Successful in 1m49s

This commit is contained in:
2026-09-08 18:39:39 +07:00 Unverified
parent bb28d79aee
commit cd66d498ab
+34 -1
View File
@@ -7,6 +7,7 @@ import {
PlusIcon,
RefreshCwIcon,
RotateCcwIcon,
SearchIcon,
XCircleIcon,
Trash2Icon,
} from "lucide-react";
@@ -41,6 +42,11 @@ import {
EmptyHeader,
EmptyTitle,
} from "@/components/ui/empty";
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/components/ui/input-group";
import { Spinner } from "@/components/ui/spinner";
import { useAdminPresence } from "@/hooks/use-presence";
import type { CatalogSyncJob } from "@/lib/catalog/sync";
@@ -71,6 +77,7 @@ export function StructuredDashboard({
}) {
const router = useRouter();
const [pending, startTransition] = useTransition();
const [query, setQuery] = useState("");
const [syncJob, setSyncJob] = useState<CatalogSyncJob | null>(null);
const presence = useAdminPresence(null);
const catalogReady = Boolean(catalogVersion);
@@ -81,6 +88,12 @@ export function StructuredDashboard({
);
const syncJobId = syncJob?.id;
const syncJobStatus = syncJob?.status;
const normalizedQuery = query.trim().toLowerCase();
const filteredGuides = guides.filter((guide) =>
`${guide.name} ${guide.characterKey} ${guide.overview}`
.toLowerCase()
.includes(normalizedQuery),
);
useEffect(() => {
if (!syncJobId || !syncJobStatus || ["completed", "unchanged", "cancelled", "error"].includes(syncJobStatus)) return;
@@ -187,8 +200,21 @@ 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>
) : null}
{filteredGuides.length ? (
<div className="grid gap-5 md:grid-cols-2 xl:grid-cols-3">
{guides.map((guide) => (
{filteredGuides.map((guide) => (
<Card
key={guide.id}
className="relative overflow-hidden py-0 transition-colors hover:bg-muted/50"
@@ -269,6 +295,13 @@ export function StructuredDashboard({
</Card>
))}
</div>
) : guides.length ? (
<Empty className="border">
<EmptyHeader>
<EmptyTitle>ไม่พบตัวละคร</EmptyTitle>
<EmptyDescription>ลองค้นหาด้วยชื่อตัวละครอื่น</EmptyDescription>
</EmptyHeader>
</Empty>
) : (
<Empty className="border">
<EmptyHeader>