Agency owner (super admin) management dashboard showing team overview, attention items, quick stats, manage actions, and today's shifts...
Build a completely separate home screen for the agency owner (super admin). This is NOT a caregiving screen โ it's a MANAGEMENT overview. The owner needs to see: who's on shift, what needs attention, and quick actions to manage their team.
subscription.plan === 'multi-agency' && user.role === 'super_admin'src/app/dashboard/page.tsx โ Where conditional rendering goessrc/types/index.ts โ Agency, CaregiverAssignment, ScheduledShift, ShiftSession interfacessrc/hooks/useAgency.ts โ If exists, agency data fetchingsrc/app/dashboard/caregivers/page.tsx โ Existing caregiver list pagesrc/app/dashboard/scheduling/page.tsx โ Existing scheduling pagesrc/lib/firebase/firestore.ts โ Existing Firestore query patternssrc/contexts/AuthContext.tsx โ User role accesssrc/lib/subscription.ts โ Subscription plan detectionAgencyOwnerDashboard
โโโ AgencyGreeting (name + agency name)
โโโ AgencyQuickStats (3 stat cards)
โโโ NeedsAttentionList (alert cards)
โโโ ManageActionGrid (2x2 action buttons)
โโโ TodaysShiftsList (shift cards)
Create src/components/dashboard/AgencyOwnerDashboard.tsx:
'use client';
import { useAuth } from '@/contexts/AuthContext';
import { useSubscription } from '@/lib/subscription';
import { AgencyGreeting } from '@/components/agency/AgencyGreeting';
import { AgencyQuickStats } from '@/components/agency/AgencyQuickStats';
import { NeedsAttentionList } from '@/components/agency/NeedsAttentionList';
import { ManageActionGrid } from '@/components/agency/ManageActionGrid';
import { TodaysShiftsList } from '@/components/agency/TodaysShiftsList';
export function AgencyOwnerDashboard() {
return (
<div className="flex flex-col gap-6 px-4 py-4 max-w-2xl mx-auto">
<AgencyGreeting />
<AgencyQuickStats />
<NeedsAttentionList />
<ManageActionGrid />
<TodaysShiftsList />
</div>
);
}
Create src/components/agency/AgencyGreeting.tsx:
Props: none (reads from AuthContext)
Display:
- "Hi {firstName}" โ 24px semibold
- "{agencyName}" โ 16px regular, secondary color
- Agency name from user's agency document in Firestore
Data: user.agencyId โ fetch agency document โ agency.name
Create src/components/agency/AgencyQuickStats.tsx:
Display: 3 stat cards in horizontal row (flex, gap-3)
Card 1: Caregivers
- Count of active caregiver_assignments where agencyId matches
- Icon: Users (blue)
Card 2: Elders
- Count of elders assigned to this agency
- Icon: Heart (rose)
Card 3: Pending Slots
- Count of scheduledShifts where status === 'pending' (awaiting response)
- Icon: Clock (amber)
Each card: shadcn Card component, compact (80px height)
- Large number (24px bold)
- Label below (12px, secondary color)
- Icon top-right corner (16px, muted)
Create src/components/agency/NeedsAttentionList.tsx:
Purpose: Show issues that need the owner's action
Scans for:
1. Uncovered shifts (scheduledShifts where date is upcoming AND no caregiver assigned)
2. Elders without caregiver assignment
3. Caregivers with low compliance (<70% today)
4. Shifts with no response (sent but not accepted/rejected)
Display per item:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ [AlertTriangle] 2 slots awaiting > โ
โ response โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- Icon color: amber for warnings, red for urgent
- Chevron right โ navigates to relevant page
- Max 3 shown, "View all" button if more
- Empty state: green CheckCircle + "All good! No issues right now."
Create src/components/agency/ManageActionGrid.tsx:
Display: 2x2 grid of action cards
1. Assign Elder
- Icon: UserPlus
- Navigate: /dashboard/caregivers (with assign modal pre-opened)
2. Send Slots
- Icon: CalendarPlus
- Navigate: /dashboard/scheduling/create
3. Onboard Caregiver
- Icon: UserCheck
- Navigate: /dashboard/caregivers/invite
4. Create Schedule
- Icon: Calendar
- Navigate: /dashboard/scheduling
Each card:
- 48px icon (centered, muted color)
- Label below (14px, center-aligned)
- Tap: navigate to action
- Subtle border, rounded-lg, hover:bg-gray-50
Create src/components/agency/TodaysShiftsList.tsx:
Purpose: Show all shifts scheduled for today
Data: scheduledShifts where date = today, joined with caregiver names and elder names
Display per shift:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Sarah J. โ Martha, John โ [Active] โ
โ 7AM-3PM โ โ [green] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Columns: caregiver name | assigned elders | status badge
Status badges:
- Active (green) โ currently on shift
- Upcoming (gray) โ shift hasn't started
- Completed (blue) โ shift ended
- Missed (red) โ shift time passed, no clock-in
Tap row โ navigate to caregiver detail view
Empty state: "No shifts scheduled today" + [Create Schedule] button
Modify src/app/dashboard/page.tsx:
// Add at top of component:
const { isMultiAgency } = useSubscription();
const isSuperAdmin = user?.role === 'super_admin' || user?.role === 'agency_owner';
// Conditional rendering:
if (isMultiAgency && isSuperAdmin) {
return <AgencyOwnerDashboard />;
}
The bottom nav items for super admin (handled in BottomNav component):
if (isMultiAgency && isSuperAdmin) {
return [
{ icon: House, label: 'Home', href: '/dashboard' },
{ icon: Users, label: 'Team', href: '/dashboard/caregivers' },
{ icon: Calendar, label: 'Schedule', href: '/dashboard/scheduling' },
{ icon: Bell, label: 'Alerts', badge: unreadCount }, // Opens notification dropdown
{ icon: Menu, label: 'More' },
];
}
Note: "Team" (NOT "Staff") โ matches the mockup exactly.
TOP:
1. Home (House)
2. Team (Users) โ /dashboard/caregivers
3. Schedule (Calendar) โ /dashboard/scheduling
4. Elders (Heart) โ /dashboard/elder-profile
5. Reports (FileText) โ /dashboard/analytics
6. Timesheets (Clock) โ /dashboard/timesheet
7. More (Menu)
BOTTOM (after spacer):
8. Bell (with badge)
9. Avatar (profile/settings/sign-out)
npm test -- --testPathPattern="agency|Agency|dashboard"