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'; import './styles/mobile.css'; 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' }, ]; // Responsive utility hook function useMediaQuery(query) { const [matches, setMatches] = useState(false); useEffect(() => { const media = window.matchMedia(query); if (media.matches !== matches) setMatches(media.matches); const listener = () => setMatches(media.matches); media.addEventListener('change', listener); return () => media.removeEventListener('change', listener); }, [matches, query]); return matches; } 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' }, }; // Mobile-responsive style overrides const mobileStyles = ` @media (max-width: 768px) { .app-nav { padding: 0 16px !important; flex-wrap: wrap; justify-content: center; } .logo-wrap { margin-right: 0 !important; padding: 12px 0 !important; width: 100%; justify-content: center; border-bottom: 1px solid #1a1b22; } .nav-tabs { display: flex; width: 100%; justify-content: space-around; } .nav-tab { flex: 1; text-align: center; padding: 14px 8px !important; font-size: 13px !important; } .docs-btn { position: absolute; top: 16px; right: 16px; padding: 4px 10px !important; font-size: 11px !important; } .docs-btn span:first-child { display: none; } .main-card { margin: 12px !important; border-radius: 8px !important; } } @media (max-width: 480px) { .logo-text { font-size: 16px !important; } .logo-img { height: 24px !important; } } `; 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); const isMobile = useMediaQuery('(max-width: 768px)'); useEffect(() => { fetch('/version.json') .then(r => r.ok ? r.json() : null) .then(v => { if (v) setVersion(v); }) .catch(() => {}); }, []); return (
{tab === 'dashboard' ? : }
{showReadme && setShowReadme(false)} />}
); }