Skip to content

feat: add Year in Code annual recap page (#1073)#1086

Open
VIDYANKSHINI wants to merge 8 commits into
Priyanshu-byte-coder:mainfrom
VIDYANKSHINI:feat/year-in-code
Open

feat: add Year in Code annual recap page (#1073)#1086
VIDYANKSHINI wants to merge 8 commits into
Priyanshu-byte-coder:mainfrom
VIDYANKSHINI:feat/year-in-code

Conversation

@VIDYANKSHINI
Copy link
Copy Markdown
Contributor

Summary

This PR introduces the "Year in Code" (Wrapped) experience, providing users with a highly engaging and shareable annual recap of their GitHub activity.

Closes #1073

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Refactor / code cleanup

Changes Made

  • Created src/app/api/wrapped/route.ts to fetch and aggregate yearly stats (commits, streaks, top month, top repo, top languages) efficiently using the GitHub GraphQL API.
  • Implemented src/app/wrapped/page.tsx with a dynamic, slide-based UI featuring smooth CSS transitions and radial gradient visuals.
  • Added src/app/api/wrapped/og/route.tsx to generate a dynamic, shareable Open Graph (og:image) summary card using next/og (ImageResponse).
  • Added a prominent promotional banner to the top of src/app/dashboard/page.tsx to guide users to their Wrapped experience.

How to Test

  1. Run npm run dev locally.
  2. Navigate to the DevTrack Dashboard. You will see a new glowing banner at the top for the Year in Code.
  3. Click "View Wrapped" to enter the recap experience.
  4. Click the right/left sides of the screen to smoothly transition between stat slides.
  5. Verify the "Share on Twitter" link on the final slide properly formats the intent URL.
  6. Verify the OG Image endpoint by navigating directly to /api/wrapped/og with test query parameters (e.g. ?login=test&year=2026&commits=500).

Checklist

  • Linked issue in summary
  • npm run lint passes locally
  • No TypeScript errors (npm run type-check)
  • Self-reviewed the diff

Copilot AI review requested due to automatic review settings May 25, 2026 10:29
@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

@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.

@github-actions github-actions Bot added gssoc26 GSSoC 2026 contribution type:feature GSSoC type bonus: new feature labels May 25, 2026
@github-actions
Copy link
Copy Markdown

GSSoC Label Checklist 🏷️

@Priyanshu-byte-coder — please apply the appropriate labels before merging:

Difficulty (pick one):

  • level:beginner — 20 pts
  • level:intermediate — 35 pts
  • level:advanced — 55 pts
  • level:critical — 80 pts

Quality (optional):

  • quality:clean — ×1.2 multiplier
  • quality:exceptional — ×1.5 multiplier

Validation (required to score):

  • gssoc:approved — counts for points
  • gssoc:invalid / gssoc:spam / gssoc:ai-slop — does not score

Type labels (type:*) are auto-detected from files and title. Review and adjust if needed.
Points formula: (difficulty × quality_multiplier) + type_bonus

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a “Year in Code / Wrapped” experience: a new dashboard promo card navigates to a slide-based recap page backed by a GitHub-powered API, plus an OG image endpoint for sharing.

Changes:

  • Added /wrapped client page with multi-slide recap UI and sharing CTA.
  • Added /api/wrapped route to aggregate yearly GitHub contribution metrics.
  • Added /api/wrapped/og edge route to generate a shareable OG image and linked entry point from the dashboard.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
src/app/wrapped/page.tsx New client-side “Wrapped” slide UI that fetches recap data and renders a share CTA.
src/app/dashboard/page.tsx Adds a promotional card linking users to the Wrapped page.
src/app/api/wrapped/route.ts New server route that fetches GitHub contribution stats and returns Wrapped JSON.
src/app/api/wrapped/og/route.tsx New edge OG image generator for sharing Wrapped results.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/api/wrapped/og/route.tsx Outdated
{year} Year in Code
</h1>
<p style={{ fontSize: "30px", color: "#a1a1aa", marginTop: "10px" }}>
@{login}&apos;s DevTrack Recap
Comment on lines +28 to +29
const year = yearParam ? parseInt(yearParam, 10) : new Date().getFullYear();

Comment thread src/app/api/wrapped/route.ts Outdated
import { authOptions } from "@/lib/auth";
import { GITHUB_API } from "@/lib/github";
import { resolveAppUser } from "@/lib/resolve-user";
import { dateDiffDays } from "@/lib/dateUtils";
Comment thread src/app/api/wrapped/route.ts Outdated
Comment on lines +162 to +168
const date = new Date(item.commit.author.date);
const hour = date.getHours(); // Local hour of the user based on server processing?
// Wait, server time is UTC. Let's just use getUTCHours or assume user's timezone if possible.
// Since it's server side, let's just use getHours() which will be UTC or server local.
// To be precise we should pass the client timezone, but for simplicity let's use UTC hour and tell user "UTC".
// Actually, many developers use UTC. Or we can just do getHours().
const h = date.getHours();
Comment thread src/app/api/wrapped/route.ts Outdated
headers: { Authorization: `Bearer ${token}` },
cache: "no-store",
}),
fetch(`${GITHUB_API}/search/commits?q=author:${login}+author-date:${year}-01-01..${year}-12-31&per_page=100`, {
Comment thread src/app/wrapped/page.tsx Outdated
Comment on lines +189 to +190
<div className="absolute inset-y-0 left-0 z-40 w-1/3 cursor-pointer" onClick={handlePrev}></div>
<div className="absolute inset-y-0 right-0 z-40 w-2/3 cursor-pointer" onClick={handleNext}></div>
Comment thread src/app/wrapped/page.tsx Outdated
Comment on lines +149 to +150
<a
href={`https://twitter.com/intent/tweet?text=Check out my ${data.year} Year in Code on DevTrack!&url=https://devtrack.com`}
@VIDYANKSHINI
Copy link
Copy Markdown
Contributor Author

VIDYANKSHINI commented May 25, 2026

Hi @Priyanshu-byte-coder, @copilot

I have fully addressed all the feedback and suggestions provided by the Copilot AI code review for the Wrapped feature.

The following fixes have been force-pushed to this PR:

  1. OG Image Typo: Replaced &apos; with a literal apostrophe ' in route.tsx to fix the rendering issue.
  2. Year Validation: Added Number.isFinite(year) and range checks in the API route, returning a 400 Bad Request if an invalid year is provided.
  3. Clean Imports: Removed unused imports from the API route to keep the module focused.
  4. UTC Timestamps: Replaced getHours() with getUTCHours() for accurate Peak Hour calculation, ensuring it aligns with the "UTC" label on the frontend.
  5. Pagination for Commits: The peak-hour calculation now paginates through the GitHub search API (up to 1000 commits / 10 pages) to ensure accurate sampling.
  6. Accessibility: Converted the navigation hit-areas in page.tsx from <div> to <button> elements and added proper aria-labels for screen-reader and keyboard support.
  7. URL Encoding: Added encodeURIComponent to the Twitter share link parameters in page.tsx to prevent broken intent URLs.

All tests and type-checks are passing locally. This PR is ready for your review!

@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

Hi! The feature looks great! However, the core CI checks (Type check, Build, Playwright) didn't run on this PR — only GitGuardian and auto-labeling triggered. Could you check your fork's Actions settings? We need all CI checks to pass before merging. If you're having trouble, let me know!

@github-actions github-actions Bot added the type:testing GSSoC type bonus: tests (+10 pts) label May 25, 2026
@VIDYANKSHINI
Copy link
Copy Markdown
Contributor Author

Hi @Priyanshu-byte-coder,

Thanks for your patience! I've resolved the issues caused by the recent merge with main.

  • Fixed the missing variable type-check error in page.tsx.
  • Resolved the unescaped apostrophe lint error in the OG image route.
  • Fixed the Playwright strict mode violation and duplicate test in landing.spec.js.

All CI checks (Build, Type-check, Lint, and Playwright smoke tests) are now completely green! ✅

Could you please review it now? Let me know if there's anything else you'd like me to change before merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc26 GSSoC 2026 contribution type:feature GSSoC type bonus: new feature type:testing GSSoC type bonus: tests (+10 pts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: "Year in Code" annual recap page (like Spotify Wrapped)

3 participants