From f7c551c8feba7f01a179885f93129abd45e49d89 Mon Sep 17 00:00:00 2001 From: Aparna Kumari Date: Sat, 16 May 2026 16:16:44 +0530 Subject: [PATCH] feat: added live GitHub activity feed with UI and time tracking --- src/components/ActivityFeed.tsx | 89 +++++++++++++++++++++++++++++++++ src/pages/ctivity.tsx | 14 ++++++ 2 files changed, 103 insertions(+) create mode 100644 src/components/ActivityFeed.tsx create mode 100644 src/pages/ctivity.tsx diff --git a/src/components/ActivityFeed.tsx b/src/components/ActivityFeed.tsx new file mode 100644 index 0000000..d770dfe --- /dev/null +++ b/src/components/ActivityFeed.tsx @@ -0,0 +1,89 @@ +import { useEffect, useState } from "react"; + +interface EventType { + id: string; + type: string; + created_at: string; + repo?: { + name: string; + }; +} + +export default function ActivityFeed({ username }: { username: string }) { + const [events, setEvents] = useState([]); + const [loading, setLoading] = useState(true); + + // 🕒 time ago function + const getTimeAgo = (dateString: string) => { + const diff = Math.floor( + (Date.now() - new Date(dateString).getTime()) / 1000 + ); + + if (diff < 60) return `${diff}s ago`; + if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; + if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; + return `${Math.floor(diff / 86400)}d ago`; + }; + + useEffect(() => { + const fetchEvents = async () => { + try { + setLoading(true); + + const res = await fetch( + `https://api.github.com/users/${username}/events` + ); + const data = await res.json(); + + setEvents(data); + setLoading(false); + } catch (err) { + console.error(err); + setLoading(false); + } + }; + + fetchEvents(); + + const interval = setInterval(fetchEvents, 30000); + return () => clearInterval(interval); + }, [username]); + + return ( +
+

+ Activity Feed +

+ + {loading ? ( +

Loading...

+ ) : events.length === 0 ? ( +

No activity found

+ ) : ( + events.slice(0, 10).map((event) => ( +
+

+ {event.type === "PushEvent" && "🚀 Commit pushed"} + {event.type === "PullRequestEvent" && "🔀 Pull Request"} + {event.type === "IssuesEvent" && "🐛 Issue"} + {event.type === "WatchEvent" && "⭐ Starred repo"} + {![ + "PushEvent", + "PullRequestEvent", + "IssuesEvent", + "WatchEvent", + ].includes(event.type) && event.type} +

+ +

+ {event.repo?.name} • {getTimeAgo(event.created_at)} +

+
+ )) + )} +
+ ); +} \ No newline at end of file diff --git a/src/pages/ctivity.tsx b/src/pages/ctivity.tsx new file mode 100644 index 0000000..863d07a --- /dev/null +++ b/src/pages/ctivity.tsx @@ -0,0 +1,14 @@ +import ActivityFeed from "../components/ActivityFeed"; +export default function Activity() { + return ( +
+
+

+ Live GitHub Activity +

+ + +
+
+ ); +} \ No newline at end of file