diff --git a/src/components/DeveloperSummary.tsx b/src/components/DeveloperSummary.tsx new file mode 100644 index 00000000..f9b20894 --- /dev/null +++ b/src/components/DeveloperSummary.tsx @@ -0,0 +1,151 @@ +import React, { useEffect, useState } from "react"; +import { + Paper, + Typography, + Box, + Avatar, + Chip, +} from "@mui/material"; + +interface DeveloperProfile { + name: string; + bio: string; + followers: number; + following: number; + public_repos: number; + avatar_url: string; +} + +interface Props { + username: string; + token?: string; +} + +const DeveloperSummary: React.FC = ({ username, token }) => { + const [profile, setProfile] = + useState(null); + +useEffect(() => { + if (!username.trim()) { + setProfile(null); + return; + } + + const controller = new AbortController(); + + const timeout = setTimeout(async () => { + try { + setProfile(null); + + const response = await fetch( + `https://api.github.com/users/${username}`, + { + signal: controller.signal, + ...(token && { + headers: { + Authorization: `Bearer ${token}`, + }, + }), + } + ); + + if (!response.ok) { + const errorData = + await response.json().catch(() => null); + + throw new Error( + errorData?.message || + `GitHub request failed (${response.status})` + ); + } + + const data = await response.json(); + + setProfile(data); + } catch (error) { + if ( + error instanceof Error && + error.name !== "AbortError" + ) { + console.error(error); + setProfile(null); + } + } + }, 500); + + return () => { + clearTimeout(timeout); + controller.abort(); + }; +}, [username, token]); + + if (!profile) return null; + + return ( + + + + + + + {profile.name || username} + + + {profile.bio && ( + + {profile.bio} + + )} + + + + + + + + + + + {profile.name || username} has{" "} + {profile.public_repos} public repositories and{" "} + {profile.followers} followers, showing active + participation in the GitHub community. + + + ); +}; + +export default DeveloperSummary; \ No newline at end of file diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 576f39bf..775a0a92 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -33,6 +33,8 @@ import { useTheme } from "@mui/material/styles"; import { useGitHubAuth } from "../../hooks/useGitHubAuth"; import { useGitHubData } from "../../hooks/useGitHubData"; import { KeyIcon } from "lucide-react"; +import DeveloperSummary from "../../components/DeveloperSummary"; + const ROWS_PER_PAGE = 10; @@ -241,7 +243,10 @@ const Home: React.FC = () => { - + {/* Filters */}