diff --git a/cdk/betasupplier-site-stack.ts b/cdk/betasupplier-site-stack.ts
index 5284e30..78c065c 100644
--- a/cdk/betasupplier-site-stack.ts
+++ b/cdk/betasupplier-site-stack.ts
@@ -20,27 +20,19 @@ export class BetaSupplierSiteStack extends cdk.Stack {
encryption: s3.BucketEncryption.S3_MANAGED,
});
- const ec2Origin = new origins.HttpOrigin('api.tipro.in', {
+ const ec2Origin = new origins.HttpOrigin('api.tradhox.com', {
protocolPolicy: cloudfront.OriginProtocolPolicy.HTTP_ONLY,
httpPort: 8080,
});
- // Look up the tipro.in hosted zone
- const zone = route53.HostedZone.fromLookup(this, 'TiproZone', {
- domainName: 'tipro.in',
- });
-
- // Create Route53 A Record for the EC2 API server
- // This allows us to use an IP address indirectly, by mapping api.tipro.in to it.
- new route53.ARecord(this, 'ApiRecord', {
- recordName: 'api.tipro.in',
- target: route53.RecordTarget.fromIpAddresses('16.113.57.127'),
- zone
+ // Look up the tradhox.com hosted zone
+ const zone = route53.HostedZone.fromLookup(this, 'TradhoxZone', {
+ domainName: 'tradhox.com',
});
// Create a certificate in us-east-1 for CloudFront
const certificate = new acm.DnsValidatedCertificate(this, 'SiteCertificate', {
- domainName: 'partners.tipro.in',
+ domainName: 'betapartners.tradhox.com',
hostedZone: zone,
region: 'us-east-1', // CloudFront requires certificates to be in us-east-1
});
@@ -49,7 +41,7 @@ export class BetaSupplierSiteStack extends cdk.Stack {
// origins.S3BucketOrigin.withOriginAccessControl will automatically create an Origin Access Control (OAC)
// and update the S3 bucket policy to allow access only from this CloudFront distribution.
const distribution = new cloudfront.Distribution(this, 'BetaSupplierSiteDistribution', {
- domainNames: ['partners.tipro.in'],
+ domainNames: ['betapartners.tradhox.com'],
certificate: certificate,
defaultRootObject: 'index.html',
defaultBehavior: {
@@ -97,7 +89,7 @@ export class BetaSupplierSiteStack extends cdk.Stack {
// 3. Create Route53 A Record to point to the CloudFront Distribution
new route53.ARecord(this, 'SiteAliasRecord', {
- recordName: 'partners.tipro.in',
+ recordName: 'betapartners.tradhox.com',
target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
zone
});
diff --git a/index.html b/index.html
index 9066c61..ceb357f 100644
--- a/index.html
+++ b/index.html
@@ -8,8 +8,34 @@
-
+
+
+
+
diff --git a/public/images/landing/benefit-1.jpg b/public/images/landing/benefit-1.jpg
new file mode 100644
index 0000000..5e4b52b
Binary files /dev/null and b/public/images/landing/benefit-1.jpg differ
diff --git a/public/images/landing/benefit-10.jpg b/public/images/landing/benefit-10.jpg
new file mode 100644
index 0000000..c2f944b
Binary files /dev/null and b/public/images/landing/benefit-10.jpg differ
diff --git a/public/images/landing/benefit-2.jpg b/public/images/landing/benefit-2.jpg
new file mode 100644
index 0000000..2f8ee60
Binary files /dev/null and b/public/images/landing/benefit-2.jpg differ
diff --git a/public/images/landing/benefit-3.jpg b/public/images/landing/benefit-3.jpg
new file mode 100644
index 0000000..43d1b22
Binary files /dev/null and b/public/images/landing/benefit-3.jpg differ
diff --git a/public/images/landing/benefit-4.jpg b/public/images/landing/benefit-4.jpg
new file mode 100644
index 0000000..a6f5935
Binary files /dev/null and b/public/images/landing/benefit-4.jpg differ
diff --git a/public/images/landing/benefit-5.jpg b/public/images/landing/benefit-5.jpg
new file mode 100644
index 0000000..5e3bed7
Binary files /dev/null and b/public/images/landing/benefit-5.jpg differ
diff --git a/public/images/landing/benefit-6.jpg b/public/images/landing/benefit-6.jpg
new file mode 100644
index 0000000..200f0cf
Binary files /dev/null and b/public/images/landing/benefit-6.jpg differ
diff --git a/public/images/landing/benefit-7.jpg b/public/images/landing/benefit-7.jpg
new file mode 100644
index 0000000..eaf2b04
Binary files /dev/null and b/public/images/landing/benefit-7.jpg differ
diff --git a/public/images/landing/benefit-8.jpg b/public/images/landing/benefit-8.jpg
new file mode 100644
index 0000000..2a66a62
Binary files /dev/null and b/public/images/landing/benefit-8.jpg differ
diff --git a/public/images/landing/benefit-9.jpg b/public/images/landing/benefit-9.jpg
new file mode 100644
index 0000000..a1be026
Binary files /dev/null and b/public/images/landing/benefit-9.jpg differ
diff --git a/public/images/landing/cat-gi.jpg b/public/images/landing/cat-gi.jpg
new file mode 100644
index 0000000..b9ac1f7
Binary files /dev/null and b/public/images/landing/cat-gi.jpg differ
diff --git a/public/images/landing/cat-odop.jpg b/public/images/landing/cat-odop.jpg
new file mode 100644
index 0000000..f0b155e
Binary files /dev/null and b/public/images/landing/cat-odop.jpg differ
diff --git a/public/images/landing/cat-sustainable.jpg b/public/images/landing/cat-sustainable.jpg
new file mode 100644
index 0000000..96ba774
Binary files /dev/null and b/public/images/landing/cat-sustainable.jpg differ
diff --git a/public/images/landing/hero-showcase.jpg b/public/images/landing/hero-showcase.jpg
new file mode 100644
index 0000000..797c0af
Binary files /dev/null and b/public/images/landing/hero-showcase.jpg differ
diff --git a/public/images/landing/tradhox-logo.png b/public/images/landing/tradhox-logo.png
new file mode 100644
index 0000000..a58ca3b
Binary files /dev/null and b/public/images/landing/tradhox-logo.png differ
diff --git a/public/images/landing/tradhox-wordmark.png b/public/images/landing/tradhox-wordmark.png
new file mode 100644
index 0000000..a58ca3b
Binary files /dev/null and b/public/images/landing/tradhox-wordmark.png differ
diff --git a/src/App.test.tsx b/src/App.test.tsx
index 5a8e631..0782bc3 100644
--- a/src/App.test.tsx
+++ b/src/App.test.tsx
@@ -55,10 +55,9 @@ describe('Supplier Portal Onboarding & Active Dashboard Tests', () => {
it('renders landing page with correct primary titles', () => {
render()
- expect(screen.getByText(/The Winter Weaves/i)).toBeInTheDocument()
+ expect(screen.getByText(/Sell Authentic Handcrafted Products Across India & Worldwide/i)).toBeInTheDocument()
-
- expect(screen.getByRole('heading', { name: /^Explore by Craft$/i })).toBeInTheDocument()
+ expect(screen.getByRole('heading', { name: /^Featured Seller Categories$/i })).toBeInTheDocument()
})
it('navigates to Support page and handles contact form submission', () => {
@@ -154,4 +153,119 @@ describe('Supplier Portal Onboarding & Active Dashboard Tests', () => {
expect(screen.getByText(/Available for Payout/i)).toBeInTheDocument()
expect(screen.getByText(/Transaction History/i)).toBeInTheDocument()
})
+
+ it('navigates to How It Works page from landing nav and renders 6-step journey', () => {
+ render()
+
+ const howItWorksBtn = screen.getAllByRole('button', { name: /^How it works$/i })[0]
+ fireEvent.click(howItWorksBtn)
+
+ expect(screen.getByText(/How it works — The Seller Journey/i)).toBeInTheDocument()
+ expect(screen.getByText(/The 6-Step Journey/i)).toBeInTheDocument()
+ expect(screen.getByText(/Guaranteed 7-Day Payouts/i)).toBeInTheDocument()
+ })
+
+ it('navigates to Pricing page and calculates artisan net payout correctly', () => {
+ render()
+
+ const pricingBtn = screen.getAllByRole('button', { name: /^Pricing$/i })[0]
+ fireEvent.click(pricingBtn)
+
+ expect(screen.getByText(/Transparent Pricing Built Solely for Maker Prosperity/i)).toBeInTheDocument()
+ expect(screen.getByText(/Estimate Your Net Take-Home Earnings/i)).toBeInTheDocument()
+ expect(screen.getByText(/Net Bank Payout/i)).toBeInTheDocument()
+ })
+
+ it('navigates to Grow Your Business page and renders growth initiatives', () => {
+ render()
+
+ const growBtn = screen.getAllByRole('button', { name: /^Grow your business$/i })[0]
+ fireEvent.click(growBtn)
+
+ expect(screen.getByText(/Scale Your Authentic Artisan Brand With Tradhox/i)).toBeInTheDocument()
+ expect(screen.getByText(/Early Maker Initiative/i)).toBeInTheDocument()
+ expect(screen.getByText(/Curated Artisan Showcases/i)).toBeInTheDocument()
+ })
+
+ it('progresses through the full 7-step onboarding wizard to Application Submitted', async () => {
+ render()
+
+ // Sign up to enter wizard
+ const getStartedBtn = screen.getByText(/^Get started$/i)
+ fireEvent.click(getStartedBtn)
+
+ fireEvent.change(screen.getByPlaceholderText(/Enter your email/i), { target: { value: 'artisan@tradhox.com' } })
+ fireEvent.change(screen.getByPlaceholderText(/9876543210/i), { target: { value: '9876543210' } })
+ fireEvent.change(screen.getByPlaceholderText(/Create a password/i), { target: { value: 'artisanPass123' } })
+ fireEvent.change(screen.getByPlaceholderText(/Repeat your password/i), { target: { value: 'artisanPass123' } })
+ fireEvent.click(screen.getByLabelText(/I agree to the/i))
+
+ const alertMock = vi.spyOn(window, 'alert').mockImplementation(() => {})
+ fireEvent.click(screen.getByRole('button', { name: /Create Account/i }))
+
+ // Now in Step 1 of Onboarding Wizard
+ expect(await screen.findByText(/Welcome to Tradhox/i)).toBeInTheDocument()
+ expect(screen.getByText(/Step 1: Account/i)).toBeInTheDocument()
+
+ // Step 1 -> Step 2
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 2: Business & GST/i)).toBeInTheDocument()
+
+ // Step 2 -> Step 3
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 3: Pickup Address/i)).toBeInTheDocument()
+
+ // Step 3 -> Step 4
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 4: Bank Details/i)).toBeInTheDocument()
+
+ // Step 4 -> Step 5
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 5: Categories/i)).toBeInTheDocument()
+
+ // Select category in Step 5
+ const categoryCard = screen.getByText(/Handloom & Textiles/i)
+ fireEvent.click(categoryCard)
+
+ // Step 5 -> Step 6
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 6: Products/i)).toBeInTheDocument()
+
+ // Step 6 -> Step 7
+ fireEvent.click(screen.getByRole('button', { name: /Save & Continue/i }))
+ expect(screen.getByText(/Step 7: Store Profile/i)).toBeInTheDocument()
+
+ // Step 7 Submit Application -> Application Submitted confirmation screen
+ const submitAppBtn = screen.getByRole('button', { name: /Submit Application/i })
+ fireEvent.click(submitAppBtn)
+
+ expect(screen.getByText(/Application submitted!/i)).toBeInTheDocument()
+ expect(screen.getByText(/What happens next:/i)).toBeInTheDocument()
+
+ alertMock.mockRestore()
+ })
+
+ it('allows demo login with any custom email and password without server session', async () => {
+ const originalFetch = globalThis.fetch
+ globalThis.fetch = vi.fn().mockRejectedValue(new Error('Server offline'))
+
+ render()
+
+ const loginBtn = screen.getByText(/^Login$/i)
+ fireEvent.click(loginBtn)
+
+ const emailInput = screen.getByPlaceholderText(/you@example.com/i)
+ const passInput = screen.getByPlaceholderText(/••••••••/)
+
+ fireEvent.change(emailInput, { target: { value: 'random_artisan_demo@craft.org' } })
+ fireEvent.change(passInput, { target: { value: 'any_password_123' } })
+
+ const submitBtn = screen.getByRole('button', { name: /Sign In/i })
+ fireEvent.click(submitBtn)
+
+ expect(await screen.findByText(/Total Sales/i)).toBeInTheDocument()
+
+ globalThis.fetch = originalFetch
+ })
})
+
diff --git a/src/App.tsx b/src/App.tsx
index 673cee1..b1bdc81 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,9 +1,11 @@
-
import React from 'react';
import { SellerProvider, useSeller } from './context/SellerContext';
import Header from './components/layout/Header';
import Footer from './components/layout/Footer';
import LandingPage from './components/pages/LandingPage';
+import HowItWorksPage from './components/pages/HowItWorksPage';
+import PricingPage from './components/pages/PricingPage';
+import GrowBusinessPage from './components/pages/GrowBusinessPage';
import AboutPage from './components/pages/AboutPage';
import ContactPage from './components/pages/ContactPage';
import AuthForms from './components/pages/AuthForms';
@@ -17,12 +19,18 @@ function AppRouter() {
return ;
}
+ if (currentPage === 'home') {
+ return ;
+ }
+
return (
-