From 7ccb6eef0e62021a8ae4b38fd2ce7c907c30ab3a Mon Sep 17 00:00:00 2001 From: Nishanth <138886231+nishanthkj@users.noreply.github.com> Date: Sun, 26 Oct 2025 14:35:53 +0000 Subject: [PATCH] feat(profile): add Profile page, AuthContext and navbar dropdown with logout Add app-wide AuthContext and Profile page, wire into navbar and routing Changes: - src/context/AuthContext.tsx: new Auth provider that stores GitHub username and personal access token, persists to localStorage, exposes getOctokit() and logout(). - src/pages/Profile/Profile.tsx: new page to view/edit GitHub username and token. Saves to AuthContext and navigates back on save. - src/Routes/Router.tsx: added /profile route. - src/components/Navbar.tsx: updated header to show username when authenticated, with a dropdown containing View/Edit Profile and Logout. Mobile menu updated similarly. - src/main.tsx: app wrapped with AuthProvider so auth is available globally. - src/pages/Tracker/Tracker.tsx: switched to using AuthContext for username/token and getOctokit instead of local hook, so auth is centralized. Rationale: Centralized auth state enables consistent UX (navbar profile dropdown, logout, and profile editing) and avoids duplicating token/username state across pages. Storing credentials in localStorage provides a simple persistence layer; consider a more secure approach for production. Testing/Validation: - Ran a production build (vite build) locally; build succeeded. Notes and next steps: - Consider adding avatar fetch for the navbar, logout confirmation, and secure storage for PATs. --- src/Routes/Router.tsx | 2 + src/components/Navbar.tsx | 84 ++++++++++++++++++++++++++++++++--- src/context/AuthContext.tsx | 74 ++++++++++++++++++++++++++++++ src/main.tsx | 9 ++-- src/pages/Profile/Profile.tsx | 63 ++++++++++++++++++++++++++ src/pages/Tracker/Tracker.tsx | 19 ++++---- 6 files changed, 233 insertions(+), 18 deletions(-) create mode 100644 src/context/AuthContext.tsx create mode 100644 src/pages/Profile/Profile.tsx diff --git a/src/Routes/Router.tsx b/src/Routes/Router.tsx index 40a7861..53f6780 100644 --- a/src/Routes/Router.tsx +++ b/src/Routes/Router.tsx @@ -6,6 +6,7 @@ import Contributors from "../pages/Contributors/Contributors"; import Signup from "../pages/Signup/Signup.tsx"; import Login from "../pages/Login/Login.tsx"; import ContributorProfile from "../pages/ContributorProfile/ContributorProfile.tsx"; +import Profile from "../pages/Profile/Profile"; import Home from "../pages/Home/Home.tsx"; const Router = () => { @@ -18,6 +19,7 @@ const Router = () => { } /> } /> } /> + } /> } /> ); diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index c6cc86d..b04522b 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,6 +1,8 @@ import { Link } from "react-router-dom"; import { useState, useContext } from "react"; import { ThemeContext } from "../context/ThemeContext"; +import { AuthContext } from "../context/AuthContext"; +import { useNavigate } from "react-router-dom"; import { Moon, Sun } from 'lucide-react'; @@ -8,6 +10,8 @@ const Navbar: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const themeContext = useContext(ThemeContext); + const auth = useContext(AuthContext); + const navigate = useNavigate(); if (!themeContext) return null; @@ -46,12 +50,57 @@ const Navbar: React.FC = () => { > Contributors - - Login - + {auth && auth.username ? ( +
+ + + {/* Dropdown */} + {isOpen && ( +
+ + +
+ )} +
+ ) : ( + + Login + + )} + + + )} + + + + + ); +}; + +export default Profile; diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 2bd4d30..16e1f1c 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -30,7 +30,8 @@ import { InputLabel, } from "@mui/material"; import { useTheme } from "@mui/material/styles"; -import { useGitHubAuth } from "../../hooks/useGitHubAuth"; +import { useContext } from "react"; +import { AuthContext } from "../../context/AuthContext"; import { useGitHubData } from "../../hooks/useGitHubData"; const ROWS_PER_PAGE = 10; @@ -49,14 +50,14 @@ const Home: React.FC = () => { const theme = useTheme(); - const { - username, - setUsername, - token, - setToken, - error: authError, - getOctokit, - } = useGitHubAuth(); + const auth = useContext(AuthContext); + + const username = auth?.username || ""; + const setUsername = auth?.setUsername || (() => {}); + const token = auth?.token || ""; + const setToken = auth?.setToken || (() => {}); + const authError = ""; + const getOctokit = auth?.getOctokit || (() => null); const { issues,