Skip to content

Added Live GitHub Activity Feed using GitHub Events API.#276

Open
aparna24bce11388 wants to merge 1 commit into
GitMetricsLab:mainfrom
aparna24bce11388:feat/activity-feed
Open

Added Live GitHub Activity Feed using GitHub Events API.#276
aparna24bce11388 wants to merge 1 commit into
GitMetricsLab:mainfrom
aparna24bce11388:feat/activity-feed

Conversation

@aparna24bce11388
Copy link
Copy Markdown

@aparna24bce11388 aparna24bce11388 commented May 16, 2026

Related Issue


Description

Added a Live GitHub Activity Feed that displays the latest user activities using the GitHub Events API.

Features implemented:

  • Fetches real-time GitHub events (commits, pull requests, issues, stars)
  • Displays events in a clean timeline-style UI
  • Uses polling (auto-refresh every 30 seconds)
  • Added event type icons (🚀 🔀 🐛 ⭐)
  • Shows relative time (e.g., 2m ago, 1h ago)
  • Includes loading and empty states
  • Fully responsive UI with dark mode support

This enhances the project by transforming it from a static tracker into a dynamic activity dashboard.


How Has This Been Tested?

  • Tested locally using npm run dev
  • Verified activity feed updates every 30 seconds
  • Checked different GitHub usernames
  • Confirmed UI responsiveness on different screen sizes
  • No console errors observed

Screenshots (if applicable)

image image image

Type of Change

  • Bug fix
  • New feature
  • Code style update
  • Breaking change
  • Documentation update

Summary by CodeRabbit

  • New Features
    • Added a live GitHub activity feed that displays user events
    • Activity feed automatically refreshes to show the latest updates
    • Events display activity type, repository name, and time information

Review Change Stack

@netlify
Copy link
Copy Markdown

netlify Bot commented May 16, 2026

Deploy Preview for github-spy ready!

Name Link
🔨 Latest commit f7c551c
🔍 Latest deploy log https://app.netlify.com/projects/github-spy/deploys/6a084d825796650008f8a4f7
😎 Deploy Preview https://deploy-preview-276--github-spy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

This PR introduces a live GitHub activity feed feature. It adds an ActivityFeed component that fetches and polls a user's public GitHub events, displays them with relative timestamps and event-type icons, and a new Activity page that integrates the feed with a titled layout.

Changes

Activity Feed Feature

Layer / File(s) Summary
Event data contract and polling setup
src/components/ActivityFeed.tsx
EventType interface defines the GitHub event shape with id, type, created_at, and optional repo.name. Component state holds events and loading flags. getTimeAgo helper formats timestamps as relative strings (e.g., "2 minutes ago"). useEffect fetches events from GitHub API for the provided username and sets up a 30-second polling interval with proper cleanup on unmount.
Activity feed UI rendering
src/components/ActivityFeed.tsx
Conditional rendering branches for loading state, no-activity fallback, and event list. Maps event types to icon/label pairs (e.g., PushEvent → "🚀 Commit"), displays up to 10 events per fetch, and shows repo name alongside relative time for each event.
Activity page integration
src/pages/ctivity.tsx
Activity page component renders a styled container titled "Live GitHub Activity" and mounts ActivityFeed with a fixed username prop pointing to a hardcoded user.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit hops through GitHub's feed,
Ten events per poll at speedy speed,
With icons bright and time so clear,
The activity dashboard now is here! 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: adding a live GitHub activity feed using the GitHub Events API, which matches the core objective of the changeset.
Description check ✅ Passed The PR description follows the template structure completely, includes all required sections with detailed information, covers features, testing approach, and provides screenshots.
Linked Issues check ✅ Passed The implementation addresses the core requirements from issue #241: fetches events via GitHub API, displays timeline UI with event type icons, uses polling for auto-refresh every 30 seconds, includes loading/empty states, and is responsive.
Out of Scope Changes check ✅ Passed Both files (ActivityFeed component and Activity page) are directly related to the linked issue objective and fit within the scope of adding a live GitHub activity feed feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with 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.

Inline comments:
In `@src/components/ActivityFeed.tsx`:
- Around line 81-83: The feed currently renders event.repo?.name directly which
can show "undefined • ..." for events without a repo; update the rendering in
ActivityFeed (the <p> block that uses event.repo?.name and getTimeAgo) to avoid
printing undefined by either: a) using a safe fallback like a default label
(e.g., "Unknown repo") when event.repo?.name is falsy, or b) conditionally
rendering the repo segment only when event.repo?.name exists so the time
(getTimeAgo(event.created_at)) still displays correctly; locate the JSX that
references event.repo?.name in ActivityFeed.tsx and replace it with one of these
approaches.
- Around line 33-39: The fetch in the ActivityFeed component should guard non-OK
responses and invalid payloads before calling setEvents: after awaiting
fetch(...) check res.ok and then parse JSON; validate the parsed data is an
array (Array.isArray) and only then call setEvents(data), otherwise
setEvents([]) (and optionally set an error state). Ensure setLoading(false) runs
in all paths (finally-equivalent) so the component doesn't hang, and avoid
passing non-array values that would break events.slice(0, 10).

