Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import ScrollProgressBar from './components/ScrollProgressBar';
Expand Down
3 changes: 2 additions & 1 deletion src/Routes/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Contact from "../pages/Contact/Contact"; // Import the Contact component
import Contributors from "../pages/Contributors/Contributors";
import Signup from "../pages/Signup/Signup.tsx";
import Login from "../pages/Login/Login.tsx";

import UserProfile from "../pages/UserProfile/UserProfile.tsx";

const Router = () => {
return (
Expand All @@ -19,6 +19,7 @@ const Router = () => {
<Route path="/contact" element={<Contact />} />
<Route path="/home" element={<Home />} />
<Route path="/contributors" element={<Contributors />} />
<Route path="/user/:username" element={<UserProfile />} />
</Routes>
);
};
Expand Down
135 changes: 72 additions & 63 deletions src/pages/Contributors/Contributors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "@mui/material";
import { FaGithub } from "react-icons/fa";
import axios from "axios";
import { Link } from "react-router-dom"; // ✅ Added

interface Contributor {
id: number;
Expand All @@ -30,7 +31,8 @@ const ContributorsPage = () => {
useEffect(() => {
const fetchContributors = async () => {
try {
const response = await axios.get("https://api.github.com/repos/GitMetricsLab/github_tracker/contributors",
const response = await axios.get(
"https://api.github.com/repos/GitMetricsLab/github_tracker/contributors",
{ withCredentials: false }
);
setContributors(response.data);
Expand Down Expand Up @@ -84,76 +86,83 @@ const ContributorsPage = () => {
<Grid container spacing={3}>
{contributors.map((contributor) => (
<Grid item xs={12} sm={6} md={4} key={contributor.id}>
<Card
sx={{
textAlign: "center",
p: 2,
borderRadius: "12px",
border: "1px solid #e0e0e0",
backgroundColor: "#F9F9F9",
transition: "transform 0.3s ease-in-out",
"&:hover": {
transform: "scale(1.03)",
boxShadow: "0 8px 15px rgba(0,0,0,0.15)",
borderColor: "#ccc",
},
}}
<Link
to={`/user/${contributor.login}`} // ✅ Add link to user profile
style={{ textDecoration: "none" }}
>
<Avatar
src={contributor.avatar_url}
alt={contributor.login}
<Card
sx={{
width: 80,
height: 80,
mx: "auto",
mb: 2,
textAlign: "center",
p: 2,
borderRadius: "12px",
border: "1px solid #e0e0e0",
backgroundColor: "#F9F9F9",
transition: "transform 0.3s ease-in-out",
"&:hover": {
transform: "scale(1.03)",
boxShadow: "0 8px 15px rgba(0,0,0,0.15)",
borderColor: "#ccc",
},
}}
/>
<CardContent>
<Typography
variant="h6"
>
<Avatar
src={contributor.avatar_url}
alt={contributor.login}
sx={{
fontWeight: "bold",
fontSize: { xs: "1rem", sm: "1.2rem" },
width: 80,
height: 80,
mx: "auto",
mb: 2,
}}
>
{contributor.login}
</Typography>
<Typography
variant="body2"
color="text.secondary"
sx={{ mt: 1 }}
>
{contributor.contributions} Contributions
</Typography>
<Typography
variant="body2"
sx={{ mt: 2, fontSize: { xs: "0.85rem", sm: "1rem" } }}
>
Thank you for your valuable contributions!
</Typography>
<Box sx={{ mt: 2 }}>
<Button
variant="contained"
startIcon={<FaGithub />}
href={contributor.html_url}
target="_blank"
/>
<CardContent>
<Typography
variant="h6"
sx={{
backgroundColor: "#24292f",
color: "#fff",
fontSize: { xs: "0.75rem", sm: "0.85rem" },
px: 2,
py: 1,
"&:hover": {
backgroundColor: "#444",
},
fontWeight: "bold",
fontSize: { xs: "1rem", sm: "1.2rem" },
color: "#333",
}}
>
GitHub Profile
</Button>
</Box>
</CardContent>
</Card>
{contributor.login}
</Typography>
<Typography
variant="body2"
color="text.secondary"
sx={{ mt: 1 }}
>
{contributor.contributions} Contributions
</Typography>
<Typography
variant="body2"
sx={{ mt: 2, fontSize: { xs: "0.85rem", sm: "1rem" } }}
>
Thank you for your valuable contributions!
</Typography>
<Box sx={{ mt: 2 }}>
<Button
variant="contained"
startIcon={<FaGithub />}
href={contributor.html_url}
target="_blank"
sx={{
backgroundColor: "#24292f",
color: "#fff",
fontSize: { xs: "0.75rem", sm: "0.85rem" },
px: 2,
py: 1,
"&:hover": {
backgroundColor: "#444",
},
}}
onClick={(e) => e.stopPropagation()} // prevent nested Link trigger
>
GitHub Profile
</Button>
</Box>
</CardContent>
</Card>
</Link>
</Grid>
))}
</Grid>
Expand Down
57 changes: 57 additions & 0 deletions src/pages/UserProfile/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";

type PR = {
title: string;
html_url: string;
repository_url: string;
};

export default function UserProfile() {
const { username } = useParams();
const [profile, setProfile] = useState<any>(null);
const [prs, setPRs] = useState<PR[]>([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
async function fetchData() {
if (!username) return;

const userRes = await fetch(`https://api.github.com/users/${username}`);
const userData = await userRes.json();
setProfile(userData);

const prsRes = await fetch(`https://api.github.com/search/issues?q=author:${username}+type:pr`);
const prsData = await prsRes.json();
setPRs(prsData.items);
setLoading(false);
}

fetchData();
}, [username]);

if (loading) return <div className="text-center mt-10">Loading...</div>;

return (
<div className="max-w-3xl mx-auto mt-10 p-4 bg-white shadow-xl rounded-xl">
{profile && (
<div className="text-center">
<img src={profile.avatar_url} className="w-24 h-24 mx-auto rounded-full" />
<h2 className="text-2xl font-bold mt-2">{profile.login}</h2>
<p className="text-gray-600">{profile.bio}</p>
</div>
)}

<h3 className="text-xl font-semibold mt-6 mb-2">Pull Requests</h3>
<ul className="list-disc ml-6 space-y-2">
{prs.map((pr, i) => (
<li key={i}>
<a href={pr.html_url} target="_blank" className="text-blue-600 hover:underline">
{pr.title}
</a>
</li>
))}
</ul>
</div>
);
}