Demo site #2
2 changed files with 50 additions and 15 deletions
|
|
@ -244,5 +244,28 @@ describe('Supplier Portal Onboarding & Active Dashboard Tests', () => {
|
|||
|
||||
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(<App />)
|
||||
|
||||
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
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -155,10 +155,10 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
const [dateFilter, setDateFilter] = useState<DateFilter>('year')
|
||||
const [customDates, setCustomDates] = useState({ start: '2026-06-01', end: '2026-06-15' })
|
||||
|
||||
// Lists
|
||||
const [products, setProducts] = useState<Product[]>([])
|
||||
const [orders, setOrders] = useState<Order[]>([])
|
||||
const [returns, setReturns] = useState<ReturnRequest[]>([])
|
||||
// Lists with rich default mock data for demo mode
|
||||
const [products, setProducts] = useState<Product[]>(CONFIG.dashboardData.initialProducts || [])
|
||||
const [orders, setOrders] = useState<Order[]>((CONFIG.dashboardData.initialOrders as Order[]) || [])
|
||||
const [returns, setReturns] = useState<ReturnRequest[]>((CONFIG.dashboardData.initialReturns as ReturnRequest[]) || [])
|
||||
|
||||
// Forms & Editing
|
||||
const [productForm, setProductForm] = useState({
|
||||
|
|
@ -264,9 +264,8 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Session restore failed:', err);
|
||||
localStorage.removeItem('access_token')
|
||||
localStorage.removeItem('refresh_token');
|
||||
console.warn('Session restore fallback to active demo session:', err);
|
||||
setIsProfileComplete(true);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
|
@ -540,16 +539,28 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
navigateTo('profile-completion')
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err.message);
|
||||
.catch(() => {
|
||||
// Offline / demo fallback
|
||||
localStorage.setItem('access_token', 'demo_access_token');
|
||||
navigateTo('profile-completion');
|
||||
});
|
||||
}
|
||||
|
||||
const handleLoginSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
|
||||
|
||||
const fallbackDemoLogin = () => {
|
||||
localStorage.setItem('access_token', 'demo_access_token');
|
||||
setEmail(email.trim() || 'demo_artisan@tradhox.com');
|
||||
setPhoneVerified(true);
|
||||
setEmailVerified(true);
|
||||
setIsGstinVerified(true);
|
||||
setIsProfileComplete(true);
|
||||
navigateTo('dashboard', true);
|
||||
};
|
||||
|
||||
if (!email.trim()) {
|
||||
alert('Please enter your email or phone number.');
|
||||
fallbackDemoLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -559,7 +570,7 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
body: JSON.stringify({ username: email, password: password })
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error('Invalid credentials.');
|
||||
if (!res.ok) throw new Error('Demo mode activated.');
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
|
|
@ -569,7 +580,7 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
const profile = data.user.profile;
|
||||
setPhone(profile.phone || '');
|
||||
setPhoneVerified(profile.phone_verified || false);
|
||||
setEmail(data.user.email || '');
|
||||
setEmail(data.user.email || email);
|
||||
setEmailVerified(profile.email_verified || false);
|
||||
setGstin(profile.gstin || '29AAAAA1111A1Z1');
|
||||
setIsGstinVerified(profile.is_gstin_verified || false);
|
||||
|
|
@ -611,8 +622,9 @@ export const SellerProvider: React.FC<{children: React.ReactNode}> = ({ children
|
|||
navigateTo('profile-completion');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
alert(err.message);
|
||||
.catch(() => {
|
||||
// Backend not running or demo credentials -> seamless fallback to demo dashboard
|
||||
fallbackDemoLogin();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue