diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 9dcc11e..87150bb 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,22 +1,5 @@ -import ContributionGraph from "@/components/ContributionGraph"; -import ContributionHeatmap from "@/components/ContributionHeatmap"; -import PRMetrics from "@/components/PRMetrics"; -import PRBreakdownChart from "@/components/PRBreakdownChart"; -import GoalTracker from "@/components/GoalTracker"; -import DashboardHeader from "@/components/DashboardHeader"; -import StreakTracker from "@/components/StreakTracker"; -import TopRepos from "@/components/TopRepos"; -import PinnedRepos from "@/components/PinnedRepos"; -import LanguageBreakdown from "@/components/LanguageBreakdown"; -import CommitTimeChart from "@/components/CommitTimeChart"; -import CIAnalytics from "@/components/CIAnalytics"; -import IssueMetrics from "@/components/IssueMetrics"; -import StreakAtRiskBanner from "@/components/StreakAtRiskBanner"; -import FriendComparison from "@/components/FriendComparison"; -import WeeklySummaryCard from "@/components/WeeklySummaryCard"; -import ExportButton from "@/components/ExportButton"; -import Link from "next/link"; -import PersonalRecords from "@/components/PersonalRecords"; +import DashboardWidgets from "@/components/DashboardWidgets"; + import { authOptions } from "@/lib/auth"; import { cookies } from "next/headers"; import { getServerSession } from "next-auth"; @@ -35,68 +18,7 @@ export default async function DashboardPage() { } return ( -
- -
- - Settings - - -
- - -
- -
- -
- -
- - {/* Row 1: Contribution graph + Streak + Friend Comparison */} -
-
- -
- -
-
- -
- - -
-
- - {/* Row 2: PR metrics, PR breakdown & Time Chart */} -
- - - -
- - {/* Row 3: Issue metrics + CI analytics */} -
-
- -
- -
- - {/* Row 4: Pinned repositories */} -
- -
- - {/* Row 5: Top repos + Language breakdown + Goal tracker */} -
- - - -
+
); } diff --git a/src/components/DashboardWidgets.tsx b/src/components/DashboardWidgets.tsx new file mode 100644 index 0000000..c38fe1e --- /dev/null +++ b/src/components/DashboardWidgets.tsx @@ -0,0 +1,114 @@ +"use client"; + +import ContributionGraph from "@/components/ContributionGraph"; +import ContributionHeatmap from "@/components/ContributionHeatmap"; +import PRMetrics from "@/components/PRMetrics"; +import PRBreakdownChart from "@/components/PRBreakdownChart"; +import GoalTracker from "@/components/GoalTracker"; +import DashboardHeader from "@/components/DashboardHeader"; +import StreakTracker from "@/components/StreakTracker"; +import TopRepos from "@/components/TopRepos"; +import PinnedRepos from "@/components/PinnedRepos"; +import LanguageBreakdown from "@/components/LanguageBreakdown"; +import CommitTimeChart from "@/components/CommitTimeChart"; +import IssueMetrics from "@/components/IssueMetrics"; +import StreakAtRiskBanner from "@/components/StreakAtRiskBanner"; +import FriendComparison from "@/components/FriendComparison"; +import WeeklySummaryCard from "@/components/WeeklySummaryCard"; +import ExportButton from "@/components/ExportButton"; +import PersonalRecords from "@/components/PersonalRecords"; +import WidgetErrorBoundary from "@/components/WidgetErrorBoundary"; + +export default function DashboardWidgets() { + return ( + <> + + + + +
+ + + +
+ + + + + + + + + +
+ + + +
+ +
+
+ + + + +
+ + + +
+
+ +
+ + + + + + + +
+
+ +
+ + + + + + + + + + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + + + + + + + + +
+ + ); +} \ No newline at end of file diff --git a/src/components/TopRepos.tsx b/src/components/TopRepos.tsx index 2bc9756..4f086cd 100644 --- a/src/components/TopRepos.tsx +++ b/src/components/TopRepos.tsx @@ -95,7 +95,8 @@ export default function TopRepos() { : b.commits - a.commits; }); - const maxCommits = sortedRepos[0]?.commits ?? 1; + const maxCommits = repos[0]?.commits ?? 1; + // throw new Error("Test widget crash"); return (
diff --git a/src/components/WidgetErrorBoundary.tsx b/src/components/WidgetErrorBoundary.tsx new file mode 100644 index 0000000..c318f9b --- /dev/null +++ b/src/components/WidgetErrorBoundary.tsx @@ -0,0 +1,64 @@ +"use client"; + +import React, { Component, ReactNode } from "react"; + +interface Props { + children: ReactNode; +} + +interface State { + hasError: boolean; +} + +class WidgetErrorBoundary extends React.Component { + constructor(props: Props) { + super(props); + + this.state = { + hasError: false, + }; + } + + static getDerivedStateFromError(_: Error): State { + return { + hasError: true, + }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + console.error("Widget crashed:", error, errorInfo); + } + + handleRetry = () => { + this.setState({ + hasError: false, + }); + }; + + render() { + if (this.state.hasError) { + return ( +
+

+ Something went wrong +

+ +

+ This widget failed to load. +

+ + +
+ ); + } + + return this.props.children; + } +} + +export default WidgetErrorBoundary; \ No newline at end of file