feat(frontend): add skeleton loading state for dashboard
Replace simple spinner with skeleton loading placeholders that match the dashboard layout structure, providing better visual feedback during data loading.
This commit is contained in:
@@ -6,6 +6,7 @@ import { useAuth } from '../contexts/AuthContext';
|
||||
import { dashboardAPI, matchesAPI } from '../services/api';
|
||||
import { connectSocket, disconnectSocket, getSocket } from '../services/socket';
|
||||
import HeatBadges from '../components/heats/HeatBadges';
|
||||
import { DashboardSkeleton } from '../components/common/Skeleton';
|
||||
import {
|
||||
Calendar,
|
||||
MapPin,
|
||||
@@ -139,12 +140,7 @@ const DashboardPage = () => {
|
||||
if (loading) {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="max-w-5xl mx-auto flex items-center justify-center min-h-[400px]">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<Loader2 className="w-12 h-12 animate-spin text-primary-600" />
|
||||
<p className="text-gray-600">Loading dashboard...</p>
|
||||
</div>
|
||||
</div>
|
||||
<DashboardSkeleton />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,12 +59,14 @@ describe('DashboardPage', () => {
|
||||
});
|
||||
|
||||
describe('Loading State', () => {
|
||||
it('should show loading spinner while fetching data', async () => {
|
||||
it('should show skeleton loading state while fetching data', async () => {
|
||||
dashboardAPI.getData.mockImplementation(() => new Promise(() => {}));
|
||||
|
||||
renderWithRouter(<DashboardPage />);
|
||||
|
||||
expect(screen.getByText('Loading dashboard...')).toBeInTheDocument();
|
||||
// Skeleton uses animate-pulse class for loading animation
|
||||
const skeletons = document.querySelectorAll('.animate-pulse');
|
||||
expect(skeletons.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -410,14 +412,13 @@ describe('DashboardPage', () => {
|
||||
|
||||
renderWithRouter(<DashboardPage />);
|
||||
|
||||
// Wait for content to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('John Lead')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Find the accept button by title attribute
|
||||
const acceptButton = document.querySelector('button[title="Accept"]');
|
||||
expect(acceptButton).toBeTruthy();
|
||||
|
||||
// Click accept using fireEvent which is synchronous
|
||||
const acceptButton = screen.getByRole('button', { name: /accept/i });
|
||||
fireEvent.click(acceptButton);
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
Reference in New Issue
Block a user