'use client' import { useField } from '@payloadcms/ui' import { useRef, useState } from 'react' type MediaDoc = { id: number | string; url?: string | null; alt?: string | null } type ImageEntry = { id?: string; image?: MediaDoc | string | null } | null | undefined type Props = { displayName?: string } function resolveFirstImage(entries: ImageEntry[] | undefined | null): { url: string; alt: string } { const first = entries?.[0]?.image if (!first) return { url: '', alt: '' } if (typeof first === 'string') return { url: '', alt: '' } return { url: first.url ?? '', alt: first.alt ?? '' } } export function ImageUploadSlot({ displayName }: Props) { const { value: images, setValue } = useField({ path: 'images' }) const fileInput = useRef(null) const [uploading, setUploading] = useState(false) const [error, setError] = useState(null) const { url, alt } = resolveFirstImage(images) const onPick = () => fileInput.current?.click() const onFile = async (e: React.ChangeEvent) => { const file = e.target.files?.[0] e.target.value = '' if (!file) return setError(null) setUploading(true) try { const fd = new FormData() fd.append('file', file) fd.append('_payload', JSON.stringify({ alt: displayName || file.name })) const res = await fetch('/api/media', { method: 'POST', body: fd, credentials: 'include' }) if (!res.ok) throw new Error(`upload ${res.status}`) const { doc } = await res.json() const media: MediaDoc = { id: doc.id, url: doc.url, alt: doc.alt } const next = [{ image: media }, ...(images ?? []).slice(1)] setValue(next) } catch (err) { setError(err instanceof Error ? err.message : 'upload failed') } finally { setUploading(false) } } return (
{url ? ( {alt ) : (
Cliquez pour
uploader une image
)}
{error ? `Erreur: ${error}` : 'Cliquez pour changer l\u2019image'}
{uploading &&
Upload…
}
) }