feat: implement responsive auth card layout, password reset page, and update navigation and footer styles
All checks were successful
Beta CI/CD Pipeline / build-and-test (push) Successful in 1m21s
Beta CI/CD Pipeline / deploy-beta (push) Successful in 41s

This commit is contained in:
vickytechkey 2026-09-17 19:20:33 +05:30
parent d23ae61c57
commit 208eede1aa
11 changed files with 1039 additions and 157 deletions

BIN
card_inputs_enhanced.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
card_middle_debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
card_step1_debug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -12,6 +12,7 @@ import { HowItWorksPage } from './pages/HowItWorksPage';
import { PricingPage } from './pages/PricingPage'; import { PricingPage } from './pages/PricingPage';
import { GrowBusinessPage } from './pages/GrowBusinessPage'; import { GrowBusinessPage } from './pages/GrowBusinessPage';
import { LoginPage } from './pages/LoginPage'; import { LoginPage } from './pages/LoginPage';
import { ResetPasswordPage } from './pages/ResetPasswordPage';
import { OnboardingPage } from './pages/OnboardingPage'; import { OnboardingPage } from './pages/OnboardingPage';
// Authenticated Seller Central Pages // Authenticated Seller Central Pages
@ -36,7 +37,7 @@ export const App: React.FC = () => {
<Route path="/pricing" element={<PricingPage />} /> <Route path="/pricing" element={<PricingPage />} />
<Route path="/why-sell" element={<GrowBusinessPage />} /> <Route path="/why-sell" element={<GrowBusinessPage />} />
<Route path="/login" element={<LoginPage />} /> <Route path="/login" element={<LoginPage />} />
<Route path="/reset-password" element={<LoginPage initialMode="reset-password" />} /> <Route path="/reset-password" element={<ResetPasswordPage />} />
<Route path="/onboarding" element={<OnboardingPage />} /> <Route path="/onboarding" element={<OnboardingPage />} />
</Route> </Route>

View file

@ -3,79 +3,79 @@ import { Link } from 'react-router-dom';
export const Footer: React.FC = () => { export const Footer: React.FC = () => {
return ( return (
<footer className="footer pt-6 pb-6" style={{ backgroundColor: '#791B2C', color: '#ffffff' }}> <footer className="footer pt-6 pb-6" style={{ backgroundColor: '#671B26', color: '#ffffff' }}>
<div className="container is-widescreen px-4"> <div className="container is-widescreen px-4">
<div className="columns is-multiline pb-6" style={{ borderBottom: '1px solid rgba(255, 255, 255, 0.2)' }}> <div className="columns is-multiline pb-5">
{/* Brand Info */} {/* Brand Info */}
<div className="column is-6-desktop is-12-tablet mb-4"> <div className="column is-6-desktop is-12-tablet mb-4">
<div className="is-flex is-align-items-center mb-3"> <div className="is-flex is-align-items-center mb-3">
<span className="has-text-weight-black is-size-4 has-text-white" style={{ letterSpacing: '0.05em' }}> <span className="has-text-weight-black is-size-4 has-text-white" style={{ letterSpacing: '0.02em' }}>
TRADHOX TRADHOX
</span> </span>
</div> </div>
<p className="is-size-7 font-weight-bold has-text-weight-bold has-text-white-ter mb-2" style={{ letterSpacing: '0.12em', textTransform: 'uppercase' }}> <p className="is-size-7 font-weight-bold has-text-weight-bold mb-2" style={{ letterSpacing: '0.12em', textTransform: 'uppercase', color: '#E2BDC4' }}>
FROM MAKERS TO THE WORLD. FROM MAKERS TO THE WORLD
</p> </p>
<p className="is-size-6" style={{ color: '#EED5D9', maxWidth: '380px', lineHeight: 1.6 }}> <p className="is-size-7" style={{ color: '#E5C3C8', maxWidth: '380px', lineHeight: 1.6 }}>
Empowering verified Indian craftsmanship and creative makers with seamless nationwide commerce, transparent payouts, and cultural storytelling. The sovereign digital trade bridge linking India's verified hereditary master artisans directly to ethical world markets.
</p> </p>
</div> </div>
{/* Company Links */} {/* Company Links */}
<div className="column is-2-desktop is-4-tablet is-6-mobile"> <div className="column is-2-desktop is-4-tablet is-4-mobile">
<h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}> <h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}>
COMPANY COMPANY
</h4> </h4>
<ul className="is-size-6" style={{ lineHeight: 2.2 }}> <ul className="is-size-7" style={{ lineHeight: 2.2 }}>
<li> <li>
<Link to="/how-it-works" style={{ color: '#E5C3C8' }}>About</Link> <Link to="/how-it-works" style={{ color: '#E5C3C8', textDecoration: 'none' }}>About</Link>
</li> </li>
<li> <li>
<Link to="/pricing" style={{ color: '#E5C3C8' }}>Contact</Link> <Link to="/pricing" style={{ color: '#E5C3C8', textDecoration: 'none' }}>Contact</Link>
</li> </li>
<li> <li>
<Link to="/why-sell" style={{ color: '#E5C3C8' }}>Grow your business</Link> <Link to="/why-sell" style={{ color: '#E5C3C8', textDecoration: 'none' }}>Grow your business</Link>
</li> </li>
</ul> </ul>
</div> </div>
{/* Policies Links */} {/* Policies Links */}
<div className="column is-2-desktop is-4-tablet is-6-mobile"> <div className="column is-2-desktop is-4-tablet is-4-mobile">
<h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}> <h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}>
POLICIES POLICIES
</h4> </h4>
<ul className="is-size-6" style={{ lineHeight: 2.2 }}> <ul className="is-size-7" style={{ lineHeight: 2.2 }}>
<li> <li>
<a href="#privacy" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8' }}>Privacy policy</a> <a href="#privacy" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8', textDecoration: 'none' }}>Privacy policy</a>
</li> </li>
<li> <li>
<a href="#terms" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8' }}>Terms of service</a> <a href="#terms" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8', textDecoration: 'none' }}>Terms of service</a>
</li> </li>
<li> <li>
<a href="#seller-agreement" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8' }}>Seller agreement</a> <a href="#seller-agreement" onClick={(e) => e.preventDefault()} style={{ color: '#E5C3C8', textDecoration: 'none' }}>Seller agreement</a>
</li> </li>
</ul> </ul>
</div> </div>
{/* Social Handlers */} {/* Social Handlers / Connect */}
<div className="column is-2-desktop is-4-tablet is-12-mobile"> <div className="column is-2-desktop is-4-tablet is-4-mobile">
<h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}> <h4 className="is-size-7 has-text-weight-bold has-text-white mb-3" style={{ letterSpacing: '0.1em', textTransform: 'uppercase' }}>
SOCIAL HANDLERS CONNECT
</h4> </h4>
<ul className="is-size-6" style={{ lineHeight: 2.2 }}> <ul className="is-size-7" style={{ lineHeight: 2.2 }}>
<li> <li>
<a href="https://instagram.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8' }}> <a href="https://instagram.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8', textDecoration: 'none' }}>
<i className="fa-brands fa-instagram mr-2"></i> Instagram Instagram
</a> </a>
</li> </li>
<li> <li>
<a href="https://facebook.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8' }}> <a href="https://facebook.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8', textDecoration: 'none' }}>
<i className="fa-brands fa-facebook mr-2"></i> Facebook Facebook
</a> </a>
</li> </li>
<li> <li>
<a href="https://youtube.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8' }}> <a href="https://youtube.com" target="_blank" rel="noreferrer" style={{ color: '#E5C3C8', textDecoration: 'none' }}>
<i className="fa-brands fa-youtube mr-2"></i> YouTube YouTube
</a> </a>
</li> </li>
</ul> </ul>

