From 1991c105b70575c1071456d51f9f4de787c43096 Mon Sep 17 00:00:00 2001 From: Jason UNRAID Date: Fri, 6 Mar 2026 13:46:12 -0600 Subject: [PATCH] Hotfixes --- client/src/components/EmployeeModal.jsx | 27 +++++++++------------ pdf/template.js | 32 +++++++++---------------- 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/client/src/components/EmployeeModal.jsx b/client/src/components/EmployeeModal.jsx index ac4b334..f49da38 100755 --- a/client/src/components/EmployeeModal.jsx +++ b/client/src/components/EmployeeModal.jsx @@ -24,20 +24,13 @@ const s = { deleteConfirm: { background: '#f8d7da', border: '1px solid #f5c6cb', borderRadius: '6px', padding: '12px', marginTop: '8px', fontSize: '12px' }, }; -const RESOLUTION_TYPES = [ - 'Corrective Training Completed', - 'Management Discretion', - 'Data Entry Error', - 'Successfully Appealed', -]; - export default function EmployeeModal({ employeeId, onClose }) { const [employee, setEmployee] = useState(null); const [score, setScore] = useState(null); const [violations, setViolations] = useState([]); const [loading, setLoading] = useState(true); - const [negating, setNegating] = useState(null); // violation object being soft-negated - const [confirmDel, setConfirmDel] = useState(null); // violation id pending hard delete + const [negating, setNegating] = useState(null); + const [confirmDel, setConfirmDel] = useState(null); const load = useCallback(() => { setLoading(true); @@ -70,12 +63,18 @@ export default function EmployeeModal({ employeeId, onClose }) { const handleHardDelete = async (id) => { await axios.delete(`/api/violations/${id}`); setConfirmDel(null); - load(); + load(); // ← refetch employee list, score, and violations }; const handleRestore = async (id) => { await axios.patch(`/api/violations/${id}/restore`); - load(); + load(); // ← refetch employee list, score, and violations + }; + + const handleNegate = async ({ resolution_type, details, resolved_by }) => { + await axios.patch(`/api/violations/${negating.id}/negate`, { resolution_type, details, resolved_by }); + setNegating(null); + load(); // ← CRITICAL FIX: refetch score immediately after negation }; const tier = score ? getTier(score.active_points) : null; @@ -232,11 +231,7 @@ export default function EmployeeModal({ employeeId, onClose }) { {negating && ( { - await axios.patch(`/api/violations/${negating.id}/negate`, { resolution_type, details, resolved_by }); - setNegating(null); - load(); - }} + onConfirm={handleNegate} onCancel={() => setNegating(null)} /> )} diff --git a/pdf/template.js b/pdf/template.js index 02e67d6..16fdc4e 100755 --- a/pdf/template.js +++ b/pdf/template.js @@ -51,17 +51,6 @@ function buildHtml(v, score) { dateStyle: 'full', timeStyle: 'short' }); - // Map violation_type to handbook chapter reference (loaded from violations.js in frontend) - // Since we're in backend, we'll reconstruct key descriptions from the violation_name - // The database already stores violation_name (e.g., "Tardy Core Hours") and category - - // Build a contextual description block - const contextBlock = v.details - ? `
- Context: ${v.details} -
` - : ''; - return ` @@ -111,13 +100,14 @@ function buildHtml(v, score) { .points-display .pts { font-size: 36px; font-weight: 800; color: #667eea; } .points-display .lbl { font-size: 12px; color: #666; } - .sig-section { margin-top: 30px; } - .sig-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 16px; } - .sig-block { border-top: 1px solid #333; padding-top: 6px; } - .sig-label { font-size: 11px; color: #555; } + .sig-section { margin-top: 40px; page-break-inside: avoid; } + .sig-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-top: 24px; } + .sig-block { border-top: 1.5px solid #333; padding-top: 8px; min-height: 60px; } + .sig-label { font-size: 11px; color: #555; font-weight: 600; } + .sig-date-block { border-top: 1.5px solid #333; padding-top: 8px; min-height: 50px; margin-top: 32px; } .footer-bar { - margin-top: 30px; padding: 10px 0; + margin-top: 40px; padding: 10px 0; border-top: 2px solid #2c3e50; font-size: 10px; color: #888; text-align: center; } @@ -249,11 +239,11 @@ function buildHtml(v, score) { Chapter 4, Section 5. This document should be reviewed with the employee and signed by all parties. - +
Acknowledgement & Signatures
-
-

+

+

By signing below, the employee acknowledges receipt of this violation record. Acknowledgement does not imply agreement. The employee may submit a written response within 5 business days. @@ -263,7 +253,7 @@ function buildHtml(v, score) {

Employee Signature
-
+
Date
@@ -271,7 +261,7 @@ function buildHtml(v, score) {
Supervisor / Documenting Officer Signature
-
+
Date
-- 2.49.1