diff --git a/client/src/components/EmployeeModal.jsx b/client/src/components/EmployeeModal.jsx index d1a57f7..e5d9d4f 100755 --- a/client/src/components/EmployeeModal.jsx +++ b/client/src/components/EmployeeModal.jsx @@ -6,6 +6,7 @@ import EditEmployeeModal from './EditEmployeeModal'; import AmendViolationModal from './AmendViolationModal'; import ExpirationTimeline from './ExpirationTimeline'; import EmployeeNotes from './EmployeeNotes'; +import { useToast } from './ToastProvider'; const s = { overlay: { @@ -97,6 +98,8 @@ export default function EmployeeModal({ employeeId, onClose }) { const [editingEmp, setEditingEmp] = useState(false); const [amending, setAmending] = useState(null); // violation object + const toast = useToast(); + const load = useCallback(() => { setLoading(true); Promise.all([ @@ -116,34 +119,54 @@ export default function EmployeeModal({ employeeId, onClose }) { useEffect(() => { load(); }, [load]); const handleDownloadPdf = async (violId, empName, date) => { - const response = await axios.get(`/api/violations/${violId}/pdf`, { responseType: 'blob' }); - const url = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' })); - const link = document.createElement('a'); - link.href = url; - link.download = `CPAS_${(empName || '').replace(/[^a-z0-9]/gi, '_')}_${date}.pdf`; - document.body.appendChild(link); - link.click(); - link.remove(); - window.URL.revokeObjectURL(url); + try { + const response = await axios.get(`/api/violations/${violId}/pdf`, { responseType: 'blob' }); + const url = window.URL.createObjectURL(new Blob([response.data], { type: 'application/pdf' })); + const link = document.createElement('a'); + link.href = url; + link.download = `CPAS_${(empName || '').replace(/[^a-z0-9]/gi, '_')}_${date}.pdf`; + document.body.appendChild(link); + link.click(); + link.remove(); + window.URL.revokeObjectURL(url); + toast.success('PDF downloaded.'); + } catch (err) { + toast.error('PDF generation failed: ' + (err.response?.data?.error || err.message)); + } }; const handleHardDelete = async (id) => { - await axios.delete(`/api/violations/${id}`); - setConfirmDel(null); - load(); + try { + await axios.delete(`/api/violations/${id}`); + toast.success('Violation permanently deleted.'); + setConfirmDel(null); + load(); + } catch (err) { + toast.error('Delete failed: ' + (err.response?.data?.error || err.message)); + } }; const handleRestore = async (id) => { - await axios.patch(`/api/violations/${id}/restore`); - setConfirmDel(null); - load(); + try { + await axios.patch(`/api/violations/${id}/restore`); + toast.success('Violation restored to active.'); + setConfirmDel(null); + load(); + } catch (err) { + toast.error('Restore failed: ' + (err.response?.data?.error || err.message)); + } }; const handleNegate = async ({ resolution_type, details, resolved_by }) => { - await axios.patch(`/api/violations/${negating.id}/negate`, { resolution_type, details, resolved_by }); - setNegating(null); - setConfirmDel(null); - load(); + try { + await axios.patch(`/api/violations/${negating.id}/negate`, { resolution_type, details, resolved_by }); + toast.success('Violation negated.'); + setNegating(null); + setConfirmDel(null); + load(); + } catch (err) { + toast.error('Negate failed: ' + (err.response?.data?.error || err.message)); + } }; const tier = score ? getTier(score.active_points) : null; @@ -203,7 +226,7 @@ export default function EmployeeModal({ employeeId, onClose }) {