const ROLES_G = [ ['hard-hat', 'Labour Contractors', 'You supply workforce to construction sites.', 'Select'], ['building-2', 'EPC / general contractor', 'You execute packages and hire workforce for them.', 'Select'], ['landmark', 'Builder / developer', 'You run projects and procure workforce across them.', 'Select'], ]; const TRADES = ['Masonry', 'Helpers', 'Carpentry', 'Bar bending', 'Electrical', 'Plumbing', 'Painting', 'Shuttering', 'Welding', 'Tiling', 'Scaffolding', 'Plastering']; function Field({ label, req, children, ph, type = 'text', half, value, onChange }) { return (
{children || }
); } function GetStartedPage() { const [step, setStep] = useState(0); const [role, setRole] = useState(1); const [trades, setTrades] = useState(['Masonry', 'Helpers']); const [pw, setPw] = useState(''); const [pw2, setPw2] = useState(''); const [showPw, setShowPw] = useState(false); const [gErr, setGErr] = useState(''); const [busy, setBusy] = useState(false); const [noGst, setNoGst] = useState(false); const [f, setF] = useState({ business_name: '', contact: '', designation: '', mobile: '', email: '', location: 'Pune city', state: 'Maharashtra', address: '', gstin: '', pan: '', years: 'Under 2 years', capacity: '1 project', kyc_gstin: '', kyc_pan: '' }); const set = k => e => setF(p => ({ ...p, [k]: e.target.value })); const saveRegistration = async () => { try { await LTData.submit('registrations', { role_type: ['contractor', 'epc', 'builder'][role], business_name: f.business_name, contact: f.contact, designation: f.designation, mobile: f.mobile, email: f.email, location: f.location, state: f.state, address: f.address, gstin: noGst ? '' : (f.kyc_gstin || f.gstin), pan: f.kyc_pan || f.pan, no_gst: noGst, years: f.years, capacity: f.capacity, trades: trades.join(', '), mobile_verified: false, status: 'Submitted', }); } catch (e) { console.warn(e); } }; const [pending, setPending] = useState(false); const createAccount = async () => { const v = (f.email || '').trim(); if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v)) { setGErr('Enter a valid email address.'); return false; } if (pw.length < 8) { setGErr('Use a password of at least eight characters.'); return false; } if (pw !== pw2) { setGErr('The two passwords do not match.'); return false; } setGErr(''); setBusy(true); try { const r = await LTAuth.signUp(v, pw, { business_name: f.business_name, contact: f.contact, role_type: ['contractor', 'epc', 'builder'][role] }); const hasSession = !!(r && r.session); setPending(!hasSession); try { localStorage.setItem('lt_role', ['contractor', 'epc', 'builder'][role]); if (hasSession) { localStorage.setItem('lt_signed_in', '1'); localStorage.setItem('lt_verified', '0'); } else localStorage.removeItem('lt_signed_in'); } catch (e) {} if (hasSession) { try { await LTAuth.sendVerification(v); } catch (e) {} } setBusy(false); return true; } catch (e) { const m = e.message || ''; setGErr(/registered|exists/i.test(m) ? 'An account already exists for this address. Sign in instead.' : (m || 'Could not create the account.')); setBusy(false); return false; } }; const next = async () => { if (step === 2 && !(await createAccount())) return; if (step === 3) saveRegistration(); setStep(step + 1); window.scrollTo(0, 0); }; const back = () => { setStep(Math.max(0, step - 1)); window.scrollTo(0, 0); }; const isContractor = role === 0; const heads = [ ['Choose your business type', 'Your role decides what you can do on the platform and which plan applies.'], ['Business details', 'Registered details as they appear on your GST certificate.'], ['Create your log-in', 'You will sign in with this email address and password. No code to wait for.'], ['GST & KYC verification', 'Bidding and posting open once verification clears. Documents are stored privately.'], ['Verification submitted', 'You can explore the dashboard while our team reviews your documents.'], ]; return (
{[0, 1, 2, 3, 4].map(i => )}
Step {step + 1} of 5

{heads[step][0]}

{heads[step][1]}

{step === 0 && (
{ROLES_G.map(([ic, t, d, p], i) => ( ))}
)} {step === 1 && (
{isContractor && } {!isContractor && }
{TRADES.map(t => ( ))}
)} {step === 2 && (
{ set('email')(e); setGErr(''); }} placeholder="you@company.com" />
{f.email && LTAuth.isFreemail(f.email) &&
That looks like a personal address. A company address is better — quotes, GST invoices and the monthly audit pack are all sent here.
} {[['Password', pw, setPw, 'At least 8 characters'], ['Confirm password', pw2, setPw2, 'Type it again']].map(([l, val, setVal, ph]) => (
{ setVal(e.target.value); setGErr(''); }} style={{ paddingRight: 62 }} />
))} {gErr &&
{gErr}
}
Your account opens straight away. We also email a verification link — confirm it to unlock contact reveals and quote requests.
)} {step === 3 && (
{!noGst &&
}
{noGst &&
You have told us you are not GST registered. We verify you on PAN and your registration or Udyam certificate instead. You can add a GSTIN later from your dashboard, and invoices we raise to you will not carry input credit until you do.
} {[['Certificate of registration or Udyam certificate', 'PDF or JPG, up to 10 MB'], noGst ? ['Shop Act / trade licence', 'PDF or JPG, up to 10 MB'] : ['GST certificate', 'PDF or JPG, up to 10 MB'], ['Identity document of authorised signatory', 'Aadhaar, passport or driving licence']].map(([t, h]) => (
Drag a file here or browse
{h}
))}
Documents are held in restricted storage. Public profiles show verification status only — never the file itself.
)} {step === 4 && (
{[['Log-in created', 'Done', 'ok'], ['Email address', pending ? 'Confirm the emailed link to sign in' : 'Verify to unlock reveals', 'wait'], ['Business details', 'Submitted', 'info'], [noGst ? 'PAN verification' : 'GST verification', 'Under review', 'wait'], ['KYC verification', 'Under review', 'wait'], ['Bidding access', 'Opens on approval', 'off']].map(([t, s, c]) => (
{t} {s}
))}

{pending ? 'Open the confirmation link we emailed to ' + f.email + ', then sign in with your password. Reviews of your documents usually complete within a few working days.' : 'Reviews usually complete within a few working days. You will be notified in-app and by email, and your subscription is not charged until verification clears.'}

{pending ? 'Go to log in' : 'Go to my dashboard'}
)}
{step > 0 && step < 4 && } {step < 4 && }
{step === 0 &&

Wrong place? Back to the website

}
); } LTMount('getstarted', );