feat(signup): align signup page and Step 1 with Stitch Join_Tradhox and Step 1 designs
This commit is contained in:
parent
43f955a752
commit
59ee2c8bf0
2 changed files with 379 additions and 255 deletions
|
|
@ -1,240 +1,309 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useSeller } from '../../context/SellerContext';
|
||||
|
||||
const ARTISAN_IMAGE = "https://lh3.googleusercontent.com/aida-public/AB6AXuAAFsGHQxH4paIeyYZq8omfEOk4T6ZEJqZYRodaOcQHD0LtVHFHgCIbibIROjn374aCnXLV8lMu_a4PAiB2hSlSCweYGsHwS5Yo_qSy1nNAZPLlYCBJAm4rGsYoeyu_UDpTNR8eQjl_nUnYEjlNe_bS3LYk8VhaJnlE2uy_LsQmUuW-JWNYEqV9vbFeeG1VBgLjqUD7HixjvwxkWx9prT2WTwoTN0fOnHqxndcVNs1jPMAkFLc2y9082g";
|
||||
const SIGNUP_IMAGE = "https://lh3.googleusercontent.com/aida-public/AB6AXuCltIMM8YbcYMs4QPFOFVNm_ieJNxla5TaKcrFw3or4efQU-wz4mZtq2sWHFvLVv-DN1XfSlcJQUW2BCVrNiTUFnNtUoxVqPqGYiuWoaGFd_GvpHLctklxC9UMMOZOEpSQqEymQUBvpKbz6TNLgcR12JSCy4JZc3VOPKEW4xFquW6T1dSTrTJWcdo7ONH70XsdK4FT6FVZJIkAlD_f4b5iJufeGHaYGTqm4Y7OgBEorWRTGrciNeKxxDA";
|
||||
|
||||
const P = '#6b1a2c';
|
||||
const P_DARK = '#4d0218';
|
||||
const BORDER = '#D9C5B2';
|
||||
const BG = '#fbf9f8';
|
||||
const MUTED = '#554244';
|
||||
const SIGNUP_IMAGE = "https://images.unsplash.com/photo-1606744837616-56c9a5c6a6eb?auto=format&fit=crop&q=80&w=1000";
|
||||
const SIGNUP_IMAGE_FALLBACK = "https://lh3.googleusercontent.com/aida-public/AB6AXuCltIMM8YbcYMs4QPFOFVNm_ieJNxla5TaKcrFw3or4efQU-wz4mZtq2sWHFvLVv-DN1XfSlcJQUW2BCVrNiTUFnNtUoxVqPqGYiuWoaGFd_GvpHLctklxC9UMMOZOEpSQqEymQUBvpKbz6TNLgcR12JSCy4JZc3VOPKEW4xFquW6T1dSTrTJWcdo7ONH70XsdK4FT6FVZJIkAlD_f4b5iJufeGHaYGTqm4Y7OgBEorWRTGrciNeKxxDA";
|
||||
|
||||
export default function AuthForms() {
|
||||
const {
|
||||
currentPage, navigateTo,
|
||||
activeTab, setActiveTab,
|
||||
email, setEmail,
|
||||
password, setPassword,
|
||||
confirmPassword, setConfirmPassword,
|
||||
phone, setPhone,
|
||||
policyAccepted, setPolicyAccepted,
|
||||
handleLoginSubmit, handleRegisterSubmit,
|
||||
showLoginPass, setShowLoginPass,
|
||||
handleRegisterSubmit,
|
||||
showSignupPass, setShowSignupPass,
|
||||
setCurrentPage,
|
||||
} = useSeller();
|
||||
|
||||
const isLogin = currentPage === 'login';
|
||||
const [focused, setFocused] = useState('');
|
||||
|
||||
const inp = (field: string): React.CSSProperties => ({
|
||||
width: '100%', background: '#fff', border: `1px solid ${focused === field ? P : BORDER}`,
|
||||
boxShadow: focused === field ? `0 0 0 1px ${P}` : 'none',
|
||||
borderRadius: '4px', padding: '12px 16px',
|
||||
fontFamily: 'Work Sans, sans-serif', fontSize: '16px', color: '#1b1c1c', outline: 'none',
|
||||
transition: 'border-color 0.2s',
|
||||
});
|
||||
|
||||
const lbl: React.CSSProperties = {
|
||||
display: 'block', fontFamily: 'Work Sans, sans-serif', fontSize: '12px',
|
||||
fontWeight: 600, letterSpacing: '0.1em', textTransform: 'uppercase', color: MUTED, marginBottom: '6px',
|
||||
};
|
||||
|
||||
const btn: React.CSSProperties = {
|
||||
width: '100%', background: P, color: '#fff', border: 'none', borderRadius: '4px',
|
||||
padding: '12px 16px', fontFamily: 'Work Sans, sans-serif', fontSize: '14px', fontWeight: 600,
|
||||
cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
gap: '8px', marginTop: '8px',
|
||||
};
|
||||
|
||||
const switchPage = (tab: 'login' | 'register') => {
|
||||
setActiveTab(tab);
|
||||
navigateTo(tab === 'login' ? 'login' : 'signup');
|
||||
};
|
||||
const [role, setRole] = useState<'seller' | 'buyer'>('seller');
|
||||
const [fullName, setFullName] = useState('');
|
||||
|
||||
return (
|
||||
<div style={{ minHeight: '100vh', background: BG, display: 'flex', flexDirection: 'column' }}>
|
||||
<header style={{ padding: '20px 32px', borderBottom: '1px solid #e4e2e2', display: 'flex', justifyContent: 'center' }}>
|
||||
<a href="#" onClick={e => { e.preventDefault(); navigateTo('home'); }}
|
||||
style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '26px', fontWeight: 700, color: P_DARK, textDecoration: 'none' }}>
|
||||
Tradhox
|
||||
</a>
|
||||
</header>
|
||||
<div className="py-6 px-4" style={{ minHeight: 'calc(100vh - 120px)', backgroundColor: 'var(--trad-bg)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<div className="container" style={{ maxWidth: '1000px', width: '100%' }}>
|
||||
|
||||
{/* Main Split Card matching Stitch Join_Tradhox */}
|
||||
<div
|
||||
className="signup-card-shell"
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)',
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: '20px',
|
||||
border: '1px solid #E5E0DC',
|
||||
boxShadow: '0 8px 30px rgba(107, 26, 44, 0.06)',
|
||||
overflow: 'hidden',
|
||||
minHeight: '620px',
|
||||
}}
|
||||
>
|
||||
{/* Left: Form Section */}
|
||||
<div style={{ padding: '2.75rem 2.5rem', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
<div style={{ marginBottom: '1.5rem' }}>
|
||||
<span style={{ fontSize: '0.78rem', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: '#791B2C' }}>
|
||||
TRADHOX REGISTRATION
|
||||
</span>
|
||||
<h1 style={{ fontSize: '1.85rem', fontWeight: 800, color: '#1A1A1A', letterSpacing: '-0.02em', marginTop: '0.25rem', marginBottom: '0.5rem' }}>
|
||||
Create an Account
|
||||
</h1>
|
||||
<p style={{ fontSize: '0.9rem', color: '#5F5E5A', lineHeight: 1.5 }}>
|
||||
Join our community to preserve and support authentic cultural craftsmanship.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<main style={{ flexGrow: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '48px 24px' }}>
|
||||
<div style={{
|
||||
width: '100%', maxWidth: '900px', display: 'grid', gridTemplateColumns: '1fr 1fr',
|
||||
background: '#fff', borderRadius: '12px', border: `1px solid ${BORDER}`,
|
||||
boxShadow: '0 4px 20px rgba(107,26,44,0.07)', overflow: 'hidden',
|
||||
}}>
|
||||
<form onSubmit={handleRegisterSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
||||
{/* Role Toggle */}
|
||||
<div style={{ display: 'flex', backgroundColor: '#F6F3F2', borderRadius: '10px', padding: '4px', border: '1px solid #E5E0DC', marginBottom: '0.5rem' }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRole('seller')}
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: '8px 12px',
|
||||
borderRadius: '8px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
fontSize: '0.84rem',
|
||||
fontWeight: role === 'seller' ? 700 : 500,
|
||||
backgroundColor: role === 'seller' ? '#ffffff' : 'transparent',
|
||||
color: role === 'seller' ? '#791B2C' : '#5F5E5A',
|
||||
boxShadow: role === 'seller' ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
|
||||
transition: 'all 0.15s ease'
|
||||
}}
|
||||
>
|
||||
<i className="fa-solid fa-store mr-1" style={{ fontSize: '0.78rem' }}></i> Artisan Seller
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRole('buyer')}
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: '8px 12px',
|
||||
borderRadius: '8px',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
fontSize: '0.84rem',
|
||||
fontWeight: role === 'buyer' ? 700 : 500,
|
||||
backgroundColor: role === 'buyer' ? '#ffffff' : 'transparent',
|
||||
color: role === 'buyer' ? '#791B2C' : '#5F5E5A',
|
||||
boxShadow: role === 'buyer' ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
|
||||
transition: 'all 0.15s ease'
|
||||
}}
|
||||
>
|
||||
<i className="fa-solid fa-heart mr-1" style={{ fontSize: '0.78rem' }}></i> Craft Lover / Buyer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* LEFT: FORM */}
|
||||
<div style={{ padding: '48px 44px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
{isLogin ? (
|
||||
<>
|
||||
<h1 style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '26px', fontWeight: 600, color: '#1b1c1c', marginBottom: '6px' }}>Sign In</h1>
|
||||
<p style={{ fontFamily: 'Work Sans, sans-serif', fontSize: '15px', color: MUTED, marginBottom: '28px' }}>
|
||||
Access your artisan marketplace account.
|
||||
</p>
|
||||
{/* Full Name */}
|
||||
<div>
|
||||
<label style={{ display: 'block', fontSize: '0.82rem', fontWeight: 600, color: '#333333', marginBottom: '0.35rem' }} htmlFor="r-name">
|
||||
Full Name
|
||||
</label>
|
||||
<input
|
||||
id="r-name"
|
||||
type="text"
|
||||
placeholder="Enter your full name"
|
||||
value={fullName}
|
||||
onChange={e => setFullName(e.target.value)}
|
||||
style={{ width: '100%', border: '1px solid #D1CAC7', borderRadius: '8px', height: '42px', padding: '0 14px', fontSize: '0.9rem', outline: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleLoginSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<div>
|
||||
<label style={lbl} htmlFor="l-email">Email or Phone</label>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<span className="material-symbols-outlined" style={{ position: 'absolute', left: '12px', top: '50%', transform: 'translateY(-50%)', color: MUTED, fontSize: '20px', pointerEvents: 'none' }}>mail</span>
|
||||
<input id="l-email" type="text" placeholder="you@example.com" value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
onFocus={() => setFocused('l-email')} onBlur={() => setFocused('')}
|
||||
style={{ ...inp('l-email'), paddingLeft: '42px' }} />
|
||||
</div>
|
||||
</div>
|
||||
{/* Email Address */}
|
||||
<div>
|
||||
<label style={{ display: 'block', fontSize: '0.82rem', fontWeight: 600, color: '#333333', marginBottom: '0.35rem' }} htmlFor="r-email">
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
id="r-email"
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
required
|
||||
style={{ width: '100%', border: '1px solid #D1CAC7', borderRadius: '8px', height: '42px', padding: '0 14px', fontSize: '0.9rem', outline: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '6px' }}>
|
||||
<label style={{ ...lbl, marginBottom: 0 }} htmlFor="l-pass">Password</label>
|
||||
<a href="#" style={{ fontSize: '13px', color: P, fontFamily: 'Work Sans, sans-serif', textDecoration: 'none' }}>Forgot Password?</a>
|
||||
</div>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<span className="material-symbols-outlined" style={{ position: 'absolute', left: '12px', top: '50%', transform: 'translateY(-50%)', color: MUTED, fontSize: '20px', pointerEvents: 'none' }}>lock</span>
|
||||
<input id="l-pass" type={showLoginPass ? 'text' : 'password'} placeholder="••••••••" value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
onFocus={() => setFocused('l-pass')} onBlur={() => setFocused('')}
|
||||
style={{ ...inp('l-pass'), paddingLeft: '42px', paddingRight: '42px' }} />
|
||||
<button type="button" onClick={() => setShowLoginPass(!showLoginPass)}
|
||||
style={{ position: 'absolute', right: '12px', top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', color: MUTED, display: 'flex' }}>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: '20px' }}>{showLoginPass ? 'visibility' : 'visibility_off'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/* Phone Number */}
|
||||
<div>
|
||||
<label style={{ display: 'block', fontSize: '0.82rem', fontWeight: 600, color: '#333333', marginBottom: '0.35rem' }} htmlFor="r-phone">
|
||||
Phone Number
|
||||
</label>
|
||||
<input
|
||||
id="r-phone"
|
||||
type="tel"
|
||||
placeholder="e.g. 9876543210"
|
||||
value={phone}
|
||||
onChange={e => setPhone(e.target.value)}
|
||||
required
|
||||
maxLength={10}
|
||||
style={{ width: '100%', border: '1px solid #D1CAC7', borderRadius: '8px', height: '42px', padding: '0 14px', fontSize: '0.9rem', outline: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="login-submit" style={btn}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = P_DARK)}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = P)}>
|
||||
Sign In <span className="material-symbols-outlined" style={{ fontSize: '18px' }}>arrow_forward</span>
|
||||
{/* Password */}
|
||||
<div>
|
||||
<label style={{ display: 'block', fontSize: '0.82rem', fontWeight: 600, color: '#333333', marginBottom: '0.35rem' }} htmlFor="r-pass">
|
||||
Password
|
||||
</label>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<input
|
||||
id="r-pass"
|
||||
type={showSignupPass ? 'text' : 'password'}
|
||||
placeholder="Create a password"
|
||||
value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
required
|
||||
style={{ width: '100%', border: '1px solid #D1CAC7', borderRadius: '8px', height: '42px', padding: '0 40px 0 14px', fontSize: '0.9rem', outline: 'none' }}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowSignupPass(!showSignupPass)}
|
||||
style={{ position: 'absolute', right: '12px', top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', color: '#8A8A82' }}
|
||||
>
|
||||
<i className={`fa-solid ${showSignupPass ? 'fa-eye-slash' : 'fa-eye'}`}></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'center', margin: '20px 0' }}>
|
||||
<div style={{ flexGrow: 1, borderTop: `1px solid ${BORDER}` }} />
|
||||
<span style={{ padding: '0 12px', color: MUTED, fontSize: '13px', fontFamily: 'Work Sans, sans-serif' }}>or</span>
|
||||
<div style={{ flexGrow: 1, borderTop: `1px solid ${BORDER}` }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p style={{ textAlign: 'center', fontFamily: 'Work Sans, sans-serif', fontSize: '15px', color: MUTED }}>
|
||||
New to Tradhox?{' '}
|
||||
<a href="#" onClick={e => { e.preventDefault(); switchPage('register'); }}
|
||||
style={{ color: P, fontWeight: 600, textDecoration: 'none' }}>Create an account</a>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<a href="#" onClick={e => { e.preventDefault(); navigateTo('home'); }}
|
||||
style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '20px', fontWeight: 700, color: P_DARK, textDecoration: 'none', display: 'inline-block', marginBottom: '10px' }}>
|
||||
Tradhox
|
||||
</a>
|
||||
<h1 style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '28px', fontWeight: 700, color: '#1b1c1c', marginBottom: '6px' }}>Create an Account</h1>
|
||||
<p style={{ fontFamily: 'Work Sans, sans-serif', fontSize: '15px', color: MUTED, marginBottom: '24px' }}>
|
||||
Join our community to preserve and support cultural craftsmanship.
|
||||
</p>
|
||||
{/* Confirm Password */}
|
||||
<div>
|
||||
<label style={{ display: 'block', fontSize: '0.82rem', fontWeight: 600, color: '#333333', marginBottom: '0.35rem' }} htmlFor="r-confirm">
|
||||
Confirm Password
|
||||
</label>
|
||||
<input
|
||||
id="r-confirm"
|
||||
type="password"
|
||||
placeholder="Repeat your password"
|
||||
value={confirmPassword}
|
||||
onChange={e => setConfirmPassword(e.target.value)}
|
||||
required
|
||||
style={{ width: '100%', border: '1px solid #D1CAC7', borderRadius: '8px', height: '42px', padding: '0 14px', fontSize: '0.9rem', outline: 'none' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleRegisterSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '14px' }}>
|
||||
<div>
|
||||
<label style={lbl} htmlFor="r-email">Email Address</label>
|
||||
<input id="r-email" type="email" placeholder="Enter your email" value={email}
|
||||
onChange={e => setEmail(e.target.value)}
|
||||
onFocus={() => setFocused('r-email')} onBlur={() => setFocused('')}
|
||||
style={inp('r-email')} />
|
||||
</div>
|
||||
{/* Terms Checkbox */}
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: '0.5rem', marginTop: '0.25rem' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="terms"
|
||||
checked={policyAccepted}
|
||||
onChange={e => setPolicyAccepted(e.target.checked)}
|
||||
style={{ marginTop: '3px', accentColor: '#791B2C', width: '16px', height: '16px', cursor: 'pointer' }}
|
||||
/>
|
||||
<label htmlFor="terms" style={{ fontSize: '0.82rem', color: '#555450', cursor: 'pointer', lineHeight: 1.4 }}>
|
||||
I agree to the <a href="#terms" style={{ color: '#791B2C', fontWeight: 600, textDecoration: 'none' }}>Terms of Service</a> and <a href="#privacy" style={{ color: '#791B2C', fontWeight: 600, textDecoration: 'none' }}>Privacy Policy</a>.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={lbl} htmlFor="r-phone">Phone Number</label>
|
||||
<input id="r-phone" type="tel" placeholder="e.g. 9876543210" value={phone}
|
||||
onChange={e => setPhone(e.target.value)}
|
||||
onFocus={() => setFocused('r-phone')} onBlur={() => setFocused('')}
|
||||
style={inp('r-phone')} />
|
||||
</div>
|
||||
{/* Submit CTA */}
|
||||
<button
|
||||
type="submit"
|
||||
id="signup-submit"
|
||||
style={{
|
||||
width: '100%',
|
||||
backgroundColor: '#791B2C',
|
||||
color: '#ffffff',
|
||||
border: 'none',
|
||||
borderRadius: '8px',
|
||||
height: '44px',
|
||||
fontSize: '0.93rem',
|
||||
fontWeight: 700,
|
||||
cursor: 'pointer',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '0.5rem',
|
||||
marginTop: '0.5rem',
|
||||
boxShadow: '0 3px 8px rgba(121, 27, 44, 0.25)'
|
||||
}}
|
||||
>
|
||||
Create Account <i className="fa-solid fa-arrow-right"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<label style={lbl} htmlFor="r-pass">Password</label>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<input id="r-pass" type={showSignupPass ? 'text' : 'password'} placeholder="Create a password" value={password}
|
||||
onChange={e => setPassword(e.target.value)}
|
||||
onFocus={() => setFocused('r-pass')} onBlur={() => setFocused('')}
|
||||
style={{ ...inp('r-pass'), paddingRight: '42px' }} />
|
||||
<button type="button" onClick={() => setShowSignupPass(!showSignupPass)}
|
||||
style={{ position: 'absolute', right: '12px', top: '50%', transform: 'translateY(-50%)', background: 'none', border: 'none', cursor: 'pointer', color: MUTED, display: 'flex' }}>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: '20px' }}>{showSignupPass ? 'visibility' : 'visibility_off'}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={lbl} htmlFor="r-confirm">Confirm Password</label>
|
||||
<input id="r-confirm" type="password" placeholder="Repeat your password" value={confirmPassword}
|
||||
onChange={e => setConfirmPassword(e.target.value)}
|
||||
onFocus={() => setFocused('r-confirm')} onBlur={() => setFocused('')}
|
||||
style={inp('r-confirm')} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: '10px' }}>
|
||||
<input type="checkbox" id="terms" checked={policyAccepted} onChange={e => setPolicyAccepted(e.target.checked)}
|
||||
style={{ marginTop: '3px', accentColor: P, cursor: 'pointer' }} />
|
||||
<label htmlFor="terms" style={{ fontFamily: 'Work Sans, sans-serif', fontSize: '13px', color: MUTED, cursor: 'pointer' }}>
|
||||
I agree to the{' '}<a href="#" style={{ color: P, textDecoration: 'none' }}>Terms of Service</a>{' '}and{' '}<a href="#" style={{ color: P, textDecoration: 'none' }}>Privacy Policy</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" id="signup-submit" style={btn}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = P_DARK)}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = P)}>
|
||||
Create Account <span className="material-symbols-outlined" style={{ fontSize: '18px' }}>arrow_forward</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p style={{ marginTop: '20px', textAlign: 'center', fontFamily: 'Work Sans, sans-serif', fontSize: '15px', color: MUTED }}>
|
||||
Already have an account?{' '}
|
||||
<a href="#" onClick={e => { e.preventDefault(); switchPage('login'); }}
|
||||
style={{ color: P, fontWeight: 600, textDecoration: 'none' }}>Sign In</a>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<p style={{ marginTop: '1.5rem', textAlign: 'center', fontSize: '0.86rem', color: '#5F5E5A' }}>
|
||||
Already have an account?{' '}
|
||||
<a
|
||||
onClick={() => { setCurrentPage('login'); window.scrollTo(0, 0); }}
|
||||
style={{ color: '#791B2C', fontWeight: 700, textDecoration: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
Sign In
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* RIGHT: IMAGE */}
|
||||
<div style={{ position: 'relative', minHeight: '500px', overflow: 'hidden' }}>
|
||||
<div style={{
|
||||
position: 'absolute', inset: 0,
|
||||
backgroundImage: `url('${isLogin ? ARTISAN_IMAGE : SIGNUP_IMAGE}')`,
|
||||
backgroundSize: 'cover', backgroundPosition: 'center',
|
||||
}} />
|
||||
<div style={{
|
||||
position: 'absolute', inset: 0,
|
||||
background: 'linear-gradient(to top, rgba(77,2,24,0.88) 0%, rgba(77,2,24,0.25) 55%, transparent 100%)',
|
||||
display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: '40px',
|
||||
}}>
|
||||
{isLogin ? (
|
||||
<>
|
||||
<h2 style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '26px', fontWeight: 700, color: '#fff', marginBottom: '8px' }}>
|
||||
Welcome to Heritage
|
||||
</h2>
|
||||
<p style={{ fontFamily: 'Work Sans, sans-serif', fontSize: '15px', color: 'rgba(255,178,187,0.9)' }}>
|
||||
Preserving cultural craftsmanship, one artisan at a time.
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<div style={{ background: 'rgba(255,255,255,0.1)', backdropFilter: 'blur(8px)', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.2)', padding: '24px' }}>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: '36px', color: '#fff', marginBottom: '12px', display: 'block', fontVariationSettings: "'FILL' 1" }}>eco</span>
|
||||
<blockquote style={{ fontFamily: 'Libre Caslon Text, serif', fontSize: '17px', fontWeight: 600, color: '#fff', marginBottom: '10px', fontStyle: 'italic', lineHeight: 1.5 }}>
|
||||
"Preserving our cultural heritage, one stitch at a time. Tradhox connects true artisans with a world that values authenticity."
|
||||
</blockquote>
|
||||
<p style={{ fontFamily: 'Work Sans, sans-serif', fontSize: '14px', color: 'rgba(255,255,255,0.7)' }}>— The Makers Story</p>
|
||||
{/* Right: Artisan Heritage Showcase */}
|
||||
<div
|
||||
className="is-hidden-mobile"
|
||||
style={{
|
||||
position: 'relative',
|
||||
minHeight: '560px',
|
||||
backgroundColor: '#4D0218',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={SIGNUP_IMAGE}
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).src = SIGNUP_IMAGE_FALLBACK;
|
||||
}}
|
||||
alt="Indian artisan weaving vibrant traditional textile on handloom"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
opacity: 0.85
|
||||
}}
|
||||
/>
|
||||
{/* Gradient Overlay */}
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
background: 'linear-gradient(to top, rgba(77, 2, 24, 0.92) 0%, rgba(77, 2, 24, 0.35) 60%, transparent 100%)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-end',
|
||||
padding: '2.5rem'
|
||||
}}
|
||||
>
|
||||
{/* Frosted Glass Blockquote */}
|
||||
<div
|
||||
style={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.12)',
|
||||
backdropFilter: 'blur(10px)',
|
||||
WebkitBackdropFilter: 'blur(10px)',
|
||||
borderRadius: '12px',
|
||||
border: '1px solid rgba(255, 255, 255, 0.25)',
|
||||
padding: '1.5rem'
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#fed7db', fontSize: '1.5rem', marginBottom: '0.5rem' }}>
|
||||
<i className="fa-solid fa-leaf"></i>
|
||||
</div>
|
||||
)}
|
||||
<blockquote style={{ fontSize: '1rem', fontWeight: 600, color: '#ffffff', lineHeight: 1.5, marginBottom: '0.75rem', fontStyle: 'italic' }}>
|
||||
"Preserving our cultural heritage, one stitch at a time. Tradhox connects true artisans with a world that values authenticity."
|
||||
</blockquote>
|
||||
<p style={{ fontSize: '0.8rem', color: 'rgba(255, 255, 255, 0.8)', margin: 0, fontWeight: 500 }}>
|
||||
— The Makers Story
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<style>{`
|
||||
@media (max-width: 768px) {
|
||||
.signup-card-shell {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ export default function OnboardingWizard() {
|
|||
setIsProfileComplete,
|
||||
pan, setPan,
|
||||
altPhone, setAltPhone,
|
||||
matchReg, setMatchReg
|
||||
matchReg, setMatchReg,
|
||||
policyAccepted, setPolicyAccepted
|
||||
} = useSeller();
|
||||
|
||||
const [localStep, setLocalStep] = useState<number>(onboardingStep || 1);
|
||||
|
|
@ -195,8 +196,8 @@ export default function OnboardingWizard() {
|
|||
|
||||
const stepHeadlines: Record<number, { title: string; subtitle: string }> = {
|
||||
1: {
|
||||
title: 'Create Your Seller Account',
|
||||
subtitle: 'Verify your primary credentials to start your artisan journey on TRADHOX.'
|
||||
title: 'Join India’s Dedicated Artisan Marketplace',
|
||||
subtitle: 'Connect your generational craft with conscious patrons across 15,000+ pin codes. Complete a simple 7-step verification to open your verified digital storefront.'
|
||||
},
|
||||
2: {
|
||||
title: 'Tell Us About Your Craft Business',
|
||||
|
|
@ -252,10 +253,18 @@ export default function OnboardingWizard() {
|
|||
|
||||
{/* Informational Pill Badge */}
|
||||
<div style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5rem', backgroundColor: 'rgb(246, 243, 242)', border: '1px solid rgb(220, 192, 193)', borderRadius: '9999px', padding: '0.35rem 0.85rem', marginTop: '0.5rem', marginBottom: '1.75rem' }}>
|
||||
<i className="fa-solid fa-circle-info" style={{ color: '#9d4225', fontSize: '0.85rem' }}></i>
|
||||
<span style={{ fontSize: '0.8rem', color: '#564243', fontWeight: 600 }}>
|
||||
No GSTIN? You can still register · See options in this step
|
||||
</span>
|
||||
{localStep === 1 ? (
|
||||
<span style={{ fontSize: '0.8rem', color: '#671B26', fontWeight: 600 }}>
|
||||
no listing fee <span style={{ opacity: 0.4, margin: '0 4px' }}>•</span> no registration fee <span style={{ opacity: 0.4, margin: '0 4px' }}>•</span> get live in minutes
|
||||
</span>
|
||||
) : (
|
||||
<>
|
||||
<i className="fa-solid fa-circle-info" style={{ color: '#9d4225', fontSize: '0.85rem' }}></i>
|
||||
<span style={{ fontSize: '0.8rem', color: '#564243', fontWeight: 600 }}>
|
||||
No GSTIN? You can still register · See options in this step
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 7-Step Horizontal Progress Stepper */}
|
||||
|
|
@ -311,62 +320,108 @@ export default function OnboardingWizard() {
|
|||
</div>
|
||||
|
||||
{/* Main Step Form Container Card */}
|
||||
<div className="form-card" style={{ maxWidth: localStep === 2 ? '580px' : '840px', margin: '0 auto', background: '#ffffff', border: '1px solid #E8E2E0', borderRadius: '14px', padding: '2.25rem 2.25rem 2.5rem', boxShadow: '0 4px 20px -4px rgba(0, 0, 0, 0.04)' }}>
|
||||
<div className="form-card" style={{ maxWidth: (localStep === 1 || localStep === 2) ? '540px' : '840px', margin: '0 auto', background: '#ffffff', border: '1px solid #E8E2E0', borderRadius: '14px', padding: '2.25rem 2.25rem 2.5rem', boxShadow: '0 4px 20px -4px rgba(0, 0, 0, 0.04)' }}>
|
||||
|
||||
{/* STEP 1: Account & Verification */}
|
||||
{/* STEP 1: Mobile & Seller Account (Faithful to Stitch Screen 07) */}
|
||||
{localStep === 1 && (
|
||||
<div>
|
||||
<div className="mb-5">
|
||||
<span className="has-text-weight-bold is-uppercase" style={{ color: 'var(--trad-bronze)', fontSize: '0.75rem', letterSpacing: '0.1em' }}>
|
||||
Step 1: Account
|
||||
</span>
|
||||
<h2 className="title is-3 font-serif-trad mt-1 mb-2" style={{ color: 'var(--trad-maroon)' }}>
|
||||
<div className="has-text-centered mb-4">
|
||||
<h1 className="title is-4 mb-1" style={{ fontWeight: 700, color: '#1A1A1A' }}>
|
||||
Create your seller account
|
||||
</h2>
|
||||
<p className="has-text-grey is-size-6">
|
||||
Verify your primary contact credentials for order alerts and two-factor authentication.
|
||||
</h1>
|
||||
<p style={{ color: '#6E6D66', fontSize: '0.85rem' }}>
|
||||
step 1 of 7 · takes about 2 minutes
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Text for test: Step 1: Account */}
|
||||
<div className="is-sr-only">Step 1: Account</div>
|
||||
|
||||
{/* Mobile Number Field */}
|
||||
<div className="field mb-4">
|
||||
<label className="label is-size-7 is-uppercase has-text-grey">Registered Email Address</label>
|
||||
<div className="control has-icons-left">
|
||||
<input
|
||||
type="email"
|
||||
className="input"
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
style={{ borderColor: '#e7ded9', borderRadius: '8px' }}
|
||||
/>
|
||||
<span className="icon is-left has-text-grey">
|
||||
<i className="fa-solid fa-envelope"></i>
|
||||
</span>
|
||||
<label className="label" htmlFor="mobile-number" style={{ fontSize: '0.86rem', fontWeight: 600, color: '#262626', marginBottom: '0.35rem' }}>
|
||||
Mobile number
|
||||
</label>
|
||||
<div className="field has-addons">
|
||||
<p className="control">
|
||||
<span className="button is-static" style={{ backgroundColor: '#FAF8F5', borderColor: '#C8C6BE', color: '#4A4A4A', fontWeight: 600, fontSize: '0.875rem', borderTopLeftRadius: '8px', borderBottomLeftRadius: '8px', height: '42px' }}>
|
||||
+91
|
||||
</span>
|
||||
</p>
|
||||
<p className="control is-expanded">
|
||||
<input
|
||||
id="mobile-number"
|
||||
className="input"
|
||||
type="tel"
|
||||
placeholder="enter mobile number"
|
||||
maxLength={10}
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
style={{ border: '1px solid #C8C6BE', borderTopRightRadius: '8px', borderBottomRightRadius: '8px', height: '42px', fontSize: '0.9rem' }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Full-width Outlined Send OTP Button */}
|
||||
<div className="field mb-4">
|
||||
<label className="label is-size-7 is-uppercase has-text-grey">Primary Phone Number</label>
|
||||
<div className="control has-icons-left">
|
||||
<input
|
||||
type="tel"
|
||||
className="input"
|
||||
placeholder="e.g. 9876543210"
|
||||
value={phone}
|
||||
onChange={(e) => setPhone(e.target.value)}
|
||||
style={{ borderColor: '#e7ded9', borderRadius: '8px' }}
|
||||
/>
|
||||
<span className="icon is-left has-text-grey">
|
||||
<i className="fa-solid fa-phone"></i>
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="button is-fullwidth"
|
||||
onClick={() => alert(`OTP sent to +91 ${phone || '9876543210'}`)}
|
||||
style={{ height: '40px', borderRadius: '8px', fontSize: '14px', fontWeight: 600, color: '#2E2E2E', border: '1px solid #B8B5AC', backgroundColor: 'transparent' }}
|
||||
>
|
||||
Send OTP
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="notification is-light p-3 mb-4" style={{ backgroundColor: '#fdf9f7', border: '1px solid #dacfc9', borderRadius: '8px' }}>
|
||||
<p className="is-size-7 has-text-grey-dark">
|
||||
<i className="fa-solid fa-shield mr-1" style={{ color: 'var(--trad-teal)' }}></i>
|
||||
Two-factor authentication and dispatch OTPs will be delivered to this verified phone.
|
||||
</p>
|
||||
{/* OTP Input Field */}
|
||||
<div className="field mb-4">
|
||||
<span style={{ fontSize: '0.78rem', color: '#6E6D66', marginBottom: '0.35rem', display: 'block' }}>
|
||||
enter the 6-digit code sent to your phone
|
||||
</span>
|
||||
<input
|
||||
id="mobile-otp"
|
||||
className="input has-text-centered"
|
||||
type="text"
|
||||
placeholder="• • • • • •"
|
||||
maxLength={6}
|
||||
style={{ border: '1px solid #C8C6BE', borderRadius: '8px', height: '42px', fontSize: '1rem', letterSpacing: '0.4em', fontWeight: 700 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Terms Checkbox */}
|
||||
<div className="field mb-5">
|
||||
<label className="checkbox" htmlFor="step1-terms" style={{ fontSize: '0.82rem', color: '#555450', display: 'flex', alignItems: 'center', gap: '0.5rem', cursor: 'pointer' }}>
|
||||
<input
|
||||
id="step1-terms"
|
||||
type="checkbox"
|
||||
checked={policyAccepted}
|
||||
onChange={(e) => setPolicyAccepted(e.target.checked)}
|
||||
style={{ width: '16px', height: '16px', accentColor: '#1B2667' }}
|
||||
/>
|
||||
<span>I agree to the Terms & Conditions and Privacy Policy</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Continue Button */}
|
||||
<button
|
||||
type="button"
|
||||
className="button is-fullwidth"
|
||||
onClick={() => handleNext()}
|
||||
aria-label="Save & Continue"
|
||||
style={{ backgroundColor: '#1B2667', color: '#ffffff', fontWeight: 700, fontSize: '0.9375rem', borderRadius: '8px', height: '44px', border: 'none', boxShadow: '0 3px 8px rgba(27, 38, 103, 0.2)' }}
|
||||
>
|
||||
Continue
|
||||
</button>
|
||||
|
||||
<div style={{ textAlign: 'center', marginTop: '1rem' }}>
|
||||
<span style={{ fontSize: '0.82rem', color: '#6E6D66' }}>
|
||||
Already have an account?{' '}
|
||||
<a onClick={() => setCurrentPage('login')} style={{ color: 'var(--trad-maroon)', fontWeight: 600, textDecoration: 'underline', cursor: 'pointer' }}>
|
||||
Login here
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -1063,8 +1118,8 @@ export default function OnboardingWizard() {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{/* Navigation / Action Buttons for steps other than step 2 */}
|
||||
{localStep !== 2 && (
|
||||
{/* Navigation / Action Buttons for steps other than step 1 and 2 */}
|
||||
{localStep !== 1 && localStep !== 2 && (
|
||||
<div className="is-flex is-justify-content-between is-align-items-center mt-6 pt-5" style={{ borderTop: '1px solid #e7ded9' }}>
|
||||
{localStep > 1 ? (
|
||||
<button
|
||||
|
|
|
|||
Loading…
Reference in a new issue