/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { checkingApi } from "@/api/checking-api"; import { Button } from "@/components/ui/button"; import { speak } from "@/lib/speak"; import { capture, formatTime } from "@/lib/utils"; import useAppStore from "@/stores/use-app-store"; import useUserStore from "@/stores/use-user-store"; import type { AxiosError } from "axios"; import { Camera, Image, Loader } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; import { toast } from "sonner"; import Register from "./register"; export default function TabFeatures({ inline = false }: { inline?: boolean }) { const timeoutRef = useRef(null); const { canvasRef, videoRef } = useAppStore(); const { currentUser, setCurrentUser } = useUserStore(); const { setRefreshLog } = useAppStore(); const [loading, setLoading] = useState(false); const [checkPoinLoading, setCheckPoinLoading] = useState(false); const createCheckpoint = async () => { if (!currentUser) { toast.warning("Vui lòng chọn user để tạo checkpoint"); return; } try { setCheckPoinLoading(true); const file = await capture(videoRef, canvasRef); const { data } = await checkingApi.register({ user: currentUser, file }); if (!data) { toast.error( (data as any)?.message || "Error In Checkpoint: " + JSON.stringify(data), ); return; } toast.success(data?.message || "Tạo checkpoint thành công"); } catch (error) { const data = error as AxiosError; toast.error( (data.response?.data as any)?.message || "Error In Checkpoint: " + JSON.stringify(data), ); } finally { setCheckPoinLoading(false); } }; const captureAndCheck = useCallback(async () => { try { setLoading(true); const file = await capture(videoRef, canvasRef); const { data } = await checkingApi.checkin({ file }); if (!data || !data?.status) { toast.error( (data as any)?.message || "Error In Checking: " + JSON.stringify(data), ); return; } const message = (data as any)?.message || `Checking thành công lúc: ${formatTime(new Date().toLocaleString())}`; toast.success(message); speak({ type: data?.status_type }); setRefreshLog(true); } catch (error) { const data = error as AxiosError; const message = (data.response?.data as any)?.message || "Error In Checking: " + JSON.stringify(data); if ((message as string).includes("No face detected")) return; toast.error(message); } finally { setLoading(false); } }, [canvasRef, setCurrentUser, videoRef]); useEffect(() => { return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current); }; }, []); useEffect(() => { const down = (e: KeyboardEvent) => { if (e.code === "Space") { // ← cách đúng nhất để detect phím cách e.preventDefault(); // nếu không muốn scroll if (loading) return; captureAndCheck(); } }; window.addEventListener("keydown", down); return () => { window.removeEventListener("keydown", down); }; }, [captureAndCheck, loading]); if (inline) { return (
{currentUser ? ( ) : ( )}
); } return (
{currentUser && ( )} {!currentUser && }
); }