import { baseUrl } from "@/api/baseUrl"; import ActivityIndicator from "@/components/indicators/activity-indicator"; import LPRDetailDialog from "@/components/overlay/dialog/LPRDetailDialog"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Toaster } from "@/components/ui/sonner"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { FrigateConfig } from "@/types/frigateConfig"; import { Event } from "@/types/event"; import { useCallback, useEffect, useMemo, useState } from "react"; import useSWR from "swr"; import { useFormattedTimestamp } from "@/hooks/use-date-utils"; import { LuTrash2 } from "react-icons/lu"; import axios from "axios"; import { toast } from "sonner"; export default function LPRDebug() { const { data: config } = useSWR("config"); // title useEffect(() => { document.title = "LPR - Frigate"; }, []); // lpr data const { data: lprData, mutate: refreshLPR } = useSWR("lpr/debug"); const lprAttempts = useMemo( () => (lprData ? Object.keys(lprData).filter((attempt) => attempt != "train") : []), [lprData], ); if (!config) { return ; } return (
License Plate Recognition
{lprAttempts.map((attempt: string) => ( ))}
); } type LPRAttemptProps = { attempt: string; config: FrigateConfig; onRefresh: () => void; }; function LPRAttempt({ attempt, config, onRefresh }: LPRAttemptProps) { const [showDialog, setShowDialog] = useState(false); const data = useMemo(() => { const parts = attempt.split("-"); return { eventId: `${parts[0]}-${parts[1]}`, plate: parts[2] || "Text not extracted", score: parts[3] || "0", }; }, [attempt]); const { data: event } = useSWR( data.eventId ? ["event", { id: data.eventId }] : null ); const timestamp = useFormattedTimestamp( event?.start_time ?? 0, config?.ui.time_format == "24hour" ? "%b %-d %Y, %H:%M" : "%b %-d %Y, %I:%M %p", config?.ui.timezone, ); const onDelete = useCallback(() => { axios .post(`/lpr/debug/delete`, { ids: [attempt] }) .then((resp) => { if (resp.status == 200) { toast.success(`Successfully deleted LPR debug image.`, { position: "top-center", }); onRefresh(); } }) .catch((error) => { if (error.response?.data?.message) { toast.error(`Failed to delete: ${error.response.data.message}`, { position: "top-center", }); } else { toast.error(`Failed to delete: ${error.message}`, { position: "top-center", }); } }); }, [attempt, onRefresh]); return ( <>
setShowDialog(true)} >
{data.plate}
{Number.parseFloat(data.score) * 100}%
{event && (
{timestamp}
)}
Delete Image
); }