diff --git a/src/components/profile/PinnedRepos.jsx b/src/components/profile/PinnedRepos.jsx new file mode 100644 index 0000000..507e444 --- /dev/null +++ b/src/components/profile/PinnedRepos.jsx @@ -0,0 +1,147 @@ +import React, { useState, useEffect } from "react"; +import { Star, GitFork } from "lucide-react"; +import Loader from "../ui/Loader"; + +const GITHUB_GRAPHQL_API = "https://api.github.com/graphql"; + +const PINNED_REPOS_QUERY = ` + query($username: String!) { + user(login: $username) { + pinnedItems(first: 6, types: REPOSITORY) { + nodes { + ... on Repository { + name + description + stargazerCount + forkCount + primaryLanguage { + name + color + } + url + } + } + } + } + } +`; + +export const PinnedRepos = ({ githubUsername, accessToken }) => { + const [pinnedRepos, setPinnedRepos] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + if (!githubUsername) return; + + const fetchPinnedRepos = async () => { + setLoading(true); + setError(null); + + try { + const response = await fetch(GITHUB_GRAPHQL_API, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${accessToken}`, + }, + body: JSON.stringify({ + query: PINNED_REPOS_QUERY, + variables: { username: githubUsername }, + }), + }); + + if (!response.ok) { + throw new Error(`GitHub API error: ${response.status}`); + } + + const result = await response.json(); + + if (result.errors) { + throw new Error(result.errors[0]?.message || "GraphQL error"); + } + + const repos = result.data?.user?.pinnedItems?.nodes || []; + setPinnedRepos(repos); + } catch (err) { + console.error("Error fetching pinned repos:", err); + setError(err.message); + } finally { + setLoading(false); + } + }; + + fetchPinnedRepos(); + }, [githubUsername, accessToken]); + + if (!githubUsername) return null; + + if (loading) return ( +
+ Top repositories pinned on GitHub +
+