import { useCallback, useEffect, useState } from 'react' import Cropper, { type Area } from 'react-easy-crop' import { ImagePlus, X } from 'lucide-react' import { getCroppedImage } from '../utils/cropImage' import { useT } from '../i18n/useT' import styles from './ImageCropper.module.css' interface ImageCropperProps { value: string | null onChange: (value: string | null) => void aspect?: number outputFormat?: 'jpeg' | 'png' accept?: string uploadLabel?: string hint?: string changeLabel?: string } export function ImageCropper({ value, onChange, aspect = 1, outputFormat = 'jpeg', accept = 'image/*', uploadLabel, hint, changeLabel, }: ImageCropperProps) { const t = useT() const resolvedUploadLabel = uploadLabel ?? t('myProducts.images.thumbnailUpload') const resolvedHint = hint ?? t('myProducts.images.thumbnailHint') const resolvedChangeLabel = changeLabel ?? t('myProducts.images.thumbnailChange') const [imageSrc, setImageSrc] = useState(null) const [crop, setCrop] = useState({ x: 0, y: 0 }) const [zoom, setZoom] = useState(1) const [croppedArea, setCroppedArea] = useState(null) useEffect(() => { setCrop({ x: 0, y: 0 }) setZoom(1) setCroppedArea(null) }, [aspect]) const onCropComplete = useCallback((_: Area, pixels: Area) => { setCroppedArea(pixels) }, []) function handleFile(e: React.ChangeEvent) { const file = e.target.files?.[0] if (!file) return const reader = new FileReader() reader.onload = () => { setImageSrc(reader.result as string) setCrop({ x: 0, y: 0 }) setZoom(1) setCroppedArea(null) } reader.readAsDataURL(file) e.target.value = '' } async function applyCrop() { if (!imageSrc || !croppedArea) return const cropped = await getCroppedImage(imageSrc, croppedArea, outputFormat) onChange(cropped) setImageSrc(null) setZoom(1) setCrop({ x: 0, y: 0 }) } function cancelCrop() { setImageSrc(null) setZoom(1) setCrop({ x: 0, y: 0 }) } function removeThumbnail() { onChange(null) } const isPortrait = aspect < 1 const frameStyle: React.CSSProperties = isPortrait ? { aspectRatio: `${aspect}`, height: 'min(480px, 65vh)', width: 'auto', maxWidth: '100%', marginInline: 'auto', } : { aspectRatio: String(aspect), width: '100%', height: 'auto', } return (
{value && !imageSrc && (
{resolvedUploadLabel}
)} {!value && !imageSrc && ( )} {imageSrc && (
)} {value && !imageSrc && ( )}
) }