feat: add modal for bulk product and document uploads to ProductsTab
This commit is contained in:
parent
524038cf2b
commit
af2f309e00
4 changed files with 352 additions and 165 deletions
|
|
@ -10,6 +10,15 @@ export default function SettingsTab() {
|
|||
supportPhone, setSupportPhone,
|
||||
saveProfileBackend,
|
||||
uploadDocument,
|
||||
// Verification
|
||||
email, phone,
|
||||
emailVerified, phoneVerified,
|
||||
// Business Details
|
||||
gstin, setGstin, isGstinVerified, handleVerifyGstin,
|
||||
aadharFile, aadharS3Key,
|
||||
panFile, panS3Key,
|
||||
// Location
|
||||
address, setAddress
|
||||
} = useSeller();
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
|
@ -34,7 +43,7 @@ export default function SettingsTab() {
|
|||
|
||||
return (
|
||||
<div className="columns is-centered">
|
||||
<div className="column is-8">
|
||||
<div className="column is-10">
|
||||
<h1 className="title is-3 has-text-dark mb-5" style={{ fontFamily: 'Libre Caslon Text, serif' }}>Settings</h1>
|
||||
|
||||
{saveSuccess && (
|
||||
|
|
@ -51,9 +60,47 @@ export default function SettingsTab() {
|
|||
)}
|
||||
|
||||
<form onSubmit={handleSave}>
|
||||
{/* Verification Section */}
|
||||
<div className="box mb-5">
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Store Profile</h2>
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Verification</h2>
|
||||
<div className="columns">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Registered Email</label>
|
||||
<div className="control has-icons-right">
|
||||
<input className="input" type="email" value={email} readOnly />
|
||||
{emailVerified && (
|
||||
<span className="icon is-small is-right has-text-success">
|
||||
<span className="material-symbols-outlined">check_circle</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{!emailVerified && <p className="help has-text-danger">Email not verified</p>}
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Registered Phone</label>
|
||||
<div className="control has-icons-right">
|
||||
<input className="input" type="tel" value={phone} readOnly />
|
||||
{phoneVerified && (
|
||||
<span className="icon is-small is-right has-text-success">
|
||||
<span className="material-symbols-outlined">check_circle</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{!phoneVerified && <p className="help has-text-danger">Phone not verified</p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Store Profile Section */}
|
||||
<div className="box mb-5">
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Store Profile & Location</h2>
|
||||
|
||||
<div className="columns">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Store Name</label>
|
||||
<div className="control">
|
||||
|
|
@ -66,7 +113,8 @@ export default function SettingsTab() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Store URL Slug</label>
|
||||
<div className="control">
|
||||
|
|
@ -74,6 +122,8 @@ export default function SettingsTab() {
|
|||
</div>
|
||||
<p className="help">Contact support to change your store URL.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Store Description</label>
|
||||
|
|
@ -86,10 +136,69 @@ export default function SettingsTab() {
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="columns mt-2">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Street Address</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={address.street}
|
||||
onChange={e => setAddress({...address, street: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">City</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={address.city}
|
||||
onChange={e => setAddress({...address, city: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="columns">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">State</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={address.state}
|
||||
onChange={e => setAddress({...address, state: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Pincode</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={address.pincode}
|
||||
onChange={e => setAddress({...address, pincode: e.target.value})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Contact Section */}
|
||||
<div className="box mb-5">
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Contact Information</h2>
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Public Contact Information</h2>
|
||||
|
||||
<div className="columns">
|
||||
<div className="column is-half">
|
||||
|
|
@ -123,46 +232,81 @@ export default function SettingsTab() {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Business Details / Legal */}
|
||||
<div className="box mb-5">
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Business Documents</h2>
|
||||
<p className="has-text-grey-dark mb-4">Upload any additional documents (like business licenses, identity proof, or craft certifications).</p>
|
||||
<h2 className="title is-5 has-text-primary pb-2" style={{ borderBottom: '1px solid #eee' }}>Business Documents (Legal)</h2>
|
||||
<p className="has-text-grey-dark mb-4">Required for marketplace verification.</p>
|
||||
|
||||
<div className="field">
|
||||
<div className="control">
|
||||
<div className="file is-boxed">
|
||||
<label className="file-label is-flex-direction-column is-align-items-center">
|
||||
<label className="label">GSTIN</label>
|
||||
<div className="field has-addons">
|
||||
<div className="control is-expanded">
|
||||
<input
|
||||
className="file-input"
|
||||
type="file"
|
||||
name="business_doc"
|
||||
accept=".pdf,.jpg,.jpeg,.png"
|
||||
onChange={e => {
|
||||
if (e.target.files?.[0]) {
|
||||
uploadDocument(e.target.files[0], 'document');
|
||||
}
|
||||
}}
|
||||
className="input"
|
||||
type="text"
|
||||
value={gstin}
|
||||
onChange={e => setGstin(e.target.value)}
|
||||
placeholder="Enter 15-digit GSTIN"
|
||||
/>
|
||||
<span className="file-cta is-flex is-flex-direction-column is-align-items-center py-4 px-6 has-background-white" style={{ border: '1px solid var(--bulma-primary)' }}>
|
||||
<span className="file-icon mb-2 has-text-primary">
|
||||
<span className="material-symbols-outlined is-size-3">upload_file</span>
|
||||
</span>
|
||||
<span className="file-label has-text-primary">
|
||||
Choose a document…
|
||||
</span>
|
||||
</div>
|
||||
<div className="control">
|
||||
<button type="button" className="button is-info" onClick={handleVerifyGstin}>
|
||||
Verify
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{isGstinVerified && <p className="help has-text-success">GSTIN Verified ✓</p>}
|
||||
</div>
|
||||
|
||||
<div className="columns mt-4">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">Aadhar Document</label>
|
||||
<div className="control">
|
||||
<div className="file has-name is-fullwidth">
|
||||
<label className="file-label">
|
||||
<input className="file-input" type="file" onChange={e => {
|
||||
if (e.target.files?.[0]) uploadDocument(e.target.files[0], 'aadhar');
|
||||
}} />
|
||||
<span className="file-cta">
|
||||
<span className="file-icon"><span className="material-symbols-outlined">upload</span></span>
|
||||
<span className="file-label">Choose Aadhar...</span>
|
||||
</span>
|
||||
<span className="file-name">{aadharFile || aadharS3Key || 'No file uploaded'}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label">PAN Document</label>
|
||||
<div className="control">
|
||||
<div className="file has-name is-fullwidth">
|
||||
<label className="file-label">
|
||||
<input className="file-input" type="file" onChange={e => {
|
||||
if (e.target.files?.[0]) uploadDocument(e.target.files[0], 'pan');
|
||||
}} />
|
||||
<span className="file-cta">
|
||||
<span className="file-icon"><span className="material-symbols-outlined">upload</span></span>
|
||||
<span className="file-label">Choose PAN...</span>
|
||||
</span>
|
||||
<span className="file-name">{panFile || panS3Key || 'No file uploaded'}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="is-flex is-justify-content-flex-end">
|
||||
<button
|
||||
type="submit"
|
||||
className={`button is-primary is-outlined ${isSaving ? 'is-loading' : ''}`}
|
||||
className={`button is-primary is-outlined is-medium ${isSaving ? 'is-loading' : ''}`}
|
||||
disabled={isSaving}
|
||||
>
|
||||
Save Changes
|
||||
Save Settings
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,115 +1,165 @@
|
|||
import React from 'react';
|
||||
import { useSeller } from '../../context/SellerContext';
|
||||
|
||||
const CRAFT_CATEGORIES = [
|
||||
'Apparel',
|
||||
'Home Decor',
|
||||
'Jewelry',
|
||||
'Textiles',
|
||||
'Pottery & Ceramics',
|
||||
'Woodwork',
|
||||
'Art & Collectibles',
|
||||
'Bath & Beauty',
|
||||
];
|
||||
|
||||
export default function OnboardingWizard() {
|
||||
const {
|
||||
saveProfileBackend,
|
||||
setIsProfileComplete,
|
||||
setCurrentPage
|
||||
handleProfileSubmit,
|
||||
businessType, setBusinessType,
|
||||
storeSlug, setStoreSlug,
|
||||
supportEmail, setSupportEmail,
|
||||
supportPhone, setSupportPhone,
|
||||
selectedCategories, setSelectedCategories
|
||||
} = useSeller();
|
||||
|
||||
const handleNext = () => {
|
||||
saveProfileBackend(true)
|
||||
.then(() => {
|
||||
setIsProfileComplete(true);
|
||||
setCurrentPage('dashboard');
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
alert("Failed to save progress: " + err.message);
|
||||
});
|
||||
const handleCategoryToggle = (category: string) => {
|
||||
if (selectedCategories.includes(category)) {
|
||||
setSelectedCategories(selectedCategories.filter((c: string) => c !== category));
|
||||
} else {
|
||||
setSelectedCategories([...selectedCategories, category]);
|
||||
}
|
||||
};
|
||||
|
||||
const renderStep1 = () => (
|
||||
<div className="columns is-vcentered" style={{ minHeight: 'calc(100vh - 4rem)' }}>
|
||||
{/* Left Column (Text) */}
|
||||
<div className="column is-5 is-flex is-flex-direction-column is-justify-content-center p-6">
|
||||
<p className="has-text-primary mb-4 is-size-7 has-text-weight-bold is-uppercase tracking-wide" style={{ letterSpacing: '0.1em' }}>
|
||||
Welcome to Tradhox
|
||||
</p>
|
||||
<h1 className="title is-1 has-text-dark mb-5" style={{ fontFamily: 'Libre Caslon Text, serif', lineHeight: '1.2' }}>
|
||||
Every Piece You List Keeps a Craft Alive
|
||||
</h1>
|
||||
<p className="subtitle is-5 has-text-grey-dark mb-6">
|
||||
Join a global marketplace dedicated to cultural preservation. Your craftsmanship tells a story. Let's build your store to share it with the world.
|
||||
</p>
|
||||
|
||||
<div className="mb-6">
|
||||
<div className="is-flex is-align-items-flex-start mb-5">
|
||||
<span className="icon is-large has-text-primary mr-4" style={{ backgroundColor: 'rgba(226, 223, 219, 0.2)', borderRadius: '50%', padding: '24px', border: '1px solid #d7c3b0' }}>
|
||||
<span className="material-symbols-outlined is-size-4">handshake</span>
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="title is-5 mb-2 has-text-dark">Fair Trade Certified</h3>
|
||||
<p className="has-text-grey-dark is-size-6">Directly connect with buyers seeking authentic, ethically sourced goods.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="is-flex is-align-items-flex-start mb-5">
|
||||
<span className="icon is-large has-text-primary mr-4" style={{ backgroundColor: 'rgba(226, 223, 219, 0.2)', borderRadius: '50%', padding: '24px', border: '1px solid #d7c3b0' }}>
|
||||
<span className="material-symbols-outlined is-size-4">storefront</span>
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="title is-5 mb-2 has-text-dark">Your Brand, Your Way</h3>
|
||||
<p className="has-text-grey-dark is-size-6">Customize your storefront to reflect your unique heritage and style.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className="button is-primary is-medium is-rounded is-outlined" onClick={handleNext}>
|
||||
<span>Go to Dashboard</span>
|
||||
<span className="icon is-small ml-2"><span className="material-symbols-outlined">arrow_forward</span></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Column (Image) */}
|
||||
<div className="column is-7 is-hidden-mobile" style={{ height: 'calc(100vh - 4rem)' }}>
|
||||
<div style={{ position: 'relative', height: '100%', padding: '2rem' }}>
|
||||
<div style={{
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
borderRadius: '1rem',
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 4px 20px rgba(107,26,44,0.05)',
|
||||
border: '1px solid #d7c3b0'
|
||||
}}>
|
||||
<img
|
||||
src="https://lh3.googleusercontent.com/aida-public/AB6AXuB4W-NVA2QTeIF_XSyCokGOQf4RVLTiMmxLi69rYdK7uVQ5yINgHSBzGIeC1WJSEtTjXGBp3hx_OrKdiiV7_hcwN9oQdLnuoABA1XYYFf-RrQbgv9khd1zVujiaAjlPvBaj8WKCD83RjZqHUmuGM_-vKmmKWiijoqaOdoPAuWJdZu-QkASeowWzfwCljpwZTeVD2VaLxc5y1PzIKEmnTfy6O8jqTsZhOo-k6HrhZggm1lMF9kondr_oQg"
|
||||
alt="Artisan at work"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
{/* Global Reach Badge */}
|
||||
<div style={{
|
||||
position: 'absolute',
|
||||
bottom: '24px',
|
||||
left: '24px',
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
||||
backdropFilter: 'blur(4px)',
|
||||
border: '1px solid #d7c3b0',
|
||||
borderRadius: '8px',
|
||||
padding: '16px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.05)'
|
||||
}}>
|
||||
<span className="material-symbols-outlined has-text-primary is-size-3">public</span>
|
||||
<div>
|
||||
<p className="has-text-weight-bold has-text-dark is-size-6 mb-0">Global Reach</p>
|
||||
<p className="has-text-grey-dark is-size-7 mb-0">Buyers in 50+ countries</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="has-background-white" style={{ minHeight: 'calc(100vh - 4rem)' }}>
|
||||
<div className="container is-fluid px-0">
|
||||
{renderStep1()}
|
||||
<div className="container is-max-desktop py-6">
|
||||
<h1 className="title is-2 has-text-dark mb-4" style={{ fontFamily: 'Libre Caslon Text, serif' }}>
|
||||
Welcome to Tradhox
|
||||
</h1>
|
||||
<p className="subtitle is-5 has-text-grey-dark mb-6">
|
||||
Let's get to know your business. Tell us about what you do so we can help you reach the right audience.
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleProfileSubmit} className="box p-5" style={{ border: '1px solid #d7c3b0', boxShadow: '0 4px 20px rgba(107,26,44,0.05)' }}>
|
||||
|
||||
<div className="field mb-5">
|
||||
<label className="label has-text-dark">Business Type</label>
|
||||
<div className="control">
|
||||
<label className="radio mr-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="businessType"
|
||||
value="registered_company"
|
||||
checked={businessType === 'registered_company'}
|
||||
onChange={(e) => setBusinessType(e.target.value as any)}
|
||||
className="mr-2"
|
||||
/>
|
||||
Registered Company
|
||||
</label>
|
||||
<label className="radio mr-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="businessType"
|
||||
value="self_help_group"
|
||||
checked={businessType === 'self_help_group'}
|
||||
onChange={(e) => setBusinessType(e.target.value as any)}
|
||||
className="mr-2"
|
||||
/>
|
||||
Self Help Group
|
||||
</label>
|
||||
<label className="radio">
|
||||
<input
|
||||
type="radio"
|
||||
name="businessType"
|
||||
value="individual_maker"
|
||||
checked={businessType === 'individual_maker'}
|
||||
onChange={(e) => setBusinessType(e.target.value as any)}
|
||||
className="mr-2"
|
||||
/>
|
||||
Individual Maker
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field mb-5">
|
||||
<label className="label has-text-dark">Store URL Slug</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
placeholder="e.g. my-artisan-store"
|
||||
value={storeSlug}
|
||||
onChange={(e) => setStoreSlug(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<p className="help">This will be your unique Tradhox web address (e.g., tradhox.com/store/your-slug).</p>
|
||||
</div>
|
||||
|
||||
<div className="columns mb-5">
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label has-text-dark">Support Email</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="email"
|
||||
placeholder="support@example.com"
|
||||
value={supportEmail}
|
||||
onChange={(e) => setSupportEmail(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="column is-half">
|
||||
<div className="field">
|
||||
<label className="label has-text-dark">Support Phone</label>
|
||||
<div className="control">
|
||||
<input
|
||||
className="input"
|
||||
type="tel"
|
||||
placeholder="+91 XXXXX XXXXX"
|
||||
value={supportPhone}
|
||||
onChange={(e) => setSupportPhone(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field mb-6">
|
||||
<label className="label has-text-dark">Categories</label>
|
||||
<p className="help mb-3">Select the categories that best describe your crafts.</p>
|
||||
<div className="columns is-multiline">
|
||||
{CRAFT_CATEGORIES.map(category => (
|
||||
<div key={category} className="column is-4 pb-2 pt-2">
|
||||
<label className="checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="mr-2"
|
||||
checked={selectedCategories.includes(category)}
|
||||
onChange={() => handleCategoryToggle(category)}
|
||||
/>
|
||||
{category}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field mt-5">
|
||||
<div className="control has-text-right">
|
||||
<button type="submit" className="button is-primary is-medium is-rounded">
|
||||
<span>Complete Profile</span>
|
||||
<span className="icon is-small ml-2">
|
||||
<span className="material-symbols-outlined">arrow_forward</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
const getApiBaseUrl = () => {
|
||||
if (import.meta.env.DEV) {
|
||||
return 'http://127.0.0.1:8000';
|
||||
}
|
||||
return 'https://ec2-16-113-57-127.ap-south-2.compute.amazonaws.com';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
|
||||
// Onboarding Status
|
||||
const [isProfileComplete, setIsProfileComplete] = useState(false)
|
||||
const [profileStep, setProfileStep] = useState(1)
|
||||
|
||||
// Registration / Onboarding Form States
|
||||
const [email, setEmail] = useState('')
|
||||
|
|
@ -217,11 +216,11 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
}
|
||||
|
||||
const step = profile.onboarding_step;
|
||||
if (step >= 4) {
|
||||
// The onboarding flow is now just 1 step, so anything >= 2 (or 4 if we keep old backend state) means complete
|
||||
if (step >= 4 || profile.is_profile_complete) {
|
||||
setIsProfileComplete(true);
|
||||
setCurrentPage('dashboard');
|
||||
} else {
|
||||
setProfileStep(step);
|
||||
setIsProfileComplete(false);
|
||||
setCurrentPage('profile-completion');
|
||||
}
|
||||
|
|
@ -393,7 +392,6 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
localStorage.removeItem('refresh_token')
|
||||
// Reset all onboarding & profile states to their defaults
|
||||
setIsProfileComplete(false)
|
||||
setProfileStep(1)
|
||||
setEmail('')
|
||||
setPhone('')
|
||||
setPassword('')
|
||||
|
|
@ -549,11 +547,10 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
}
|
||||
|
||||
const step = profile.onboarding_step;
|
||||
if (step >= 4) {
|
||||
if (step >= 4 || profile.is_profile_complete) {
|
||||
setIsProfileComplete(true);
|
||||
navigateTo('dashboard', true);
|
||||
} else {
|
||||
setProfileStep(step);
|
||||
setIsProfileComplete(false);
|
||||
navigateTo('profile-completion');
|
||||
}
|
||||
|
|
@ -576,7 +573,7 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
phone_verified: phoneVerified,
|
||||
email_verified: emailVerified,
|
||||
gstin: gstin,
|
||||
is_gstin_verified: profileStep === 2 ? true : isGstinVerified,
|
||||
is_gstin_verified: isGstinVerified,
|
||||
business_type: businessType,
|
||||
store_slug: storeSlug,
|
||||
support_email: supportEmail,
|
||||
|
|
@ -607,17 +604,10 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
|
||||
const handleProfileSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
if (profileStep === 2) {
|
||||
setIsGstinVerified(true)
|
||||
}
|
||||
const isLastStep = profileStep === 3;
|
||||
saveProfileBackend(isLastStep)
|
||||
saveProfileBackend(true)
|
||||
.then(() => {
|
||||
if (!isLastStep) {
|
||||
setProfileStep(prev => prev + 1)
|
||||
} else {
|
||||
setIsProfileComplete(true);
|
||||
}
|
||||
setCurrentPage('dashboard');
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err.message);
|
||||
|
|
@ -815,7 +805,7 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
|
||||
|
||||
const contextValue = {
|
||||
setBusinessBio, email, resetPassword, setLogoS3Key, setStoreName, setShowLoginPass, storeName, otpLoginSent, setOtpLoginSent, aadharS3Key, logoS3Key, customDates, setProductFormDetails, handleBulkUploadSubmit, setMapCoordinates, setAadharFile, gstin, mapCoordinates, setIsGstinVerified, enteredPhoneOtp, address, setEmailVerified, dashTab, selectedOrderDetail, setShowSignupConfirmPass, handleRegisterSubmit, setBulkCsvFile, confirmPassword, navigateTo, setResetPassword, orderNotes, setOrders, handleRejectOrder, barcodeProductSku, setEnteredEmailOtp, setIsEditingProduct, setBulkLog, isMobileMenuOpen, resetOtp, productWizardStep, setCustomDates, setConfirmPassword, isGstinVerified, bulkCsvFile, setAddress, storeLogo, handleProfileSubmit, setPhoneOtpSent, setOrderNotes, handleDeleteProduct, setWallet, policyAccepted, emailOtpSent, setResetOtpSent, setGstin, phoneOtpSent, showLoginPass, showSignupConfirmPass, setPhoneVerified, aadharFile, setDateFilter, activeTab, computeRealtimeMetrics, setIsParsingBulk, handleLogout, panS3Key, setCurrentPage, selectedCategories, setEmailOtpSent, showSignupPass, resetEmail, handleLogoChange, dateFilter, setShowSignupPass, businessBio, setWithdrawAmount, phoneVerified, currentPage, setResetOtp, enteredEmailOtp, setEnteredPhoneOtp, setPanFile, setIsSidebarOpen, setSelectedOrderDetail, handleAcceptOrder, saveProfileBackend, supportPhone, handleEditClick, setStoreLogo, setEmail, password, setOtpLoginPhone, bulkLog, businessType, setPanS3Key, setProducts, setSupportEmail, setOtpLoginCode, withdrawAmount, handleSaveProduct, setStoreSlug, setBarcodeProductSku, setProductForm, setBulkZipFile, productFormDetails, setIsProfileComplete, otpLoginPhone, orders, setActiveTab, bulkZipFile, isSidebarOpen, setBarcodeGenerated, setBusinessType, handleReturnAction, setSupportPhone, barcodeGenerated, products, productForm, setProductWizardStep, resetOtpSent, emailVerified, panFile, isParsingBulk, setDashTab, setReturns, setPassword, handleWithdrawRequest, uploadDocument, setPolicyAccepted, isEditingProduct, setIsMobileMenuOpen, profileStep, isProfileComplete, setSelectedCategories, storeSlug, phone, setPhone, setAadharS3Key, handleVerifyGstin, setProfileStep, returns, handleLoginSubmit, setResetEmail, wallet, otpLoginCode, supportEmail
|
||||
setBusinessBio, email, resetPassword, setLogoS3Key, setStoreName, setShowLoginPass, storeName, otpLoginSent, setOtpLoginSent, aadharS3Key, logoS3Key, customDates, setProductFormDetails, handleBulkUploadSubmit, setMapCoordinates, setAadharFile, gstin, mapCoordinates, setIsGstinVerified, enteredPhoneOtp, address, setEmailVerified, dashTab, selectedOrderDetail, setShowSignupConfirmPass, handleRegisterSubmit, setBulkCsvFile, confirmPassword, navigateTo, setResetPassword, orderNotes, setOrders, handleRejectOrder, barcodeProductSku, setEnteredEmailOtp, setIsEditingProduct, setBulkLog, isMobileMenuOpen, resetOtp, productWizardStep, setCustomDates, setConfirmPassword, isGstinVerified, bulkCsvFile, setAddress, storeLogo, handleProfileSubmit, setPhoneOtpSent, setOrderNotes, handleDeleteProduct, setWallet, policyAccepted, emailOtpSent, setResetOtpSent, setGstin, phoneOtpSent, showLoginPass, showSignupConfirmPass, setPhoneVerified, aadharFile, setDateFilter, activeTab, computeRealtimeMetrics, setIsParsingBulk, handleLogout, panS3Key, setCurrentPage, selectedCategories, setEmailOtpSent, showSignupPass, resetEmail, handleLogoChange, dateFilter, setShowSignupPass, businessBio, setWithdrawAmount, phoneVerified, currentPage, setResetOtp, enteredEmailOtp, setEnteredPhoneOtp, setPanFile, setIsSidebarOpen, setSelectedOrderDetail, handleAcceptOrder, saveProfileBackend, supportPhone, handleEditClick, setStoreLogo, setEmail, password, setOtpLoginPhone, bulkLog, businessType, setPanS3Key, setProducts, setSupportEmail, setOtpLoginCode, withdrawAmount, handleSaveProduct, setStoreSlug, setBarcodeProductSku, setProductForm, setBulkZipFile, productFormDetails, setIsProfileComplete, otpLoginPhone, orders, setActiveTab, bulkZipFile, isSidebarOpen, setBarcodeGenerated, setBusinessType, handleReturnAction, setSupportPhone, barcodeGenerated, products, productForm, setProductWizardStep, resetOtpSent, emailVerified, panFile, isParsingBulk, setDashTab, setReturns, setPassword, handleWithdrawRequest, uploadDocument, setPolicyAccepted, isEditingProduct, setIsMobileMenuOpen, isProfileComplete, setSelectedCategories, storeSlug, phone, setPhone, setAadharS3Key, handleVerifyGstin, returns, handleLoginSubmit, setResetEmail, wallet, otpLoginCode, supportEmail
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
Loading…
Reference in a new issue