From a1d550c689f4f2c5626c40e26fcdf92011abca7b Mon Sep 17 00:00:00 2001 From: Kokila-chandrakar Date: Mon, 8 Jun 2026 14:42:55 +0530 Subject: [PATCH] fix: improve dashboard responsiveness for mobile and tablet screens --- src/app/dashboard/page.tsx | 254 ++++++++++++++++++++++++----- src/components/DashboardHeader.tsx | 228 ++++---------------------- 2 files changed, 251 insertions(+), 231 deletions(-) diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 3c7a6a7d..163459ee 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,15 +1,102 @@ -import TodayFocusHero from "@/components/TodayFocusHero"; +import LazyWidget from "@/components/LazyWidget"; +import DiscussionsWidget from "@/components/DiscussionsWidget"; +import CommunityMetrics from "@/components/CommunityMetrics"; +import GoalTracker from "@/components/GoalTracker"; +import TodayFocusHero from "@/components/TodayFocusHero"; import DashboardHeader from "@/components/DashboardHeader"; +import StreakTracker from "@/components/StreakTracker"; +import TopRepos from "@/components/TopRepos"; +import PinnedReposWidget from "@/components/PinnedReposWidget"; +import InactiveRepositoriesCard from "@/components/InactiveRepositoriesCard"; +import LanguageBreakdown from "@/components/LanguageBreakdown"; +import CIAnalytics from "@/components/CIAnalytics"; +import IssueMetrics from "@/components/IssueMetrics"; +import StreakAtRiskBanner from "@/components/StreakAtRiskBanner"; +import RepoAnalyticsExplorer from "@/components/repo-analytics/RepoAnalyticsExplorer"; +import dynamic from "next/dynamic"; +import WeeklySummaryCard from "@/components/WeeklySummaryCard"; +import { AIMentorWidget } from "@/components/AIMentorWidget"; import ExportButton from "@/components/ExportButton"; import Link from "next/link"; -import { ChevronRight } from "lucide-react"; +import PersonalRecords from "@/components/PersonalRecords"; +import LocalCodingTime from "@/components/LocalCodingTime"; +import CodingTimeWidget from "@/components/CodingTimeWidget"; +import RecentActivity from "@/components/RecentActivity"; import { authOptions } from "@/lib/auth"; import { getServerSession } from "next-auth"; import { redirect } from "next/navigation"; import DashboardSSEProvider from "@/components/DashboardSSEProvider"; -import StreakAtRiskBanner from "@/components/StreakAtRiskBanner"; -import ThrottleBanner from "@/components/ThrottleBanner"; -import CustomizableDashboard from "@/components/dashboard/CustomizableDashboard"; + +const SkeletonCard = () => ( +
+
+
+
+); + +const ContributionGraphSkeleton = () => ( +
+

Your Commits

+
+
+); + +const PRMetricsSkeleton = () => ( +
+

PR Analytics

+
+
+); + +const CodingActivityInsightsCard = dynamic( + () => import("@/components/CodingActivityInsightsCard"), + { ssr: false, loading: () => }, +); + +const FriendComparison = dynamic( + () => import("@/components/FriendComparison"), + { ssr: false, loading: () => }, +); + +const ActivityRingChart = dynamic( + () => import("@/components/ActivityRingChart"), + { ssr: false, loading: () => }, +); + +const ContributionGraph = dynamic( + () => import("@/components/ContributionGraph"), + { ssr: false, loading: () => }, +); + +const ContributionHeatmap = dynamic( + () => import("@/components/ContributionHeatmap"), + { ssr: false, loading: () => }, +); + +const PRMetrics = dynamic(() => import("@/components/PRMetrics"), { + ssr: false, + loading: () => , +}); + +const PRBreakdownChart = dynamic( + () => import("@/components/PRBreakdownChart"), + { ssr: false, loading: () => }, +); + +const CommitTimeChart = dynamic( + () => import("@/components/CommitTimeChart"), + { ssr: false, loading: () => }, +); + +const PRReviewTrendChart = dynamic( + () => import("@/components/PRReviewTrendChart"), + { ssr: false, loading: () => }, +); export default async function DashboardPage() { const session = await getServerSession(authOptions); @@ -17,11 +104,11 @@ export default async function DashboardPage() { return ( -
+
{/* Quick actions */} -
+
{/* Left side actions */}
Year in Code -
- + {/* Right side exports */}
-
- +
+ {/* Hero Section */}
-
-
-
-
- - New Feature - - - AI Resume Generator - + {/* 1. OVERVIEW SECTION */} +
+
+
+

Overview

+
+
+ +
+
+
+ +
+
+ +
+
+
+ + {/* 2. ACTIVITY & CODING TIME */} +
+
+
+

Activity & Coding

+
+ +
+
+
+ +
+
+
+ }> + + + }> + + +
+
+ + + + }> + + +
+
+
-

- Generate an ATS-Friendly CV Backed by Your Real Code -

+ {/* 3. ANALYTICS & REPOSITORIES */} +
+
+
+

Analytics & Repositories

+
-

- Analyze your GitHub contributions, merged PRs, and lines of code - changed to automatically generate professional bullet points for - your target roles. -

-
+ {/* Repo Analytics Explorer spans full width */} +
+ }> + + +
- - Build Resume - - +
+
+ + }> + + + }> + + + }> + + +
+
+ + }> + + + }> + + + }> + + +
- + {/* 4. GOALS & INSIGHTS */} +
+
+
+

