"use client" import { useEffect, useState } from "react" import { useDuplicates, useResolveDuplicate } from "@/hooks/use-duplicates" import { getTokens } from "@/lib/auth" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Skeleton } from "@/components/ui/skeleton" import { Card, CardContent, CardHeader, CardTitle, } from "@/components/ui/card" import { Spinner } from "@/components/ui/spinner" import { toast } from "sonner" function AssetThumb({ assetId }: { assetId: string }) { const [src, setSrc] = useState(null) useEffect(() => { let revoke: string | null = null const { access } = getTokens() const headers: HeadersInit = access ? { Authorization: `Bearer ${access}` } : {} fetch(`/api/v1/assets/${assetId}/derivatives/thumbnail_square`, { headers }) .then((r) => (r.ok ? r.blob() : Promise.reject())) .catch(() => fetch(`/api/v1/assets/${assetId}/file`, { headers }).then((r) => r.ok ? r.blob() : Promise.reject(), ), ) .then((blob) => { revoke = URL.createObjectURL(blob) setSrc(revoke) }) .catch(() => {}) return () => { if (revoke) URL.revokeObjectURL(revoke) } }, [assetId]) return src ? ( ) : ( ) } export default function DuplicatesPage() { const { data: groups, isLoading } = useDuplicates() const resolve = useResolveDuplicate() return (

Duplicate Resolution

{isLoading ? ( ) : (groups ?? []).length === 0 ? (

No duplicate groups found.

) : ( (groups ?? []).map((group) => ( {group.group_id.slice(0, 8)}... {group.detection_method} {group.status}
{group.candidates.map((c) => (

{c.asset_id.slice(0, 12)}...

{(c.similarity_score * 100).toFixed(1)}% match

))}
)) )}
) }