Skip to content

Commit 2441f80

Browse files
feat: implement server-side contribution streaks and longest streak tracking
1 parent 9065fed commit 2441f80

8 files changed

Lines changed: 783 additions & 46 deletions

File tree

GITHUB_ISSUE_DRAFT.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Enhancement: Add Contribution Streaks, Activity Distribution, and Profile Dashboard V2
2+
3+
## 🎯 Overview
4+
5+
This issue proposes adding enhanced analytics and visualization features to individual contributor profile pages, building on the recently merged base implementation (PR #26).
6+
7+
## 💡 Motivation
8+
9+
Currently, the leaderboard shows basic contribution metrics. These enhancements will:
10+
11+
- **Gamify contributions** with streak tracking (similar to GitHub)
12+
- **Provide deeper insights** into contribution patterns
13+
- **Improve user engagement** with visual feedback
14+
- **Help maintainers** identify active contributors at a glance
15+
16+
## ✨ Proposed Features
17+
18+
### 1. 🔥 Contribution Streaks
19+
20+
Track and display contributor momentum:
21+
22+
- **Current Streak**: Consecutive days with at least one contribution
23+
- **Longest Streak**: All-time best streak record
24+
- **Visual Indicators**: Fire emoji (🔥) for current, Trophy (🏆) for longest
25+
- **Subtle Animation**: Pulsing effect on active streaks
26+
27+
**Value**: Motivates consistent contributions, similar to GitHub's contribution graph psychology.
28+
29+
### 2. 📊 Activity Distribution Analytics
30+
31+
Visual breakdown of contribution types:
32+
33+
- **Progress Bars**: Show percentage of PRs vs Issues vs Other activities
34+
- **Color Coding**: Green for PRs, Blue for Issues, Gray for Others
35+
- **At-a-Glance Insights**: Quickly understand a contributor's focus area
36+
37+
**Value**: Helps identify specialists (PR reviewers, issue reporters, etc.) and contribution patterns.
38+
39+
### 3. 🎨 Profile Dashboard V2 Layout
40+
41+
Modern 2-column grid design:
42+
43+
- **Sidebar**: User card with avatar, stats, and streaks
44+
- **Main Content**: Enhanced heatmap + activity timeline
45+
- **Responsive**: Collapses to single column on mobile
46+
- **Theme Support**: Full Light/Dark mode compatibility
47+
48+
**Value**: Professional, information-dense layout inspired by modern dashboards.
49+
50+
### 4. 🗓️ Enhanced Activity Heatmap
51+
52+
Improvements to the existing heatmap:
53+
54+
- **Daily Tooltips**: Show exact contribution count and points per day
55+
- **Month Labels**: Uppercase, tracking-tight typography for modern look
56+
- **Accessibility**: ARIA labels and keyboard navigation
57+
58+
**Value**: Makes the heatmap more informative and accessible.
59+
60+
## 🛠️ Technical Implementation
61+
62+
### Backend Changes (`lib/db.ts`)
63+
64+
```typescript
65+
// Add to getContributorProfile function:
66+
- Calculate currentStreak and longestStreak from dailyActivity
67+
- Add distribution object to stats (prs, issues, others counts)
68+
- Ensure null safety for all date operations
69+
```
70+
71+
### Frontend Changes
72+
73+
```typescript
74+
// app/[username]/page.tsx
75+
- Implement 2-column grid layout
76+
- Add DistributionBar component
77+
- Add streak indicators with animation
78+
- Improve TimelineItem styling
79+
80+
// app/globals.css
81+
- Add @keyframes pulse-slow animation
82+
```
83+
84+
### Type Safety
85+
86+
- ✅ 100% TypeScript coverage
87+
- ✅ Proper null checks
88+
- ✅ No `any` types
89+
90+
## 📸 Screenshots
91+
92+
_(Will add screenshots from local development once approved)_
93+
94+
## 🔗 Related Work
95+
96+
- Builds on PR #26 by @Supreeth-C
97+
- Inspired by @Utpal Sen's mockup feedback
98+
- Discussed in Slack: [link to thread]
99+
100+
## 🎓 GSoC Context
101+
102+
This work is part of my GSoC 2026 preparation. I'm focusing on:
103+
104+
- Code quality and type safety
105+
- User experience enhancements
106+
- Community collaboration
107+
108+
## ✅ Acceptance Criteria
109+
110+
- [ ] Streak calculation logic is accurate
111+
- [ ] Activity distribution percentages are correct
112+
- [ ] Layout is responsive on all screen sizes
113+
- [ ] Light/Dark mode works perfectly
114+
- [ ] No TypeScript errors
115+
- [ ] No console warnings
116+
- [ ] Accessible (WCAG 2.1 AA)
117+
118+
## 🚀 Implementation Plan
119+
120+
1. **Phase 1**: Backend logic for streaks and distribution
121+
2. **Phase 2**: Frontend layout and components
122+
3. **Phase 3**: Styling and animations
123+
4. **Phase 4**: Testing and accessibility
124+
125+
## 📝 Notes
126+
127+
- All code is already implemented in my branch: `vivek/circuitverse-pages`
128+
- Ready to submit PR pending maintainer approval
129+
- Open to feedback and iterations
130+
131+
---
132+
133+
**Would you like me to proceed with implementing this, or would you prefer a different approach?**
134+
135+
cc: @Naman-Chhabra @Aboobacker-MK @Utpal-Sen

ISSUE_STREAKS_ONLY.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Enhancement: Add Contribution Streaks to User Profiles
2+
3+
## 🎯 Overview
4+
5+
Add GitHub-style contribution streak tracking to individual contributor profile pages, showing both current and longest streaks to gamify and motivate consistent contributions.
6+
7+
## 💡 Motivation
8+
9+
Contribution streaks are a proven engagement mechanism (popularized by GitHub's contribution graph). They:
10+
11+
- **Motivate consistency**: Encourages daily/regular contributions
12+
- **Provide recognition**: Highlights dedicated contributors
13+
- **Add gamification**: Makes contributing more engaging
14+
- **Show commitment**: Helps identify highly active community members
15+
16+
## ✨ Proposed Feature
17+
18+
### Current Streak 🔥
19+
20+
- Tracks **consecutive days** with at least one contribution
21+
- Displays with fire emoji (🔥)
22+
- Shows subtle pulse animation when active
23+
- Resets when a day is missed
24+
25+
### Longest Streak 🏆
26+
27+
- Tracks **all-time best** consecutive contribution streak
28+
- Displays with trophy emoji (🏆)
29+
- Serves as a personal record/achievement
30+
31+
### Visual Design
32+
33+
```
34+
┌─────────────────────────┐
35+
│ 👤 User Card │
36+
│ 69 Points | 34 Acts │
37+
│ 🔥 0 Days (Current) │ ← Animated pulse
38+
│ 🏆 22 Days (Best) │
39+
└─────────────────────────┘
40+
```
41+
42+
## 🛠️ Technical Implementation
43+
44+
### Backend Changes (`lib/db.ts`)
45+
46+
```typescript
47+
// Add streak calculation helper
48+
function calculateStreaks(dailyActivity: DailyActivity[]) {
49+
let currentStreak = 0;
50+
let longestStreak = 0;
51+
let tempStreak = 0;
52+
53+
const sortedDays = dailyActivity
54+
.filter((d) => d.count > 0)
55+
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
56+
57+
// Calculate current streak
58+
const today = new Date();
59+
today.setHours(0, 0, 0, 0);
60+
61+
for (let i = 0; i < sortedDays.length; i++) {
62+
const dayDate = new Date(sortedDays[i].date);
63+
dayDate.setHours(0, 0, 0, 0);
64+
65+
const expectedDate = new Date(today);
66+
expectedDate.setDate(today.getDate() - i);
67+
68+
if (dayDate.getTime() === expectedDate.getTime()) {
69+
currentStreak++;
70+
} else {
71+
break;
72+
}
73+
}
74+
75+
// Calculate longest streak
76+
// ... (similar logic for all-time longest)
77+
78+
return { current: currentStreak, longest: longestStreak };
79+
}
80+
81+
// Update getContributorProfile
82+
export async function getContributorProfile(username: string) {
83+
// ... existing code ...
84+
85+
const streaks = calculateStreaks(dailyActivity);
86+
87+
return {
88+
// ... existing fields ...
89+
stats: {
90+
// ... existing stats ...
91+
currentStreak: streaks.current,
92+
longestStreak: streaks.longest,
93+
},
94+
};
95+
}
96+
```
97+
98+
### Frontend Changes (`app/[username]/page.tsx`)
99+
100+
```tsx
101+
// Display streaks in user card
102+
<div className="flex items-center gap-2">
103+
<span className={currentStreak > 0 ? "animate-pulse-slow" : ""}>
104+
🔥 {currentStreak} Days
105+
</span>
106+
<span className="text-muted-foreground text-sm">Current</span>
107+
</div>
108+
109+
<div className="flex items-center gap-2">
110+
<span>🏆 {longestStreak} Days</span>
111+
<span className="text-muted-foreground text-sm">Best</span>
112+
</div>
113+
```
114+
115+
### Styling (`app/globals.css`)
116+
117+
```css
118+
@keyframes pulse-slow {
119+
0%,
120+
100% {
121+
opacity: 1;
122+
}
123+
50% {
124+
opacity: 0.7;
125+
}
126+
}
127+
128+
.animate-pulse-slow {
129+
animation: pulse-slow 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
130+
}
131+
```
132+
133+
## 📸 Screenshots
134+
135+
_(Will add after approval)_
136+
137+
## ✅ Acceptance Criteria
138+
139+
- [ ] Current streak calculates correctly (consecutive days)
140+
- [ ] Longest streak tracks all-time best
141+
- [ ] Streak resets properly when days are missed
142+
- [ ] Animation works on active streaks
143+
- [ ] No TypeScript errors
144+
- [ ] Null-safe date handling
145+
- [ ] Works in both Light/Dark mode
146+
- [ ] Responsive on mobile
147+
148+
## 🧪 Testing Plan
149+
150+
### Manual Tests
151+
152+
1. User with active streak (today + yesterday)
153+
2. User with broken streak (gap in contributions)
154+
3. User with no contributions
155+
4. User with longest streak in the past
156+
157+
### Edge Cases
158+
159+
- Timezone handling
160+
- Leap years
161+
- Month boundaries
162+
- New users (no history)
163+
164+
## 📝 Implementation Notes
165+
166+
- Uses existing `dailyActivity` data (no new API calls)
167+
- Purely additive (no breaking changes)
168+
- Backward compatible with current JSON format
169+
- Performance: O(n) where n = days in activity history
170+
171+
## 🔗 Related
172+
173+
- Part of Profile Enhancement series
174+
- Builds on PR #26 by @Supreeth-C
175+
- Inspired by GitHub's contribution streak
176+
177+
---
178+
179+
**Ready to implement!** This will be submitted as a focused PR once approved.
180+
181+
cc: @Naman-Chhabra @Aboobacker-MK @Supreeth-C

0 commit comments

Comments
 (0)