From dcfac35141f0024de353666fa40d4f350b4458ec Mon Sep 17 00:00:00 2001 From: sahilsultane Date: Tue, 26 May 2026 16:08:20 +0530 Subject: [PATCH 1/2] feat: enhance tracker page with glassmorphism UI --- src/pages/Tracker/Tracker.css | 586 ++++++++++++++++++++++++++++++++++ src/pages/Tracker/Tracker.tsx | 463 +++++++++++++-------------- 2 files changed, 814 insertions(+), 235 deletions(-) create mode 100644 src/pages/Tracker/Tracker.css diff --git a/src/pages/Tracker/Tracker.css b/src/pages/Tracker/Tracker.css new file mode 100644 index 00000000..2160cd4e --- /dev/null +++ b/src/pages/Tracker/Tracker.css @@ -0,0 +1,586 @@ +/* ============================================================ + Tracker Page – Modern Dark Glassmorphism Theme + Mirrors the Home page design language (Hero / Features) + ============================================================ */ + +/* ---------- Page wrapper ---------- */ +.tracker-root { + min-height: 80vh; + width: 100%; + padding: 2.5rem 1.5rem 4rem; + position: relative; + overflow: hidden; + /* dark base matching Hero's #030712 */ + background: #030712; + color: #f1f5f9; + transition: background 0.4s ease, color 0.4s ease; +} + +/* ── Light mode overrides ── */ +:root:not(.dark) .tracker-root { + background: #f8fafc; /* slate-50 – matches Hero light bg */ + color: #0f172a; +} + +/* Ambient glow blobs – same as Hero */ +.tracker-root::before { + content: ""; + position: absolute; + top: 10%; + left: 10%; + width: 520px; + height: 520px; + background: rgba(59, 130, 246, 0.08); + border-radius: 50%; + filter: blur(120px); + pointer-events: none; + z-index: 0; +} +.tracker-root::after { + content: ""; + position: absolute; + bottom: 10%; + right: 10%; + width: 600px; + height: 600px; + background: rgba(34, 211, 238, 0.07); + border-radius: 50%; + filter: blur(160px); + pointer-events: none; + z-index: 0; +} + +/* Light mode: softer, lighter glow blobs */ +:root:not(.dark) .tracker-root::before { + background: rgba(59, 130, 246, 0.06); +} +:root:not(.dark) .tracker-root::after { + background: rgba(34, 211, 238, 0.05); +} + +/* Cyber grid overlay – same as Hero */ +.tracker-grid-overlay { + position: absolute; + inset: 0; + background-image: + linear-gradient(to right, #1f293710 1px, transparent 1px), + linear-gradient(to bottom, #1f293710 1px, transparent 1px); + background-size: 4rem 4rem; + -webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 70%, transparent 100%); + mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 70%, transparent 100%); + pointer-events: none; + z-index: 0; +} + +/* Light mode grid uses the same slate tones Hero uses */ +:root:not(.dark) .tracker-grid-overlay { + background-image: + linear-gradient(to right, #e2e8f0 1px, transparent 1px), + linear-gradient(to bottom, #e2e8f0 1px, transparent 1px); +} + +/* Inner content sits above the decorative layers */ +.tracker-inner { + position: relative; + z-index: 1; + max-width: 1100px; + margin: 0 auto; +} + +/* ---------- Page heading ---------- */ +.tracker-heading { + text-align: center; + margin-bottom: 2.5rem; +} +.tracker-heading h1 { + font-size: clamp(1.75rem, 4vw, 2.75rem); + font-weight: 800; + letter-spacing: -0.02em; + line-height: 1.15; + color: #f1f5f9; +} +:root:not(.dark) .tracker-heading h1 { + color: #0f172a; +} +.tracker-heading h1 span { + display: block; + margin-top: 0.25rem; + background: linear-gradient(to right, #3b82f6, #22d3ee, #2dd4bf); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + filter: drop-shadow(0 0 28px rgba(56, 189, 248, 0.35)); +} +.tracker-heading p { + margin-top: 0.75rem; + color: #94a3b8; + font-size: 1rem; +} +:root:not(.dark) .tracker-heading p { + color: #475569; +} + +/* ---------- Glass card (shared) ---------- */ +.tracker-glass-card { + background: rgba(15, 23, 42, 0.65); + backdrop-filter: blur(18px); + -webkit-backdrop-filter: blur(18px); + border: 1px solid rgba(148, 163, 184, 0.12); + border-radius: 1rem; + box-shadow: + 0 4px 24px rgba(0, 0, 0, 0.4), + 0 0 0 1px rgba(56, 189, 248, 0.04) inset; + padding: 1.75rem; + margin-bottom: 1.5rem; + transition: box-shadow 0.3s ease; +} +.tracker-glass-card:hover { + box-shadow: + 0 8px 40px rgba(0, 0, 0, 0.5), + 0 0 0 1px rgba(56, 189, 248, 0.1) inset; +} + +/* Light mode glass card – white/70 with slate border, matching Hero's dashboard card */ +:root:not(.dark) .tracker-glass-card { + background: rgba(255, 255, 255, 0.75); + border: 1px solid rgba(226, 232, 240, 0.9); + box-shadow: + 0 4px 24px rgba(148, 163, 184, 0.15), + 0 1px 4px rgba(148, 163, 184, 0.1); +} +:root:not(.dark) .tracker-glass-card:hover { + box-shadow: + 0 8px 32px rgba(148, 163, 184, 0.25), + 0 0 0 1px rgba(59, 130, 246, 0.12) inset; +} + +/* ---------- Section label ---------- */ +.tracker-section-label { + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: #38bdf8; + margin-bottom: 1rem; + display: flex; + align-items: center; + gap: 0.5rem; +} +:root:not(.dark) .tracker-section-label { + color: #2563eb; +} +.tracker-section-label::before { + content: ""; + display: inline-block; + width: 18px; + height: 2px; + background: linear-gradient(to right, #3b82f6, #22d3ee); + border-radius: 9999px; +} + +/* ---------- Input fields ---------- */ +.tracker-input-row { + display: flex; + flex-wrap: wrap; + gap: 1rem; +} + +/* Override MUI TextField for dark glass look */ +.tracker-root .MuiTextField-root .MuiOutlinedInput-root { + background: rgba(15, 23, 42, 0.7) !important; + border-radius: 0.625rem !important; + color: #e2e8f0 !important; + transition: box-shadow 0.25s ease, border-color 0.25s ease !important; +} +.tracker-root .MuiTextField-root .MuiOutlinedInput-root fieldset { + border-color: rgba(148, 163, 184, 0.2) !important; + transition: border-color 0.25s ease !important; +} +.tracker-root .MuiTextField-root .MuiOutlinedInput-root:hover fieldset { + border-color: rgba(56, 189, 248, 0.45) !important; +} +.tracker-root .MuiTextField-root .MuiOutlinedInput-root.Mui-focused fieldset { + border-color: #22d3ee !important; + border-width: 1.5px !important; + box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.12) !important; +} +.tracker-root .MuiTextField-root .MuiInputLabel-root { + color: #64748b !important; +} +.tracker-root .MuiTextField-root .MuiInputLabel-root.Mui-focused { + color: #22d3ee !important; +} +.tracker-root .MuiTextField-root input { + color: #e2e8f0 !important; +} +.tracker-root .MuiTextField-root input::placeholder { + color: #475569 !important; + opacity: 1 !important; +} +/* Helper text / links */ +.tracker-root .MuiFormHelperText-root { + color: #64748b !important; +} +.tracker-root .MuiFormHelperText-root a { + color: #38bdf8 !important; +} +.tracker-root .MuiFormHelperText-root a:hover { + color: #22d3ee !important; +} + +/* Light mode TextField overrides */ +:root:not(.dark) .tracker-root .MuiTextField-root .MuiOutlinedInput-root { + background: rgba(255, 255, 255, 0.85) !important; + color: #0f172a !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root .MuiOutlinedInput-root fieldset { + border-color: rgba(203, 213, 225, 0.9) !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root .MuiOutlinedInput-root:hover fieldset { + border-color: rgba(59, 130, 246, 0.5) !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root .MuiOutlinedInput-root.Mui-focused fieldset { + border-color: #3b82f6 !important; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12) !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root .MuiInputLabel-root { + color: #64748b !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root .MuiInputLabel-root.Mui-focused { + color: #3b82f6 !important; +} +:root:not(.dark) .tracker-root .MuiTextField-root input { + color: #0f172a !important; +} +:root:not(.dark) .tracker-root .MuiFormHelperText-root a { + color: #2563eb !important; +} +:root:not(.dark) .tracker-root .MuiFormHelperText-root a:hover { + color: #1d4ed8 !important; +} + +/* ---------- Fetch Data button ---------- */ +.tracker-fetch-btn-wrapper { + /* gradient border trick – same as Hero "Start Tracking" */ + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 2px; + border-radius: 0.75rem; + background: linear-gradient(135deg, #3b82f6, #22d3ee, #2dd4bf); + box-shadow: 0 0 20px rgba(59, 130, 246, 0.3); + transition: box-shadow 0.3s ease, transform 0.2s ease; + align-self: flex-start; + min-height: 55px; +} +.tracker-fetch-btn-wrapper:hover { + box-shadow: 0 0 35px rgba(34, 211, 238, 0.55); + transform: translateY(-2px) scale(1.02); +} +.tracker-fetch-btn-wrapper button.MuiButton-root { + background: #030712 !important; + color: #f1f5f9 !important; + border-radius: 0.625rem !important; + font-weight: 600 !important; + font-size: 0.9rem !important; + letter-spacing: 0.02em !important; + padding: 0.75rem 1.75rem !important; + min-height: 51px !important; + min-width: 130px !important; + text-transform: none !important; + transition: background 0.2s ease, color 0.2s ease !important; + box-shadow: none !important; +} +.tracker-fetch-btn-wrapper:hover button.MuiButton-root { + background: transparent !important; + color: #fff !important; +} + +/* Light mode: inner fill matches slate-50 */ +:root:not(.dark) .tracker-fetch-btn-wrapper button.MuiButton-root { + background: #f8fafc !important; + color: #0f172a !important; +} +:root:not(.dark) .tracker-fetch-btn-wrapper:hover button.MuiButton-root { + background: transparent !important; + color: #fff !important; +} + +/* ---------- Filters row ---------- */ +.tracker-filters-row { + display: flex; + flex-wrap: wrap; + gap: 1rem; +} + +/* ---------- Tabs ---------- */ +.tracker-root .MuiTabs-root .MuiTab-root { + color: #64748b !important; + font-weight: 600 !important; + font-size: 0.875rem !important; + text-transform: none !important; + letter-spacing: 0.01em !important; + transition: color 0.2s ease !important; + padding: 0.5rem 1.25rem !important; +} +.tracker-root .MuiTabs-root .MuiTab-root.Mui-selected { + color: #22d3ee !important; +} +:root:not(.dark) .tracker-root .MuiTabs-root .MuiTab-root.Mui-selected { + color: #2563eb !important; +} +.tracker-root .MuiTabs-root .MuiTabs-indicator { + background: linear-gradient(to right, #3b82f6, #22d3ee) !important; + height: 2.5px !important; + border-radius: 9999px !important; + box-shadow: 0 0 10px rgba(34, 211, 238, 0.6) !important; +} +:root:not(.dark) .tracker-root .MuiTabs-root .MuiTabs-indicator { + box-shadow: 0 0 8px rgba(59, 130, 246, 0.4) !important; +} + +/* ---------- State dropdown (Select) ---------- */ +.tracker-root .MuiFormControl-root .MuiOutlinedInput-root { + background: rgba(15, 23, 42, 0.7) !important; + border-radius: 0.625rem !important; + color: #e2e8f0 !important; +} +.tracker-root .MuiFormControl-root .MuiOutlinedInput-root fieldset { + border-color: rgba(148, 163, 184, 0.2) !important; +} +.tracker-root .MuiFormControl-root .MuiOutlinedInput-root:hover fieldset { + border-color: rgba(56, 189, 248, 0.45) !important; +} +.tracker-root .MuiFormControl-root .MuiOutlinedInput-root.Mui-focused fieldset { + border-color: #22d3ee !important; + box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.12) !important; +} +.tracker-root .MuiFormControl-root .MuiInputLabel-root { + color: #64748b !important; +} +.tracker-root .MuiFormControl-root .MuiInputLabel-root.Mui-focused { + color: #22d3ee !important; +} +.tracker-root .MuiFormControl-root .MuiSelect-icon { + color: #64748b !important; +} + +/* Light mode Select overrides */ +:root:not(.dark) .tracker-root .MuiFormControl-root .MuiOutlinedInput-root { + background: rgba(255, 255, 255, 0.85) !important; + color: #0f172a !important; +} +:root:not(.dark) .tracker-root .MuiFormControl-root .MuiOutlinedInput-root fieldset { + border-color: rgba(203, 213, 225, 0.9) !important; +} +:root:not(.dark) .tracker-root .MuiFormControl-root .MuiOutlinedInput-root:hover fieldset { + border-color: rgba(59, 130, 246, 0.5) !important; +} +:root:not(.dark) .tracker-root .MuiFormControl-root .MuiOutlinedInput-root.Mui-focused fieldset { + border-color: #3b82f6 !important; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.12) !important; +} +:root:not(.dark) .tracker-root .MuiFormControl-root .MuiInputLabel-root.Mui-focused { + color: #3b82f6 !important; +} + +/* ---------- Alert ---------- */ +.tracker-root .MuiAlert-root { + background: rgba(239, 68, 68, 0.12) !important; + border: 1px solid rgba(239, 68, 68, 0.3) !important; + color: #fca5a5 !important; + border-radius: 0.75rem !important; + backdrop-filter: blur(8px) !important; +} +.tracker-root .MuiAlert-icon { + color: #f87171 !important; +} + +/* ---------- Table ---------- */ +.tracker-table-wrapper { + max-height: 420px; + overflow-y: auto; + border-radius: 0.875rem; + /* custom scrollbar */ + scrollbar-width: thin; + scrollbar-color: rgba(56, 189, 248, 0.3) transparent; +} +.tracker-table-wrapper::-webkit-scrollbar { + width: 6px; +} +.tracker-table-wrapper::-webkit-scrollbar-track { + background: transparent; +} +.tracker-table-wrapper::-webkit-scrollbar-thumb { + background: rgba(56, 189, 248, 0.3); + border-radius: 9999px; +} + +.tracker-root .MuiTableContainer-root { + background: transparent !important; + box-shadow: none !important; +} +.tracker-root .MuiTable-root { + border-collapse: separate !important; + border-spacing: 0 !important; +} + +/* Table head */ +.tracker-root .MuiTableHead-root .MuiTableCell-root { + background: rgba(15, 23, 42, 0.9) !important; + color: #38bdf8 !important; + font-weight: 700 !important; + font-size: 0.75rem !important; + letter-spacing: 0.08em !important; + text-transform: uppercase !important; + border-bottom: 1px solid rgba(56, 189, 248, 0.2) !important; + padding: 0.875rem 1rem !important; +} +:root:not(.dark) .tracker-root .MuiTableHead-root .MuiTableCell-root { + background: rgba(241, 245, 249, 0.95) !important; + color: #2563eb !important; + border-bottom: 1px solid rgba(59, 130, 246, 0.2) !important; +} +.tracker-root .MuiTableHead-root .MuiTableCell-root:first-child { + border-radius: 0.75rem 0 0 0 !important; +} +.tracker-root .MuiTableHead-root .MuiTableCell-root:last-child { + border-radius: 0 0.75rem 0 0 !important; +} + +/* Table body rows */ +.tracker-root .MuiTableBody-root .MuiTableRow-root { + transition: background 0.2s ease !important; +} +.tracker-root .MuiTableBody-root .MuiTableRow-root:hover { + background: rgba(56, 189, 248, 0.06) !important; +} +:root:not(.dark) .tracker-root .MuiTableBody-root .MuiTableRow-root:hover { + background: rgba(59, 130, 246, 0.05) !important; +} +.tracker-root .MuiTableBody-root .MuiTableCell-root { + color: #cbd5e1 !important; + border-bottom: 1px solid rgba(148, 163, 184, 0.07) !important; + font-size: 0.875rem !important; + padding: 0.75rem 1rem !important; +} +:root:not(.dark) .tracker-root .MuiTableBody-root .MuiTableCell-root { + color: #334155 !important; + border-bottom: 1px solid rgba(203, 213, 225, 0.5) !important; +} + +/* Links inside table */ +.tracker-root .MuiTableBody-root a { + color: #38bdf8 !important; + text-decoration: none !important; + transition: color 0.2s ease !important; +} +.tracker-root .MuiTableBody-root a:hover { + color: #22d3ee !important; + text-decoration: underline !important; +} +:root:not(.dark) .tracker-root .MuiTableBody-root a { + color: #2563eb !important; +} +:root:not(.dark) .tracker-root .MuiTableBody-root a:hover { + color: #1d4ed8 !important; +} + +/* ---------- Pagination ---------- */ +.tracker-root .MuiTablePagination-root { + background: rgba(15, 23, 42, 0.8) !important; + color: #94a3b8 !important; + border-top: 1px solid rgba(148, 163, 184, 0.08) !important; + border-radius: 0 0 0.875rem 0.875rem !important; +} +:root:not(.dark) .tracker-root .MuiTablePagination-root { + background: rgba(241, 245, 249, 0.95) !important; + color: #64748b !important; + border-top: 1px solid rgba(203, 213, 225, 0.6) !important; +} +.tracker-root .MuiTablePagination-root .MuiIconButton-root { + color: #64748b !important; + transition: color 0.2s ease !important; +} +.tracker-root .MuiTablePagination-root .MuiIconButton-root:hover { + color: #22d3ee !important; + background: rgba(34, 211, 238, 0.08) !important; +} +:root:not(.dark) .tracker-root .MuiTablePagination-root .MuiIconButton-root:hover { + color: #2563eb !important; + background: rgba(59, 130, 246, 0.08) !important; +} +.tracker-root .MuiTablePagination-root .MuiIconButton-root.Mui-disabled { + color: #334155 !important; +} +:root:not(.dark) .tracker-root .MuiTablePagination-root .MuiIconButton-root.Mui-disabled { + color: #cbd5e1 !important; +} +.tracker-root .MuiTablePagination-selectLabel, +.tracker-root .MuiTablePagination-displayedRows { + color: #64748b !important; + font-size: 0.8rem !important; +} + +/* ---------- Loading spinner ---------- */ +.tracker-root .MuiCircularProgress-root { + color: #22d3ee !important; +} +:root:not(.dark) .tracker-root .MuiCircularProgress-root { + color: #3b82f6 !important; +} + +/* ---------- Empty state ---------- */ +.tracker-empty-state { + text-align: center; + padding: 3rem 1rem; + color: #475569; +} +.tracker-empty-state svg { + margin: 0 auto 1rem; + opacity: 0.35; +} +.tracker-empty-state p { + font-size: 0.95rem; +} + +/* ---------- Tabs + filter bar ---------- */ +.tracker-tabs-bar { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; + margin-bottom: 1.25rem; +} + +/* ---------- Responsive ---------- */ +@media (max-width: 768px) { + .tracker-root { + padding: 1.5rem 1rem 3rem; + } + .tracker-glass-card { + padding: 1.25rem; + } + .tracker-input-row, + .tracker-filters-row { + flex-direction: column; + } + .tracker-fetch-btn-wrapper { + width: 100%; + } + .tracker-fetch-btn-wrapper button.MuiButton-root { + width: 100% !important; + } + .tracker-tabs-bar { + flex-direction: column; + align-items: flex-start; + } +} + +@media (max-width: 480px) { + .tracker-heading h1 { + font-size: 1.6rem; + } +} diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 576f39bf..4d15056d 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -7,7 +7,6 @@ import { GitMergeIcon, } from '@primer/octicons-react'; import { - Container, Box, TextField, Button, @@ -29,10 +28,10 @@ import { FormControl, InputLabel, } from "@mui/material"; -import { useTheme } from "@mui/material/styles"; import { useGitHubAuth } from "../../hooks/useGitHubAuth"; import { useGitHubData } from "../../hooks/useGitHubData"; -import { KeyIcon } from "lucide-react"; +import { KeyIcon, GitBranchIcon } from "lucide-react"; +import "./Tracker.css"; const ROWS_PER_PAGE = 10; @@ -48,14 +47,11 @@ interface GitHubItem { const Home: React.FC = () => { - const theme = useTheme(); - const { username, setUsername, token, setToken, - error: authError, getOctokit, } = useGitHubAuth(); @@ -139,264 +135,261 @@ const Home: React.FC = () => { }; const getStatusIcon = (item: GitHubItem) => { - if (item.pull_request) { - - if (item.pull_request.merged_at) - return ; - - if (item.state === 'closed') - return ; - - return ; + if (item.pull_request.merged_at) + return ; + if (item.state === 'closed') + return ; + return ; } - if (item.state === 'closed') - return ; - + return ; return ; }; - // 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 Form */} - -
- - setUsername(e.target.value)} - required - sx={{ flex: 1, minWidth: 150 }} - /> - setToken(e.target.value)} - type="password" - required - sx={{ flex: 1, minWidth: 150 }} - helperText={ - + {/* Decorative cyber grid overlay */} + ); }; From 7095620e228278237ec664827d894d04ab1aa012 Mon Sep 17 00:00:00 2001 From: sahilsultane Date: Tue, 26 May 2026 16:34:54 +0530 Subject: [PATCH 2/2] fix: use correct lucide git branch icon --- src/pages/Tracker/Tracker.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 4d15056d..f0a422d4 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -30,7 +30,7 @@ import { } from "@mui/material"; import { useGitHubAuth } from "../../hooks/useGitHubAuth"; import { useGitHubData } from "../../hooks/useGitHubData"; -import { KeyIcon, GitBranchIcon } from "lucide-react"; +import { KeyIcon, GitBranch } from "lucide-react"; import "./Tracker.css"; const ROWS_PER_PAGE = 10; @@ -171,7 +171,7 @@ const Home: React.FC = () => { {/* ── Auth Form ── */}
- + Authentication
@@ -339,7 +339,7 @@ const Home: React.FC = () => {
- +

{username ? "No results found. Try adjusting your filters."