import React, { useState, useRef } from 'react'; import { createPortal } from 'react-dom'; // ─── Confirmation Dialog ────────────────────────────────────────────────────── function ConfirmDialog({ isOpen, title, message, confirmLabel, confirmColor, onConfirm, onCancel, icon }) { if (!isOpen) return null; return createPortal(

{title}

{message}

, document.body ); } // ─── Restitution Modal ──────────────────────────────────────────────────────── function RestitutionModal({ isOpen, onClose, submitUrl, objetTitre, objetImage, objetReference, csrfToken }) { const [photoFile, setPhotoFile] = useState(null); const [photoPreview, setPhotoPreview] = useState(null); const [commentaire, setCommentaire] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const fileInputRef = useRef(null); const handlePhotoChange = (e) => { const file = e.target.files[0]; if (!file) return; setPhotoFile(file); const reader = new FileReader(); reader.onload = (ev) => setPhotoPreview(ev.target.result); reader.readAsDataURL(file); }; const handleSubmit = async (e) => { e.preventDefault(); if (!photoFile) { setError('Veuillez joindre une photo de preuve.'); return; } setIsSubmitting(true); setError(null); const body = new FormData(); body.append('photo', photoFile); body.append('commentaire', commentaire); body.append('_token', csrfToken); try { const res = await fetch(submitUrl, { method: 'POST', body, headers: { Accept: 'application/json' } }); const data = await res.json(); if (data.success) { setSuccess(true); setTimeout(() => window.location.reload(), 2500); } else setError(data.message || 'Une erreur est survenue.'); } catch { setError('Erreur de connexion.'); } finally { setIsSubmitting(false); } }; if (!isOpen) return null; return createPortal(
{ if (e.target === e.currentTarget && !isSubmitting) onClose(); }}>
{/* Header */}
Confirmer la restitution
Joignez une preuve photographique
{success ? (

Restitution confirmée !

{objetTitre} est maintenant marqué comme restitué.

Redirection en cours…

) : (
{/* Sidebar */}
Objet concerné
{objetImage ? {objetTitre} :
}
{objetTitre}
REF: {objetReference}
Important : Cette action confirme la remise physique de l'objet. Elle est définitive.
{/* Form */}
{error && (
{error}
)}

Photo lors de la remise, reçu signé, etc.

fileInputRef.current?.click()} style={{ border: '2px dashed #28a745', borderRadius: 14, padding: 20, cursor: 'pointer', background: photoPreview ? '#f0fdf4' : '#fafafa', minHeight: 120, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', transition: 'all 0.2s' }}> {photoPreview ? preview : <> Cliquer pour choisir une photo JPG, PNG, WEBP • Max 5 MB }
{photoFile && (
{photoFile.name}
)}