import { useState, useEffect } from 'react' import { CONFIG, apiFetch } from './config' type Page = 'home' | 'about' | 'contact' | 'login' | 'signup' | 'profile-completion' | 'confirmation' | 'dashboard' | 'forgot-password' | 'login-otp' | 'welcome-tour' type DashboardTab = 'overview' | 'products' | 'orders' | 'returns' | 'wallet' | 'settings' | 'barcode-generator' type DateFilter = 'year' | 'week' | 'day' | 'custom' interface Product { id: string title: string category: string price: number stock: number sku: string image: string } interface Order { id: string date: string item: string quantity: number customer: string total: number status: 'Ready to Ship test' | 'Ready to Ship' | 'Shipped' | 'Delivered' | 'Cancelled' | 'Pending Acceptance' | 'Rejected' carrier: string tracking: string eta: string } interface ReturnRequest { id: string orderId: string customer: string item: string reason: string status: 'Pending Approval' | 'Approved' | 'Rejected' | 'In Transit' image: string returningTracking: string } export default function App() { const [currentPage, setCurrentPage] = useState('home') const [activeTab, setActiveTab] = useState<'login' | 'register'>('login') // Onboarding Status const [isProfileComplete, setIsProfileComplete] = useState(false) const [profileStep, setProfileStep] = useState(1) // Registration / Onboarding Form States const [email, setEmail] = useState('') const [phone, setPhone] = useState('') const [password, setPassword] = useState('') // Step 1: Verification const [phoneVerified, setPhoneVerified] = useState(false) const [emailVerified, setEmailVerified] = useState(false) const [phoneOtpSent, setPhoneOtpSent] = useState(false) const [emailOtpSent, setEmailOtpSent] = useState(false) const [enteredPhoneOtp, setEnteredPhoneOtp] = useState('') const [enteredEmailOtp, setEnteredEmailOtp] = useState('') // Step 2: Business details (moved GSTIN here) const [gstin, setGstin] = useState('29AAAAA1111A1Z1') const [isGstinVerified, setIsGstinVerified] = useState(false) const [aadharFile, setAadharFile] = useState(null) const [panFile, setPanFile] = useState(null) const [aadharS3Key, setAadharS3Key] = useState(null) const [panS3Key, setPanS3Key] = useState(null) // Step 3: Store and Location details const [storeName, setStoreName] = useState('My Artisan Handloom') const [storeLogo, setStoreLogo] = useState(null) const [logoS3Key, setLogoS3Key] = useState(null) const [businessBio, setBusinessBio] = useState('Traditional weaving and local sustainable designs.') const [address, setAddress] = useState({ street: '123 Handloom Lane', city: 'Textile Town', state: 'Karnataka', pincode: '560001' }) const [mapCoordinates, setMapCoordinates] = useState({ lat: 12.9716, lng: 77.5946 }) // --- Password visibility, confirm password and policy states --- const [showLoginPass, setShowLoginPass] = useState(false) const [showSignupPass, setShowSignupPass] = useState(false) const [showSignupConfirmPass, setShowSignupConfirmPass] = useState(false) const [confirmPassword, setConfirmPassword] = useState('') const [policyAccepted, setPolicyAccepted] = useState(false) // --- Password Reset Page States --- const [resetEmail, setResetEmail] = useState('') const [resetOtpSent, setResetOtpSent] = useState(false) const [resetOtp, setResetOtp] = useState('') const [resetPassword, setResetPassword] = useState('') // --- OTP Login States --- const [otpLoginPhone, setOtpLoginPhone] = useState('') const [otpLoginSent, setOtpLoginSent] = useState(false) const [otpLoginCode, setOtpLoginCode] = useState('') // --- Barcode Generator States --- const [barcodeProductSku, setBarcodeProductSku] = useState('') const [barcodeGenerated, setBarcodeGenerated] = useState(false) // --- Active Dashboard States --- const [dashTab, setDashTab] = useState('overview') const [dateFilter, setDateFilter] = useState('year') const [customDates, setCustomDates] = useState({ start: '2026-06-01', end: '2026-06-15' }) // Lists const [products, setProducts] = useState([]) const [orders, setOrders] = useState([]) const [returns, setReturns] = useState([]) // Forms & Editing const [productForm, setProductForm] = useState({ id: '', title: '', category: 'Apparel', price: 0, stock: 0, sku: '', image: 'https://images.unsplash.com/photo-1544022613-e87ca75a784a?auto=format&fit=crop&q=80&w=100' }) const [isEditingProduct, setIsEditingProduct] = useState(false) // Payout outstanding states const [wallet, setWallet] = useState({ outstanding: 850.00, withdrawn: 1250.00, history: [ { id: 'TX-9031', date: '2026-08-01', amount: 500.00, status: 'Transferred' }, { id: 'TX-9022', date: '2026-07-15', amount: 750.00, status: 'Transferred' } ] }) const [withdrawAmount, setWithdrawAmount] = useState('') // Load data from backend on mount or when profile is complete / logged in useEffect(() => { const token = localStorage.getItem('access_token'); if (token) { apiFetch(`${CONFIG.apiBaseUrl}/api/profile/`) .then(res => { if (res.ok) return res.json(); throw new Error('Session expired'); }) .then(user => { if (user && user.profile) { const profile = user.profile; setPhone(profile.phone || ''); setPhoneVerified(profile.phone_verified || false); setEmail(user.email || ''); setEmailVerified(profile.email_verified || false); setGstin(profile.gstin || '29AAAAA1111A1Z1'); setIsGstinVerified(profile.is_gstin_verified || false); setAadharFile(profile.aadhar_file || null); setPanFile(profile.pan_file || null); setAadharS3Key(profile.aadhar_s3_key || null); setPanS3Key(profile.pan_s3_key || null); setStoreName(profile.store_name || 'My Artisan Handloom'); setStoreLogo(profile.store_logo || null); setLogoS3Key(profile.logo_s3_key || null); setBusinessBio(profile.business_bio || 'Traditional weaving and local sustainable designs.'); setAddress({ street: profile.street || '123 Handloom Lane', city: profile.city || 'Textile Town', state: profile.state || 'Karnataka', pincode: profile.pincode || '560001' }); if (profile.latitude && profile.longitude) { setMapCoordinates({ lat: Number(profile.latitude), lng: Number(profile.longitude) }); } const step = profile.onboarding_step; if (step >= 4) { setIsProfileComplete(true); setCurrentPage('dashboard'); } else { setProfileStep(step); setIsProfileComplete(false); setCurrentPage('profile-completion'); } } }) .catch(err => { console.error('Session restore failed:', err); localStorage.removeItem('access_token'); }); } }, []); useEffect(() => { if (isProfileComplete || currentPage === 'dashboard') { // Fetch Products apiFetch(`${CONFIG.apiBaseUrl}/api/products/`) .then(res => res.json()) .then(data => { if (Array.isArray(data)) setProducts(data); else if (data && Array.isArray(data.results)) setProducts(data.results); }) .catch(err => console.error('Error fetching products:', err)); // Fetch Orders apiFetch(`${CONFIG.apiBaseUrl}/api/orders/`) .then(res => res.json()) .then(data => { if (Array.isArray(data)) setOrders(data); else if (data && Array.isArray(data.results)) setOrders(data.results); }) .catch(err => console.error('Error fetching orders:', err)); // Fetch Returns apiFetch(`${CONFIG.apiBaseUrl}/api/returns/`) .then(res => res.json()) .then(data => { if (Array.isArray(data)) setReturns(data); else if (data && Array.isArray(data.results)) setReturns(data.results); }) .catch(err => console.error('Error fetching returns:', err)); // Fetch Wallet apiFetch(`${CONFIG.apiBaseUrl}/api/wallet/`) .then(res => res.json()) .then(data => { if (data) setWallet(data); }) .catch(err => console.error('Error fetching wallet:', err)); } }, [isProfileComplete, currentPage]); const uploadDocument = async (file: File, fileType: string) => { try { const response = await apiFetch(`${CONFIG.apiBaseUrl}/api/profile/presigned-url/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ file_type: fileType, content_type: file.type }) }); if (!response.ok) throw new Error('Failed to get presigned URL'); const data = await response.json(); // Simulate file upload PUT to mock presigned_url await fetch(data.presigned_url, { method: 'PUT', body: file, headers: { 'Content-Type': file.type } }).catch(err => console.log('Mock S3 upload:', err)); return data.s3_key; } catch (err) { console.error(err); return `suppliers/default/${fileType}.jpg`; } }; const handleAcceptOrder = (id: string) => { apiFetch(`${CONFIG.apiBaseUrl}/api/orders/${id}/accept/`, { method: 'POST' }) .then(res => res.json()) .then(updatedOrder => { setOrders(orders.map(o => o.id === updatedOrder.id ? updatedOrder : o)) alert(`Order accepted successfully!`) }) .catch(err => console.error(err)) } const handleRejectOrder = (id: string) => { apiFetch(`${CONFIG.apiBaseUrl}/api/orders/${id}/reject/`, { method: 'POST' }) .then(res => res.json()) .then(updatedOrder => { setOrders(orders.map(o => o.id === updatedOrder.id ? updatedOrder : o)) alert(`Order rejected.`) }) .catch(err => console.error(err)) } // Bulk Upload const [bulkLog, setBulkLog] = useState([]) const [isParsingBulk, setIsParsingBulk] = useState(false) const [bulkCsvFile, setBulkCsvFile] = useState(null) const [bulkZipFile, setBulkZipFile] = useState(null) // GSTIN verification simulator const handleVerifyGstin = () => { if (!gstin.trim() || gstin.length !== 15) { alert('Invalid GSTIN length. Must be 15 chars.'); return; } apiFetch(`${CONFIG.apiBaseUrl}/api/profile/submit-gstin/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ gstin }) }) .then(res => { if (!res.ok) throw new Error('Failed to verify GSTIN.'); return res.json(); }) .then(data => { if (data.verified) { setIsGstinVerified(true); } }) .catch(err => { alert(err.message); }); } // Handle Logo Upload simulation const handleLogoChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0] if (file) { const reader = new FileReader() reader.onloadend = () => { setStoreLogo(reader.result as string) } reader.readAsDataURL(file) const s3Key = await uploadDocument(file, 'logo'); setLogoS3Key(s3Key); } } // Route/Navigation Guard: If profile is not complete, redirect to profile-completion const navigateTo = (page: Page, forceComplete: boolean = false) => { const publicPages: Page[] = ['home', 'about', 'contact', 'login', 'signup', 'forgot-password', 'login-otp'] const complete = isProfileComplete || forceComplete if (!complete && !publicPages.includes(page) && page !== 'profile-completion') { alert('Access Denied: Please complete your supplier profile first!') setCurrentPage('profile-completion') } else { setCurrentPage(page) } window.scrollTo({ top: 0, behavior: 'smooth' }) } const handleLogout = () => { apiFetch(`${CONFIG.apiBaseUrl}/api/auth/logout/`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }) .catch(err => console.error('Error logging out:', err)) .finally(() => { localStorage.removeItem('access_token') // Reset all onboarding & profile states to their defaults setIsProfileComplete(false) setProfileStep(1) setEmail('') setPhone('') setPassword('') setConfirmPassword('') setPolicyAccepted(false) setPhoneVerified(false) setEmailVerified(false) setPhoneOtpSent(false) setEmailOtpSent(false) setEnteredPhoneOtp('') setEnteredEmailOtp('') setGstin('29AAAAA1111A1Z1') setIsGstinVerified(false) setAadharFile(null) setPanFile(null) setAadharS3Key(null) setPanS3Key(null) setStoreName('My Artisan Handloom') setStoreLogo(null) setLogoS3Key(null) setBusinessBio('Traditional weaving and local sustainable designs.') setAddress({ street: '123 Handloom Lane', city: 'Textile Town', state: 'Karnataka', pincode: '560001' }) setMapCoordinates({ lat: 12.9716, lng: 77.5946 }) navigateTo('home', true) }) } const handleRegisterSubmit = (e: React.FormEvent) => { e.preventDefault() // Email Validation const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { alert('Please enter a valid email address.'); return; } // Phone Validation const phoneRegex = /^[6-9]\d{9}$/; if (!phoneRegex.test(phone)) { alert('Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9.'); return; } // Password Validation if (password.length < 8) { alert('Password must be at least 8 characters long.'); return; } if (password !== confirmPassword) { alert('Passwords do not match.'); return; } // Policy Validation if (!policyAccepted) { alert('You must accept the Terms of Service and Privacy Policy.'); return; } apiFetch(`${CONFIG.apiBaseUrl}/api/auth/register/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: email, email: email, phone: phone, password: password, confirm_password: confirmPassword, policy_accepted: policyAccepted }) }) .then(res => { if (!res.ok) throw new Error('Registration failed. Username/email might already be taken.'); return res.json(); }) .then(() => { // Auto login after signup apiFetch(`${CONFIG.apiBaseUrl}/api/auth/login/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: email, password: password }) }) .then(res => { if (!res.ok) throw new Error('Auto-login failed.'); return res.json(); }) .then(data => { localStorage.setItem('access_token', data.access_token); navigateTo('profile-completion') }) }) .catch(err => { alert(err.message); }); } const handleLoginSubmit = (e: React.FormEvent) => { e.preventDefault() if (!email.trim()) { alert('Please enter your email or phone number.'); return; } apiFetch(`${CONFIG.apiBaseUrl}/api/auth/login/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: email, password: password }) }) .then(res => { if (!res.ok) throw new Error('Invalid credentials.'); return res.json(); }) .then(data => { localStorage.setItem('access_token', data.access_token); if (data.user && data.user.profile) { const profile = data.user.profile; setPhone(profile.phone || ''); setPhoneVerified(profile.phone_verified || false); setEmail(data.user.email || ''); setEmailVerified(profile.email_verified || false); setGstin(profile.gstin || '29AAAAA1111A1Z1'); setIsGstinVerified(profile.is_gstin_verified || false); setAadharFile(profile.aadhar_file || null); setPanFile(profile.pan_file || null); setAadharS3Key(profile.aadhar_s3_key || null); setPanS3Key(profile.pan_s3_key || null); setStoreName(profile.store_name || 'My Artisan Handloom'); setStoreLogo(profile.store_logo || null); setLogoS3Key(profile.logo_s3_key || null); setBusinessBio(profile.business_bio || 'Traditional weaving and local sustainable designs.'); setAddress({ street: profile.street || '123 Handloom Lane', city: profile.city || 'Textile Town', state: profile.state || 'Karnataka', pincode: profile.pincode || '560001' }); if (profile.latitude && profile.longitude) { setMapCoordinates({ lat: Number(profile.latitude), lng: Number(profile.longitude) }); } const step = profile.onboarding_step; if (step >= 4) { setIsProfileComplete(true); navigateTo('dashboard', true); } else { setProfileStep(step); setIsProfileComplete(false); navigateTo('profile-completion'); } } else { setIsProfileComplete(false); navigateTo('profile-completion'); } }) .catch(err => { alert(err.message); }); } const saveProfileBackend = (isComplete: boolean) => { return apiFetch(`${CONFIG.apiBaseUrl}/api/profile/`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone: phone, phone_verified: phoneVerified, email_verified: emailVerified, gstin: gstin, is_gstin_verified: isGstinVerified, aadhar_file: aadharFile, pan_file: panFile, aadhar_s3_key: aadharS3Key || 'suppliers/default/aadhar.pdf', pan_s3_key: panS3Key || 'suppliers/default/pan.pdf', store_name: storeName, store_logo: storeLogo || 'https://images.unsplash.com/photo-1513519245088-0e12902e5a38?auto=format&fit=crop&q=80&w=800', logo_s3_key: logoS3Key || 'suppliers/default/logo.jpg', business_bio: businessBio, street: address.street, city: address.city, state: address.state, pincode: address.pincode, latitude: mapCoordinates.lat, longitude: mapCoordinates.lng, is_profile_complete: isComplete }) }) .then(res => { if (!res.ok) throw new Error('Failed to update profile.'); return res.json(); }); }; const handleProfileSubmit = (e: React.FormEvent) => { e.preventDefault() if (profileStep === 2) { setIsGstinVerified(true) } const isLastStep = profileStep === 3; saveProfileBackend(isLastStep) .then(() => { if (!isLastStep) { setProfileStep(prev => prev + 1) } else { setIsProfileComplete(true) navigateTo('welcome-tour', true) } }) .catch(err => { alert(err.message); }); } // --- Dashboard Logic Actions --- // Product creation/modification const handleSaveProduct = (e: React.FormEvent) => { e.preventDefault() const url = isEditingProduct ? `${CONFIG.apiBaseUrl}/api/products/${productForm.id}/` : `${CONFIG.apiBaseUrl}/api/products/` const method = isEditingProduct ? 'PUT' : 'POST' apiFetch(url, { method: method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: productForm.title, category: productForm.category, price: String(productForm.price), stock: Number(productForm.stock), sku: productForm.sku || `PROD-${Date.now().toString().slice(-6)}`, image: productForm.image }) }) .then(res => res.json()) .then(() => { // Refresh products from backend apiFetch(`${CONFIG.apiBaseUrl}/api/products/`) .then(r => r.json()) .then(prods => { if (Array.isArray(prods)) setProducts(prods); else if (prods && Array.isArray(prods.results)) setProducts(prods.results); }) setIsEditingProduct(false) alert(isEditingProduct ? 'Product modified successfully!' : 'Product uploaded successfully!') }) .catch(err => console.error(err)) // reset form setProductForm({ id: '', title: '', category: 'Apparel', price: 0, stock: 0, sku: '', image: 'https://images.unsplash.com/photo-1544022613-e87ca75a784a?auto=format&fit=crop&q=80&w=100' }) } const handleEditClick = (p: Product) => { setProductForm(p) setIsEditingProduct(true) } const handleDeleteProduct = (id: string) => { if (confirm('Are you sure you want to delete this listing?')) { apiFetch(`${CONFIG.apiBaseUrl}/api/products/${id}/`, { method: 'DELETE' }) .then(() => { setProducts(products.filter(p => p.id !== id)) }) .catch(err => console.error(err)) } } const handleBulkUploadSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!bulkCsvFile) { alert("Please select a CSV file to upload."); return; } setIsParsingBulk(true); setBulkLog(['Uploading files to server...', 'Parsing CSV data and extracting ZIP images...']); const formData = new FormData(); formData.append('csv_file', bulkCsvFile); if (bulkZipFile) { formData.append('zip_file', bulkZipFile); } try { const token = localStorage.getItem('access_token'); const response = await fetch(`${CONFIG.apiBaseUrl}/api/products/bulk-upload/`, { method: 'POST', headers: { ...(token ? { 'Authorization': `Bearer ${token}` } : {}) }, body: formData }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Failed to complete bulk upload.'); } setBulkLog([ 'CSV file parsed successfully.', `Extracted and matched images for SKUs from ZIP file.`, `Successfully added ${data.products?.length || 0} product listings!`, ]); // Refresh product list const prodRes = await apiFetch(`${CONFIG.apiBaseUrl}/api/products/`); const prods = await prodRes.json(); if (Array.isArray(prods)) { setProducts(prods); } else if (prods && Array.isArray(prods.results)) { setProducts(prods.results); } setBulkCsvFile(null); setBulkZipFile(null); } catch (err: any) { setBulkLog(prev => [...prev, `Error: ${err.message}`]); } finally { setIsParsingBulk(false); } }; // Wallet outstanding requests const handleWithdrawRequest = (e: React.FormEvent) => { e.preventDefault() const amount = Number(withdrawAmount) if (isNaN(amount) || amount <= 0) { alert('Please enter a valid amount') return } apiFetch(`${CONFIG.apiBaseUrl}/api/wallet/withdraw/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ amount: String(amount) }) }) .then(res => { if (!res.ok) throw new Error('Insufficient funds or invalid request'); return res.json(); }) .then(updatedWallet => { setWallet(updatedWallet) setWithdrawAmount('') alert(`Payout of $${amount} successfully transferred!`) }) .catch(err => { alert(err.message) }) } // Returns actions const handleReturnAction = (id: string, action: 'Approved' | 'Rejected') => { apiFetch(`${CONFIG.apiBaseUrl}/api/returns/${id}/action/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: action }) }) .then(res => res.json()) .then(updatedReturn => { setReturns(returns.map(ret => ret.id === id ? updatedReturn : ret)) alert(`Return request ${action.toLowerCase()}!`) }) .catch(err => console.error(err)) } // Compute realtime metrics based on state loaded from backend const computeRealtimeMetrics = () => { const totalSales = orders .filter(o => o.status !== 'Cancelled' && o.status !== 'Rejected') .reduce((sum, o) => sum + Number(o.total), 0) const totalEarned = Number(wallet.outstanding) + Number(wallet.withdrawn) const totalStock = products.reduce((sum, p) => sum + Number(p.stock), 0) const totalReturns = returns.length const isLoggedIn = currentPage === 'dashboard' || currentPage === 'profile-completion' || currentPage === 'welcome-tour' || isProfileComplete if (isLoggedIn) { return { totalSales, totalEarned, stockDetails: totalStock, returnedItems: totalReturns, chartValues: orders.length > 0 ? orders.map(o => Number(o.total)) : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } } return { totalSales: 45280.00, totalEarned: 38488.00, stockDetails: 342, returnedItems: 12, chartValues: CONFIG.dashboardData.filters[dateFilter]?.chartValues || [30, 45, 35, 60, 50, 75, 65, 80, 70, 95, 90, 110] } } const selectedMetrics = computeRealtimeMetrics() return ( <> {/* Dynamic Header */}
navigateTo('home')}>
{CONFIG.logoLetter}
{CONFIG.companyName}
{currentPage === 'dashboard' ? ( ) : ( <> )}
{/* Main Content Area */} {currentPage !== 'dashboard' ? (
{/* HOMEPAGE VIEW */} {currentPage === 'home' && (

{CONFIG.hero.title.split('. ')[0]}.
{CONFIG.hero.title.split('. ')[1]}

{CONFIG.hero.subtitle}

Artisans Crafting
{CONFIG.features.map((feature, i) => (
{feature.icon}

{feature.title}

{feature.description}

))}
Featured Artisan

Featured Artisan

{CONFIG.featuredArtisan.quote}

- {CONFIG.featuredArtisan.name} ({CONFIG.featuredArtisan.role})

)} {/* ABOUT US VIEW */} {currentPage === 'about' && (

{CONFIG.about.missionTitle}

{CONFIG.about.missionDescription}

Meet Our Leaders

{CONFIG.about.team.map((member, i) => (
{member.name}

{member.name}

{member.role}

))}
)} {/* CONTACT US VIEW */} {currentPage === 'contact' && (

Get in Touch

{ e.preventDefault(); alert('Thank you for contacting us! We will get back to you shortly.'); navigateTo('home'); }}>

Address

') }}>

Support Email

{CONFIG.supportEmail}

Partner Hotline

{CONFIG.supportPhone}

📍 Interactive Map Preview
)} {/* AUTHENTICATION VIEW (LOGIN & SIGNUP) */} {(currentPage === 'login' || currentPage === 'signup') && (
{activeTab === 'login' ? (

Supplier Portal Access

setEmail(e.target.value)} required />
setPassword(e.target.value)} required style={{ paddingRight: '45px' }} />
) : (

Create Your Supplier Account

setEmail(e.target.value)} required />
setPhone(e.target.value)} required />
setPassword(e.target.value)} required style={{ paddingRight: '45px' }} />
setConfirmPassword(e.target.value)} required style={{ paddingRight: '45px' }} />
setPolicyAccepted(e.target.checked)} required />
)}
)} {/* FORGOT PASSWORD PAGE */} {currentPage === 'forgot-password' && (

Reset Your Password

Enter your registered business email or mobile number to receive a secure password reset link / OTP.

{!resetOtpSent ? (
{ e.preventDefault(); if (resetEmail.trim()) { setResetOtpSent(true); alert('Simulated Reset Code (123456) sent successfully!'); } }}>
setResetEmail(e.target.value)} required />
) : (
{ e.preventDefault(); if (resetOtp === '123456') { setPassword(resetPassword); alert('Password updated successfully! Please login with your new password.'); setResetOtpSent(false); setResetEmail(''); setResetOtp(''); setResetPassword(''); navigateTo('login'); } else { alert('Invalid OTP. Please enter 123456'); } }}>
setResetOtp(e.target.value)} required />
setResetPassword(e.target.value)} required />
)}
)} {/* LOGIN WITH OTP PAGE */} {currentPage === 'login-otp' && (

Login with OTP

Access your seller portal using a temporary verification code sent to your mobile.

{!otpLoginSent ? (
{ e.preventDefault(); if (otpLoginPhone.trim()) { setOtpLoginSent(true); alert('Simulated Login Code (123456) sent to mobile!'); } }}>
setOtpLoginPhone(e.target.value)} required />
) : (
{ e.preventDefault(); if (otpLoginCode === '123456') { setOtpLoginSent(false); setOtpLoginPhone(''); setOtpLoginCode(''); if (!isProfileComplete) { navigateTo('profile-completion'); } else { navigateTo('dashboard'); } } else { alert('Invalid OTP. Please enter 123456'); } }}>
setOtpLoginCode(e.target.value)} required />
)}
)} {currentPage === 'profile-completion' && (
Step {profileStep} of 3: { profileStep === 1 ? 'Contact Verification' : profileStep === 2 ? 'Tax & Identity Verification' : 'Store & Pickup Location' }

Complete Your Supplier Profile

{profileStep === 1 && (

Step 1: Verify Contacts

{/* Phone/WhatsApp Verification */}
setPhone(e.target.value)} disabled={phoneVerified} />
{phoneOtpSent && !phoneVerified && (
setEnteredPhoneOtp(e.target.value)} style={{ maxWidth: '150px' }} />
)} {phoneVerified && (
✓ Mobile & WhatsApp Verified
)}
{/* Email Verification */}
setEmail(e.target.value)} disabled={emailVerified} />
{emailOtpSent && !emailVerified && (
setEnteredEmailOtp(e.target.value)} style={{ maxWidth: '150px' }} />
)} {emailVerified && (
✓ Email Verified
)}
)} {profileStep === 2 && (

Step 2: GSTIN, PAN & Aadhaar

{/* GSTIN verification */}
setGstin(e.target.value)} required />
{isGstinVerified && (

verification will be completed within next 24 hrs

)}
{/* Aadhaar Upload */}
{ if (e.target.files?.[0]) { const file = e.target.files[0]; setAadharFile(file.name); alert(`Aadhaar card selected: ${file.name}. Uploading...`); const s3Key = await uploadDocument(file, 'aadhar'); setAadharS3Key(s3Key); alert(`Aadhaar card uploaded successfully!`); } }} style={{ display: 'none' }} /> {aadharFile ? `Selected: ${aadharFile}` : 'No file uploaded yet'}
{/* PAN Upload */}
{ if (e.target.files?.[0]) { const file = e.target.files[0]; setPanFile(file.name); alert(`PAN card selected: ${file.name}. Uploading...`); const s3Key = await uploadDocument(file, 'pan'); setPanS3Key(s3Key); alert(`PAN card uploaded successfully!`); } }} style={{ display: 'none' }} /> {panFile ? `Selected: ${panFile}` : 'No file uploaded yet'}
)} {profileStep === 3 && (

Step 3: Store Details & Location Map

setStoreName(e.target.value)} required />
{/* Interactive Location Map Picker */}
{ const rect = e.currentTarget.getBoundingClientRect(); const x = Math.round(e.clientX - rect.left); const y = Math.round(e.clientY - rect.top); setMapCoordinates({ lat: Number((12.9 + y * 0.001).toFixed(4)), lng: Number((77.5 + x * 0.001).toFixed(4)) }); setAddress(prev => ({ ...prev, street: `Plot ${x}, Sector ${Math.round(y/10)}, Handicraft Park` })); alert(`Location Pinned: Lat: ${(12.9 + y * 0.001).toFixed(4)}, Lng: ${(77.5 + x * 0.001).toFixed(4)}`); }} > {/* Map Marker Pin */}
📍
Coordinates: Lat {mapCoordinates.lat}, Lng {mapCoordinates.lng} (Click map to change pin)
Click anywhere on the map grid to pin location
setAddress({ ...address, street: e.target.value })} required />
setAddress({ ...address, city: e.target.value })} required />
setAddress({ ...address, pincode: e.target.value })} required />
)}
)} {/* ONBOARDING CONFIRMATION / REVIEW STATUS VIEW (Step 3 of 3) */} {currentPage === 'confirmation' && (
Step 3 of 3: Verification
🎉

Welcome to {CONFIG.companyName}!

Your registration is under review. We will verify your GSTIN credentials and activate your dashboard access within 24-48 hours.

Total Sales
$0.00
Active Orders
0
Balance
$0.00
)} {/* WELCOME PAGE & SETUP TOUR FOR NEW SELLERS */} {currentPage === 'welcome-tour' && ( navigateTo('dashboard')} /> )}
) : ( /* --- FULL SERVICE SUPPLIER ACTIVE DASHBOARD PAGE --- */
{/* Sidebar */} {/* Main Dashboard Space */}
{/* OVERVIEW PANEL */} {dashTab === 'overview' && (

Performance Analytics

{dateFilter === 'custom' && (
setCustomDates({ ...customDates, start: e.target.value })} />
setCustomDates({ ...customDates, end: e.target.value })} />
)}
Total Sales Volume
${selectedMetrics.totalSales.toFixed(2)}
Total Net Earned
${selectedMetrics.totalEarned.toFixed(2)}
Available Stock
{selectedMetrics.stockDetails} units
Returned Items
{selectedMetrics.returnedItems} requests

Revenue Trajectory

Filtered by {dateFilter} metrics
{selectedMetrics.chartValues.map((val, idx) => (
))}
)} {/* PRODUCTS TAB */} {dashTab === 'products' && (

Product Listings & Upload

{/* Products Grid list */}

Active Inventory ({products.length})

{products.map(p => ( ))}
Product SKU Category Price Stock Actions
{p.title} {p.title} {p.sku} {p.category} ${Number(p.price).toFixed(2)} {p.stock} pcs
{/* Bulk tools */}

Bulk Operations

To upload products in bulk, use our standard Excel/CSV template. Review the sample format below, download the template, populate your inventory rows, and upload.

{/* Sample Template Table */}
Title * SKU * Category * Price ($) * Stock * Description
Silk Banarasi Saree SAR-BAN-101 Apparel 120.00 15 Pure handloom zardozi border
Wooden Carved Ganesha 雕-GAN-302 Home Decor 85.00 5 Premium teak wood hand carved
setBulkCsvFile(e.target.files?.[0] || null)} style={{ display: 'block', marginTop: '0.5rem', width: '100%', padding: '0.5rem', border: '1px solid var(--border)', borderRadius: '6px' }} /> {bulkCsvFile && ✓ Selected: {bulkCsvFile.name}}
setBulkZipFile(e.target.files?.[0] || null)} style={{ display: 'block', marginTop: '0.5rem', width: '100%', padding: '0.5rem', border: '1px solid var(--border)', borderRadius: '6px' }} /> {bulkZipFile && ✓ Selected: {bulkZipFile.name}}
{bulkLog.length > 0 && (

Import log:

{bulkLog.map((log, i) =>
{log}
)}
)}
{/* Add/Edit Form */}

