diff --git a/index.html b/index.html index b6d940d0..ee60b122 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,31 @@ - Github Tracker + + GitHub Tracker - Monitor GitHub User Activity + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/public/og-image.png b/public/og-image.png new file mode 100644 index 00000000..8aeea9cc Binary files /dev/null and b/public/og-image.png differ diff --git a/src/hooks/usePageTitle.ts b/src/hooks/usePageTitle.ts new file mode 100644 index 00000000..c6d3e06a --- /dev/null +++ b/src/hooks/usePageTitle.ts @@ -0,0 +1,14 @@ +import { useEffect } from 'react'; + +const APP_NAME = 'GitHub Tracker'; + +const usePageTitle = (title: string): void => { + useEffect(() => { + document.title = title ? `${title} — ${APP_NAME}` : APP_NAME; + return () => { + document.title = APP_NAME; + }; + }, [title]); +}; + +export default usePageTitle; \ No newline at end of file diff --git a/src/pages/About/About.tsx b/src/pages/About/About.tsx index 04af2048..5bd92b8b 100644 --- a/src/pages/About/About.tsx +++ b/src/pages/About/About.tsx @@ -1,5 +1,6 @@ import { motion } from "framer-motion"; import { Lightbulb, Users, Settings, Search } from "lucide-react"; +import usePageTitle from "../../hooks/usePageTitle"; const features = [ { @@ -20,6 +21,7 @@ const features = [ ]; const About = () => { + usePageTitle("About"); return (
diff --git a/src/pages/Activity.tsx b/src/pages/Activity.tsx index ccc3d207..975191d6 100644 --- a/src/pages/Activity.tsx +++ b/src/pages/Activity.tsx @@ -1,5 +1,7 @@ +import usePageTitle from "../hooks/usePageTitle"; import ActivityFeed from "../components/ActivityFeed"; export default function Activity() { + usePageTitle("Activity"); return (
diff --git a/src/pages/Contact/Contact.tsx b/src/pages/Contact/Contact.tsx index a0bfccbd..5c9369f7 100644 --- a/src/pages/Contact/Contact.tsx +++ b/src/pages/Contact/Contact.tsx @@ -9,8 +9,9 @@ import { } from "lucide-react"; import { ThemeContext } from "../../context/ThemeContext"; import type { ThemeContextType } from "../../context/ThemeContext"; - +import usePageTitle from "../../hooks/usePageTitle"; function Contact() { + usePageTitle("Contact"); const [showPopup, setShowPopup] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const themeContext = useContext(ThemeContext) as ThemeContextType; diff --git a/src/pages/ContributorProfile/ContributorProfile.tsx b/src/pages/ContributorProfile/ContributorProfile.tsx index ed1b714d..935ff660 100644 --- a/src/pages/ContributorProfile/ContributorProfile.tsx +++ b/src/pages/ContributorProfile/ContributorProfile.tsx @@ -1,6 +1,7 @@ import { useParams } from "react-router-dom"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; +import usePageTitle from "../../hooks/usePageTitle"; type PR = { title: string; @@ -16,6 +17,7 @@ type Profile = { export default function ContributorProfile() { const { username } = useParams(); + usePageTitle(username ? `${username} — Contributor` : "Contributor Profile"); const [profile, setProfile] = useState(null); const [prs, setPRs] = useState([]); const [loading, setLoading] = useState(true); diff --git a/src/pages/Contributors/Contributors.tsx b/src/pages/Contributors/Contributors.tsx index d4fee52c..ac62e7a7 100644 --- a/src/pages/Contributors/Contributors.tsx +++ b/src/pages/Contributors/Contributors.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import usePageTitle from "../../hooks/usePageTitle"; import { Container, Grid, @@ -25,6 +26,7 @@ interface Contributor { } const ContributorsPage = () => { + usePageTitle("Contributors"); const [contributors, setContributors] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 03759ab4..1020ffd2 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -1,8 +1,10 @@ import Hero from "../../components/Hero"; import HowItWorks from "../../components/HowItWorks"; import Features from "../../components/Features"; +import usePageTitle from "../../hooks/usePageTitle"; function Home() { + usePageTitle("Home"); return (
diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index 92b7073e..ec91b427 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -3,6 +3,7 @@ import axios from "axios"; import { useNavigate, Link } from "react-router-dom"; import { ThemeContext } from "../../context/ThemeContext"; import type { ThemeContextType } from "../../context/ThemeContext"; +import usePageTitle from "../../hooks/usePageTitle"; const backendUrl = import.meta.env.VITE_BACKEND_URL; @@ -12,6 +13,7 @@ interface LoginFormData { } const Login: React.FC = () => { + usePageTitle("Login"); const [formData, setFormData] = useState({ email: "", password: "" }); const [message, setMessage] = useState(""); const [isLoading, setIsLoading] = useState(false); diff --git a/src/pages/Privacy/PrivacyPolicy.tsx b/src/pages/Privacy/PrivacyPolicy.tsx index 783d4e82..886f5386 100644 --- a/src/pages/Privacy/PrivacyPolicy.tsx +++ b/src/pages/Privacy/PrivacyPolicy.tsx @@ -1,10 +1,12 @@ import React from 'react'; +import usePageTitle from '../../hooks/usePageTitle'; import { FaShieldAlt, FaKey, FaDatabase, FaUserCheck, FaCheckCircle, FaLock, FaClock, FaShareAlt, FaCookieBite, FaChild } from 'react-icons/fa'; const PrivacyPolicy: React.FC = () => { + usePageTitle("Privacy Policy"); return (
diff --git a/src/pages/Signup/Signup.tsx b/src/pages/Signup/Signup.tsx index 2ac51dcc..05ceb061 100644 --- a/src/pages/Signup/Signup.tsx +++ b/src/pages/Signup/Signup.tsx @@ -5,6 +5,8 @@ import { motion } from "framer-motion"; import { User, Mail, Lock, Eye, EyeOff } from "lucide-react"; import { ThemeContext } from "../../context/ThemeContext"; import type { ThemeContextType } from "../../context/ThemeContext"; +import usePageTitle from "../../hooks/usePageTitle"; + const backendUrl = import.meta.env.VITE_BACKEND_URL; @@ -15,6 +17,7 @@ interface SignUpFormData { } const SignUp: React.FC = () => { + usePageTitle("Sign Up") const [formData, setFormData] = useState({ username: "", email: "", diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 576f39bf..63ebb36b 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -33,6 +33,7 @@ import { useTheme } from "@mui/material/styles"; import { useGitHubAuth } from "../../hooks/useGitHubAuth"; import { useGitHubData } from "../../hooks/useGitHubData"; import { KeyIcon } from "lucide-react"; +import usePageTitle from "../../hooks/usePageTitle"; const ROWS_PER_PAGE = 10; @@ -49,6 +50,7 @@ interface GitHubItem { const Home: React.FC = () => { const theme = useTheme(); + usePageTitle("Tracker"); const { username,