feat: implement demo mode fallback for authentication and initial dashboard data loading
All checks were successful
Beta CI/CD Pipeline / build-and-test (push) Successful in 1m6s
Beta CI/CD Pipeline / deploy-beta (push) Successful in 25s

This commit is contained in:
vickytechkey 2026-09-10 18:38:11 +05:30
parent c2f72e20dc
commit 2869321fb5
2 changed files with 50 additions and 15 deletions

View file

@ -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
})
})

View file

@ -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();
});
}