{isEditingProduct ? 'Modify Product Listing' : 'Upload New Product'}

setProductForm({ ...productForm, title: e.target.value })} required />
setProductForm({ ...productForm, sku: e.target.value })} />
setProductForm({ ...productForm, price: Number(e.target.value) })} required />
setProductForm({ ...productForm, stock: Number(e.target.value) })} required />
{isEditingProduct && ( )}
)} {/* ORDERS & TRACKING TAB */} {dashTab === 'orders' && (

Active Orders & Payout status

{orders.map(o => ( ))}
Order ID Order Date Item Details Qty Customer Total Status Logistics & Carrier Details / Actions
{o.id} {o.date} {o.item} {o.quantity} {o.customer} ${Number(o.total).toFixed(2)} {o.status} {o.status === 'Pending Acceptance' ? (
) : (
Carrier: {o.carrier}
Tracking: {o.tracking}
ETA / Delivery: {o.eta}
)}
)} {dashTab === 'barcode-generator' && (

Customer Address Printer

Select an accepted order to view and print the shipping address label for the customer.

Print Configuration

{barcodeGenerated && barcodeProductSku ? ( (() => { const selectedOrder = orders.find(o => String(o.id) === String(barcodeProductSku)); return selectedOrder ? (

Shipping Label Preview

GLOBAL ARTISANS POSTAGE PAID
FROM:
{storeName || 'Artisan Partner Shop'}
{address.street || '123 Handloom Lane'}
{address.city || 'Textile Town'}, {address.state || 'Karnataka'} - {address.pincode || '560001'}
TO (SHIP TO):
{selectedOrder.customer}
12 Weaver Lane, Kanchipuram
Tamil Nadu, India - 631502
ORDER ID: {selectedOrder.id} QTY: {selectedOrder.quantity}
ITEM: {selectedOrder.item}
) : null; })() ) : (
🖨️

Select an accepted order configuration to render the visual shipping label preview.

)}
)} {/* RETURNS MANAGEMENT TAB */} {dashTab === 'returns' && (

Returns & Quality Assurance Center

Items Requested for Return

{returns.filter(r => r.status === 'Pending Approval').map(r => ( ))}
Return ID Original Order ID Item Info Customer Reason Given Status Actions
{r.id} {r.orderId} {r.item} {r.item} {r.customer} "{r.reason}" {r.status}

In-Transit Return Tracking

{returns.filter(r => r.status !== 'Pending Approval').map(r => ( ))}
Return ID Item Customer Return Tracking Number Progress Status
{r.id} {r.item} {r.customer} {r.returningTracking} {r.status}
)} {/* WALLET & PAYOUTS TAB */} {dashTab === 'wallet' && (

Wallet & Payout Portal

Outstanding Ready Balance
${Number(wallet.outstanding).toFixed(2)}
Total Payouts Withdrawn
${Number(wallet.withdrawn).toFixed(2)}
{/* Withdrawal form */}

Withdraw Payout Funds

setWithdrawAmount(e.target.value)} required />
{/* Payout History */}

Transaction Payout Logs

{(wallet.history || (wallet as any).transactions || []).map((tx: any) => ( ))}
Transaction ID Transfer Date Amount Status
{tx.id || tx.tx_id} {tx.date} ${Number(tx.amount).toFixed(2)} {tx.status}
)} {/* SETTINGS TAB */} {dashTab === 'settings' && (

Store Configurations

{ e.preventDefault(); alert('Store configurations updated successfully!'); }}>
setStoreName(e.target.value)} required />
{storeLogo ? ( Logo ) : ( 🖼️ )}
setAddress({ ...address, street: e.target.value })} required /> setAddress({ ...address, city: e.target.value })} required />
setAddress({ ...address, state: e.target.value })} required /> setAddress({ ...address, pincode: e.target.value })} required />
setGstin(e.target.value)} disabled />

