Files
work-club-manager/frontend/src/app/(protected)/dashboard/page.tsx
WorkClub Automation c29cff3cd8 feat(ui): add login page, club picker, and dashboard
Implements Task 21: Login Page + First-Login Club Picker + Dashboard

New pages:
- Login page: Sign in with Keycloak button, clean centered layout
- Select club page: Club selection cards for multi-club users
- Dashboard: Summary with task/shift counts and quick links

Key features:
- Login delegates to Keycloak via NextAuth signIn('keycloak')
- Club picker shows cards with name + sport type
- Clicking club → setActiveClub() → redirects to /dashboard
- Dashboard shows active club name, open tasks count, upcoming shifts count
- Quick action links to /tasks and /shifts pages
- TanStack Query hooks with proper filters (status: 'Open', future shifts only)

TDD:
- 2 login tests (component export, signIn exists)
- 2 select-club tests (component export, useTenant exists)
- 4 dashboard tests (component export, hooks exist)

Task 21 tests: 8/8 pass. Build succeeds (9 routes registered).

Note: 38 pre-existing tests from Tasks 10,18-20 fail due to Bun+vitest
test infrastructure issues (vi.mocked() not supported, localStorage mock).
This is technical debt to be addressed separately.
2026-03-03 20:44:07 +01:00

59 lines
1.7 KiB
TypeScript

'use client';
import { useTenant } from '@/contexts/tenant-context';
import { useShifts } from '@/hooks/useShifts';
import { useTasks } from '@/hooks/useTasks';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import Link from 'next/link';
export default function DashboardPage() {
const { activeClubId, clubs } = useTenant();
const activeClub = clubs.find(c => c.id === activeClubId);
const { data: tasksData } = useTasks({ status: 'Open' });
const { data: shiftsData } = useShifts({
startDate: new Date().toISOString()
});
const openTasksCount = tasksData?.total || 0;
const upcomingShiftsCount = shiftsData?.total || 0;
return (
<div className="p-6">
<h1 className="text-3xl font-bold mb-6">
Welcome to {activeClub?.name || 'WorkClub'}
</h1>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3 mb-6">
<Card>
<CardHeader>
<CardTitle>My Open Tasks</CardTitle>
</CardHeader>
<CardContent>
<div className="text-4xl font-bold">{openTasksCount}</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>My Upcoming Shifts</CardTitle>
</CardHeader>
<CardContent>
<div className="text-4xl font-bold">{upcomingShiftsCount}</div>
</CardContent>
</Card>
</div>
<div className="flex gap-4">
<Link href="/tasks">
<Button>View All Tasks</Button>
</Link>
<Link href="/shifts">
<Button variant="outline">View All Shifts</Button>
</Link>
</div>
</div>
);
}