From 970bc0efeac9d90c2e9c7b99abeb0b839572c743 Mon Sep 17 00:00:00 2001 From: jason Date: Sat, 7 Mar 2026 09:26:33 -0600 Subject: [PATCH] feat: add Audit Log button to Dashboard toolbar --- client/src/components/Dashboard.jsx | 56 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/client/src/components/Dashboard.jsx b/client/src/components/Dashboard.jsx index 8e8b143..d333e7a 100755 --- a/client/src/components/Dashboard.jsx +++ b/client/src/components/Dashboard.jsx @@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback } from 'react'; import axios from 'axios'; import CpasBadge, { getTier } from './CpasBadge'; import EmployeeModal from './EmployeeModal'; +import AuditLog from './AuditLog'; const AT_RISK_THRESHOLD = 2; @@ -28,30 +29,33 @@ function isAtRisk(points) { } const s = { - wrap: { padding: '32px 40px', color: '#f8f9fa' }, - header: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px', flexWrap: 'wrap', gap: '12px' }, - title: { fontSize: '24px', fontWeight: 700, color: '#f8f9fa' }, - subtitle: { fontSize: '13px', color: '#b5b5c0', marginTop: '3px' }, - statsRow: { display: 'flex', gap: '16px', flexWrap: 'wrap', marginBottom: '28px' }, - statCard: { flex: '1', minWidth: '140px', background: '#181924', border: '1px solid #30313f', borderRadius: '8px', padding: '16px', textAlign: 'center' }, - statNum: { fontSize: '28px', fontWeight: 800, color: '#f8f9fa' }, - statLbl: { fontSize: '11px', color: '#b5b5c0', marginTop: '4px' }, - search: { padding: '10px 14px', border: '1px solid #333544', borderRadius: '6px', fontSize: '14px', width: '260px', background: '#050608', color: '#f8f9fa' }, - table: { width: '100%', borderCollapse: 'collapse', background: '#111217', borderRadius: '8px', overflow: 'hidden', boxShadow: '0 1px 8px rgba(0,0,0,0.6)', border: '1px solid #222' }, - th: { background: '#000000', color: '#f8f9fa', padding: '10px 14px', textAlign: 'left', fontSize: '12px', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.5px' }, - td: { padding: '11px 14px', borderBottom: '1px solid #1c1d29', fontSize: '13px', verticalAlign: 'middle', color: '#f8f9fa' }, - nameBtn: { background: 'none', border: 'none', cursor: 'pointer', fontWeight: 600, color: '#d4af37', fontSize: '14px', padding: 0, textDecoration: 'underline dotted' }, - atRiskBadge: { display: 'inline-block', marginLeft: '8px', padding: '2px 8px', borderRadius: '10px', fontSize: '10px', fontWeight: 700, background: '#3b2e00', color: '#ffd666', border: '1px solid #d4af37', verticalAlign: 'middle' }, - zeroRow: { color: '#77798a', fontStyle: 'italic', fontSize: '12px' }, - refreshBtn: { padding: '9px 18px', background: '#d4af37', color: '#000', border: 'none', borderRadius: '6px', cursor: 'pointer', fontWeight: 600, fontSize: '13px' }, + wrap: { padding: '32px 40px', color: '#f8f9fa' }, + header: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px', flexWrap: 'wrap', gap: '12px' }, + title: { fontSize: '24px', fontWeight: 700, color: '#f8f9fa' }, + subtitle: { fontSize: '13px', color: '#b5b5c0', marginTop: '3px' }, + statsRow: { display: 'flex', gap: '16px', flexWrap: 'wrap', marginBottom: '28px' }, + statCard: { flex: '1', minWidth: '140px', background: '#181924', border: '1px solid #30313f', borderRadius: '8px', padding: '16px', textAlign: 'center' }, + statNum: { fontSize: '28px', fontWeight: 800, color: '#f8f9fa' }, + statLbl: { fontSize: '11px', color: '#b5b5c0', marginTop: '4px' }, + search: { padding: '10px 14px', border: '1px solid #333544', borderRadius: '6px', fontSize: '14px', width: '260px', background: '#050608', color: '#f8f9fa' }, + table: { width: '100%', borderCollapse: 'collapse', background: '#111217', borderRadius: '8px', overflow: 'hidden', boxShadow: '0 1px 8px rgba(0,0,0,0.6)', border: '1px solid #222' }, + th: { background: '#000000', color: '#f8f9fa', padding: '10px 14px', textAlign: 'left', fontSize: '12px', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.5px' }, + td: { padding: '11px 14px', borderBottom: '1px solid #1c1d29', fontSize: '13px', verticalAlign: 'middle', color: '#f8f9fa' }, + nameBtn: { background: 'none', border: 'none', cursor: 'pointer', fontWeight: 600, color: '#d4af37', fontSize: '14px', padding: 0, textDecoration: 'underline dotted' }, + atRiskBadge: { display: 'inline-block', marginLeft: '8px', padding: '2px 8px', borderRadius: '10px', fontSize: '10px', fontWeight: 700, background: '#3b2e00', color: '#ffd666', border: '1px solid #d4af37', verticalAlign: 'middle' }, + zeroRow: { color: '#77798a', fontStyle: 'italic', fontSize: '12px' }, + toolbarRight: { display: 'flex', gap: '10px', alignItems: 'center' }, + refreshBtn: { padding: '9px 18px', background: '#d4af37', color: '#000', border: 'none', borderRadius: '6px', cursor: 'pointer', fontWeight: 600, fontSize: '13px' }, + auditBtn: { padding: '9px 18px', background: 'none', color: '#9ca0b8', border: '1px solid #2a2b3a', borderRadius: '6px', cursor: 'pointer', fontWeight: 600, fontSize: '13px' }, }; export default function Dashboard() { - const [employees, setEmployees] = useState([]); - const [filtered, setFiltered] = useState([]); - const [search, setSearch] = useState(''); - const [selectedId, setSelectedId] = useState(null); - const [loading, setLoading] = useState(true); + const [employees, setEmployees] = useState([]); + const [filtered, setFiltered] = useState([]); + const [search, setSearch] = useState(''); + const [selectedId, setSelectedId] = useState(null); + const [showAudit, setShowAudit] = useState(false); + const [loading, setLoading] = useState(true); const load = useCallback(() => { setLoading(true); @@ -77,9 +81,6 @@ export default function Dashboard() { const maxPoints = employees.reduce((m, e) => Math.max(m, e.active_points), 0); return ( - // FIX: Fragment wraps both s.wrap AND EmployeeModal so the modal is - // outside the s.wrap div — React synthetic events will no longer bubble - // from inside the modal up through the Dashboard's DOM tree. <>
@@ -87,13 +88,14 @@ export default function Dashboard() {
Company Dashboard
Click any employee name to view their full profile
-
+
setSearch(e.target.value)} /> +
@@ -179,15 +181,13 @@ export default function Dashboard() { )}
- {/* FIX: EmployeeModal is now OUTSIDE
. - React synthetic events no longer bubble from modal buttons - up through Dashboard's component tree. */} {selectedId && ( { setSelectedId(null); load(); }} /> )} + {showAudit && setShowAudit(false)} />} ); }