import { useEffect, useRef, useState } from 'react'; import { toast, toastAfterReload } from '@/lib/toast'; type Item = { cantidad: number; material: { nombre: string; cantidad_disponible: number } | null }; type Prestamo = { id: number; items: Item[]; maestro_responsable: string; alumno: { nombre: string | null; email: string } | null; }; const hoy = () => new Date().toISOString().split('T')[0]; const enDias = (d: number) => new Date(Date.now() + d * 86400000).toISOString().split('T')[0]; const resumenNombres = (items: Item[]) => items.map((i) => i.material?.nombre ?? 'Material').join(', '); export default function AccionesSolicitud({ prestamo }: { prestamo: Prestamo }) { return (
); } function useDialog() { const ref = useRef(null); const open = () => ref.current?.showModal(); const close = () => ref.current?.close(); // Cerrar al hacer click en backdrop useEffect(() => { const d = ref.current; if (!d) return; const onClick = (e: MouseEvent) => { if (e.target === d) d.close(); }; d.addEventListener('click', onClick); return () => d.removeEventListener('click', onClick); }, []); return { ref, open, close }; } function AprobarDialog({ prestamo }: { prestamo: Prestamo }) { const dlg = useDialog(); const [fecha, setFecha] = useState(enDias(1)); const [notas, setNotas] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const stockInsuficiente = prestamo.items.some((i) => (i.material?.cantidad_disponible ?? 0) < i.cantidad); const submit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!fecha || fecha < hoy()) { setError('La fecha de devolución debe ser hoy o posterior.'); return; } setLoading(true); try { const res = await fetch(`/api/admin/solicitudes/${prestamo.id}/aprobar`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ fecha_devolucion_estimada: fecha, notas: notas.trim() || undefined }), }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body?.error ?? `Error ${res.status}`); } toastAfterReload({ kind: 'success', title: 'Solicitud aprobada', description: `${resumenNombres(prestamo.items)} · ${prestamo.alumno?.nombre ?? prestamo.alumno?.email ?? ''}`, }); location.reload(); } catch (err: any) { const msg = err.message ?? 'Error al aprobar.'; setError(msg); toast({ kind: 'error', title: 'No se pudo aprobar', description: msg }); setLoading(false); } }; return ( <>

Aprobar solicitud

{prestamo.alumno?.nombre ?? prestamo.alumno?.email} solicita, para {prestamo.maestro_responsable}:

    {prestamo.items.map((i, idx) => (
  • {i.cantidad} de {i.material?.nombre ?? '—'} {(i.material?.cantidad_disponible ?? 0) < i.cantidad && ( — stock insuficiente ({i.material?.cantidad_disponible ?? 0} disp.) )}
  • ))}
{stockInsuficiente && (
Uno o más materiales no tienen stock suficiente.
)}
setFecha(e.target.value)} required autoFocus />