Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions ACTIVITY_REMINDER_FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Daily Activity Reminder System - Feature Documentation

## Overview

The Daily Activity Reminder System is a new enhancement to the GitHub Tracker dashboard that motivates users to maintain consistent contribution streaks. It provides real-time insights into your GitHub activity, tracks contribution streaks, and displays motivational reminders to encourage daily contributions.

## Features

### 1. **Daily Activity Status**
- **Real-time Activity Tracking**: Monitors commits, pull requests, issues, and other GitHub activities throughout the day
- **Activity Count**: Shows how many contributions you've made today
- **Last Activity Date**: Displays when your last contribution was

### 2. **Contribution Streak**
- **Streak Counter**: Tracks consecutive days with GitHub contributions
- **Visual Indicator**: 🔥 Flame emoji indicates active streaks
- **Risk Detection**: Alerts you when your streak is at risk (if you haven't contributed today)
- **Motivational Messages**:
- 1-day streak: 🎯 Keep it going!
- 7-day streak: 🔥 You're on a roll!
- 30-day streak: 🚀 Amazing consistency!
- 100+ days: 👑 Legendary contributor!

### 3. **Productivity Score**
- **Dynamic Calculation**: Based on daily activity metrics
- **Weighted System**:
- 25% each for commits, PRs, merges, and issues
- Bonus points for consecutive streaks (7, 30, 100+ days)
- **Visual Progress Bar**: Shows score with color coding:
- Red: 0-50% (Needs improvement)
- Orange: 50-75% (Good)
- Green: 75-100% (Excellent)

### 4. **Motivational Reminders**
- **Inactivity Alerts**: Reminds you when you haven't contributed today
- **Activity-Specific Messages**:
- 📌 "Time to make your first contribution today"
- 🚀 "You haven't committed today"
- 💻 "No pull requests opened today"
- 📝 "Consider creating or working on an issue"
- **Positive Reinforcement**: Congratulatory messages when you're active

### 5. **Activity Breakdown**
- **Visual Status Indicators**: Quick checklist of today's contributions:
- Commits
- Pull Requests Opened
- Pull Requests Merged
- Issues Created
- **Color-Coded**: Green checkmarks for completed activities, gray for pending

## How It Works

### Data Collection
The system analyzes GitHub activity data from the last 30 days by default and identifies:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if the 30-day window is configurable or hard-coded

# Search for 30-day calculations or configurations
rg -n "30.*day|days.*30" src/hooks/useGitHubActivity.ts src/utils/activityReminders.ts

# Look for any configuration or parameter that might control the time window
ast-grep --pattern 'const $_ = 30'

Repository: GitMetricsLab/github_tracker

Length of output: 54


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ACTIVITY_REMINDER_FEATURE.md excerpt (around line 54) =="
nl -ba ACTIVITY_REMINDER_FEATURE.md | sed -n '40,80p'

echo
echo "== Repo-wide search for 30-day wording =="
rg -n --hidden --no-ignore-vcs -S "last 30 days|30[- ]day|30 days|thirty" \
  -g'*.md' -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx' -g'*.json' -g'*.yml' -g'*.yaml' || true

echo
echo "== Search for numeric 30-day windows (seconds/days multipliers) =="
rg -n --hidden --no-ignore-vcs -S \
  "30\s*\*\s*24\s*\*\s*60|30\s*\*\s*24\s*\*|2592000|time.*30|days?.*30" \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx' || true

echo
echo "== Find likely integration files (Tracker.tsx, reminder/activity code) =="
fd -e ts -e tsx -e js -e jsx -a "Tracker.tsx" . || true
fd -e ts -e tsx -e js -e jsx -a "useGitHubActivity" . || true
fd -e ts -e tsx -e js -e jsx -a "*activity*remind*" . || true

echo
echo "== Search for config keys that might control time window =="
rg -n --hidden --no-ignore-vcs -S \
  "config.*(day|days)|days.*(window|range)|time.*(window|range)|reminder.*(day|days)" \
  -g'*.ts' -g'*.tsx' -g'*.json' -g'*.yml' -g'*.yaml' || true

Repository: GitMetricsLab/github_tracker

Length of output: 193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Tool availability =="
for c in rg fd find sed awk head tail; do
  command -v "$c" >/dev/null 2>&1 && echo "found: $c" || echo "missing: $c"
done

echo
echo "== ACTIVITY_REMINDER_FEATURE.md excerpt (approx lines 45-75) =="
awk 'NR>=45 && NR<=75 {printf "%d\t%s\n", NR, $0}' ACTIVITY_REMINDER_FEATURE.md

echo
echo "== Repo search for exact 'last 30 days' / '30 days' wording =="
rg -n --hidden --no-ignore-vcs -S "last 30 days|last 30 day|30 days|30-day|30[- ]days" || true

echo
echo "== Repo search for likely time window math =="
rg -n --hidden --no-ignore-vcs -S \
  "2592000|30\s*\*\s*24\s*\*\s*60|30\s*\*\s*24\s*\*|time.*(window|range)|days?.*(ago|back)|lookback.*30|past.*30" \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx' -g'*.json' -g'*.yml' -g'*.yaml' || true

echo
echo "== Find likely integration/entry points (Tracker.tsx, activity hooks) =="
if command -v fd >/dev/null 2>&1; then
  fd -e ts -e tsx -e js -e jsx -a "Tracker.tsx" . || true
  fd -e ts -e tsx -e js -e jsx -a "useGitHubActivity" . || true
  fd -e ts -e tsx -e js -e jsx -a "*activity*remind*" . || true
fi

echo
echo "== Repo search for 'display condition' hints (issues/prs) =="
rg -n --hidden --no-ignore-vcs -S "display.*(condition|when)|issues.*pr|pull requests|issues or PRs|some GitHub activity" ACTIVITY_REMINDER_FEATURE.md . || true

Repository: GitMetricsLab/github_tracker

Length of output: 50700


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Repo top-level (quick) =="
find . -maxdepth 2 -type d -name "src" -o -name "app" -o -name "packages" -o -name "frontend" -o -name "." | head

echo
echo "== Search (exclude node_modules) for 30-day window wording =="
rg -n --hidden --no-ignore-vcs -S "last 30 days|30[- ]day|30 days" \
  --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'

echo
echo
echo "== Search (exclude node_modules) for likely lookback math (days/range) =="
rg -n --hidden --no-ignore-vcs -S \
  "2592000|30\s*\*\s*24\s*\*\s*60|30\s*\*\s*24\s*\*|lookback.*30|past.*30|days?.*(ago|back)|time.*window.*30" \
  --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx'

echo
echo
echo "== Search for reminder/activity/streak implementation entry points =="
rg -n --hidden --no-ignore-vcs -S "activity reminder|Activity Reminder|reminder|streak|daily activity" \
  --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx'

echo
echo
echo "== Attempt to locate Tracker.tsx and related components =="
fd -e ts -e tsx -e js -e jsx "Tracker\.tsx" . --max-results 20 2>/dev/null || true
fd -e ts -e tsx -e js -e jsx "Tracker" . --max-results 50 2>/dev/null || true

echo
echo
echo "== Search for 'issues or PRs' display condition implementation =="
rg -n --hidden --no-ignore-vcs -S "issues|pull requests|PRs" \
  --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx'

Repository: GitMetricsLab/github_tracker

Length of output: 8203


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== useGitHubActivity.ts (key sections around streak/30-day logic) =="
awk 'NR>=1 && NR<=220 {print}' src/hooks/useGitHubActivity.ts | sed -n '1,220p'

echo
echo "== activityReminders.ts (any 30-day assumptions) =="
awk 'NR>=1 && NR<=260 {print}' src/utils/activityReminders.ts | sed -n '1,260p'

echo
echo "== Tracker.tsx (Activity Reminder display gating) =="
awk 'NR>=300 && NR<=380 {print}' src/pages/Tracker/Tracker.tsx

echo
echo "== useGitHubData.ts (where issues/PRs date range is chosen) =="
rg -n --hidden --no-ignore-vcs -S "created:|updated:|pushed:|since:|startDate|endDate|lookback|daysAgo|30\s*day|30\s*\*" src/hooks/useGitHubData.ts || true
awk 'NR>=1 && NR<=320 {print}' src/hooks/useGitHubData.ts | sed -n '1,320p'

echo
echo "== Repo-wide search (exclude node_modules) for 30-day window in source =="
rg -n --hidden --no-ignore-vcs -S "last\s*30\s*day|last\s*30\s*days|\b30\s*days\b|30[- ]day|daysAgo|lookback.*30|created:.*30|since:.*30" \
  --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx' || true

Repository: GitMetricsLab/github_tracker

Length of output: 17521


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ACTIVITY_REMINDER_FEATURE.md around Historical Data (110-140) =="
awk 'NR>=105 && NR<=145 {print}' ACTIVITY_REMINDER_FEATURE.md

echo
echo "== Where useGitHubData startDate/endDate are set/passed =="
rg -n --hidden --no-ignore-vcs -S "startDate\s*:|endDate\s*:|filters\.startDate|filters\.endDate|fetchData\(" src --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' -g'*.ts' -g'*.tsx' -g'*.js' -g'*.jsx'

echo
echo "== Search for default 30-day lookback math =="
rg -n --hidden --no-ignore-vcs -S \
  "startDate.*-.*30|endDate.*-.*30|30\s*\*\s*24\s*\*\s*60\s*\*\s*60|30\s*\*\s*24\s*\*\s*60|30\s*\*\s*24|30\s*days|last 30|lookback|DEFAULT_.*30|DAYS.*30" \
  src --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'

echo
echo "== Tracker.tsx: locate fetchData call + any filters construction =="
rg -n --hidden --no-ignore-vcs -S "fetchData\(" src/pages/Tracker/Tracker.tsx
awk 'NR>=1 && NR<=260 {print}' src/pages/Tracker/Tracker.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 2688


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Tracker.tsx: search for startDate/endDate/30-day/filters =="
rg -n --hidden --no-ignore-vcs -S "startDate|endDate|filters|created:>=|created:<=" src/pages/Tracker/Tracker.tsx src/pages/ContributorProfile/ContributorProfile.tsx || true

echo
echo "== Tracker.tsx: search for '30' near date/window usage =="
rg -n --hidden --no-ignore-vcs -S "30" src/pages/Tracker/Tracker.tsx src/pages/ContributorProfile/ContributorProfile.tsx || true

echo
echo "== Tracker.tsx: inspect around the fetchData calls (lines ~60-110) =="
awk 'NR>=60 && NR<=120 {print}' src/pages/Tracker/Tracker.tsx

echo
echo "== Tracker.tsx: inspect around any helper that builds filters (whole file, but limited output) =="
rg -n --hidden --no-ignore-vcs -S "FetchFilters|filters|startDate|endDate" src/pages/Tracker/Tracker.tsx || true

echo
echo "== useGitHubData.ts: check for any default date range constants =="
rg -n --hidden --no-ignore-vcs -S "30|last 30|lookback|window|daysAgo|DEFAULT" src/hooks/useGitHubData.ts || true

echo
echo "== useGitHubData.ts: inspect top 120 lines to ensure no hidden date logic =="
awk 'NR>=1 && NR<=160 {print}' src/hooks/useGitHubData.ts

Repository: GitMetricsLab/github_tracker

Length of output: 6979


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Tracker.tsx: where startDate/endDate are mutated =="
rg -n "setStartDate|setEndDate" src/pages/Tracker/Tracker.tsx

echo
echo "== Tracker.tsx: any fetchData calls that pass filters (startDate/endDate) =="
rg -n "fetchData\(username|fetchData\(" src/pages/Tracker/Tracker.tsx

echo
echo "== Tracker.tsx: grep for filters object usage with startDate/endDate =="
rg -n "fetchData\(.*filters|filters\s*:\s*\{|startDate\s*,|endDate\s*," src/pages/Tracker/Tracker.tsx || true

echo
echo "== Tracker.tsx: locate date filter UI + how filterData is applied =="
rg -n "startDate|endDate|filterData|currentFilteredData" src/pages/Tracker/Tracker.tsx

echo
echo "== Tracker.tsx: view around filterData (approx 110-190) =="
awk 'NR>=100 && NR<=210 {print NR":"$0}' src/pages/Tracker/Tracker.tsx

echo
echo "== Tracker.tsx: view around input fields / date pickers (approx 240-300) =="
awk 'NR>=230 && NR<=310 {print NR":"$0}' src/pages/Tracker/Tracker.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 8198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for computed '30 days ago' style logic in src =="
rg -n --hidden --no-ignore-vcs -S \
  "30\s*\*\s*24\s*\*\s*60\s*\*\s*60\s*\*|30\s*\*\s*24\s*\*\s*60\s*\*|Date\.now\(\)\s*-\s*.*30|now\(\)\s*-\s*.*30|last 30 days|lookback.*30|DEFAULT_.*30" \
  src --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' || true

echo
echo "== Search for 'created:>=' / 'created:<=' being set via filters =="
rg -n --hidden --no-ignore-vcs -S \
  "created:>=|created:<=|filters\.startDate|filters\.endDate" \
  src --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' || true

echo
echo "== Find where startDate/endDate are used in any fetch/filter wiring =="
rg -n --hidden --no-ignore-vcs -S "startDate|endDate" \
  src --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  -g'*.ts' -g'*.tsx' | head -n 80

echo
echo "== Find ROWS_PER_PAGE and how pagination stops/limits fetched range =="
rg -n --hidden --no-ignore-vcs -S "ROWS_PER_PAGE|maxPages|pageLimit|hasMore|infinite|IntersectionObserver|loadMore|onScroll|load more" \
  src/pages/Tracker/Tracker.tsx src/pages/ContributorProfile/ContributorProfile.tsx src/hooks/useGitHubData.ts || true

echo
echo "== Inspect Tracker.tsx around ROWS_PER_PAGE and pagination controls =="
rg -n "ROWS_PER_PAGE" src/pages/Tracker/Tracker.tsx
awk 'NR>=1 && NR<=160 {print NR":"$0}' src/pages/Tracker/Tracker.tsx | sed -n '1,160p'

echo
echo "== Inspect Tracker.tsx for load-more/pagination handlers (later portion) =="
awk 'NR>=160 && NR<=260 {print NR":"$0}' src/pages/Tracker/Tracker.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 10694


Correct the “last 30 days by default” documentation

  • ACTIVITY_REMINDER_FEATURE.md says the feature analyzes “the last 30 days by default”, but the code does not enforce any fixed 30-day lookback in GitHub queries: useGitHubData only applies created:>=startDate / created:<=endDate when filters are provided, while src/pages/Tracker/Tracker.tsx calls fetchData(username, page + 1, ROWS_PER_PAGE) with no filters.
  • The “Start Date/End Date” inputs only filter the already-loaded issues/prs client-side (default is empty), so this is not a hard-coded “last 30 days” window.
  • The display condition (“some GitHub activity (issues or PRs)”) matches the UI gate in Tracker.tsx (username && !loading && (issues.length > 0 || prs.length > 0)).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ACTIVITY_REMINDER_FEATURE.md` at line 54, The docs claim a "last 30 days by
default" window but the code does not enforce a 30-day GitHub query; update
implementation so server/client behavior matches the doc: modify useGitHubData
(the filter application logic around created:>=startDate / created:<=endDate)
and the fetchData call site in src/pages/Tracker/Tracker.tsx (where
fetchData(username, page + 1, ROWS_PER_PAGE) is invoked) to apply a default
startDate = today - 30 days and endDate = today when no filters are provided,
and ensure the Start Date/End Date inputs still perform client-side filtering of
issues/prs arrays while the GitHub query itself is constrained by the default
30-day window (adjust any variable names like issues and prs usage to pass the
default filters through).

- **Commits**: Estimated from PR creation activity
- **Pull Requests**: Tracked separately as opened and merged
- **Issues**: Issues created or interacted with
- **Daily Activity**: All contributions made within a 24-hour period

### Streak Calculation
- Streaks are calculated by checking for consecutive days with at least one contribution
- A streak requires activity every day to maintain continuity
- If you miss a day, your streak resets

### Display Logic
The Activity Reminder appears on the Tracker page when:
1. You've successfully fetched GitHub data (entered username and token)
2. Data has been loaded (not in loading state)
3. You have at least some GitHub activity (issues or PRs)

## Using the Feature

### Step 1: Access the Tracker
Navigate to the **Tracker** page in the GitHub Tracker application.

### Step 2: Authenticate
1. Enter your GitHub username
2. Enter your Personal Access Token (PAT)
3. Click "Fetch Data"

### Step 3: View Your Activity
Once data is loaded, the Daily Activity Status section appears above the data table with:
- Today's contribution count
- Current streak
- Productivity score
- Motivational reminders
- Activity breakdown

### Step 4: Respond to Reminders
Use the motivational reminders as guidance to:
- Plan your contributions for the day
- Maintain your contribution streak
- Reach productivity goals

## Token Requirements

**Authentication with a Personal Access Token (PAT) is required** to view and use the ActivityReminder UI. The component is only displayed when you have successfully authenticated with both a GitHub username and a valid PAT.

Your PAT should have the following permissions:
- `public_repo` (access to public repositories)
- `repo` (access to private repositories - if tracking private repos)

Without valid authentication, the Daily Activity Status reminder widget will not be accessible.

## Technical Details

### Components
- **`useGitHubActivity` Hook**: Analyzes activity data and returns activity status
- **`ActivityReminder` Component**: Displays the reminder UI with all statistics
- **Utility Functions** (`activityReminders.ts`):
- `generateReminders()` - Creates motivational alert messages
- `generateStreakData()` - Calculates streak and generates streak messages
- `getActivitySummary()` - Generates text summary of daily activities
- `getActivityColor()` - Returns color coding based on activity level
- `calculateProductivityScore()` - Computes dynamic productivity score (0-100%)
- `getMotivationLevel()` - Determines motivation tier based on streak

### API Integration
The feature leverages the existing GitHub API integration through:
- `useGitHubData` hook for fetching issues and PRs
- `useGitHubAuth` hook for authentication
- Octokit client for GitHub API requests

### Data Processing
- Activity timestamps are extracted from GitHub API responses
- Daily activity is compared against the current date (00:00-23:59)
- Streak calculation traverses activity history backward in time
- Scores are calculated based on weighted activity metrics

## Limitations

1. **Commit Detection**: Direct commit data requires the `/repos/{owner}/{repo}/commits` endpoint, which is not currently used. Commits are estimated from PR activity.
2. **Historical Data**: Only analyzes the last 30 days of issues and PRs due to GitHub API pagination limits.
3. **Rate Limiting**: GitHub API has rate limits (60 requests/hour for unauthenticated, 5000/hour with token).
4. **Timezone**: Activity is determined based on UTC timezone (when GitHub timestamps are recorded).

## Future Enhancements

Potential improvements for future versions:
- [ ] Weekly productivity heatmap
- [ ] Monthly contribution statistics
- [ ] Achievement badges (First commit, 100-day streak, etc.)
- [ ] Custom notification preferences
- [ ] Email/browser notifications for streak reminders
- [ ] Integration with GitHub contributions graph
- [ ] Detailed contribution analytics
- [ ] Goal setting and tracking

## Troubleshooting

### Activity Reminder not showing
- Ensure you've entered your GitHub username and token
- Click "Fetch Data" to load your GitHub activity
- Check that you have at least one issue or PR in your GitHub history

### Streak not updating
- Wait for the page to fully load data
- The streak is calculated based on your GitHub activity timestamps
- Ensure your GitHub activity has timestamps from recent days

### Incorrect productivity score
- Scores are recalculated based on daily activity (commits, PRs, issues)
- The score includes bonus points for longer streaks
- Refresh the page to recalculate with latest data

## Contact & Feedback

If you encounter issues or have suggestions for improvements, please:
1. Check the existing GitHub issues
2. Create a new issue with detailed information
3. Include screenshots if relevant

---

**Happy contributing! Keep your streak alive!** 🔥
Loading