diff --git a/src/Routes/Router.tsx b/src/Routes/Router.tsx
index 40a7861..c08dee8 100644
--- a/src/Routes/Router.tsx
+++ b/src/Routes/Router.tsx
@@ -7,6 +7,7 @@ import Signup from "../pages/Signup/Signup.tsx";
import Login from "../pages/Login/Login.tsx";
import ContributorProfile from "../pages/ContributorProfile/ContributorProfile.tsx";
import Home from "../pages/Home/Home.tsx";
+import Issues from "../pages/Issues/Issues.tsx";
const Router = () => {
return (
@@ -19,6 +20,7 @@ const Router = () => {
} />
} />
} />
+ } />
);
};
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index c6cc86d..c876cb2 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -40,6 +40,12 @@ const Navbar: React.FC = () => {
>
Tracker
+
+ Issues
+
{
>
Contributors
+ setIsOpen(false)}
+ >
+ Issues
+
{
+ const theme = useTheme();
+
+ const [issues, setIssues] = useState([]);
+ const [totalIssues, setTotalIssues] = useState(0);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState("");
+ const [page, setPage] = useState(0);
+
+ const [language, setLanguage] = useState("");
+ const [tag, setTag] = useState("");
+ const [sortOrder, setSortOrder] = useState("desc");
+
+ const fetchIssues = useCallback(async (currentPage: number, currentLanguage: string, currentTag: string, currentOrder: string) => {
+ setLoading(true);
+ setError("");
+
+ try {
+ let q = "is:issue is:open";
+ if (currentLanguage) {
+ q += ` language:${currentLanguage}`;
+ }
+ if (currentTag) {
+ q += ` label:"${currentTag}"`;
+ }
+
+ const response = await fetch(
+ `https://api.github.com/search/issues?q=${encodeURIComponent(q)}&sort=created&order=${currentOrder}&per_page=${ROWS_PER_PAGE}&page=${currentPage + 1}`
+ );
+
+ if (!response.ok) {
+ if (response.status === 403) {
+ throw new Error("GitHub API rate limit exceeded.");
+ }
+ throw new Error("Failed to fetch data");
+ }
+
+ const data = await response.json();
+ setIssues(data.items);
+ setTotalIssues(data.total_count > 1000 ? 1000 : data.total_count); // GitHub limits search results to 1000
+ } catch (err: unknown) {
+ if (err instanceof Error) {
+ setError(err.message || "Failed to fetch issues");
+ } else {
+ setError("Failed to fetch issues");
+ }
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ useEffect(() => {
+ fetchIssues(page, language, tag, sortOrder);
+ }, [page, language, tag, sortOrder, fetchIssues]);
+
+ const handlePageChange = (_: unknown, newPage: number) => {
+ setPage(newPage);
+ };
+
+ const formatDate = (dateString: string): string =>
+ new Date(dateString).toLocaleDateString();
+
+ return (
+
+
+ Explore GitHub Issues
+
+
+
+
+
+ Language
+
+
+
+
+ Tags / Labels
+
+
+
+
+ Sort by Time
+
+
+
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+ {loading ? (
+
+
+
+ ) : (
+
+
+
+
+
+ Title
+ Repository
+ State
+ Created
+
+
+
+ {issues.map((item) => (
+
+
+ {item.state === "closed" ? (
+
+ ) : (
+
+ )}
+
+ {item.title}
+
+
+
+ {item.repository_url.split("/").slice(-2).join("/")}
+
+ {item.state}
+ {formatDate(item.created_at)}
+
+ ))}
+ {issues.length === 0 && !loading && !error && (
+
+
+ No issues found.
+
+
+ )}
+
+
+
+
+
+ )}
+
+ );
+};
+
+export default Issues;