Added Live GitHub Activity Feed using GitHub Events API.#276
Added Live GitHub Activity Feed using GitHub Events API.#276aparna24bce11388 wants to merge 3 commits into
Conversation
✅ Deploy Preview for github-spy ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThis PR introduces a live GitHub activity feed. The ActivityFeed component fetches a user's public events from the GitHub API on a 30-second polling interval, displays them in a list with relative timestamps, and includes a new Activity page and ChangesActivity Feed Feature
Sequence DiagramsequenceDiagram
participant ActivityFeed
participant GitHubAPI as GitHub API
participant ReactState as React State
ActivityFeed->>GitHubAPI: GET /users/{username}/events
GitHubAPI-->>ActivityFeed: JSON events[]
ActivityFeed->>ReactState: set events, set loading=false
ActivityFeed->>ActivityFeed: schedule next poll (30s)
Note over ActivityFeed: Interval repeats until unmount (cleanup)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🎉 Thank you @aparna24bce11388 for your contribution. Please make sure your PR follows https://github.com/GitMetricsLab/github_tracker/blob/main/CONTRIBUTING.md#-pull-request-guidelines
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
src/components/ActivityFeed.tsxsrc/pages/ctivity.tsx
| const res = await fetch( | ||
| `https://api.github.com/users/${username}/events` | ||
| ); | ||
| const data = await res.json(); | ||
|
|
||
| setEvents(data); | ||
| setLoading(false); |
There was a problem hiding this comment.
🧩 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__}")
PYRepository: GitMetricsLab/github_tracker
Length of output: 2690
🏁 Script executed:
git ls-files | head -20Repository: GitMetricsLab/github_tracker
Length of output: 567
🏁 Script executed:
fd -t f "ActivityFeed" --case-sensitiveRepository: GitMetricsLab/github_tracker
Length of output: 104
🏁 Script executed:
find . -name "*.tsx" -o -name "*.ts" | grep -i activityRepository: GitMetricsLab/github_tracker
Length of output: 106
🏁 Script executed:
wc -l src/components/ActivityFeed.tsxRepository: GitMetricsLab/github_tracker
Length of output: 107
🏁 Script executed:
cat -n src/components/ActivityFeed.tsxRepository: 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).
| <p className="text-xs text-gray-500 mt-1"> | ||
| {event.repo?.name} • {getTimeAgo(event.created_at)} | ||
| </p> |
There was a problem hiding this comment.
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.
| <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.
| import ActivityFeed from "../components/ActivityFeed"; | ||
| export default function Activity() { |
There was a problem hiding this comment.
🧩 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.tsxRepository: GitMetricsLab/github_tracker
Length of output: 1271
🏁 Script executed:
cat -n src/pages/ctivity.tsxRepository: 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.
| Live GitHub Activity | ||
| </h1> | ||
|
|
||
| <ActivityFeed username="aparna24bce11388" /> |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
@aparna24bce11388 : please see this , remove hardcorded username
There was a problem hiding this comment.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
|
All checks are passing and the requested changes have been implemented.
Ready for review and merge . |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/Routes/Router.tsx`:
- Line 10: The import in Router.tsx incorrectly references
"../pages/ctivity.tsx" (missing leading "A") which will fail to resolve; rename
the page file to "Activity.tsx" (matching the component name Activity) if it's
currently lowercase/typo'd, then update the import in Router.tsx to import
Activity from "../pages/Activity.tsx" so the symbol Activity resolves correctly
and matches the other page components.
🪄 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: f6fcbb05-74ef-4259-8973-7096e13f7a07
📒 Files selected for processing (2)
src/Routes/Router.tsxsrc/pages/ctivity.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/ctivity.tsx
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/pages/Activity.tsx (1)
10-10:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHardcoded username prevents user-specific activity tracking.
On Line 10,
username="octocat"makes the page always show Octocat events, so this page can’t represent the selected user’s live activity.Suggested fix
import ActivityFeed from "../components/ActivityFeed"; +import { useParams } from "react-router-dom"; export default function Activity() { + const { username } = useParams<{ username: string }>(); + return ( <div className="w-full h-full p-6 bg-gray-50 dark:bg-gray-800"> <div className="max-w-2xl mx-auto"> <h1 className="text-2xl font-bold mb-4 text-center"> Live GitHub Activity </h1> - - <ActivityFeed username="octocat" /> + {username ? ( + <ActivityFeed username={username} /> + ) : ( + <p className="text-center text-sm text-gray-500">No username provided.</p> + )} </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/Activity.tsx` at line 10, The Activity page currently hardcodes the username prop on the ActivityFeed component (ActivityFeed username="octocat"), preventing per-user activity; change Activity.tsx to pass the dynamic username (e.g., from props, context, auth state, or route params) into <ActivityFeed /> instead of "octocat"—locate ActivityFeed usage and replace the fixed string with the appropriate dynamic value (currentUser.username, user.username, params.username, or similar) and add a null/loading fallback if the username may be undefined.
🤖 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.
Duplicate comments:
In `@src/pages/Activity.tsx`:
- Line 10: The Activity page currently hardcodes the username prop on the
ActivityFeed component (ActivityFeed username="octocat"), preventing per-user
activity; change Activity.tsx to pass the dynamic username (e.g., from props,
context, auth state, or route params) into <ActivityFeed /> instead of
"octocat"—locate ActivityFeed usage and replace the fixed string with the
appropriate dynamic value (currentUser.username, user.username, params.username,
or similar) and add a null/loading fallback if the username may be undefined.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f1dc5522-9614-4254-a5c1-601b736d3690
📒 Files selected for processing (2)
src/Routes/Router.tsxsrc/pages/Activity.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Routes/Router.tsx
Related Issue
Description
Added a Live GitHub Activity Feed that displays the latest user activities using the GitHub Events API.
Features implemented:
This enhances the project by transforming it from a static tracker into a dynamic activity dashboard.
How Has This Been Tested?
npm run devScreenshots (if applicable)
Type of Change
Summary by CodeRabbit
Release Notes