'use client'; import React, { Suspense } from 'react'; import dynamic from 'next/dynamic'; import { useDashboardStore } from '@/lib/stores/use-dashboard-store'; import { WidgetErrorBoundary } from '@/components/widget-error-boundary'; import { Button } from '@/components/ui/button'; // Lazy load react-grid-layout (client-only, ~45KB) const ResponsiveGridLayout = dynamic( () => import('@/components/dashboard/responsive-grid-layout'), { ssr: false, loading: () => (
{Array.from({ length: 8 }).map((_, i) => (
))}
), } ); // Lazy load individual widgets — each is code-split into its own chunk const TodayTasksWidget = dynamic( () => import('@/components/dashboard/widgets/today-tasks-widget').then((m) => m.TodayTasksWidget), { ssr: false, loading: () => , } ); const HabitChecklistWidget = dynamic( () => import('@/components/dashboard/widgets/habit-checklist-widget').then( (m) => m.HabitChecklistWidget ), { ssr: false, loading: () => , } ); const WeeklyStatsWidget = dynamic( () => import('@/components/dashboard/widgets/weekly-stats-widget').then((m) => m.WeeklyStatsWidget), { ssr: false, loading: () => , } ); const ProjectProgressWidget = dynamic( () => import('@/components/dashboard/widgets/project-progress-widget').then( (m) => m.ProjectProgressWidget ), { ssr: false, loading: () => , } ); const HabitStreaksWidget = dynamic( () => import('@/components/dashboard/widgets/habit-streaks-widget').then((m) => m.HabitStreaksWidget), { ssr: false, loading: () => , } ); const CalendarMiniWidget = dynamic( () => import('@/components/dashboard/widgets/calendar-mini-widget').then((m) => m.CalendarMiniWidget), { ssr: false, loading: () => , } ); const QuickAddWidget = dynamic( () => import('@/components/dashboard/widgets/quick-add-widget').then((m) => m.QuickAddWidget), { ssr: false, loading: () => , } ); const RecentActivityWidget = dynamic( () => import('@/components/dashboard/widgets/recent-activity-widget').then( (m) => m.RecentActivityWidget ), { ssr: false, loading: () => , } ); function WidgetSkeleton() { return (
); } const widgetComponents: Record = { 'today-tasks': TodayTasksWidget, 'habit-checklist': HabitChecklistWidget, 'weekly-stats': WeeklyStatsWidget, 'project-progress': ProjectProgressWidget, 'habit-streaks': HabitStreaksWidget, 'calendar-mini': CalendarMiniWidget, 'quick-add': QuickAddWidget, 'recent-activity': RecentActivityWidget, }; export default function DashboardPage() { const { widgets, setWidgets } = useDashboardStore(); const [layoutAnnouncement, setLayoutAnnouncement] = React.useState(''); const layout = widgets.map((w) => ({ i: w.id, x: w.x, y: w.y, w: w.w, h: w.h, })); function handleLayoutChange(newLayout: ReadonlyArray<{ i: string; x: number; y: number; w: number; h: number }>) { const updated = widgets.map((w) => { const layoutItem = newLayout.find((l) => l.i === w.id); if (layoutItem) { return { ...w, x: layoutItem.x, y: layoutItem.y, w: layoutItem.w, h: layoutItem.h, }; } return w; }); setWidgets(updated); } function moveWidget(id: string, direction: -1 | 1) { const ordered = [...widgets].sort((a, b) => a.y - b.y || a.x - b.x); const index = ordered.findIndex((widget) => widget.id === id); const targetIndex = index + direction; if (index < 0 || targetIndex < 0 || targetIndex >= ordered.length) return; const current = ordered[index]; const target = ordered[targetIndex]; setWidgets(widgets.map((widget) => { if (widget.id === current.id) return { ...widget, x: target.x, y: target.y }; if (widget.id === target.id) return { ...widget, x: current.x, y: current.y }; return widget; })); setLayoutAnnouncement(`${current.type} moved ${direction < 0 ? 'earlier' : 'later'} on the dashboard.`); } function resizeWidget(id: string, direction: -1 | 1) { const widget = widgets.find((item) => item.id === id); if (!widget) return; const width = Math.max(2, Math.min(12, widget.w + direction)); if (width === widget.w) return; setWidgets(widgets.map((item) => item.id === id ? { ...item, w: width } : item)); setLayoutAnnouncement(`${widget.type} is now ${width} columns wide.`); } return (

Dashboard

Your day, at a glance.

Customize dashboard layout

Use these controls to reorder or resize widgets without dragging.

{[...widgets].sort((a, b) => a.y - b.y || a.x - b.x).map((widget, index, ordered) => (
{widget.type}
))}

{layoutAnnouncement}

{widgets.map((widget) => { const WidgetComponent = widgetComponents[widget.id]; if (!WidgetComponent) return null; return (
}>
); })}
); }