import React, { useState, useEffect } from 'react'; import ViolationForm from './components/ViolationForm'; import Dashboard from './components/Dashboard'; import ReadmeModal from './components/ReadmeModal'; import ToastProvider from './components/ToastProvider'; const REPO_URL = 'https://git.alwisp.com/jason/cpas'; const PROJECT_START = new Date('2026-03-06T11:33:32-06:00'); function elapsed(from) { const totalSec = Math.floor((Date.now() - from.getTime()) / 1000); const d = Math.floor(totalSec / 86400); const h = Math.floor((totalSec % 86400) / 3600); const m = Math.floor((totalSec % 3600) / 60); const s = totalSec % 60; return `${d}d ${String(h).padStart(2,'0')}h ${String(m).padStart(2,'0')}m ${String(s).padStart(2,'0')}s`; } function DevTicker() { const [tick, setTick] = useState(() => elapsed(PROJECT_START)); useEffect(() => { const id = setInterval(() => setTick(elapsed(PROJECT_START)), 1000); return () => clearInterval(id); }, []); return ( {tick} ); } function GiteaIcon() { return ( ); } function AppFooter({ version }) { const year = new Date().getFullYear(); const sha = version?.shortSha || null; const built = version?.buildTime ? new Date(version.buildTime).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : null; return ( <> > ); } const tabs = [ { id: 'dashboard', label: '📊 Dashboard' }, { id: 'violation', label: '+ New Violation' }, ]; const s = { app: { minHeight: '100vh', background: '#050608', fontFamily: "'Segoe UI', Arial, sans-serif", color: '#f8f9fa', display: 'flex', flexDirection: 'column' }, nav: { background: '#000000', padding: '0 40px', display: 'flex', alignItems: 'center', gap: 0, borderBottom: '1px solid #333' }, logoWrap: { display: 'flex', alignItems: 'center', marginRight: '32px', padding: '14px 0' }, logoImg: { height: '28px', marginRight: '10px' }, logoText: { color: '#f8f9fa', fontWeight: 800, fontSize: '18px', letterSpacing: '0.5px' }, tab: (active) => ({ padding: '18px 22px', color: active ? '#f8f9fa' : 'rgba(248,249,250,0.6)', borderBottom: active ? '3px solid #d4af37' : '3px solid transparent', cursor: 'pointer', fontWeight: active ? 700 : 400, fontSize: '14px', background: 'none', border: 'none', }), docsBtn: { marginLeft: 'auto', background: 'none', border: '1px solid #2a2b3a', color: '#9ca0b8', borderRadius: '6px', padding: '6px 14px', fontSize: '12px', cursor: 'pointer', fontWeight: 600, letterSpacing: '0.3px', display: 'flex', alignItems: 'center', gap: '6px', }, main: { flex: 1 }, card: { maxWidth: '1100px', margin: '30px auto', background: '#111217', borderRadius: '10px', boxShadow: '0 2px 16px rgba(0,0,0,0.6)', border: '1px solid #222' }, }; const sf = { footer: { borderTop: '1px solid #1a1b22', padding: '12px 40px', display: 'flex', alignItems: 'center', gap: '12px', fontSize: '11px', color: 'rgba(248,249,250,0.35)', background: '#000', flexShrink: 0, }, copy: { color: 'rgba(248,249,250,0.35)' }, sep: { color: 'rgba(248,249,250,0.15)' }, link: { color: 'rgba(248,249,250,0.35)', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: '4px', transition: 'color 0.15s', }, }; export default function App() { const [tab, setTab] = useState('dashboard'); const [showReadme, setShowReadme] = useState(false); const [version, setVersion] = useState(null); useEffect(() => { fetch('/version.json') .then(r => r.ok ? r.json() : null) .then(v => { if (v) setVersion(v); }) .catch(() => {}); }, []); return ( CPAS Tracker {tabs.map(t => ( setTab(t.id)}> {t.label} ))} setShowReadme(true)} title="Open admin documentation"> ? Docs {tab === 'dashboard' ? : } {showReadme && setShowReadme(false)} />} ); }