From 35b4ded10c4e902a17c0e10d32faf19f736d8fd1 Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 6 Mar 2026 15:25:48 -0600 Subject: [PATCH] Upload files to "client/src/components" --- client/src/components/EmployeeModal.jsx | 8 +- client/src/components/NegateModal.jsx | 232 ++++++++++++++++++------ 2 files changed, 182 insertions(+), 58 deletions(-) diff --git a/client/src/components/EmployeeModal.jsx b/client/src/components/EmployeeModal.jsx index 500ea7d..bd3c017 100755 --- a/client/src/components/EmployeeModal.jsx +++ b/client/src/components/EmployeeModal.jsx @@ -68,12 +68,18 @@ export default function EmployeeModal({ employeeId, onClose }) { const handleRestore = async (id) => { await axios.patch(`/api/violations/${id}/restore`); + setConfirmDel(null); load(); }; const handleNegate = async ({ resolution_type, details, resolved_by }) => { - await axios.patch(`/api/violations/${negating.id}/negate`, { resolution_type, details, resolved_by }); + await axios.patch(`/api/violations/${negating.id}/negate`, { + resolution_type, + details, + resolved_by, + }); setNegating(null); + setConfirmDel(null); load(); }; diff --git a/client/src/components/NegateModal.jsx b/client/src/components/NegateModal.jsx index 1ea38a1..e52614b 100755 --- a/client/src/components/NegateModal.jsx +++ b/client/src/components/NegateModal.jsx @@ -1,68 +1,186 @@ import React, { useState } from 'react'; -const RESOLUTION_TYPES = [ - 'Corrective Training Completed', - 'Management Discretion', - 'Data Entry Error', - 'Successfully Appealed', -]; - const s = { - overlay: { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.65)', zIndex: 2000, display: 'flex', alignItems: 'center', justifyContent: 'center' }, - box: { background: 'white', borderRadius: '10px', padding: '28px', width: '440px', maxWidth: '95vw', boxShadow: '0 8px 32px rgba(0,0,0,0.22)' }, - title: { fontSize: '17px', fontWeight: 700, color: '#2c3e50', marginBottom: '6px' }, - sub: { fontSize: '12px', color: '#888', marginBottom: '20px' }, - label: { fontWeight: 600, color: '#555', fontSize: '12px', marginBottom: '5px', display: 'block' }, - input: { width: '100%', padding: '9px 12px', border: '1px solid #ddd', borderRadius: '5px', fontSize: '13px', fontFamily: 'inherit', marginBottom: '14px' }, - btnRow: { display: 'flex', gap: '10px', justifyContent: 'flex-end', marginTop: '8px' }, - btnOk: { padding: '10px 22px', background: '#856404', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer', fontWeight: 700, fontSize: '13px' }, - btnCancel:{ padding: '10px 22px', background: '#f1f3f5', color: '#555', border: 'none', borderRadius: '6px', cursor: 'pointer', fontWeight: 600, fontSize: '13px' }, - violBox: { background: '#fff3cd', border: '1px solid #ffc107', borderRadius: '6px', padding: '10px 14px', marginBottom: '18px', fontSize: '13px' }, + overlay: { + position: 'fixed', + inset: 0, + background: 'rgba(0,0,0,0.75)', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + zIndex: 1100, + }, + modal: { + width: '480px', + maxWidth: '95vw', + background: '#111217', + borderRadius: '12px', + boxShadow: '0 16px 40px rgba(0,0,0,0.8)', + color: '#f8f9fa', + overflow: 'hidden', + border: '1px solid #2a2b3a', + }, + header: { + padding: '18px 24px', + borderBottom: '1px solid #222', + background: 'linear-gradient(135deg, #000000, #151622)', + }, + title: { + fontSize: '18px', + fontWeight: 700, + }, + subtitle: { + fontSize: '12px', + color: '#c0c2d6', + marginTop: '4px', + }, + body: { + padding: '18px 24px 8px 24px', + }, + pill: { + background: '#3b2e00', + borderRadius: '6px', + padding: '8px 10px', + fontSize: '12px', + color: '#ffd666', + border: '1px solid #d4af37', + marginBottom: '14px', + }, + label: { + fontSize: '13px', + fontWeight: 600, + marginBottom: '4px', + color: '#e5e7f1', + }, + input: { + width: '100%', + padding: '9px 10px', + borderRadius: '6px', + border: '1px solid #333544', + background: '#050608', + color: '#f8f9fa', + fontSize: '13px', + fontFamily: 'inherit', + marginBottom: '14px', + }, + textarea: { + width: '100%', + minHeight: '80px', + resize: 'vertical', + padding: '9px 10px', + borderRadius: '6px', + border: '1px solid #333544', + background: '#050608', + color: '#f8f9fa', + fontSize: '13px', + fontFamily: 'inherit', + marginBottom: '14px', + }, + footer: { + display: 'flex', + justifyContent: 'flex-end', + gap: '10px', + padding: '16px 24px 20px 24px', + background: '#0c0d14', + borderTop: '1px solid #222', + }, + btnCancel: { + padding: '10px 20px', + borderRadius: '6px', + border: '1px solid #333544', + background: '#050608', + color: '#f8f9fa', + fontWeight: 600, + fontSize: '13px', + cursor: 'pointer', + }, + btnConfirm: { + padding: '10px 22px', + borderRadius: '6px', + border: 'none', + background: 'linear-gradient(135deg, #d4af37 0%, #ffdf8a 100%)', + color: '#000', + fontWeight: 700, + fontSize: '13px', + cursor: 'pointer', + textTransform: 'uppercase', + }, }; export default function NegateModal({ violation, onConfirm, onCancel }) { - const [resType, setResType] = useState(''); - const [details, setDetails] = useState(''); - const [resolvedBy, setResolvedBy] = useState(''); - const [error, setError] = useState(''); + const [resolutionType, setResolutionType] = useState('Corrective Training Completed'); + const [details, setDetails] = useState(''); + const [resolvedBy, setResolvedBy] = useState(''); - const handleSubmit = () => { - if (!resType) { setError('Please select a resolution type.'); return; } - onConfirm({ resolution_type: resType, details, resolved_by: resolvedBy }); - }; + if (!violation) return null; - return ( -
-
-
⊘ Negate Violation Points
-
This will zero out the points from this incident. The record remains in the audit log.
+ const handleConfirm = () => { + onConfirm({ + resolution_type: resolutionType, + details, + resolved_by: resolvedBy, + }); + }; -
- {violation.violation_name}  ·  {violation.points} pts  ·  {violation.incident_date} -
- - - - - -