feat(ui): add skeleton loaders for dashboard components during API fetch#2180
feat(ui): add skeleton loaders for dashboard components during API fetch#2180VIDYANKSHINI wants to merge 2 commits into
Conversation
|
@VIDYANKSHINI is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel. A member of the Team first needs to authorize it. |
GSSoC Label Checklist 🏷️@Priyanshu-byte-coder — please apply the appropriate labels before merging: Difficulty (pick one):
Quality (optional):
Validation (required to score):
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR refreshes loading experiences across the dashboard and leaderboard by introducing more tailored skeleton UIs and wiring them into dynamic widget loading fallbacks.
Changes:
- Replaced the generic dashboard
SkeletonCardwith multiple purpose-specific skeleton components and updated dynamic/LazyWidget fallbacks accordingly. - Updated loading placeholders in
TopReposandPinnedReposWidgetto better match the final layouts. - Added a dedicated
src/app/leaderboard/loading.tsxroute-level skeleton for the public leaderboard page.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/components/dashboard/CustomizableDashboard.tsx | Introduces exported skeleton components and updates dynamic/LazyWidget fallbacks to use them. |
| src/components/TopRepos.tsx | Updates the loading skeleton rows to a more detailed “label + bar” skeleton layout. |
| src/components/PinnedReposWidget.tsx | Replaces the previous shimmer placeholders with a structured card skeleton matching pinned repo cards. |
| src/app/leaderboard/loading.tsx | Adds a full-page loading skeleton for the leaderboard route. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {[1, 2, 3, 4, 5].map((i) => ( | ||
| <div key={i}> | ||
| <div className="flex items-center justify-between mb-2"> | ||
| <div className="h-4 w-1/3 bg-[var(--card-muted)] rounded animate-pulse" /> | ||
| <div className="h-4 w-16 bg-[var(--card-muted)] rounded animate-pulse" /> | ||
| </div> | ||
| <div className="h-1.5 w-full bg-[var(--control)] rounded-full overflow-hidden"> | ||
| <div className="h-full bg-[var(--card-muted)] animate-pulse w-1/2" /> | ||
| </div> | ||
| </div> | ||
| ))} |
| export const RepoWidgetSkeleton = () => ( | ||
| <div | ||
| role="status" | ||
| aria-busy="true" | ||
| aria-live="polite" | ||
| className="rounded-xl border border-[var(--border)] bg-[var(--card)] p-6 shadow-sm" | ||
| className="rounded-xl border border-[var(--border)] bg-[var(--card)] p-6 shadow-sm flex flex-col h-full" | ||
| > | ||
| <div className="h-6 w-48 bg-[var(--card-muted)] rounded mb-4 animate-pulse" /> | ||
| <div className="h-40 bg-[var(--card-muted)] rounded animate-pulse" /> | ||
| <div className="flex items-center justify-between mb-6"> | ||
| <div className="h-6 w-40 bg-[var(--card-muted)] rounded animate-pulse" /> | ||
| <div className="h-6 w-20 bg-[var(--card-muted)] rounded animate-pulse" /> | ||
| </div> |
| const PRMetrics = dynamic(() => import("@/components/PRMetrics"), { | ||
| ssr: false, | ||
| loading: () => <PRMetricsSkeleton />, | ||
| loading: () => <ProfileStatsSkeleton />, | ||
| }); |
| <div className="h-1.5 w-full bg-[var(--control)] rounded-full overflow-hidden"> | ||
| <div className="h-full bg-[var(--card-muted)] animate-pulse w-1/2" /> | ||
| </div> |
Summary
Implemented custom responsive skeleton loaders for dashboard components to prevent layout shifts and improve perceived performance while API data is being fetched.
Closes #1144
Type of Change
Changes Made
SkeletonCardinCustomizableDashboard.tsxwith specialized layout-matching skeletons (RepoWidgetSkeleton,ChartSkeleton,ProfileStatsSkeleton,ContributionHeatmapSkeleton).TopRepos.tsxandPinnedReposWidget.tsxto utilize the detailed skeleton designs.src/app/leaderboard/loading.tsxto provide an instant skeleton state for the server-rendered leaderboard route.How to Test
Steps for the reviewer to verify this works:
loading.tsxskeleton while the data is being fetched.Screenshots (if UI change)
N/A
Checklist
npm run lintpasses locallynpm run type-check)Accessibility Checklist
aria-busyandaria-liveon skeletons)Additional Notes
This enhancement uses Tailwind's
animate-pulseutility along with the existing CSS variables to ensure the skeletons natively support both light and dark themes without any hardcoded colors.