// 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 */}
{[
{ 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 */}
{/* Floating widget — payroll summary card */}
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 }) => (
);
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
{/* 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 = () => (
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')}
))}
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
);
};
// ============== 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) => (
))}
))}
);
};
// ============== PERFORMANCE CARD ==============
const PerfCardGfx = () => (
Q2 · appraisal
Rahul Sharma · Sales
{[
{ 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) => (
))}
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) => (
))}
);
};
Object.assign(window, { DashboardMock, HiringFunnelGfx, FieldMapGfx, PayrollSlipGfx, InvoiceGfx, CashFlowChart, KanbanGfx, PerfCardGfx, AboutUsMock });