import { useEffect, useMemo, useState } from 'react' import { readContributorName } from '../utils/contributorName' import { ArrowDown, ArrowUp, FileText, Image, MapPin, Mic, Plus, Quote, Route, Trash2, Upload, Video, X } from 'lucide-react' import { getAcceptForMediaType } from '../utils/mediaUpload' import GeoMediaThumbnail from './GeoMediaThumbnail' import './MediaManagerPanel.css' import PzBusy from './PzBusy.jsx' import { t } from '../i18n/index.js' const MEDIA_TYPES = [ { value: 'photo', label: t('Photo'), Icon: Image }, { value: 'video', label: t('Vidéo'), Icon: Video }, { value: 'audio', label: t('Voix'), Icon: Mic }, { value: 'citation', label: t('Citation'), Icon: Quote }, { value: 'document', label: t('Document'), Icon: FileText }, { value: 'geojson', label: t('Carte'), Icon: MapPin }, { value: 'gpx', label: t('Trace GPX'), Icon: Route }, ] // La famille garde l'essentiel ; carte et trace GPX restent au propriétaire const FAMILY_TYPES = ['photo', 'video', 'audio', 'citation', 'document'] const TYPE_NAMES = { photo: t('Photo'), video: t('Vidéo'), audio: t('Voix'), citation: t('Citation'), document: t('Document'), geojson: t('Carte'), gpx: t('Trace GPX') } const TYPE_SHORT = { video: t('Vidéo'), audio: t('Voix'), citation: '«', document: t('Doc') } const YOUTUBE_RE = /^https:\/\/(www\.)?(youtube\.com|youtu\.be)\// const HTTP_URL_RE = /^https?:\/\/\S+$/i const MediaManagerPanel = ({ visible, person, medias, loading, errorMessage, notice = '', canManage = true, onClose, onUpload, onMove, onDelete, }) => { const [caption, setCaption] = useState('') const [source, setSource] = useState('') const [file, setFile] = useState(null) const [mediaType, setMediaType] = useState('photo') const [citationText, setCitationText] = useState('') const [videoMode, setVideoMode] = useState('file') // 'file' | 'youtube' const [youtubeUrl, setYoutubeUrl] = useState('') const [contributorName, setContributorName] = useState(() => readContributorName()) // Le panneau est monté dès le départ : relire le prénom à chaque ouverture (il a pu être donné entre-temps) useEffect(() => { if (visible) setContributorName((current) => current || readContributorName()) }, [visible]) const isCitation = mediaType === 'citation' const isYoutubeVideo = mediaType === 'video' && videoMode === 'youtube' const canUpload = useMemo(() => { if (loading) { return false } if (!canManage && !contributorName.trim()) { return false } if (isCitation) { return citationText.trim().length > 0 } if (isYoutubeVideo) { return YOUTUBE_RE.test(youtubeUrl.trim()) } return Boolean(file) }, [canManage, citationText, contributorName, file, isCitation, isYoutubeVideo, loading, youtubeUrl]) const fileAccept = useMemo(() => getAcceptForMediaType(mediaType), [mediaType]) if (!visible || !person) { return null } const handleSubmit = async (event) => { event.preventDefault() if (!canUpload) { return } await onUpload({ file, caption: caption.trim() || null, source: source.trim() || null, mediaType, citationText: citationText.trim(), youtubeUrl: isYoutubeVideo ? youtubeUrl.trim() : null, submittedByLabel: canManage ? null : contributorName.trim(), }) setFile(null) setCaption('') setSource('') setMediaType('photo') setCitationText('') setVideoMode('file') setYoutubeUrl('') } const handleOverlayClick = (event) => { if (event.target === event.currentTarget) { onClose() } } const renderSource = (value) => { const normalized = String(value || '').trim() if (!normalized) { return null } if (HTTP_URL_RE.test(normalized)) { return ( {normalized} ) } return normalized } const changeType = (value) => { setMediaType(value) setFile(null) setCitationText('') setVideoMode('file') setYoutubeUrl('') } return (

{canManage ? t('Souvenirs') : t('Ajouter un souvenir pour')}

{person.firstName} {person.lastName}

{canManage ? t('Ajouter') : t('Que voulez-vous ajouter ?')}
{MEDIA_TYPES.filter((type) => canManage || FAMILY_TYPES.includes(type.value)).map((type) => ( ))}
{mediaType === 'video' && (
)} {!isCitation && !isYoutubeVideo && (
setFile(event.target.files?.[0] || null)} />
)} {isYoutubeVideo && (
setYoutubeUrl(event.target.value)} placeholder="https://www.youtube.com/watch?v=…" />
)} {isCitation && (