Files
cve-dashboard/frontend/src/components/StatsBar.js
Jordan Ramos 306950e360 Extract inline styles to CSS classes
Move JavaScript style objects from home page components into reusable
CSS classes in App.css. This follows the existing pattern (intel-button,
intel-card, intel-input) and consolidates all visual styling in one place.

New CSS classes added:
- .panel-card (--accent, --warning, --teal) — sidebar panels
- .section-heading (--accent, --warning, --teal) — monospace headings
- .stat-card modifiers (--clickable, --active, --warning, --danger)
- .stat-card__label / .stat-card__value (--accent, --neutral, etc.)
- .severity-badge (--critical, --high, --medium, --low)
- .glow-dot (--critical, --high, --medium, --low)
- .sidebar-ticket — compact ticket cards
- .workflow-item — Ivanti workflow entries
- .workflow-state-badge — teal state pill
- .ticket-status-badge — small status indicator
- .archive-item (--active, --resolved) — finding archive entries
- .big-counter (--warning, --teal) — large centered stat numbers

Benefits:
- 578 fewer lines of JavaScript across components
- Styles are browser-cached separately from JS bundle
- Single source of truth for the design system
- Easier to update colors/spacing project-wide
2026-06-23 11:58:44 -06:00

59 lines
1.6 KiB
JavaScript

import React from 'react';
function StatCard({ label, value, color = 'accent', variant, onClick, active }) {
const cardClasses = [
'stat-card',
onClick && 'stat-card--clickable',
active && 'stat-card--active',
variant && `stat-card--${variant}`,
].filter(Boolean).join(' ');
const valueClass = `stat-card__value stat-card__value--${color}`;
return (
<div
className={cardClasses}
onClick={onClick}
role={onClick ? 'button' : undefined}
tabIndex={onClick ? 0 : undefined}
aria-label={`${label}: ${value}`}
>
<div className="stat-card__label">{label}</div>
<div className={valueClass}>{value}</div>
</div>
);
}
export default function StatsBar({ totalCVEs, vendorEntries, openTickets, criticalCount, onFilterSeverity, activeSeverity }) {
return (
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<StatCard
label="Total CVEs"
value={totalCVEs}
color="accent"
onClick={() => onFilterSeverity && onFilterSeverity('All Severities')}
active={activeSeverity === 'All Severities'}
/>
<StatCard
label="Vendor Entries"
value={vendorEntries}
color="neutral"
/>
<StatCard
label="Open Tickets"
value={openTickets}
color="warning"
variant="warning"
/>
<StatCard
label="Critical"
value={criticalCount}
color="danger"
variant="danger"
onClick={() => onFilterSeverity && onFilterSeverity(activeSeverity === 'Critical' ? 'All Severities' : 'Critical')}
active={activeSeverity === 'Critical'}
/>
</div>
);
}