Goals & Insights

+
+ +
+
+ }> + + + + }> + + +
+
+ }> + + + }> + + + }> + + +
+
+
); -} \ No newline at end of file +} diff --git a/src/components/DashboardHeader.tsx b/src/components/DashboardHeader.tsx index ac6ec6e5..a51a1f86 100644 --- a/src/components/DashboardHeader.tsx +++ b/src/components/DashboardHeader.tsx @@ -16,8 +16,6 @@ import SignOutButton from "@/components/SignOutButton"; import ThemeToggle from "@/components/ThemeToggle"; import UserAvatar from "@/components/UserAvatar"; import KeyboardShortcuts from "@/components/KeyboardShortcuts"; -import { Moon, Sun } from "lucide-react"; -import { toast } from "sonner"; type DashboardSyncContextValue = { lastSynced: Date | null; @@ -53,10 +51,7 @@ function isDashboardDataRequest(input: RequestInfo | URL): boolean { } export function DashboardSyncProvider({ children }: { children: ReactNode }) { - const [lastSynced, setLastSynced] = useState(() => { - const stored = localStorage.getItem("devtrack-last-synced"); - return stored ? new Date(stored) : null; - }); + const [lastSynced, setLastSynced] = useState(null); useLayoutEffect(() => { const originalFetch = window.fetch; @@ -65,9 +60,7 @@ export function DashboardSyncProvider({ children }: { children: ReactNode }) { const response = await originalFetch(...args); if (response.ok && isDashboardDataRequest(args[0])) { - const now = new Date(); - setLastSynced(now); - localStorage.setItem("devtrack-last-synced", now.toISOString()); + setLastSynced(new Date()); } return response; @@ -96,66 +89,24 @@ export default function DashboardHeader() { const [isPublic, setIsPublic] = useState(null); const [greeting, setGreeting] = useState("Welcome back"); - const [isNightOwl, setIsNightOwl] = useState(false); - const [isEarlyBird, setIsEarlyBird] = useState(false); - + // Determine the user's personalized greeting string based on local timestamp metrics useEffect(() => { const computeCurrentGreeting = () => { const currentHour = new Date().getHours(); - if (currentHour >= 5 && currentHour < 12) return "Good morning ☀️"; - if (currentHour >= 12 && currentHour < 17) return "Good afternoon 🌤️"; - if (currentHour >= 17 && currentHour < 22) return "Good evening 🌙"; - return "Burning the midnight oil 🦉"; + + if (currentHour >= 5 && currentHour < 12) { + return "Good morning ☀️"; + } else if (currentHour >= 12 && currentHour < 17) { + return "Good afternoon 🌤️"; + } else if (currentHour >= 17 && currentHour < 22) { + return "Good evening 🌙"; + } else { + return "Burning the midnight oil 🦉"; + } }; + setGreeting(computeCurrentGreeting()); }, []); - - useEffect(() => { - if (!session?.githubLogin) return; - - async function evaluateCodingDistributionMilestones() { - try { - const res = await fetch("/api/metrics/repos?days=90"); - if (!res.ok) return; - - const data = await res.json(); - const commitsArray = data.repos || []; - - let nightOwlCommitsCount = 0; - let earlyBirdCommitsCount = 0; - - commitsArray.forEach((repo: any) => { - if (repo.last_commit_date) { - const commitHour = new Date(repo.last_commit_date).getHours(); - if (commitHour >= 0 && commitHour <= 4) nightOwlCommitsCount++; - if (commitHour >= 5 && commitHour <= 8) earlyBirdCommitsCount++; - } - }); - - if (nightOwlCommitsCount >= 1) setIsNightOwl(true); - if (earlyBirdCommitsCount >= 1) setIsEarlyBird(true); - } catch (err) { - console.error("Failed to compile milestone hour distribution profiles:", err); - } - } - - evaluateCodingDistributionMilestones(); - }, [session]); - const [copied, setCopied] = useState(false); - - const handleCopyLink = () => { - if (!session?.githubLogin) return; - const profileUrl = `${window.location.origin}/u/${session.githubLogin}`; - navigator.clipboard.writeText(profileUrl).then(() => { - setCopied(true); - toast.success("Profile link copied!"); - setTimeout(() => setCopied(false), 2000); - }).catch(() => { - toast.error("Failed to copy link"); - }); - }; - const [menuOpen, setMenuOpen] = useState(false); - const { lastSynced } = useDashboardSync(); const [now, setNow] = useState(() => Date.now()); @@ -204,65 +155,40 @@ export default function DashboardHeader() {
-
+
{/* Left Section */} -
-
-
+
+
+ {/* Dynamic Personalized Friendly Greeting Badge Element Overlay */} +
- {greeting}, {displayName}! + + {greeting}, {displayName}! +
- {isNightOwl && ( -
- - Night Owl -
- )} - {isEarlyBird && ( -
- - Early Bird -
- )} -
-
-

- Dashboard overview -

-

+ +

Dashboard

-

- coding activity at a glance -

- {minutesAgo !== null && ( -

- {minutesAgo <= 0 ? "Synced just now" : `Synced ${minutesAgo} min ago`} -

- )}
+ +

+ Your coding activity at a glance 🚀 +

+ {minutesAgo !== null && ( +

+ {minutesAgo <= 0 ? "Synced just now" : `Synced ${minutesAgo} min ago`} +

+ )}
{/* Right Section */} - {/* Right Section */} -