Skip to content
Closed
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
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>GitHub Tracker</title>
</head>
<body>
<div id="root"></div>
Expand Down
2 changes: 2 additions & 0 deletions src/Routes/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import Contact from "../pages/Contact/Contact"; // Import the Contact component
import Contributors from "../pages/Contributors/Contributors";
import Login from "../pages/Auth/Login";
import Signup from "../pages/Auth/Signup";
import PRlist from "../components/PRlist";

const Router = () => {
return (
<Routes>
{/* Redirect from root (/) to the home page */}
<Route path="/" element={<Navigate to="/home" replace />} />
<Route path="/prs/:gitusername?" element={<PRlist />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/home" element={<Home />} />
Expand Down
118 changes: 118 additions & 0 deletions src/components/PRlist.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import {
Container,
Paper,
Box,
CircularProgress,
Alert,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Link,
} from "@mui/material";


interface PR {
id: number;
title: string;
html_url: string;
repository_url: string;
state: string;
created_at: string;
}


const PRlist = () => {
const { gitusername } = useParams<{ gitusername: string }>();
const [prs, setPrs] = useState<PR[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string>("");

useEffect(() => {
if (gitusername) {
const fetchPRs = async () => {
setLoading(true);
setError("");
try {
// Fetch PRs from GitHub API (public repos only)
const response = await fetch(`https://api.github.com/search/issues?q=type:pr+author:${gitusername}+state:open`);
const data = await response.json();
setPrs(data.items || []);
} catch (err) {
console.error("Error fetching PRs:", err);
setError("Error fetching pull requests.");
} finally {
setLoading(false);
}
};

fetchPRs();
}
}, [gitusername]);

const formatDate = (dateString: string): string => {
return new Date(dateString).toLocaleDateString();
};

return (
<Container maxWidth="lg" sx={{ mt: 4 }}>
<Paper elevation={1} sx={{ p: 2, mb: 3 }}>
<h1 className="text-red-400 flex justify-center">{gitusername && `You are viewing ${gitusername}'s Open Pull Requests`}</h1>
{error && <Alert severity="error" sx={{ mb: 2 }}>{error}</Alert>}

{loading ? (
<Box display="flex" justifyContent="center" my={4}>
<CircularProgress />
</Box>
) : (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell sx={{ textAlign: "left" }}>Title</TableCell>
<TableCell sx={{ textAlign: "center" }}>Repository</TableCell>
<TableCell sx={{ textAlign: "center" }}>State</TableCell>
<TableCell sx={{ textAlign: "center" }}>Created</TableCell>
</TableRow>
</TableHead>
<TableBody>
{prs.length > 0 ? (
prs.map((pr) => (
<TableRow key={pr.id}>
<TableCell sx={{ textAlign: "left" }}>
<Link href={pr.html_url} target="_blank" rel="noopener noreferrer">
{pr.title}
</Link>
</TableCell>
<TableCell sx={{ textAlign: "center" }}>
{pr.repository_url.replace("https://api.github.com/repos/", "")}
</TableCell>
<TableCell sx={{ textAlign: "center" }}>
{pr.state}
</TableCell>
<TableCell sx={{ textAlign: "center" }}>
{formatDate(pr.created_at)}
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={3} sx={{ textAlign: "center" }}>
No open pull requests found for {gitusername}.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
)}
</Paper>
</Container>
);
};

export default PRlist;
16 changes: 16 additions & 0 deletions src/pages/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { useGitHubAuth } from "../../hooks/useGitHubAuth";
import { useGitHubData } from "../../hooks/useGitHubData";
import { usePagination } from "../../hooks/usePagination";
import toast from "react-hot-toast";

const ROWS_PER_PAGE = 10;

Expand Down Expand Up @@ -82,6 +83,13 @@ const Home: React.FC = () => {
return new Date(dateString).toLocaleDateString();
};

// generates the shareable link
const generateSharableLink = () => {
const link = `${window.location.origin}/prs/${username}`;
window.navigator.clipboard.writeText(link);
toast.success("link copied to the clipboard");
};

// Filter data based on selected criteria
const filterData = (
data: GitHubItem[],
Expand Down Expand Up @@ -214,6 +222,14 @@ const Home: React.FC = () => {
<Tab label={`Issues (${filterData(issues, issueFilter).length})`} />
<Tab label={`Pull Requests (${filterData(prs, prFilter).length})`} />
</Tabs>
<Button
variant="contained"
className="bg-blue-400"
onClick={generateSharableLink}
disabled={!username}
>
Share PRs
</Button>
<FormControl sx={{ minWidth: 150 }}>
<InputLabel sx={{ fontSize: "14px", color: "#555" }}>State</InputLabel>
<Select
Expand Down