View file

@ -49,11 +49,14 @@ export const Navbar: React.FC = () => {
onClick={closeMenu} onClick={closeMenu}
style={{ textDecoration: 'none' }} style={{ textDecoration: 'none' }}
> >
<span className="has-text-weight-bold is-size-4" style={{ color: 'var(--trad-maroon)', letterSpacing: '-0.03em' }}> <span className="has-text-weight-bold is-size-4" style={{ color: 'var(--trad-maroon)', letterSpacing: '-0.02em', lineHeight: 1 }}>
TRADHOX TRADHOX
</span> </span>
<span className="tag is-trad-wine is-rounded ml-2 is-size-7 is-hidden-touch is-hidden-desktop-only"> <span className="is-hidden-touch is-align-items-center ml-2.5" style={{ display: 'inline-flex', gap: '0.45rem' }}>
SELLER CENTRAL <span style={{ color: 'var(--trad-maroon)', fontSize: '0.9rem', lineHeight: 1 }}>•</span>
<span style={{ color: '#4A5568', fontSize: '0.75rem', fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
SELLER CENTRAL
</span>
</span> </span>
</Link> </Link>
@ -107,9 +110,19 @@ export const Navbar: React.FC = () => {
<Link <Link
to="/onboarding" to="/onboarding"
className="button is-trad-primary px-4" className={`button px-4 ${location.pathname === '/onboarding' ? 'is-outlined' : 'is-trad-primary'}`}
onClick={closeMenu} onClick={closeMenu}
style={{ whiteSpace: 'nowrap', borderRadius: '9999px', fontSize: '0.875rem', fontWeight: 600 }} style={{
whiteSpace: 'nowrap',
borderRadius: '9999px',
fontSize: '0.875rem',
fontWeight: 600,
...(location.pathname === '/onboarding' ? {
backgroundColor: '#FFFFFF',
borderColor: 'var(--trad-maroon)',
color: 'var(--trad-maroon)'
} : {})
}}
> >
<span>Become a seller</span> <span>Become a seller</span>
</Link> </Link>

View file

@ -138,20 +138,12 @@ export const LoginPage: React.FC<LoginPageProps> = ({ initialMode }) => {
overflow: 'hidden' overflow: 'hidden'
}} }}
> >
<div className="is-flex is-flex-direction-column is-flex-direction-row-desktop" style={{ width: '100%' }}> <div className="auth-card-layout">
{/* ------------------------------------------------------------------ */} {/* ------------------------------------------------------------------ */}
{/* LEFT COLUMN: Artisan Story, Image & Guarantee Highlights */} {/* LEFT COLUMN: Artisan Story, Image & Guarantee Highlights */}
{/* ------------------------------------------------------------------ */} {/* ------------------------------------------------------------------ */}
<div <div className="auth-card-left">
className="is-hidden-touch"
style={{
flex: '0 0 42%',
borderRight: '1px solid #EAE5DD',
backgroundColor: '#FAF9F6',
padding: '2.5rem'
}}
>
{mode === 'login' ? ( {mode === 'login' ? (
<div> <div>
{/* Badge */} {/* Badge */}
@ -356,14 +348,7 @@ export const LoginPage: React.FC<LoginPageProps> = ({ initialMode }) => {
</div> </div>
{/* ------------------------------------------------------------------ */} {/* ------------------------------------------------------------------ */}
<div <div className="auth-card-right">
style={{
flex: '1 1 auto',
padding: 'clamp(1.25rem, 4vw, 3rem)',
minWidth: 0,
width: '100%'
}}
>
{/* ================================================================ */} {/* ================================================================ */}
{/* VIEW A: LOGIN FORM */} {/* VIEW A: LOGIN FORM */}

View file

@ -1,5 +1,5 @@
import React from 'react'; import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate, Link } from 'react-router-dom';
import { useSeller } from '../context/SellerContext'; import { useSeller } from '../context/SellerContext';
import { import {
Check, Check,
@ -31,15 +31,37 @@ export const OnboardingPage: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const stepLabels = [ const stepLabels = [
'Account', 'Mobile',
'GST & Tax', 'Business & GST',
'Pickup Address', 'Pickup address',
'Bank Account', 'Bank details',
'Categories', 'Categories',
'Sample Craft', 'Products',
'Store Profile' 'Store profile'
]; ];
// Step 1 Specific State matching stitch wireframe
const [step1Phone, setStep1Phone] = useState(onboarding.phone || '9845012345');
const [step1Otp, setStep1Otp] = useState<string[]>(['4', '8', '2', '9', '', '']);
const [termsAgreed, setTermsAgreed] = useState(true);
const [isPhoneFocused, setIsPhoneFocused] = useState(false);
const handleStep1OtpChange = (index: number, val: string) => {
const clean = val.replace(/[^0-9]/g, '').slice(-1);
const newOtp = [...step1Otp];
newOtp[index] = clean;
setStep1Otp(newOtp);
if (clean && index < 5) {
document.getElementById(`step1-otp-${index + 1}`)?.focus();
}
};
const handleStep1OtpKeyDown = (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Backspace' && !step1Otp[index] && index > 0) {
document.getElementById(`step1-otp-${index - 1}`)?.focus();
}
};
const craftCategoryOptions = [ const craftCategoryOptions = [
'Handloom & Textiles', 'Handloom & Textiles',
'Handmade Pottery & Ceramics', 'Handmade Pottery & Ceramics',
@ -340,22 +362,63 @@ export const OnboardingPage: React.FC = () => {
); );
} }
/* ----------------------------------------------------
Render Onboarding Wizard (Steps 1 to 7)
---------------------------------------------------- */
/* ---------------------------------------------------- /* ----------------------------------------------------
Render Onboarding Wizard (Steps 1 to 7) Render Onboarding Wizard (Steps 1 to 7)
---------------------------------------------------- */ ---------------------------------------------------- */
return ( return (
<div className="section py-4 py-6-tablet"> <div className="section py-5 py-6-tablet" style={{ backgroundColor: '#FCF9F8', minHeight: 'calc(100vh - 80px)' }}>
<div className="container is-widescreen px-3 px-4-tablet"> <div className="container is-widescreen px-3 px-4-tablet">
{/* Wizard Header */}
<div className="has-text-centered mb-4 mb-5-tablet"> {/* Page Hero Header matching stitch screen */}
<span className="tag is-trad-wine is-rounded mb-2">Seller Registration Wizard</span> <div className="mb-5 mb-6-tablet" style={{ maxWidth: '820px', margin: '0 auto 2.25rem auto' }}>
<h1 className="title is-size-4-mobile is-size-3-tablet is-size-2-desktop mb-2">Setup Your Artisan Workshop</h1> <h1
<p className="subtitle is-size-7-mobile is-size-6-tablet has-text-grey">Step {onboardingStep} of 7: {stepLabels[onboardingStep - 1]}</p> className="title mb-2"
style={{
fontSize: 'clamp(1.75rem, 3.5vw, 2.35rem)',
fontWeight: 800,
color: '#111827',
letterSpacing: '-0.025em',
lineHeight: 1.2
}}
>
Join India’s Dedicated Artisan Marketplace
</h1>
<p
className="subtitle mb-3"
style={{
color: '#4B5563',
fontSize: '0.92rem',
lineHeight: 1.55,
maxWidth: '650px'
}}
>
Connect your generational craft with conscious patrons across 15,000+ pin codes. Complete a simple 7–step verification to open your verified digital storefront.
</p>
<div
className="is-flex is-align-items-center is-flex-wrap-wrap"
style={{ gap: '0.45rem', color: '#9C381E', fontSize: '0.85rem', fontWeight: 600 }}
>
<span>no listing fee</span>
<span style={{ color: '#D1D5DB' }}>•</span>
<span>no registration fee</span>
<span style={{ color: '#D1D5DB' }}>•</span>
<span>get live in minutes</span>
</div>
</div> </div>
{/* Responsive Step Progress Bar */} {/* Responsive 7-Step Stepper matching stitch screen */}
<div className="card p-3 p-4-desktop mb-5" style={{ borderRadius: '16px', border: '1px solid var(--trad-border)' }}> <div className="mb-5 mb-6-tablet" style={{ maxWidth: '820px', margin: '0 auto 2.75rem auto', width: '100%' }}>
<div className="is-flex is-align-items-center is-justify-content-space-between px-1 px-3-desktop"> <div
className="is-flex is-align-items-flex-start is-justify-content-space-between"
style={{
width: '100%',
overflowX: 'auto',
paddingBottom: '0.5rem'
}}
>
{stepLabels.map((lbl, idx) => { {stepLabels.map((lbl, idx) => {
const stepNum = idx + 1; const stepNum = idx + 1;
const isDone = stepNum < onboardingStep; const isDone = stepNum < onboardingStep;
@ -363,47 +426,56 @@ export const OnboardingPage: React.FC = () => {
return ( return (
<React.Fragment key={idx}> <React.Fragment key={idx}>
{/* Step Node */}
<div <div
onClick={() => stepNum <= onboardingStep && setOnboardingStep(stepNum)} onClick={() => stepNum <= onboardingStep && setOnboardingStep(stepNum)}
className="is-flex is-align-items-center" className="is-flex is-flex-direction-column is-align-items-center"
style={{ cursor: stepNum <= onboardingStep ? 'pointer' : 'default', flexShrink: 0 }} style={{
title={`Step ${stepNum}: ${lbl}`} cursor: stepNum <= onboardingStep ? 'pointer' : 'default',
flex: '0 0 auto',
width: '84px',
textAlign: 'center'
}}
> >
<div <div
className="is-flex is-align-items-center is-justify-content-center" className="is-flex is-align-items-center is-justify-content-center"
style={{ style={{
width: '32px', width: '34px',
height: '32px', height: '34px',
borderRadius: '50%', borderRadius: '50%',
fontSize: '0.8rem', fontSize: '0.88rem',
fontWeight: 'bold', fontWeight: 700,
backgroundColor: isActive ? 'var(--trad-maroon)' : isDone ? 'var(--trad-forest)' : '#ffffff', backgroundColor: (isActive || isDone) ? '#1B2A4A' : '#FFFFFF',
color: isActive || isDone ? '#ffffff' : 'var(--trad-text-secondary)', color: (isActive || isDone) ? '#FFFFFF' : '#6B7280',
border: isActive ? '2px solid var(--trad-maroon)' : isDone ? '2px solid var(--trad-forest)' : '2px solid var(--trad-border)', border: (isActive || isDone) ? '2px solid #1B2A4A' : '1.5px solid #D1D5DB',
boxShadow: isActive ? '0 0 0 3px rgba(121, 27, 44, 0.18)' : 'none', boxShadow: isActive ? '0 0 0 3px rgba(27, 42, 74, 0.15)' : 'none',
transition: 'all 0.2s ease' transition: 'all 0.2s ease'
}} }}
> >
{isDone ? <Check size={16} /> : stepNum} {stepNum}
</div> </div>
<span <span
className="is-size-7 is-hidden-touch ml-2" className="mt-1.5"
style={{ style={{
fontWeight: isActive ? 700 : 500, fontWeight: isActive ? 700 : 500,
color: isActive ? 'var(--trad-maroon)' : isDone ? 'var(--trad-text-primary)' : 'var(--trad-text-secondary)', color: isActive ? '#111827' : '#6B7280',
whiteSpace: 'nowrap' lineHeight: 1.25,
fontSize: '0.76rem'
}} }}
> >
{lbl} {lbl}
</span> </span>
</div> </div>
{/* Connecting Line */}
{idx !== stepLabels.length - 1 && ( {idx !== stepLabels.length - 1 && (
<div <div
className="is-flex-grow-1 mx-1 mx-3-desktop" className="is-flex-grow-1"
style={{ style={{
height: '2px', height: '1.5px',
minWidth: '8px', minWidth: '14px',
backgroundColor: isDone ? 'var(--trad-forest)' : 'var(--trad-border)', backgroundColor: isDone ? '#1B2A4A' : '#E5E7EB',
marginTop: '16px',
transition: 'background-color 0.25s ease' transition: 'background-color 0.25s ease'
}} }}
/> />
@ -412,81 +484,193 @@ export const OnboardingPage: React.FC = () => {
); );
})} })}
</div> </div>
{/* Mobile Current Step Banner */}
<div className="is-hidden-desktop has-text-centered mt-2 pt-2" style={{ borderTop: '1px dashed var(--trad-border)' }}>
<span className="is-size-7 has-text-weight-bold" style={{ color: 'var(--trad-maroon)' }}>
Step {onboardingStep} of 7: {stepLabels[onboardingStep - 1]}
</span>
</div>
</div> </div>
{/* Step Content Container */} {/* =================================================================== */}
<div className="columns is-centered"> {/* STEP 1: Create Your Seller Account (Centered 480px Card) */}
<div className="column is-8-desktop is-10-tablet is-12-mobile"> {/* =================================================================== */}
<div className="card p-4 p-5-tablet p-6-desktop" style={{ borderRadius: '20px', border: '1.5px solid var(--trad-border)' }}> {onboardingStep === 1 && (
<div className="mx-auto mb-6" style={{ maxWidth: '480px', width: '100%' }}>
{/* STEP 1: Account Creation */} <div
{onboardingStep === 1 && ( className="card p-5 p-6-tablet"
<div> style={{
<h2 className="title is-size-4 mb-2">Step 1: Create Your Seller Account</h2> borderRadius: '24px',
<p className="subtitle is-size-7 has-text-grey mb-5">Basic contact information for order alerts and dashboard login</p> border: '1px solid #E5E7EB',
backgroundColor: '#FFFFFF',
boxShadow: '0 8px 30px rgba(0, 0, 0, 0.04)'
}}
>
<div className="has-text-centered mb-5">
<h2
className="title mb-1.5"
style={{
fontSize: 'clamp(1.35rem, 3vw, 1.55rem)',
fontWeight: 800,
color: '#111827',
letterSpacing: '-0.02em'
}}
>
Create your seller account
</h2>
<p className="subtitle is-size-7 mb-0" style={{ color: '#6B7280' }}>
step 1 of 7 · takes about 2 minutes
</p>
</div>
<div className="field mb-4"> <form onSubmit={(e) => { e.preventDefault(); handleNext(); }}>
<label className="label is-size-7 has-text-grey">Master Artisan / Contact Person Full Name</label> {/* Phone Input */}
<div className="control"> <div className="field mb-4">
<input <div
className="input" className="is-flex is-align-items-center"
type="text" style={{
placeholder="e.g. Raghavendra Sharma" border: isPhoneFocused ? '1.5px solid #1B2A4A' : '1.5px solid #CBD5E0',
value={onboarding.fullName} borderRadius: '10px',
onChange={(e) => updateOnboarding({ fullName: e.target.value })} backgroundColor: '#FFFFFF',
/> height: '46px',
</div> padding: '0 12px',
</div> boxShadow: isPhoneFocused ? '0 0 0 3px rgba(27, 42, 74, 0.12)' : 'none',
transition: 'all 0.15s ease'
<div className="columns mb-2"> }}
<div className="column is-6"> >
<div className="field"> <span style={{ fontWeight: 700, color: '#111827', fontSize: '0.88rem' }}>IN</span>
<label className="label is-size-7 has-text-grey">Official Email Address</label> <span style={{ color: '#4B5563', fontSize: '0.88rem', marginLeft: '4px' }}>+91</span>
<div className="control"> <div style={{ width: '1px', height: '20px', backgroundColor: '#E2E8F0', margin: '0 10px' }} />
<input <input
className="input" type="tel"
type="email" maxLength={10}
placeholder="artisan@guild.com" value={step1Phone}
value={onboarding.email} onChange={(e) => {
onChange={(e) => updateOnboarding({ email: e.target.value })} setStep1Phone(e.target.value);
/> updateOnboarding({ phone: e.target.value });
</div> }}
</div> onFocus={() => setIsPhoneFocused(true)}
</div> onBlur={() => setIsPhoneFocused(false)}
<div className="column is-6"> placeholder="9845012345"
<div className="field"> style={{
<label className="label is-size-7 has-text-grey">10-Digit Mobile Number</label> border: 'none',
<div className="field has-addons"> outline: 'none',
<p className="control"><span className="button is-static">+91</span></p> backgroundColor: 'transparent',
<div className="control is-expanded"> height: '100%',
<input fontSize: '0.9rem',
className="input" color: '#111827',
type="tel" fontWeight: 600,
maxLength={10} flex: 1,
value={onboarding.phone} minWidth: 0
onChange={(e) => updateOnboarding({ phone: e.target.value })} }}
/> />
</div>
</div>
</div>
</div>
</div>
<div className="notification is-success is-light p-3 is-size-7 mb-4">
<span className="is-flex is-align-items-center font-weight-bold">
<CheckCircle2 size={16} className="mr-2" />
Mobile number pre-verified via simulated OTP (4829)
</span>
</div> </div>
</div> </div>
)}
{/* OTP code prompt and 6 boxes */}
<div className="field mb-4">
<div className="mb-2">
<span style={{ color: '#4B5563', fontSize: '0.85rem' }}>
enter the 6–digit code sent to your phone
</span>
</div>
<div className="is-flex is-align-items-center is-justify-content-space-between mb-2" style={{ gap: '8px' }}>
{step1Otp.map((digit, idx) => (
<input
key={idx}
id={`step1-otp-${idx}`}
type="text"
inputMode="numeric"
maxLength={1}
value={digit}
placeholder="•"
onChange={(e) => handleStep1OtpChange(idx, e.target.value)}
onKeyDown={(e) => handleStep1OtpKeyDown(idx, e)}
className="has-text-centered has-text-weight-bold"
style={{
width: '46px',
height: '46px',
borderRadius: '10px',
border: '1.5px solid #CBD5E0',
fontSize: digit ? '1.15rem' : '1.4rem',
color: '#111827',
outline: 'none',
backgroundColor: '#FFFFFF',
flex: '1 1 0',
minWidth: '36px',
maxWidth: '48px',
padding: 0,
transition: 'border-color 0.15s ease, box-shadow 0.15s ease'
}}
onFocus={(e) => {
e.target.style.borderColor = '#1B2A4A';
e.target.style.boxShadow = '0 0 0 3px rgba(27, 42, 74, 0.12)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#CBD5E0';
e.target.style.boxShadow = 'none';
}}
/>
))}
</div>
</div>
{/* Terms & Policies Checkbox */}
<div className="field mb-5">
<label className="checkbox is-flex is-align-items-center" style={{ fontSize: '0.85rem', color: '#4B5563', cursor: 'pointer' }}>
<input
type="checkbox"
checked={termsAgreed}
onChange={(e) => setTermsAgreed(e.target.checked)}
className="mr-2.5"
style={{ accentColor: '#1B2A4A', width: '16px', height: '16px' }}
/>
<span>I agree to the seller terms &amp; policies</span>
</label>
</div>
{/* Continue Button */}
<button
type="submit"
disabled={!termsAgreed}
className="button is-fullwidth"
style={{
backgroundColor: '#1B2A4A',
color: '#FFFFFF',
borderRadius: '9999px',
height: '48px',
fontSize: '0.95rem',
fontWeight: 700,
border: 'none',
boxShadow: '0 4px 14px rgba(27, 42, 74, 0.25)',
transition: 'all 0.2s ease',
cursor: termsAgreed ? 'pointer' : 'not-allowed',
opacity: termsAgreed ? 1 : 0.6
}}
>
<span>Continue</span>
</button>
{/* Already registered? Log in */}
<div className="has-text-centered mt-4 pt-1">
<span style={{ color: '#4B5563', fontSize: '0.85rem' }}>Already registered? </span>
<Link to="/login" style={{ color: '#791B2C', fontWeight: 700, textDecoration: 'none' }}>Log in</Link>
</div>
</form>
</div>
</div>
)}
{/* =================================================================== */}
{/* STEPS 2 TO 7: Business, Pickup, Bank, Categories, Products, Profile */}
{/* =================================================================== */}
{onboardingStep > 1 && (
<div className="columns is-centered">
<div className="column is-8-desktop is-10-tablet is-12-mobile">
<div
className="card p-4 p-5-tablet p-6-desktop mb-6"
style={{
borderRadius: '24px',
border: '1px solid #E5E7EB',
backgroundColor: '#FFFFFF',
boxShadow: '0 8px 30px rgba(0, 0, 0, 0.04)'
}}
>
{/* STEP 2: Business & GST / Enrolment ID */} {/* STEP 2: Business & GST / Enrolment ID */}
{onboardingStep === 2 && ( {onboardingStep === 2 && (
@ -940,6 +1124,78 @@ export const OnboardingPage: React.FC = () => {
</div> </div>
</div> </div>
</div> </div>
)}
{/* Trust Badges Strip matching stitch screen */}
<div className="mt-6 mb-4">
<div className="container" style={{ maxWidth: '720px' }}>
<div className="columns is-mobile has-text-centered">
<div className="column is-4">
<div className="is-flex is-flex-direction-column is-align-items-center">
<div
className="mb-2 is-flex is-align-items-center is-justify-content-center"
style={{
width: '42px',
height: '42px',
borderRadius: '50%',
backgroundColor: '#FFFFFF',
border: '1px solid #E5E7EB',
boxShadow: '0 2px 6px rgba(0, 0, 0, 0.03)'
}}
>
<Lock size={16} color="#4B5563" />
</div>
<span style={{ color: '#374151', fontSize: '0.82rem', fontWeight: 600 }}>
Secure &amp; encrypted
</span>
</div>
</div>
<div className="column is-4">
<div className="is-flex is-flex-direction-column is-align-items-center">
<div
className="mb-2 is-flex is-align-items-center is-justify-content-center"
style={{
width: '42px',
height: '42px',
borderRadius: '50%',
backgroundColor: '#FFFFFF',
border: '1px solid #E5E7EB',
boxShadow: '0 2px 6px rgba(0, 0, 0, 0.03)'
}}
>
<span style={{ fontSize: '1.1rem', fontWeight: 700, color: '#4B5563', lineHeight: 1 }}>₹</span>
</div>
<span style={{ color: '#374151', fontSize: '0.82rem', fontWeight: 600 }}>
No registration fee
</span>
</div>
</div>
<div className="column is-4">
<div className="is-flex is-flex-direction-column is-align-items-center">
<div
className="mb-2 is-flex is-align-items-center is-justify-content-center"
style={{
width: '42px',
height: '42px',
borderRadius: '50%',
backgroundColor: '#FFFFFF',
border: '1px solid #E5E7EB',
boxShadow: '0 2px 6px rgba(0, 0, 0, 0.03)'
}}
>
<Headphones size={16} color="#4B5563" />
</div>
<span style={{ color: '#374151', fontSize: '0.82rem', fontWeight: 600 }}>
Dedicated onboarding support
</span>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
); );

View file

@ -0,0 +1,589 @@
import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useSeller } from '../context/SellerContext';
import {
Star,
Check,
ArrowRight,
ArrowLeft,
Smartphone,
Mail,
Eye,
EyeOff,
PhoneCall
} from 'lucide-react';
const SolidGreenCheck: React.FC<{ size?: number }> = ({ size = 16 }) => (
<svg width={size} height={size} viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className="is-flex-shrink-0">
<circle cx="8" cy="8" r="8" fill="#1E8E3E" />
<path d="M4.8 8.2L7 10.4L11.4 5.8" stroke="white" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
</svg>
);
export const ResetPasswordPage: React.FC = () => {
const navigate = useNavigate();
const { login } = useSeller();
// Reset tab: 'email' or 'mobile' (matches screenshot: default is 'email')
const [resetTab, setResetTab] = useState<'email' | 'mobile'>('email');
const [resetEmail, setResetEmail] = useState('artisan.weaver@craftguild.in');
const [resetMobile, setResetMobile] = useState('9845012345');
// OTP Digits matching screenshot: 7, 3, 9, 4, and empty for 5 and 6
const [otpDigits, setOtpDigits] = useState<string[]>(['7', '3', '9', '4', '', '']);
const [newPassword, setNewPassword] = useState('craftatelier2026');
const [confirmPassword, setConfirmPassword] = useState('craftatelier2026');
const [showNewPassword, setShowNewPassword] = useState(false);
const [resendTimer, setResendTimer] = useState(28);
const [isEmailFocused, setIsEmailFocused] = useState(false);
const [isNewPassFocused, setIsNewPassFocused] = useState(false);
const [isConfirmPassFocused, setIsConfirmPassFocused] = useState(false);
useEffect(() => {
if (resendTimer > 0) {
const timer = setTimeout(() => setResendTimer(resendTimer - 1), 1000);
return () => clearTimeout(timer);
}
}, [resendTimer]);
const handleOtpDigitChange = (index: number, value: string) => {
// Only accept numeric or clean char
const cleanValue = value.replace(/[^0-9]/g, '').slice(-1);
const newDigits = [...otpDigits];
newDigits[index] = cleanValue;
setOtpDigits(newDigits);
// Auto focus next input
if (cleanValue && index < 5) {
const nextInput = document.getElementById(`otp-digit-${index + 1}`);
nextInput?.focus();
}
};
const handleOtpKeyDown = (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Backspace') {
if (!otpDigits[index] && index > 0) {
const prevInput = document.getElementById(`otp-digit-${index - 1}`);
prevInput?.focus();
}
}
};
const handleResetSubmit = (e: React.FormEvent) => {
e.preventDefault();
login(resetEmail || 'artisan.weaver@craftguild.in');
navigate('/dashboard');
};
return (
<div className="section py-5 py-6-desktop" style={{ minHeight: 'calc(100vh - 80px)', display: 'flex', alignItems: 'center' }}>
<div className="container is-widescreen px-3 px-4-desktop">
<div className="columns is-centered">
<div className="column is-11-widescreen is-12-desktop is-9-tablet is-12-mobile">
{/* 2-Column Authentication Card */}
<div
className="card"
style={{
borderRadius: '24px',
border: '1px solid #EAE5DD',
boxShadow: '0 12px 40px rgba(0, 0, 0, 0.04)',
backgroundColor: '#FFFFFF',
overflow: 'hidden'
}}
>
<div className="auth-card-layout">
{/* ------------------------------------------------------------------ */}
{/* LEFT COLUMN: Artisan Security, Guarantee Highlights & Helpline */}
{/* ------------------------------------------------------------------ */}
<div className="auth-card-left">
<div>
{/* Badge */}
<div className="mb-3">
<span
className="is-inline-flex is-align-items-center px-3 py-1"
style={{
backgroundColor: '#FDF2F4',
border: '1px solid rgba(103, 27, 38, 0.15)',
borderRadius: '9999px',
color: 'var(--trad-maroon)',
fontSize: '0.72rem',
fontWeight: 700,
letterSpacing: '0.08em',
textTransform: 'uppercase'
}}
>
<Star size={11} className="mr-1.5" fill="var(--trad-maroon)" color="var(--trad-maroon)" />
<span>ARTISAN SECURITY</span>
</span>
</div>
{/* Headline */}
<h2
className="title mb-2"
style={{
fontSize: '1.6rem',
fontWeight: 800,
color: '#1A202C',
lineHeight: 1.3,
letterSpacing: '-0.02em'
}}
>
Protecting your craft atelier &amp; earnings.
</h2>
{/* Subtitle */}
<p className="subtitle mb-4 is-size-7" style={{ color: '#4A5568', lineHeight: 1.55 }}>
Ensure seamless recovery to your master workshop ledger, scheduled bank settlements, and global artisan trade orders.
</p>
{/* Artisan Image */}
<div className="mb-5">
<img
src="/images/login-potter.jpg"
alt="Authentic Indian Artisan Potter"
style={{
width: '100%',
height: '215px',
objectFit: 'cover',
borderRadius: '16px',
display: 'block',
boxShadow: '0 4px 16px rgba(0, 0, 0, 0.06)'
}}
/>
</div>
{/* Checklist */}
<div className="is-flex is-flex-direction-column" style={{ gap: '0.85rem' }}>
<div className="is-flex is-align-items-center">
<div
className="mr-2.5 is-flex is-align-items-center is-justify-content-center is-flex-shrink-0"
style={{ width: '20px', height: '20px', borderRadius: '50%', backgroundColor: '#E6F4EA' }}
>
<Check size={13} color="#137333" strokeWidth={3} />
</div>
<span className="is-size-7" style={{ color: '#2D3748', fontWeight: 500 }}>
Quick OTP recovery via registered email or mobile SIM
</span>
</div>
<div className="is-flex is-align-items-center">
<div
className="mr-2.5 is-flex is-align-items-center is-justify-content-center is-flex-shrink-0"
style={{ width: '20px', height: '20px', borderRadius: '50%', backgroundColor: '#E6F4EA' }}
>
<Check size={13} color="#137333" strokeWidth={3} />
</div>
<span className="is-size-7" style={{ color: '#2D3748', fontWeight: 500 }}>
Zero interruption to your ongoing orders and payouts
</span>
</div>
<div className="is-flex is-align-items-center">
<div
className="mr-2.5 is-flex is-align-items-center is-justify-content-center is-flex-shrink-0"
style={{ width: '20px', height: '20px', borderRadius: '50%', backgroundColor: '#E6F4EA' }}
>
<Check size={13} color="#137333" strokeWidth={3} />
</div>
<span className="is-size-7" style={{ color: '#2D3748', fontWeight: 500 }}>
Dedicated 24/7 maker helpline in 7 regional languages
</span>
</div>
</div>
{/* Toll Free Callout */}
<div
className="mt-5 pt-4 is-flex is-align-items-center is-size-7"
style={{ borderTop: '1px solid #EAE5DD', color: '#4A5568' }}
>
<PhoneCall size={15} className="mr-2 has-text-grey" />
<span>
Kala Setu Support:{' '}
<strong style={{ color: '#1A202C' }}>1800–419–8723</strong>{' '}
<span className="has-text-grey">(Toll Free)</span>
</span>
</div>
</div>
</div>
{/* ------------------------------------------------------------------ */}
{/* RIGHT COLUMN: Reset Password Form */}
{/* ------------------------------------------------------------------ */}
<div className="auth-card-right">
<div>
{/* Back to login button */}
<div className="mb-3">
<Link
to="/login"
className="is-inline-flex is-align-items-center"
style={{
color: 'var(--trad-maroon)',
fontSize: '0.85rem',
fontWeight: 600,
textDecoration: 'none'
}}
>
<ArrowLeft size={16} className="mr-1.5" />
<span>Back to login</span>
</Link>
</div>
<h1
className="title mb-1.5"
style={{
fontSize: 'clamp(1.45rem, 4vw, 1.85rem)',
fontWeight: 800,
color: '#1A202C',
letterSpacing: '-0.02em',
lineHeight: 1.25
}}
>
Reset your password
</h1>
<p className="subtitle is-size-7 mb-4" style={{ color: '#718096', lineHeight: 1.5 }}>
Enter your registered email address to receive a verification code and create a new password.
</p>
{/* Segmented Toggle Tabs */}
<div
className="mb-5 p-1 is-flex"
style={{
backgroundColor: '#F1F3F5',
borderRadius: '9999px',
width: '100%',
maxWidth: '280px'
}}
>
<button
type="button"
onClick={() => setResetTab('mobile')}
className="button is-small is-flex-grow-1"
style={{
backgroundColor: resetTab === 'mobile' ? '#FFFFFF' : 'transparent',
color: resetTab === 'mobile' ? '#1A202C' : '#718096',
fontWeight: resetTab === 'mobile' ? 700 : 500,
border: 'none',
borderRadius: '9999px',
boxShadow: resetTab === 'mobile' ? '0 2px 6px rgba(0, 0, 0, 0.08)' : 'none',
height: '34px',
fontSize: '0.8rem',
transition: 'all 0.15s ease'
}}
>
<span>Mobile Number</span>
</button>
<button
type="button"
onClick={() => setResetTab('email')}
className="button is-small is-flex-grow-1"
style={{
backgroundColor: resetTab === 'email' ? '#FFFFFF' : 'transparent',
color: resetTab === 'email' ? '#1A202C' : '#718096',
fontWeight: resetTab === 'email' ? 700 : 500,
border: 'none',
borderRadius: '9999px',
boxShadow: resetTab === 'email' ? '0 2px 6px rgba(0, 0, 0, 0.08)' : 'none',
height: '34px',
fontSize: '0.8rem',
transition: 'all 0.15s ease'
}}
>
<span>Email ID</span>
</button>
</div>
<form onSubmit={handleResetSubmit}>
{/* Registered Email / Mobile Field */}
<div className="field mb-4">
<label
className="label mb-1.5"
style={{
fontSize: '0.68rem',
fontWeight: 700,
color: '#718096',
letterSpacing: '0.06em',
textTransform: 'uppercase'
}}
>
{resetTab === 'email' ? 'REGISTERED EMAIL ADDRESS' : 'REGISTERED MOBILE NUMBER'}
</label>
<div
className="is-flex is-align-items-center"
style={{
border: isEmailFocused ? '1.5px solid var(--trad-maroon)' : '1.5px solid #CBD5E0',
borderRadius: '10px',
backgroundColor: '#FFFFFF',
height: '46px',
padding: '0 12px',
boxShadow: isEmailFocused ? '0 0 0 3px rgba(103, 27, 38, 0.12)' : 'none',
transition: 'border-color 0.15s ease, box-shadow 0.15s ease'
}}
>
<span className="mr-2.5 is-flex is-align-items-center is-flex-shrink-0" style={{ color: '#718096' }}>
{resetTab === 'email' ? <Mail size={16} /> : <Smartphone size={16} />}
</span>
<input
type={resetTab === 'email' ? 'email' : 'tel'}
value={resetTab === 'email' ? resetEmail : resetMobile}
onChange={(e) => resetTab === 'email' ? setResetEmail(e.target.value) : setResetMobile(e.target.value)}
onFocus={() => setIsEmailFocused(true)}
onBlur={() => setIsEmailFocused(false)}
style={{
border: 'none',
outline: 'none',
boxShadow: 'none',
backgroundColor: 'transparent',
height: '100%',
fontSize: '0.88rem',
color: '#1A202C',
flex: 1,
minWidth: 0
}}
/>
<SolidGreenCheck size={16} />
</div>
</div>
{/* 6-Digit OTP Verification Field */}
<div className="field mb-4">
<div className="is-flex is-justify-content-space-between is-align-items-center mb-1.5">
<label
className="label mb-0"
style={{
fontSize: '0.68rem',
fontWeight: 700,
color: '#718096',
letterSpacing: '0.06em',
textTransform: 'uppercase'
}}
>
VERIFICATION CODE ({resetTab === 'email' ? 'EMAIL OTP' : 'SMS OTP'})
</label>
<span
className="is-size-7"
style={{
color: 'var(--trad-maroon)',
fontWeight: 600,
fontSize: '0.75rem',
cursor: 'pointer'
}}
>
Resend code in {resendTimer}s
</span>
</div>
{/* 6 Distinct OTP Boxes */}
<div className="is-flex is-align-items-center" style={{ gap: '8px', maxWidth: '340px' }}>
{otpDigits.map((digit, idx) => (
<input
key={idx}
id={`otp-digit-${idx}`}
type="text"
inputMode="numeric"
maxLength={1}
value={digit}
placeholder="•"
onChange={(e) => handleOtpDigitChange(idx, e.target.value)}
onKeyDown={(e) => handleOtpKeyDown(idx, e)}
className="has-text-centered has-text-weight-bold"
style={{
width: '46px',
height: '48px',
borderRadius: '10px',
border: '1.5px solid #CBD5E0',
fontSize: digit ? '1.15rem' : '1.4rem',
color: '#1A202C',
outline: 'none',
backgroundColor: '#FFFFFF',
flex: '1 1 0',
minWidth: '36px',
maxWidth: '48px',
padding: 0,
transition: 'border-color 0.15s ease, box-shadow 0.15s ease'
}}
onFocus={(e) => {
e.target.style.borderColor = 'var(--trad-maroon)';
e.target.style.boxShadow = '0 0 0 3px rgba(103, 27, 38, 0.12)';
}}
onBlur={(e) => {
e.target.style.borderColor = '#CBD5E0';
e.target.style.boxShadow = 'none';
}}
/>
))}
</div>
<p className="help mt-1.5 is-flex is-align-items-center" style={{ color: '#1E8E3E', fontSize: '0.75rem' }}>
<SolidGreenCheck size={13} />
<span className="ml-1.5">Code sent to artisa*****@craftguild.in</span>
</p>
</div>
{/* Create New Password */}
<div className="field mb-3">
<label
className="label mb-1.5"
style={{
fontSize: '0.68rem',
fontWeight: 700,
color: '#718096',
letterSpacing: '0.06em',
textTransform: 'uppercase'
}}
>
CREATE NEW PASSWORD
</label>
<div
className="is-flex is-align-items-center"
style={{
border: isNewPassFocused ? '1.5px solid var(--trad-maroon)' : '1.5px solid #CBD5E0',
borderRadius: '10px',
backgroundColor: '#FFFFFF',
height: '46px',
padding: '0 12px',
boxShadow: isNewPassFocused ? '0 0 0 3px rgba(103, 27, 38, 0.12)' : 'none',
transition: 'border-color 0.15s ease, box-shadow 0.15s ease'
}}
>
<input
type={showNewPassword ? 'text' : 'password'}
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
onFocus={() => setIsNewPassFocused(true)}
onBlur={() => setIsNewPassFocused(false)}
style={{
border: 'none',
outline: 'none',
boxShadow: 'none',
backgroundColor: 'transparent',
height: '100%',
fontSize: '0.88rem',
color: '#1A202C',
flex: 1,
minWidth: 0,
letterSpacing: showNewPassword ? 'normal' : '0.12em'
}}
/>
<span
className="is-clickable ml-2 is-flex is-align-items-center"
style={{ cursor: 'pointer', color: '#718096' }}
onClick={() => setShowNewPassword(!showNewPassword)}
>
{showNewPassword ? <EyeOff size={16} /> : <Eye size={16} />}
</span>
</div>
{/* Password Strength Meter (3 green segments, 1 gray, Strong (8+ chars)) */}
<div className="is-flex is-align-items-center mt-2">
<div className="is-flex is-flex-grow-1 mr-3" style={{ gap: '4px' }}>
<div style={{ flex: 1, height: '4px', backgroundColor: '#1E6548', borderRadius: '2px' }} />
<div style={{ flex: 1, height: '4px', backgroundColor: '#1E6548', borderRadius: '2px' }} />
<div style={{ flex: 1, height: '4px', backgroundColor: '#1E6548', borderRadius: '2px' }} />
<div style={{ flex: 1, height: '4px', backgroundColor: '#E2E8F0', borderRadius: '2px' }} />
</div>
<span style={{ color: '#1E6548', fontWeight: 600, fontSize: '0.72rem', whiteSpace: 'nowrap' }}>
Strong (8+ chars)
</span>
</div>
</div>
{/* Confirm New Password */}
<div className="field mb-5">
<label
className="label mb-1.5"
style={{
fontSize: '0.68rem',
fontWeight: 700,
color: '#718096',
letterSpacing: '0.06em',
textTransform: 'uppercase'
}}
>
CONFIRM NEW PASSWORD
</label>
<div
className="is-flex is-align-items-center"
style={{
border: isConfirmPassFocused ? '1.5px solid var(--trad-maroon)' : '1.5px solid #CBD5E0',
borderRadius: '10px',
backgroundColor: '#FFFFFF',
height: '46px',
padding: '0 12px',
boxShadow: isConfirmPassFocused ? '0 0 0 3px rgba(103, 27, 38, 0.12)' : 'none',
transition: 'border-color 0.15s ease, box-shadow 0.15s ease'
}}
>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
onFocus={() => setIsConfirmPassFocused(true)}
onBlur={() => setIsConfirmPassFocused(false)}
style={{
border: 'none',
outline: 'none',
boxShadow: 'none',
backgroundColor: 'transparent',
height: '100%',
fontSize: '0.88rem',
color: '#1A202C',
flex: 1,
minWidth: 0,
letterSpacing: '0.12em'
}}
/>
<SolidGreenCheck size={16} />
</div>
</div>
{/* Reset Password & Log In Button */}
<button
type="submit"
className="button is-fullwidth"
style={{
backgroundColor: 'var(--trad-maroon)',
color: '#FFFFFF',
borderRadius: '9999px',
height: '48px',
fontSize: '0.95rem',
fontWeight: 700,
border: 'none',
boxShadow: '0 4px 12px rgba(103, 27, 38, 0.25)',
transition: 'all 0.2s ease'
}}
>
<span>Reset Password &amp; Log In</span>
<ArrowRight size={17} className="ml-2" />
</button>
</form>
{/* Footer Support Desk Link */}
<div className="has-text-centered mt-4 pt-2">
<span className="is-size-7" style={{ color: '#718096' }}>
Having trouble?{' '}
<a
href="#support"
onClick={(e) => { e.preventDefault(); alert('Kala Setu Support Helpline: 1800-419-8723'); }}
style={{ color: 'var(--trad-maroon)', fontWeight: 600, textDecoration: 'none' }}
>
Request assistance from our Onboarding Desk
</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};

View file

@ -621,3 +621,41 @@ h1, h2, h3, h4, h5, h6, .title {
} }
} }
/* ==========================================================================
Responsive Auth Two-Column Layout (.auth-card-layout)
========================================================================== */
.auth-card-layout {
display: flex !important;
flex-direction: column !important;
width: 100% !important;
}
@media screen and (min-width: 1024px) {
.auth-card-layout {
flex-direction: row !important;
}
}
.auth-card-left {
flex: 0 0 42% !important;
max-width: 42% !important;
border-right: 1px solid #EAE5DD !important;
background-color: #FAF9F6 !important;
padding: 2.5rem !important;
box-sizing: border-box !important;
}
@media screen and (max-width: 1023px) {
.auth-card-left {
display: none !important;
}
}
.auth-card-right {
flex: 1 1 auto !important;
min-width: 0 !important;
width: 100% !important;
padding: clamp(1.25rem, 4vw, 3rem) !important;
box-sizing: border-box !important;
}