// Real graphic components for product UI mockups, charts, illustrations // ============== ANIMATED HERO DASHBOARD MOCKUP ============== const DashboardMock = () => { const [tick, setTick] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1800); return () => clearInterval(id); }, []); return (
{/* Background ambient glow */}
{/* Main app frame */}
{/* App chrome */}
app.primehr.in/dashboard
{/* Sidebar */}
PrimeHR
{[ { i: 'chart', l: 'Dashboard', active: true }, { i: 'users', l: 'People' }, { i: 'cal', l: 'Attendance' }, { i: 'coin', l: 'Payroll' }, { i: 'pin', l: 'Field Force' }, { i: 'doc', l: 'Reports' }, ].map((item, i) => (
{item.l}
))}
{/* Main panel */}
{/* Greet row */}
Good morning, Priya 👋
TUE · 30 APR · 09:14
142 present 6 leave
{/* KPI row */}
{(28_42_500 + tick * 14320).toLocaleString('en-IN').slice(0, -1)}…} delta="ready" tickAccent />
{/* Chart card */}
Attendance · this week ● live
{/* Activity */}
Live activity
{/* Floating widget — payroll summary card */}
Apr Payroll
92% calculated · TDS ready
{/* Floating widget — hiring */}
Sales Lead role
{1284 + tick} applicants
{[100, 78, 56, 36, 22].map((w, i) => (
))}
AI screened in 2 min
); }; const KPI = ({ label, value, delta, good = false, tickAccent = false }) => (
{label}
{value}
{delta}
); const BarsRow = ({ tick }) => { const heights = [70, 85, 60, 92, 78, 45]; return (
{heights.map((base, i) => { const offset = ((tick + i) % 5 - 2) * 4; const h = Math.max(20, Math.min(95, base + offset)); const isActive = i === (tick % 6); return (
); })}
{['Mon','Tue','Wed','Thu','Fri','Sat'].map((d, i) => ( {d} ))}
); }; const ActivityList = ({ tick }) => { const items = [ { who: 'RS', name: 'Rahul', what: 'clocked in', where: 'Vijay Nagar', t: '9:12am', color: 'var(--brand-500)' }, { who: 'AI', name: 'AI Screen', what: 'shortlisted 3 for Sales Lead', where: '', t: '9:08am', color: 'var(--accent-500)', spark: true }, { who: 'MK', name: 'Meera', what: 'submitted ₹2,400 expense', where: 'Pithampur', t: '8:55am', color: 'var(--warn-500)' }, ]; return (
{items.map((it, i) => (
{it.spark ? : it.who}
{it.name} {it.what} {it.where && · {it.where}}
{it.t}
))}
); }; // ============== HIRING FUNNEL ============== const HiringFunnelGfx = () => { const [t, setT] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setT(x => x + 1), 1800); return () => clearInterval(id); }, []); const stages = [ { label: 'Applied', count: 1284, w: 100, color: 'var(--brand-200)' }, { label: 'AI Screened', count: 412, w: 80, color: 'var(--brand-500)', ai: true }, { label: 'Interview', count: 86, w: 60, color: 'var(--brand-600)' }, { label: 'Offer', count: 18, w: 38, color: 'var(--brand-700)' }, { label: 'Hired', count: 9, w: 22, color: 'var(--accent-500)' }, ]; return (
ATS · live funnel
Sales Lead — Indore
AI auto-screen
{stages.map((s, i) => (
1 ? '#fff' : 'var(--ink-900)', padding: '12px 18px', borderRadius: 8, display: 'flex', justifyContent: 'space-between', alignItems: 'center', boxShadow: i === stages.length - 1 ? '0 8px 20px -8px rgba(16, 185, 129, 0.5)' : 'none', transform: i === (t % stages.length) ? 'translateX(4px)' : 'translateX(0)', transition: 'transform 0.5s', }}> {s.ai && } {s.label} {s.count.toLocaleString('en-IN')}
))} {/* Flowing dots */} {Array.from({ length: 6 }).map((_, i) => ( ))}
14 days time-to-hire
62 hrs saved
Interview at 3pm
); }; // ============== FFA MAP ============== const FieldMapGfx = () => { const [pulse, setPulse] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setPulse(p => p + 1), 1800); return () => clearInterval(id); }, []); const pins = [ { x: 110, y: 90, status: 'active', label: 'RA' }, { x: 230, y: 160, status: 'active', label: 'MK' }, { x: 380, y: 110, status: 'idle', label: 'VR' }, { x: 470, y: 220, status: 'active', label: 'AN' }, { x: 320, y: 280, status: 'offline', label: 'SM' }, ]; const colorOf = (s) => s === 'active' ? '#10b981' : s === 'idle' ? '#f59e0b' : '#94a3b8'; return (
field force · live map
Indore region
{/* zones */} {/* roads */} {/* courier path */} {/* radius search */} 5km radius {/* pins */} {pins.map((p, i) => ( {p.status === 'active' && ( )} {p.label} ))} {/* live info card */}
Meera K. ● live
Visit #{4 + (pulse % 9)} · 2.3 km away
📍 geotagged 📷 photo proof
); }; const Legend = ({ dot, label }) => ( {label} ); // ============== PAYROLL SLIP ============== const PayrollSlipGfx = () => { const [run, setRun] = React.useState(false); const [step, setStep] = React.useState(0); const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver(es => es.forEach(e => { if (e.isIntersecting) setRun(true); }), { threshold: 0.3 }); io.observe(el); return () => io.disconnect(); }, []); React.useEffect(() => { if (!run) return; if (step >= 8) { const id = setTimeout(() => setStep(0), 3500); return () => clearTimeout(id); } const id = setTimeout(() => setStep(s => s + 1), 420); return () => clearTimeout(id); }, [run, step]); const lines = [ { l: 'Basic', a: 45000, sign: '+' }, { l: 'HRA', a: 18000, sign: '+' }, { l: 'Special Allowance', a: 12500, sign: '+' }, { l: 'PF (employee)', a: -5400, sign: '−' }, { l: 'Professional Tax', a: -200, sign: '−' }, { l: 'TDS', a: -3850, sign: '−' }, { l: 'Loan EMI', a: -2500, sign: '−' }, ]; return (
payslip · apr 2026
Priya Sharma
auto-calc
EMP-0142 · UAN 100xxxxx789
{lines.map((ln, i) => (
i ? (ln.a < 0 ? '#fef3c7' : '#dcfce7') : 'transparent', borderRadius: 6, opacity: step > i ? 1 : 0, transform: step > i ? 'translateX(0)' : 'translateX(-8px)', transition: 'all 0.35s ease', }}> {ln.sign} {ln.l} ₹ {Math.abs(ln.a).toLocaleString('en-IN')}
))}
= 7 ? 'linear-gradient(135deg, var(--brand-600), var(--brand-800))' : 'var(--ink-100)', color: step >= 7 ? '#fff' : 'var(--ink-500)', borderRadius: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center', transition: 'all 0.5s', }}> Net pay ₹ {step >= 7 ? : '—'}
✓ Statutory ready ✓ TDS filed ✓ Tally sync
); }; // ============== INVOICE / FINANCE MOCK ============== const InvoiceGfx = () => (
INVOICE
WH-2026-0481
Paid · 2 hrs ago
Bill to
Surya Pharma Pvt Ltd
GSTIN 27AABCS1234A1Z5
Issued
30 Apr 2026
Due: 30 May 2026
{[ { l: 'PrimeHR Growth · 80 emp × 12 mo', amt: 8_54_400 }, { l: 'FFA module · 25 field staff', amt: 1_50_000 }, { l: 'Tally premium connector', amt: 24_000 }, ].map((row, i) => (
{row.l} ₹ {row.amt.toLocaleString('en-IN')}
))}
Total ₹ 12,13,512
Tally synced e-Invoice + IRN
); const Row = ({ k, v }) => (
{k}{v}
); // ============== CASH FLOW CHART ============== const CashFlowChart = () => { const data = [ { m: 'Jan', inc: 84, exp: 62 }, { m: 'Feb', inc: 92, exp: 68 }, { m: 'Mar', inc: 78, exp: 71 }, { m: 'Apr', inc: 110, exp: 74 }, { m: 'May', inc: 124, exp: 82 }, { m: 'Jun', inc: 138, exp: 88 }, ]; const max = 150; const w = 480, h = 220, pad = 30; const xStep = (w - pad * 2) / (data.length - 1); const yOf = v => h - pad - (v / max) * (h - pad * 2); const line = (key) => data.map((d, i) => `${i === 0 ? 'M' : 'L'} ${pad + i * xStep} ${yOf(d[key])}`).join(' '); const area = (key) => `${line(key)} L ${pad + (data.length-1) * xStep} ${h - pad} L ${pad} ${h - pad} Z`; return (
cash flow · h1 2026
+ ₹ 28.4 L surplus
Income Expenses
{/* gridlines */} {[0.25, 0.5, 0.75].map(g => ( ))} {data.map((d, i) => ( {d.m} ))}
); }; // ============== KANBAN ============== const KanbanGfx = () => { const [tick, setTick] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 2400); return () => clearInterval(id); }, []); const cols = [ { name: 'Open', color: '#94a3b8', cards: [{ t: 'AC repair · Bhawarkua', urgent: true, sla: '2h' }, { t: 'Demo · Surya Pharma', sla: '4h' }, { t: 'Order delivery · Super Corridor', sla: '6h' }] }, { name: 'In progress', color: '#4f46e5', cards: [{ t: 'Site survey · Palasia', urgent: true, sla: '1h' }, { t: 'Collection · Vijay Nagar', sla: '3h' }] }, { name: 'Resolved', color: '#10b981', cards: [{ t: 'Service · Rau', sla: '✓' }, { t: 'Inspection · Pithampur', sla: '✓' }, { t: 'Demo · HQ', sla: '✓' }] }, ]; return (
complaint board · today auto-routes via SLA
{cols.map((c, ci) => (
{c.name} {c.cards.length}
{c.cards.map((card, ji) => (
{card.t} {card.sla}
))}
))}
); }; // ============== PERFORMANCE CARD ============== const PerfCardGfx = () => (
Q2 · appraisal
Rahul Sharma · Sales
4.3
{[ { k: 'Revenue target', s: 88, c: 'var(--accent-500)' }, { k: 'Customer NPS', s: 72, c: 'var(--brand-500)' }, { k: 'Pipeline hygiene', s: 95, c: 'var(--accent-500)' }, { k: 'Team mentoring', s: 60, c: 'var(--warn-500)' }, ].map((k, i) => (
{k.k} {k.s}%
))}
AI insight: Punctuality up 18% vs Q1. Suggest stretch goal on team mentoring.
); // ============== ABOUT US MOCK ============== const AboutUsMock = () => { return (
admin.primehr.in/directory
PrimeHR
{[ { i: 'users', l: 'Directory', active: true }, { i: 'chart', l: 'Company Stats' }, { i: 'pin', l: 'Office Locations' }, { i: 'shield', l: 'Compliance' }, ].map((item, i) => (
{item.l}
))}
Company Overview
TUE · 30 APR · 09:14
Active Status
Department Headcount
{[80, 60, 45, 90, 50].map((h, i) => (
))}
{['Eng','Sales','HR','Ops','Fin'].map((d, i) => ( {d} ))}
Company Updates
{[ { icon: 'spark', name: 'New AI feature deployed', t: '1h ago', c: 'var(--accent-500)' }, { icon: 'users', name: 'Onboarded 12 new engineers', t: '3h ago', c: 'var(--brand-500)' }, { icon: 'target', name: 'Q2 Goals successfully met', t: '1d ago', c: 'var(--ink-500)' }, ].map((it, i) => (
{it.name}
{it.t}
))}
); }; Object.assign(window, { DashboardMock, HiringFunnelGfx, FieldMapGfx, PayrollSlipGfx, InvoiceGfx, CashFlowChart, KanbanGfx, PerfCardGfx, AboutUsMock });