GSTIN cannot be modified after verification.

)}
)} {/* Footer Section */} ) } function WelcomeTourWizard({ onComplete }: { onComplete: () => void }) { const [tourStep, setTourStep] = useState(1) const steps = [ { title: "Supplier Account Under Review ⏳", description: `Thank you for completing your profile! Your GSTIN, PAN, and Aadhaar card details have been submitted. Our compliance team is verifying your documents. This review is typically completed within the next 24 hours. While we verify your credentials, let's take a quick animated tour to get you familiar with your dashboard!`, icon: "⏳", action: "Start Guided Tour 🎬" }, { title: "📦 Products & Inventory Management", description: "Under the 'Manage Products' tab, you can add new product listings, edit stock values, and perform bulk uploads using our structured Excel template.", icon: "📦", action: "Next: Order Management" }, { title: "🚚 Order Acceptance Control", description: "When customers place orders, they arrive in your queue. You must review and Accept or Reject each order from the 'Orders & Transit' tab before shipping them.", icon: "🚚", action: "Next: Barcode Generation" }, { title: "🏷️ Barcode Identification & Tracking", description: "Track your sales in real-time. Use the 'Barcode Generator' tab to create unique visual barcodes for each product SKU. You can download and print them easily.", icon: "🏷️", action: "Next: Earnings & Wallet" }, { title: "💼 Wallet & Payout Withdrawals", description: "Monitor outstanding payouts and withdraw your earnings directly to your bank account anytime. Keep track of transaction receipts directly inside the Wallet tab.", icon: "💼", action: "Explore Dashboard 🚀" } ] const current = steps[tourStep - 1] return (
{current.icon}

{current.title}

{current.description}

{steps.map((_, idx) => (
))}
{tourStep > 1 ? ( ) : (
)}
) }