In `@src/pages/ctivity.tsx`:
- Around line 1-2: The Activity component in src/pages/ctivity.tsx is orphaned
and embeds a hardcoded username "aparna24bce11388"; either delete the Activity
component file or register it in the app router (e.g., add a route path like
"/activity/:username" in Router.tsx) and refactor Activity to read the username
from route params and pass it into ActivityFeed (change ActivityFeed usage to
accept a username prop instead of the hardcoded string); ensure the route
registration uses the same component name Activity and that ActivityFeed’s prop
signature is updated to accept and use the dynamic username.
- Line 10: The ActivityFeed instance is using a hardcoded username
("aparna24bce11388"); update the page to obtain the selected username from
parent or router state instead of hardcoding: replace the literal in the
ActivityFeed JSX with a dynamic value (e.g., a prop like selectedUser or router
query value from useRouter()) and ensure the page component accepts/derives that
username and passes it into ActivityFeed (look for ActivityFeed and the page
component in ctivity.tsx to change the prop wiring).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bc6008b-5d28-41a4-b1c5-425bc79d8802

📥 Commits

Reviewing files that changed from the base of the PR and between 7a15543 and f7c551c.

📒 Files selected for processing (2)
  • src/components/ActivityFeed.tsx
  • src/pages/ctivity.tsx

Comment on lines +33 to +39
const res = await fetch(
`https://api.github.com/users/${username}/events`
);
const data = await res.json();

setEvents(data);
setLoading(false);
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
set -euo pipefail
python - <<'PY'
import json
from urllib.request import urlopen
from urllib.error import HTTPError

def fetch(url):
    try:
        with urlopen(url) as r:
            return r.status, json.load(r)
    except HTTPError as e:
        body = e.read().decode("utf-8")
        try:
            parsed = json.loads(body)
        except Exception:
            parsed = body
        return e.code, parsed

urls = [
    "https://api.github.com/users/octocat/events",
    "https://api.github.com/users/this-user-should-not-exist-xyz/events",
]
for u in urls:
    status, payload = fetch(u)
    print(f"{u} -> status={status}, json_type={type(payload).__name__}")
PY

Repository: GitMetricsLab/github_tracker

Length of output: 2690


🏁 Script executed:

git ls-files | head -20

Repository: GitMetricsLab/github_tracker

Length of output: 567


🏁 Script executed:

fd -t f "ActivityFeed" --case-sensitive

Repository: GitMetricsLab/github_tracker

Length of output: 104


🏁 Script executed:

find . -name "*.tsx" -o -name "*.ts" | grep -i activity

Repository: GitMetricsLab/github_tracker

Length of output: 106


🏁 Script executed:

wc -l src/components/ActivityFeed.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 107


🏁 Script executed:

cat -n src/components/ActivityFeed.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 3146


Guard non-OK and invalid GitHub payloads before setting events.

The code assigns the JSON response directly to events without checking res.ok or validating the payload shape. When GitHub returns an error (e.g., 404, 403), it sends a JSON object, not an event array. This causes a runtime crash when the component later calls events.slice(0, 10).

Proposed fix
-        const data = await res.json();
-
-        setEvents(data);
-        setLoading(false);
+        if (!res.ok) {
+          throw new Error(`GitHub events request failed: ${res.status}`);
+        }
+        const data: unknown = await res.json();
+        setEvents(Array.isArray(data) ? (data as EventType[]) : []);
       } catch (err) {
         console.error(err);
-        setLoading(false);
+        setEvents([]);
+      } finally {
+        setLoading(false);
       }
🤖 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 `@src/components/ActivityFeed.tsx` around lines 33 - 39, The fetch in the
ActivityFeed component should guard non-OK responses and invalid payloads before
calling setEvents: after awaiting fetch(...) check res.ok and then parse JSON;
validate the parsed data is an array (Array.isArray) and only then call
setEvents(data), otherwise setEvents([]) (and optionally set an error state).
Ensure setLoading(false) runs in all paths (finally-equivalent) so the component
doesn't hang, and avoid passing non-array values that would break
events.slice(0, 10).

