The Platform Dashboard provides role-based personalized views for 8 different user types. All dashboards follow a unified 6-section layout with role-specific content for relevant metrics, quick actions, and data visualizations.
src/components/platform/dashboard/ # ~100 files
│
│ # Core Files
├── content.tsx # Role routing (main entry point)
├── client.tsx # Client wrapper component
├── actions.ts # Server actions (~80KB, ~3200 lines)
├── config.ts # Role mappings, icons, colors
├── validation.ts # Zod schemas
├── types.ts # TypeScript interfaces
│
│ # Role-Based Dashboards
├── admin.tsx # Admin dashboard (server component)
├── admin-client.tsx # Admin dashboard (client component)
├── student.tsx # Student dashboard
├── teacher.tsx # Teacher dashboard
├── parent.tsx # Parent/Guardian dashboard
├── principal.tsx # Principal dashboard
├── accountant.tsx # Accountant dashboard
├── staff.tsx # Staff dashboard
│
│ # Unified Section Components (NEW)
├── section-heading.tsx # Unified section title styling
├── upcoming.tsx # Role-specific flip card (3D animation)
├── weather.tsx # Functional weather component
├── quick-look-section.tsx # User-specific counts (no title)
├── quick-actions.tsx # Quick actions grid
├── quick-actions-config.ts # Role-specific action definitions (4 per role)
├── resource-usage-section.tsx # Role-specific usage metrics
├── invoice-history-section.tsx # Role-relevant invoice history
├── financial-overview-section.tsx # Role-relevant financial stats + charts
│
│ # Shared Widgets
├── metric-card.tsx # Key stat with icon and trend
├── activity-rings.tsx # Apple-style progress indicators
├── schedule-item.tsx # Timetable entries
├── announcement-card.tsx # School announcements
├── progress-card.tsx # Goal tracking with progress bar
├── chart-card.tsx # Chart container wrapper
├── empty-state.tsx # No data placeholder
│
│ # Chart Components
├── attendance-chart.tsx # Attendance trends over time
├── grade-chart.tsx # Grade distribution
├── revenue-chart.tsx # Revenue vs expenses comparison
├── performance-gauge.tsx # Single metric radial gauge
├── weekly-chart.tsx # Weekly bar chart
├── comparison-chart.tsx # Period comparison line chart
│
│ # Showcase Components
├── card-activity-goal.tsx # Activity goal card
├── card-chat.tsx # Chat card
├── card-cookie-settings.tsx # Cookie settings card
├── card-create-account.tsx # Create account card
├── card-exercise-minutes.tsx # Exercise minutes card
├── card-forms.tsx # Forms card
├── card-metric.tsx # Metric display card
├── card-payment-method.tsx # Payment method card
├── card-payments.tsx # Payments history card
├── card-report-issue.tsx # Report issue card
├── card-share.tsx # Share card
├── card-showcase.tsx # Cards showcase entry
├── card-stats.tsx # Statistics card
├── card-team-members.tsx # Team members card
├── chart-area-stacked.tsx # Stacked area chart
├── chart-bar-mixed.tsx # Mixed bar chart
├── chart-interactive-bar.tsx # Interactive bar chart
├── chart-line-multiple.tsx # Multiple line chart
├── chart-radar-simple.tsx # Simple radar chart
├── chart-radial-grid.tsx # Radial grid chart
├── chart-radial-shape.tsx # Radial shape chart
├── chart-radial-stacked.tsx # Stacked radial chart
├── chart-radial-text.tsx # Radial text chart
├── chart-showcase.tsx # Charts showcase entry
├── stat-apple-activity.tsx # Apple-style activity stat
├── stat-area-chart.tsx # Area chart stat
├── stat-badges.tsx # Badges stat
├── stat-borders.tsx # Bordered stat
├── stat-card-flip.tsx # Flip card stat
├── stat-cards.tsx # Multiple stat cards
├── stat-circular-links.tsx # Circular links stat
├── stat-circular.tsx # Circular stat
├── stat-currency-transfer.tsx # Currency transfer stat
├── stat-dashboard.tsx # Dashboard stat
├── stat-links.tsx # Links stat
├── stat-progress.tsx # Progress stat
├── stat-segmented.tsx # Segmented stat
├── stat-showcase.tsx # Stats showcase entry
├── stat-status.tsx # Status stat
├── stat-trending.tsx # Trending stat
├── stat-usage.tsx # Usage stat
├── stat-weather.tsx # Weather stat
├── dashboard-showcase.tsx # Full showcase page
│
│ # Infrastructure
├── header.tsx # Dashboard header
├── loading.tsx # Loading skeleton
├── error-boundary.tsx # Error handling component
├── search-command.tsx # Command palette (⌘K)
├── notification-service.tsx # Notification service
├── project-switcher.tsx # Project/school switcher
├── section-columns.tsx # Section column layout
├── transactions-list.tsx # Transactions list
├── upgrade-card.tsx # Upgrade prompt card
├── info-card.tsx # Information card
├── delete-account.tsx # Delete account component
│
│ # Settings Subdirectory
└── settings/
├── content.tsx # Settings main content
└── user-name-form.tsx # User name form
The dashboard uses a switch-case routing pattern in content.tsx:
switch (userRole) {
case "STUDENT":
return (
<StudentDashboard user={user} dictionary={safeDict} locale={locale} />
)
case "TEACHER":
return (
<TeacherDashboard user={user} dictionary={safeDict} locale={locale} />
)
case "GUARDIAN":
return <ParentDashboard user={user} dictionary={safeDict} locale={locale} />
case "STAFF":
return <StaffDashboard user={user} dictionary={safeDict} locale={locale} />
case "ADMIN":
case "DEVELOPER":
return <AdminDashboard user={user} dictionary={safeDict} locale={locale} />
case "PRINCIPAL":
return (
<PrincipalDashboard user={user} dictionary={safeDict} locale={locale} />
)
case "ACCOUNTANT":
return (
<AccountantDashboard user={user} dictionary={safeDict} locale={locale} />
)
default:
return <DefaultDashboard user={user} dictionary={safeDict} />
}Unified section title styling for all dashboards.
interface SectionHeadingProps {
title: string
icon?: LucideIcon
badge?: { label: string; variant?: string }
action?: { label: string; href: string }
description?: string
className?: string
}Role-specific critical info with 3D flip animation:
Functional weather component with:
Role-specific usage metrics (4 metrics per role):
Role-based invoice visibility:
Role-relevant financial metrics with optional charts:
Dashboard data is fetched via server actions in actions.ts:
Each role-based dashboard follows the unified section structure:
export async function RoleDashboard({ user, dictionary, locale }: Props) {
try {
// 1. Get tenant context
const { schoolId } = await getTenantContext()
const school = await db.school.findUnique({ where: { id: schoolId } })
const subdomain = school?.domain || ""
// 2. Render unified sections
return (
<div className="space-y-6">
{/* Section 1: Upcoming + Weather */}
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
<Upcoming role="ROLE" locale={locale} subdomain={subdomain} />
<Weather />
</div>
{/* Section 2: Quick Look (no title) */}
<QuickLookSection />
{/* Section 3: Quick Actions */}
<SectionHeading title="Quick Actions" icon={Zap} />
<QuickActionsSection
role="ROLE"
locale={locale}
subdomain={subdomain}
/>
{/* Section 4: Resource Usage */}
<ResourceUsageSection role="ROLE" />
{/* Section 5: Invoice History */}
<InvoiceHistorySection role="ROLE" />
{/* Section 6: Financial Overview */}
<FinancialOverviewSection role="ROLE" />
</div>
)
} catch (error) {
return <ErrorCard message={error.message} />
}
}