const DEMO = [['u5', 'Employee'], ['u4', 'Manager'], ['u3', 'HR admin'], ['u1', 'Super admin']]; const DEMO_OTP = '1234'; const OTP_LEN = 4; function OtpBoxes({ value, onChange }) { const refs = React.useRef([]); const set = (i, ch) => { const digits = value.split(''); digits[i] = ch; const next = digits.join('').slice(0, OTP_LEN); onChange(next); if (ch && i < OTP_LEN - 1) refs.current[i + 1].focus(); }; return (
{Array.from({ length: OTP_LEN }, (_, i) => ( (refs.current[i] = el)} inputMode="numeric" maxLength={1} aria-label={'Digit ' + (i + 1)} value={value[i] || ''} onChange={(e) => set(i, e.target.value.replace(/\D/g, '').slice(-1))} onKeyDown={(e) => { if (e.key === 'Backspace' && !value[i] && i > 0) refs.current[i - 1].focus(); }} onPaste={(e) => { const p = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, OTP_LEN); if (p) { e.preventDefault(); onChange(p); refs.current[Math.min(p.length, OTP_LEN - 1)].focus(); } }} style={{ width: '100%', minWidth: 0, height: '56px', textAlign: 'center', fontSize: '22px', fontWeight: 800, color: '#06367E', background: value[i] ? '#fff' : '#F8FAFE', border: '1px solid ' + (value[i] ? '#2F80EC' : '#E1E8F4'), borderRadius: '12px', outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box' }} /> ))}
); } function AuthNote({ icon, tone = 'blue', title, children }) { const c = { blue: ['#E7F1FD', '#1D6AE3'], amber: ['#FDF1DC', '#8A5A00'], red: ['#FCEAE8', '#B9382F'], green: ['#E3F5EC', '#0F7A55'] }[tone]; return (

{title}

{children}
); } function AuthScreen() { const { m } = useApp(); const [step, setStep] = React.useState('login'); const [mode, setMode] = React.useState('mobile'); const [id, setId] = React.useState(''); const [acct, setAcct] = React.useState(null); const [otp, setOtp] = React.useState(''); const [err, setErr] = React.useState(''); const [timer, setTimer] = React.useState(0); const [reg, setReg] = React.useState({ name: '', email: '', phone: '', dept: 'Recruitment', designation: '' }); React.useEffect(() => { if (!timer) return; const t = setTimeout(() => setTimer(timer - 1), 1000); return () => clearTimeout(t); }, [timer]); const sendOtp = () => { setErr(''); if (mode === 'mobile' && id.replace(/\D/g, '').length !== 10) return setErr('Enter your 10-digit mobile number.'); if (mode === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(id.trim())) return setErr('Enter a valid email address.'); const u = AKStore.act.findAccount(id); if (!u || u.status === 'rejected') return setErr("We couldn't find an account with that " + (mode === 'mobile' ? 'number' : 'email') + '. New here? Request access below.'); setAcct(u); if (u.status === 'pending') return setStep('pending'); if (u.status === 'suspended') return setStep('suspended'); setOtp(''); setTimer(30); setStep('otp'); }; const verify = () => { if (otp.length < OTP_LEN) return setErr('Enter all ' + OTP_LEN + ' digits.'); if (otp !== DEMO_OTP) return setErr('That code is incorrect. Check the message and try again.'); AKStore.act.signIn(acct.id); }; const register = () => { setErr(''); if (!reg.name.trim() || !reg.designation.trim()) return setErr('Fill in your name and designation.'); if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(reg.email.trim())) return setErr('Enter a valid email address.'); if (reg.phone.replace(/\D/g, '').length !== 10) return setErr('Enter your 10-digit mobile number.'); if (AKStore.act.findAccount(reg.email) || AKStore.act.findAccount(reg.phone)) return setErr('An account already exists with that email or mobile number.'); setAcct(AKStore.act.register(reg)); setStep('registered'); }; const masked = acct ? (mode === 'mobile' ? '+91 ••••• ' + acct.phone.slice(-5) : acct.email.replace(/^(.{2}).*(@.*)$/, '$1•••$2')) : ''; const back = (s) => () => { setErr(''); setStep(s); }; let body; if (step === 'login') body = ( <>

Sign in

Use the mobile number or email you registered with. We'll send you a one-time code.

{ setMode(v); setId(''); setErr(''); }} />
{ e.preventDefault(); sendOtp(); }} style={{ display: 'grid', gap: '16px', marginTop: '20px' }}> {mode === 'mobile' ? setId(e.target.value.replace(/[^\d ]/g, '').slice(0, 11))} /> : setId(e.target.value)} />} {err} Send code

New to Aarniksha? { e.preventDefault(); setErr(''); setStep('register'); }} style={{ fontWeight: 700 }}>Request access

Demo accounts

{DEMO.map(([uid, role]) => { const u = AKH.user(uid); return ( ); })}
); if (step === 'otp') body = ( <>

Enter the code

We sent a 4-digit code to {masked}. It expires in 10 minutes.

{ e.preventDefault(); verify(); }} style={{ display: 'grid', gap: '16px' }}> { setOtp(v); setErr(''); }} />
Demo: the code is {DEMO_OTP}
{err} Verify and sign in

{timer ? 'Resend code in 0:' + String(timer).padStart(2, '0') : { e.preventDefault(); setTimer(30); }} style={{ fontWeight: 700 }}>Resend code}

); if (step === 'register') body = ( <>

Request access

HR reviews every request. You'll get an email as soon as your account is approved.

{ e.preventDefault(); register(); }} style={{ display: 'grid', gap: '14px' }}> setReg({ ...reg, name: e.target.value })} placeholder="As on your ID" /> setReg({ ...reg, email: e.target.value })} placeholder="you@example.com" /> setReg({ ...reg, phone: e.target.value.replace(/[^\d ]/g, '').slice(0, 11) })} placeholder="10-digit number" />
setReg({ ...reg, designation: e.target.value })} placeholder="e.g. Recruiter" />
{err} Submit request
); if (step === 'registered') body = ( <>

Request sent

Your request is with HR. We'll email {acct.email} once it's approved — usually within one working day.
Back to sign in
); if (step === 'pending') body = ( <>

Almost there

HR hasn't approved {acct.name.split(' ')[0]}'s access yet. You'll get an email at {acct.email} as soon as it's done. ); if (step === 'suspended') body = ( <>

Access suspended

Your portal access has been suspended{acct.suspendedReason ? ' (' + acct.suspendedReason.toLowerCase() + ')' : ''}. Please contact hr@aarnikshasolutions.com. ); const brand = (
Aarniksha Solutions

Aarniksha Solutions

Employee portal

Your workday, in one place.

{!m ?
{[['Clock', 'Check in from the office or from home'], ['CalendarDays', 'Apply for leave and follow every approval'], ['ListChecks', 'Tasks, goals and the holiday calendar together']].map(([ic, t]) => (
{t}
))}
: null}
{!m ? ← Back to aarnikshasolutions.com : null}
); return (
{brand}
{body}
); } const hS = { margin: '0 0 8px', fontSize: '30px', lineHeight: 1.08, letterSpacing: '-.03em', fontWeight: 800, color: '#101B33' }; const pS = { margin: '0 0 22px', fontSize: '15px', lineHeight: 1.6, color: '#5B6577' }; function BackLink({ onClick }) { return ; } Object.assign(window, { AuthScreen });