Comment on lines +81 to +83
<p className="text-xs text-gray-500 mt-1">
{event.repo?.name} • {getTimeAgo(event.created_at)}
</p>
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 | 🟡 Minor | ⚡ Quick win

Avoid rendering undefined for missing repo names.

Some events may not carry repo.name; current UI can show undefined • ....

Proposed fix
-              {event.repo?.name} • {getTimeAgo(event.created_at)}
+              {event.repo?.name ?? "Unknown repository"} • {getTimeAgo(event.created_at)}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p className="text-xs text-gray-500 mt-1">
{event.repo?.name} {getTimeAgo(event.created_at)}
</p>
<p className="text-xs text-gray-500 mt-1">
{event.repo?.name ?? "Unknown repository"} {getTimeAgo(event.created_at)}
</p>
🤖 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 `@src/components/ActivityFeed.tsx` around lines 81 - 83, The feed currently
renders event.repo?.name directly which can show "undefined • ..." for events
without a repo; update the rendering in ActivityFeed (the <p> block that uses
event.repo?.name and getTimeAgo) to avoid printing undefined by either: a) using
a safe fallback like a default label (e.g., "Unknown repo") when
event.repo?.name is falsy, or b) conditionally rendering the repo segment only
when event.repo?.name exists so the time (getTimeAgo(event.created_at)) still
displays correctly; locate the JSX that references event.repo?.name in
ActivityFeed.tsx and replace it with one of these approaches.

Comment thread src/pages/ctivity.tsx
Comment on lines +1 to +2
import ActivityFeed from "../components/ActivityFeed";
export default function Activity() {
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Candidate page/router files =="
fd -i 'ctivity\.tsx|Activity\.tsx|App\.tsx|router\.tsx|routes\.tsx'

echo
echo "== References to activity routes/imports =="
rg -n -C2 --type=tsx 'ctivity|Activity|/activity|Live GitHub Activity'

Repository: GitMetricsLab/github_tracker

Length of output: 253


🏁 Script executed:

cat -n src/Routes/Router.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 1271


🏁 Script executed:

cat -n src/pages/ctivity.tsx

Repository: GitMetricsLab/github_tracker

Length of output: 573


Remove the orphaned Activity component or register it properly in the router.

The file src/pages/ctivity.tsx is not imported or registered in src/Routes/Router.tsx, making the page unreachable. Additionally, the hardcoded username aparna24bce11388 at line 10 prevents dynamic per-user tracking behavior. Either delete the unused component or register the route (e.g., /activity/:username) and refactor ActivityFeed to accept a username prop from the router.

🤖 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 `@src/pages/ctivity.tsx` around lines 1 - 2, The Activity component in
src/pages/ctivity.tsx is orphaned and embeds a hardcoded username
"aparna24bce11388"; either delete the Activity component file or register it in
the app router (e.g., add a route path like "/activity/:username" in Router.tsx)
and refactor Activity to read the username from route params and pass it into
ActivityFeed (change ActivityFeed usage to accept a username prop instead of the
hardcoded string); ensure the route registration uses the same component name
Activity and that ActivityFeed’s prop signature is updated to accept and use the
dynamic username.

Comment thread src/pages/ctivity.tsx
Live GitHub Activity
</h1>

<ActivityFeed username="aparna24bce11388" />
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 | 🏗️ Heavy lift

Remove hardcoded username from the page contract.

This locks the feature to one account instead of tracking the selected user.

Proposed direction (wire username from parent/router state)
-export default function Activity() {
+export default function Activity({ username }: { username: string }) {
   return (
@@
-        <ActivityFeed username="aparna24bce11388" />
+        <ActivityFeed username={username} />
       </div>
     </div>
   );
 }
🤖 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 `@src/pages/ctivity.tsx` at line 10, The ActivityFeed instance is using a
hardcoded username ("aparna24bce11388"); update the page to obtain the selected
username from parent or router state instead of hardcoding: replace the literal
in the ActivityFeed JSX with a dynamic value (e.g., a prop like selectedUser or
router query value from useRouter()) and ensure the page component
accepts/derives that username and passes it into ActivityFeed (look for
ActivityFeed and the page component in ctivity.tsx to change the prop wiring).

@aparna24bce11388
Copy link
Copy Markdown
Author

All checks are passing and the requested changes have been implemented.

  • Fixed analytics issues
  • Cleaned Prisma schema & migrations
  • Removed unused dependencies
  • Added Live GitHub Activity Feed with real-time updates, icons, and timestamps

Ready for review and merge .

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 Feature: Add real-time activity feed showing latest GitHub events

1 participant