diff --git a/src/App.tsx b/src/App.tsx
index ccc6c670..d6ab9121 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -4,6 +4,7 @@ import Footer from "./components/Footer";
import ScrollProgressBar from "./components/ScrollProgressBar";
import { Toaster } from "react-hot-toast";
import Router from "./Routes/Router";
+import ScrollToTopButton from "./components/ScrollToTopButton";
const FULLSCREEN_ROUTES = ["/signup", "/login"];
@@ -12,35 +13,41 @@ function App() {
const isFullscreen = FULLSCREEN_ROUTES.includes(location.pathname);
return (
-
- {!isFullscreen && }
-
- {!isFullscreen && }
-
-
-
-
-
- {!isFullscreen && }
-
-
+ {!isFullscreen && }
+
+ {!isFullscreen && }
+
+
+
+
+
+ {!isFullscreen && }
+ {!isFullscreen && }
+
-
+ },
+ }}
+ />
+
);
}
diff --git a/src/components/ScrollToTopButton.tsx b/src/components/ScrollToTopButton.tsx
new file mode 100644
index 00000000..9d877da6
--- /dev/null
+++ b/src/components/ScrollToTopButton.tsx
@@ -0,0 +1,55 @@
+import { useEffect, useState } from "react";
+import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
+
+const ScrollToTopButton = () => {
+ const [visible, setVisible] = useState(false);
+
+ useEffect(() => {
+ const toggleVisibility = () => {
+ if (window.scrollY > 10) {
+ setVisible(true);
+ } else {
+ setVisible(false);
+ }
+ };
+
+ window.addEventListener("scroll", toggleVisibility);
+
+ return () => {
+ window.removeEventListener("scroll", toggleVisibility);
+ };
+ }, []);
+
+ const scrollToTop = () => {
+ window.scrollTo({
+ top: 0,
+ behavior: "smooth",
+ });
+ };
+
+ return (
+ visible && (
+
+ )
+ );
+};
+
+export default ScrollToTopButton;
diff --git a/src/pages/Contributors/Contributors.tsx b/src/pages/Contributors/Contributors.tsx
index d4fee52c..56816ad1 100644
--- a/src/pages/Contributors/Contributors.tsx
+++ b/src/pages/Contributors/Contributors.tsx
@@ -1,4 +1,6 @@
import { useEffect, useState } from "react";
+import { TextField, InputAdornment } from "@mui/material";
+import { FaSearch } from "react-icons/fa";
import {
Container,
Grid,
@@ -28,6 +30,7 @@ const ContributorsPage = () => {
const [contributors, setContributors] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
+ const [searchTerm, setSearchTerm] = useState("");
// Fetch contributors from GitHub API
useEffect(() => {
@@ -47,6 +50,10 @@ const ContributorsPage = () => {
fetchContributors();
}, []);
+ const filteredContributors = contributors.filter((contributor) =>
+ contributor.login.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+
if (loading) {
return (
@@ -65,74 +72,136 @@ const ContributorsPage = () => {
return (
-
+
🤝 Contributors
+
+ setSearchTerm(e.target.value)}
+ sx={{
+ width: {
+ xs: "100%",
+ sm: "400px",
+ },
+ maxWidth: "100%",
+ backgroundColor: "white",
+ borderRadius: "10px",
+ }}
+ InputProps={{
+ startAdornment: (
+
+
+
+ ),
+ }}
+ />
+
-
- {contributors.map((contributor) => (
-
-
+ {filteredContributors.length === 0 && (
+
+ No contributors found.
+
+ )}
+ {filteredContributors.map((contributor) => (
+
+
+
-
-
-
-
- {contributor.login}
-
+
+
+
+ {contributor.login}
+
-
- {contributor.contributions} Contributions
-
- {/*
+
+ {contributor.contributions} Contributions
+
+ {/*
Thank you for your valuable contributions to our
community!
*/}
-
-
+
+
-
- }
- href={contributor.html_url}
- target="_blank"
- sx={{
- backgroundColor: "#333333",
- textTransform: "none",
- color: "#FFFFFF",
- "&:hover": {
- backgroundColor: "#555555",
- },
- }}
- >
- GitHub
-
-
-
+
+ }
+ href={contributor.html_url}
+ target="_blank"
+ rel="noopener noreferrer"
+ sx={{
+ backgroundColor: "#333333",
+ textTransform: "none",
+ color: "#FFFFFF",
+ "&:hover": {
+ backgroundColor: "#555555",
+ },
+ }}
+ >
+ GitHub
+
+
+
))}
diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx
index b03eb5a4..2ee04866 100644
--- a/src/pages/Tracker/Tracker.tsx
+++ b/src/pages/Tracker/Tracker.tsx
@@ -6,7 +6,6 @@ import {
GitPullRequestClosedIcon,
GitMergeIcon,
} from "@primer/octicons-react";
-
import {
Container,
Box,
@@ -161,37 +160,58 @@ const Home: React.FC = () => {
const formatDate = (dateString: string): string =>
new Date(dateString).toLocaleDateString();
+ const filterData = (data: GitHubItem[], filterType: string): GitHubItem[] => {
+ let filtered = [...data];
+ if (["open", "closed", "merged"].includes(filterType)) {
+ filtered = filtered.filter((item) => {
+ if (filterType === "merged") {
+ return !!item.pull_request?.merged_at;
+ } else if (filterType === "closed") {
+ return item.state === "closed" && !item.pull_request?.merged_at;
+ } else {
+ //open
+ return item.state === "open";
+ }
+ });
+ }
+ if (searchTitle) {
+ filtered = filtered.filter((item) =>
+ item.title.toLowerCase().includes(searchTitle.toLowerCase()),
+ );
+ }
+ if (selectedRepo) {
+ filtered = filtered.filter((item) =>
+ item.repository_url.includes(selectedRepo),
+ );
+ }
+ if (startDate) {
+ filtered = filtered.filter(
+ (item) => new Date(item.created_at) >= new Date(startDate),
+ );
+ }
+ if (endDate) {
+ filtered = filtered.filter(
+ (item) => new Date(item.created_at) <= new Date(endDate),
+ );
+ }
+ return filtered;
+ };
+
const getStatusIcon = (item: GitHubItem) => {
if (item.pull_request) {
- if (item.pull_request.merged_at) {
+ if (item.pull_request.merged_at)
return ;
- }
- if (item.state === "closed") {
+ if (item.state === "closed")
return (
-
+
);
- }
- return (
-
- );
+ return ;
}
- if (item.state === "closed") {
- return (
-
- );
- }
+ if (item.state === "closed")
+ return ;
return (
{
);
};
- const currentData = tab === 0 ? issues : prs;
+ // Current data and filtered data according to tab and filters
+ const currentRawData = tab === 0 ? issues : prs;
+ const currentFilteredData = filterData(
+ currentRawData,
+ tab === 0 ? issueFilter : prFilter,
+ );
const totalCount = tab === 0 ? totalIssues : totalPrs;
return (
- {/* Auth Inputs */}
+ {/* Auth Form */}
-
- setUsername(e.target.value)}
- placeholder="Start typing to search..."
- sx={{ flex: 1, minWidth: 150 }}
- />
-
- setToken(e.target.value)}
- type="password"
- sx={{ flex: 1, minWidth: 150 }}
- helperText={
-
-
-
- Generate new token
-
-
+
+
+
+ Generate new token
+
+
+
+ •
+
+
+
+ Learn more
+
+
+ }
+ />
+
+
+
{/* Filters */}
@@ -406,20 +427,11 @@ const Home: React.FC = () => {
)}
{loading ? (
-
+
) : (
-
+
@@ -442,23 +454,15 @@ const Home: React.FC = () => {
{currentData.map((item) => (
{getStatusIcon(item)}
-
{item.title}
@@ -478,9 +482,7 @@ const Home: React.FC = () => {
: item.state}
-
- {formatDate(item.created_at)}
-
+ {formatDate(item.created_at)}
))}