import { router, usePage } from '@inertiajs/react'; import { useEffect, useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogTitle, } from '@/components/ui/dialog'; export function WorkContextChange() { const page = usePage(); const dirty = useRef(new Set()); const pending = useRef(false); const savingForm = useRef(null); const [open, setOpen] = useState(false); const [message, setMessage] = useState(''); useEffect(() => { dirty.current.clear(); }, [page.url]); useEffect(() => { const formChanged = (event: Event) => { if ( !(event instanceof CustomEvent) || !(event.detail.form instanceof HTMLFormElement) ) return; if (event.detail.dirty) dirty.current.add(event.detail.form); else dirty.current.delete(event.detail.form); }; const changed = (event: Event) => { const input = event.target; if ( input instanceof HTMLInputElement || input instanceof HTMLTextAreaElement || input instanceof HTMLSelectElement ) { if (input.form) dirty.current.add(input.form); } }; const click = (event: MouseEvent) => { if (!(event.target instanceof Element)) return; const link = event.target.closest('a'); if ( !link || new URL(link.href).pathname !== '/dashboard' || !dirty.current.size ) return; event.preventDefault(); event.stopPropagation(); setMessage(''); setOpen(true); }; const unload = (event: BeforeUnloadEvent) => { if (dirty.current.size) { event.preventDefault(); event.returnValue = ''; } }; const saved = (event: Event) => { if (!(event instanceof CustomEvent)) return; if (event.detail.success) dirty.current.delete(event.detail.form); if (!pending.current || event.detail.form !== savingForm.current) return; if (event.detail.success) { pending.current = false; dirty.current.clear(); setOpen(false); router.visit('/dashboard'); } else { pending.current = false; setOpen(true); setMessage( 'A gravação falhou. O contexto actual foi mantido. Corrija os campos antes de mudar.', ); } }; const failure = () => { if (pending.current) { pending.current = false; setOpen(true); setMessage( 'Não foi possível concluir a gravação. O contexto actual foi mantido.', ); } }; const offException = router.on('httpException', failure); const offNetwork = router.on('networkError', failure); document.addEventListener('input', changed); document.addEventListener('change', changed); document.addEventListener('click', click, true); window.addEventListener('beforeunload', unload); window.addEventListener('sgc:context-save-result', saved); window.addEventListener('sgc:context-dirty', formChanged); return () => { document.removeEventListener('input', changed); document.removeEventListener('change', changed); document.removeEventListener('click', click, true); window.removeEventListener('beforeunload', unload); window.removeEventListener('sgc:context-save-result', saved); window.removeEventListener('sgc:context-dirty', formChanged); offException(); offNetwork(); }; }, []); return ( Alterações por guardar Guarde as alterações antes de escolher outro contexto, ou descarte-as. {message &&

{message}

}
); }