Files
cpas/client/src/components/NegateModal.jsx

200 lines
4.9 KiB
React
Raw Normal View History

2026-03-06 12:53:40 -06:00
import React, { useState } from 'react';
const s = {
overlay: {
position: 'fixed',
inset: 0,
background: 'rgba(0,0,0,0.75)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
zIndex: 2000,
},
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',
},
2026-03-06 12:53:40 -06:00
};
export default function NegateModal({ violation, onConfirm, onCancel }) {
const [resolutionType, setResolutionType] = useState('Corrective Training Completed');
const [details, setDetails] = useState('');
const [resolvedBy, setResolvedBy] = useState('');
2026-03-06 12:53:40 -06:00
if (!violation) return null;
2026-03-06 12:53:40 -06:00
const handleConfirm = () => {
if (!onConfirm) return;
onConfirm({
resolution_type: resolutionType,
details,
resolved_by: resolvedBy,
});
};
2026-03-06 12:53:40 -06:00
const handleOverlayClick = (e) => {
if (e.target === e.currentTarget && onCancel) onCancel();
};
return (
<div style={s.overlay} onClick={handleOverlayClick}>
<div style={s.modal}>
<div style={s.header}>
<div style={s.title}> Negate Violation Points</div>
<div style={s.subtitle}>
This will zero out the points from this incident. The record remains in the audit log.
</div>
</div>
2026-03-06 12:53:40 -06:00
<div style={s.body}>
<div style={s.pill}>
{violation.violation_name} · {violation.points} pts · {violation.incident_date}
</div>
2026-03-06 12:53:40 -06:00
<div>
<div style={s.label}>Resolution Type *</div>
<select
style={s.input}
value={resolutionType}
onChange={e => setResolutionType(e.target.value)}
>
<option>Corrective Training Completed</option>
<option>Documentation Error</option>
<option>Policy Clarification / Exception</option>
<option>Management Discretion</option>
</select>
</div>
2026-03-06 12:53:40 -06:00
<div>
<div style={s.label}>Additional Details</div>
<textarea
style={s.textarea}
value={details}
onChange={e => setDetails(e.target.value)}
placeholder="Briefly describe why points are being negated..."
/>
</div>
2026-03-06 12:53:40 -06:00
<div>
<div style={s.label}>Resolved By</div>
<input
style={s.input}
value={resolvedBy}
onChange={e => setResolvedBy(e.target.value)}
placeholder="Supervisor or HR"
/>
</div>
</div>
2026-03-06 12:53:40 -06:00
<div style={s.footer}>
<button
type="button"
style={s.btnCancel}
onClick={() => onCancel && onCancel()}
>
Cancel
</button>
<button
type="button"
style={s.btnConfirm}
onClick={handleConfirm}
>
Confirm Negation
</button>
2026-03-06 12:53:40 -06:00
</div>
</div>
</div>
);
2026-03-06 12:53:40 -06:00
}