"use client"; import { useRef, useState } from "react"; import Cropper, { type Area } from "react-easy-crop"; import { cropImageToBlob } from "@/lib/image"; import { IconClose } from "@/components/icons"; import { AgoraLogo } from "@/components/agora-logo"; export function AvatarPicker({ hasExistingPhoto = false, onCropped, onClear, }: { hasExistingPhoto?: boolean; onCropped: (blob: Blob) => void; onClear?: () => void; }) { const inputRef = useRef(null); const [rawImageSrc, setRawImageSrc] = useState(null); const [pendingFileName, setPendingFileName] = useState(null); const [fileName, setFileName] = useState(null); const [crop, setCrop] = useState({ x: 0, y: 0 }); const [zoom, setZoom] = useState(1); const [croppedAreaPixels, setCroppedAreaPixels] = useState(null); const [error, setError] = useState(null); function handleFileChange(event: React.ChangeEvent) { const file = event.target.files?.[0]; event.target.value = ""; if (!file) return; const reader = new FileReader(); reader.onload = () => { setRawImageSrc(reader.result as string); setPendingFileName(file.name); setCrop({ x: 0, y: 0 }); setZoom(1); setError(null); }; reader.readAsDataURL(file); } async function handleValidate() { if (!rawImageSrc || !croppedAreaPixels) return; try { const blob = await cropImageToBlob(rawImageSrc, croppedAreaPixels); onCropped(blob); setFileName(pendingFileName); setRawImageSrc(null); setPendingFileName(null); } catch { setError("Impossible de traiter cette image, réessaie."); } } function handleClearSelection() { setFileName(null); onClear?.(); } function truncate(name: string): string { return name.length > 28 ? `${name.slice(0, 12)}…${name.slice(-10)}` : name; } if (rawImageSrc) { return (
setCroppedAreaPixels(pixels)} />
setZoom(Number(event.target.value))} className="w-48" aria-label="Zoom" />
{error &&

{error}

}
); } return (
{fileName ? (
{truncate(fileName)}
) : ( Aucune photo sélectionnée )} {error &&

{error}

}
); }