const DS = window.AarnikshaDesignSystem_f93754; const AKH = window.AKStore.h; const AppCtx = React.createContext(null); const useApp = () => React.useContext(AppCtx); function useStore() { const [, force] = React.useReducer((x) => x + 1, 0); React.useEffect(() => window.AKStore.subscribe(force), []); return window.AKStore.get(); } /* Lucide outline icons (CDN) drawn at the brand's 1.6 stroke — see HANDOFF.md, "Icon substitution". */ function PIcon({ name, size = 18, stroke = 1.6, color, style }) { const ref = React.useRef(null); React.useEffect(() => { const L = window.lucide; const el = ref.current; if (!L || !el || !L.icons || !L.icons[name]) return; const NS = 'http://www.w3.org/2000/svg'; const node = L.icons[name]; const svg = document.createElementNS(NS, 'svg'); const a = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': stroke, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }; Object.keys(a).forEach((k) => svg.setAttribute(k, a[k])); (Array.isArray(node[0]) ? node : node[2] || []).forEach(([tag, at]) => { const c = document.createElementNS(NS, tag); Object.keys(at).forEach((k) => c.setAttribute(k, at[k])); svg.appendChild(c); }); el.replaceChildren(svg); }, [name, size, stroke]); return ; } const TONES = { blue: ['#E7F1FD', '#1D6AE3'], green: ['#E3F5EC', '#0F7A55'], amber: ['#FDF1DC', '#8A5A00'], red: ['#FCEAE8', '#B9382F'], grey: ['#EDF1F8', '#4A5670'], navy: ['#06367E', '#FFFFFF'] }; const STATUS = { pending: ['amber', 'Pending'], approved: ['green', 'Approved'], rejected: ['red', 'Declined'], cancelled: ['grey', 'Cancelled'], active: ['green', 'Active'], suspended: ['red', 'Suspended'], todo: ['grey', 'To do'], in_progress: ['blue', 'In progress'], done: ['green', 'Done'] }; function Badge({ tone = 'grey', children, style }) { const [bg, fg] = TONES[tone]; return {children}; } const StatusBadge = ({ status }) => {(STATUS[status] || [0, status])[1]}; function Btn({ variant = 'primary', size = 'md', icon, children, full, style, disabled, ...rest }) { const [h, setH] = React.useState(false); const on = h && !disabled; const skins = { primary: { background: on ? '#06367E' : '#2F80EC', color: '#fff', border: '1px solid transparent', boxShadow: on ? '0 10px 22px rgba(47,128,236,.28)' : 'none' }, outline: { background: '#fff', color: on ? '#06367E' : '#101B33', border: '1px solid ' + (on ? '#06367E' : '#DCE3EE') }, ghost: { background: on ? '#EDF1F8' : 'transparent', color: '#43506A', border: '1px solid transparent' }, danger: { background: on ? '#FCEAE8' : '#fff', color: '#B9382F', border: '1px solid #F2C9C5' }, white: { background: '#fff', color: '#06367E', border: '1px solid transparent', boxShadow: on ? '0 12px 26px rgba(2,22,56,.26)' : '0 8px 20px rgba(2,22,56,.16)' }, glass: { background: on ? 'rgba(255,255,255,.2)' : 'rgba(255,255,255,.1)', color: '#fff', border: '1px solid rgba(255,255,255,.24)' }, }; return ( ); } function Card({ children, pad = '24px', style, tint }) { return
{children}
; } function CardHead({ title, sub, action, style }) { return (

{title}

{sub ?

{sub}

: null}
{action || null}
); } function PageHeader({ eyebrow, title, sub, actions }) { const { m } = useApp(); return (
{eyebrow ?

{eyebrow}

: null}

{title}

{sub ?

{sub}

: null}
{actions ?
{actions}
: null}
); } function Stat({ label, value, sub, tone }) { return (

{label}

{value}

{sub ?

{sub}

: null}
); } const AV_COLORS = ['#06367E', '#2F80EC', '#0A4497', '#1D6AE3', '#0B4A78', '#123A86']; function Avatar({ name = '?', size = 36 }) { const ini = name.split(' ').map((p) => p[0]).slice(0, 2).join('').toUpperCase(); const c = AV_COLORS[[...name].reduce((a, ch) => a + ch.charCodeAt(0), 0) % AV_COLORS.length]; return ; } function Person({ u, sub, size = 36 }) { if (!u) return —; return (

{u.name}

{sub != null ? sub : u.designation}

); } function Progress({ value, h = 8, color = '#2F80EC' }) { return
; } function Segmented({ options, value, onChange, dark, full }) { return (
{options.map(([k, label, count]) => { const on = value === k; return ( ); })}
); } function Empty({ icon = 'Inbox', title, body }) { return (

{title}

{body ?

{body}

: null}
); } function Modal({ open, onClose, eyebrow, title, children, width = 520 }) { if (!open) return null; return
{children}
; } const inputStyle = { width: '100%', fontSize: '15px', color: '#101B33', background: '#F8FAFE', border: '1px solid #E1E8F4', borderRadius: '12px', padding: '13px 14px', outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box' }; function Label({ children, hint }) { return {children}{hint ? {hint} : null}; } function Input({ label, hint, prefix, style, ...rest }) { const [f, setF] = React.useState(false); return ( ); } function Select({ label, options, style, ...rest }) { return ( ); } function TextArea({ label, hint, rows = 3, style, ...rest }) { return ( ); } const ErrorLine = ({ children }) => children ?

{children}

: null; const TH = { textAlign: 'left', padding: '12px 16px', fontSize: '11px', fontWeight: 800, letterSpacing: '.1em', textTransform: 'uppercase', color: '#8A94A6', borderBottom: '1px solid #E9EDF5', whiteSpace: 'nowrap', background: '#F8FAFE' }; const TD = { padding: '14px 16px', fontSize: '14px', color: '#43506A', borderBottom: '1px solid #EDF1F8', verticalAlign: 'middle' }; function Table({ head, children, minWidth = 640 }) { return (
{head.map((h, i) => )}{children}
') ? 'right' : 'left' }}>{h && h.replace ? h.replace(/^>/, '') : h}
); } const fmt = { d: (s) => AKH.parse(s).toLocaleDateString('en-IN', { day: 'numeric', month: 'short' }), dw: (s) => AKH.parse(s).toLocaleDateString('en-IN', { weekday: 'short', day: 'numeric', month: 'short' }), long: (s) => AKH.parse(s).toLocaleDateString('en-IN', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }), range: (a, b) => a === b ? fmt.dw(a) : fmt.d(a) + ' – ' + fmt.d(b), t: (hm) => { if (!hm) return '—'; const [h, mm] = hm.split(':').map(Number); return ((h + 11) % 12 + 1) + ':' + String(mm).padStart(2, '0') + (h < 12 ? ' am' : ' pm'); }, ago: (isoTs) => { const s = (Date.now() - new Date(isoTs).getTime()) / 1000; if (s < 60) return 'Just now'; if (s < 3600) return Math.floor(s / 60) + 'm ago'; if (s < 86400) return Math.floor(s / 3600) + 'h ago'; const d = Math.floor(s / 86400); return d === 1 ? 'Yesterday' : d + 'd ago'; }, dur: (a, b) => { const m = AKH.mins(b) - AKH.mins(a); return Math.floor(m / 60) + 'h ' + String(m % 60).padStart(2, '0') + 'm'; }, }; const greet = () => { const h = new Date().getHours(); return h < 12 ? 'Good morning' : h < 17 ? 'Good afternoon' : 'Good evening'; }; const firstName = (u) => u.name.split(' ')[0]; function dayInfo(S, userId, k) { const d = AKH.parse(k); const t = AKH.todayIso(); const u = AKH.user(userId); const rec = (S.attendance[userId] || {})[k]; const hol = AKH.holidayOn(k); if (rec && rec.status === 'leave') return { kind: 'leave', label: 'Leave', tone: 'amber', rec }; if (AKH.isWeekend(d)) return { kind: 'weekend', label: 'Weekend', tone: null }; if (hol) return { kind: 'holiday', label: hol.name, tone: 'navy', hol }; if (rec && rec.in) { if (!rec.out && k < t) return { kind: 'missed', label: 'Missed punch', tone: 'red', rec }; return { kind: rec.status, label: rec.status === 'wfh' ? 'WFH' : 'Office', tone: rec.status === 'wfh' ? 'grey' : 'blue', rec, late: AKH.mins(rec.in) > AKH.mins(window.AKStore.LATE_AFTER) }; } if (k === t) return { kind: 'today', label: 'Not checked in', tone: null }; if (k > t || (u && u.joined && k < u.joined)) return { kind: 'future', label: '', tone: null }; return { kind: 'absent', label: 'Absent', tone: 'red' }; } Object.assign(window, { DS, AKH, AppCtx, useApp, useStore, PIcon, Badge, StatusBadge, STATUS, Btn, Card, CardHead, PageHeader, Stat, Avatar, Person, Progress, Segmented, Empty, Modal, Input, Select, TextArea, Label, ErrorLine, Table, TH, TD, fmt, greet, firstName, dayInfo, inputStyle });