diff --git a/frontend/src/pages/AccountCenterPage.jsx b/frontend/src/pages/AccountCenterPage.jsx index 245d122..fcda22a 100644 --- a/frontend/src/pages/AccountCenterPage.jsx +++ b/frontend/src/pages/AccountCenterPage.jsx @@ -58,7 +58,7 @@ function StatusBadge({ connected }) { function AuthMethodCard({ user }) { const isGitHub = user?.authProvider === "github"; - const isLocal = user?.authProvider === "local" || !user?.authProvider; + const isLocal = user?.authProvider === "local" || !user?.authProvider; return (
@@ -73,11 +73,11 @@ function AuthMethodCard({ user }) {
- - - - - + + + + +
{isLocal && ( @@ -97,10 +97,10 @@ function AuthMethodCard({ user }) { // ── GitHub Connection Card ──────────────────────────────────────────────────── function GitHubCard({ user }) { - const ghIdentity = user?.oauth?.github; - const isConnected = !!ghIdentity?.id; - const ghUsername = ghIdentity?.username || user?.handles?.github; - const ghAvatar = user?.profile?.avatar; + const ghIdentity = user?.oauth?.github; + const isConnected = !!ghIdentity?.id; + const ghUsername = ghIdentity?.username || user?.handles?.github; + const ghAvatar = user?.profile?.avatar; const [msg, setMsg] = useState(""); const [connectLoading, setConnectLoading] = useState(false); @@ -138,7 +138,7 @@ function GitHubCard({ user }) {
{/* GitHub SVG icon */}

GitHub @@ -176,8 +176,8 @@ function GitHubCard({ user }) {

- - + +
@@ -219,7 +219,7 @@ function GitHubCard({ user }) { ) : ( )} {connectLoading ? "Connecting..." : "Connect GitHub Account"} @@ -239,7 +239,7 @@ function GitHubCard({ user }) { // ── Codeforces Card ─────────────────────────────────────────────────────────── function CodeforcesCard({ user }) { - const cfHandle = user?.handles?.codeforces; + const cfHandle = user?.handles?.codeforces; const isConnected = !!cfHandle; return ( @@ -330,7 +330,7 @@ function DangerZone({ onLogout }) { > Cancel - -
- )} +
+ Account Center - CodeLens +
+
+ + {/* ── Page Header ──────────────────────────────────────────────── */} +
+

+ Settings & Connections +

+

+ Account Center +

+

+ Manage your authentication methods, connected platforms, and account preferences. All connections unlock richer analytics and AI insights. +

+
- {/* ── User identity quick-view ─────────────────────────────────── */} - {user && ( -
- {user.profile?.avatar ? ( - {user.name} - ) : ( -
- {(user.name || "U")[0].toUpperCase()} + {/* ── Success banner ────────────────────────────────────────── */} + {banner && ( +
+

{banner}

+ +
+ )} + + {/* ── User identity quick-view ─────────────────────────────────── */} + {user && ( +
+ {user.profile?.avatar ? ( + {user.name} + ) : ( +
+ {(user.name || "U")[0].toUpperCase()} +
+ )} +
+

Logged in as

+

+ {user.name} +

+

+ {user.email} · {user.authProvider === "github" ? "GitHub Auth" : "Email Auth"} +

- )} -
-

Logged in as

-

- {user.name} -

-

- {user.email} · {user.authProvider === "github" ? "GitHub Auth" : "Email Auth"} -

+ )} + + {/* ── Card Grid ────────────────────────────────────────────────── */} +
+ + + +
- )} - {/* ── Card Grid ────────────────────────────────────────────────── */} -
- - - -
-
-
+
); } diff --git a/frontend/src/pages/AlgoVersePage.jsx b/frontend/src/pages/AlgoVersePage.jsx index 111b529..0720399 100644 --- a/frontend/src/pages/AlgoVersePage.jsx +++ b/frontend/src/pages/AlgoVersePage.jsx @@ -96,6 +96,8 @@ export default function AlgoVersePage() { }; return ( +
+ AlgoVerse - CodeLens
{/* Hero Section */}
@@ -148,7 +150,7 @@ export default function AlgoVersePage() { value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} className="w-full border-4 border-black px-6 py-4 font-bold text-base uppercase tracking-wide placeholder:text-black placeholder:opacity-40 focus:outline-none focus:shadow-[4px_4px_0_0_rgba(0,0,0,1)] transition-shadow" - /> + />
{/* Filter Button */}
); } diff --git a/frontend/src/pages/ApexAIPage.jsx b/frontend/src/pages/ApexAIPage.jsx index e9e50d4..0b92271 100644 --- a/frontend/src/pages/ApexAIPage.jsx +++ b/frontend/src/pages/ApexAIPage.jsx @@ -59,6 +59,8 @@ export default function ApexAIPage() { const typedText = useTypewriter("Stop guessing. Start executing.", 40, 500); return ( +
+ Apex AI - CodeLens
{/* ───── SECTION 1: HERO (100vh) ───── */} @@ -133,10 +135,10 @@ export default function ApexAIPage() { { title: "Skill Imbalance", desc: "You might be a Grandmaster at algorithms but write terrible, unmaintainable monolithic code." }, ].map((item, idx) => (
0{idx + 1}

{item.title}

@@ -269,7 +271,7 @@ export default function ApexAIPage() { viewport={{ once: true, amount: 0.4 }} variants={staggerContainer} className="max-w-5xl mx-auto flex flex-col items-center text-center relative z-10" - > + >
@@ -300,5 +302,6 @@ export default function ApexAIPage() {
+
); } diff --git a/frontend/src/pages/ApexWorkspacePage.jsx b/frontend/src/pages/ApexWorkspacePage.jsx index 66b232c..584bc6e 100644 --- a/frontend/src/pages/ApexWorkspacePage.jsx +++ b/frontend/src/pages/ApexWorkspacePage.jsx @@ -427,6 +427,8 @@ export default function ApexWorkspacePage() { // ── Render ────────────────────────────────────────────────────────────────── return ( +
+ Apex Workspace - CodeLens
+
); } diff --git a/frontend/src/pages/BugReportsPage.jsx b/frontend/src/pages/BugReportsPage.jsx index 4a0d601..50db357 100644 --- a/frontend/src/pages/BugReportsPage.jsx +++ b/frontend/src/pages/BugReportsPage.jsx @@ -32,6 +32,8 @@ const BugReportsPage = () => { }; return ( +
+ Bug Reports - CodeLens
{/* ───── Dynamic Hero Section ───── */} @@ -343,6 +345,7 @@ const BugReportsPage = () => {
+
); }; diff --git a/frontend/src/pages/CodeforcesPage.jsx b/frontend/src/pages/CodeforcesPage.jsx index 2dfed82..4fcddf9 100644 --- a/frontend/src/pages/CodeforcesPage.jsx +++ b/frontend/src/pages/CodeforcesPage.jsx @@ -320,12 +320,15 @@ export default function CodeforcesPage() { // ── Loading ────────────────────────────────────────────────────────────── if (loading) { return ( +
+ Codeforces - CodeLens

Loading Codeforces Data...

+
); } @@ -333,6 +336,8 @@ export default function CodeforcesPage() { if (!isConnected) { return ( <> +
+ Codeforces - CodeLens setModalOpen(true)} /> +
); } @@ -359,6 +365,8 @@ export default function CodeforcesPage() { // ── Connected — full data view ──────────────────────────────────────────── return ( +
+ Codeforces - CodeLens
{/* ── Profile Header ─────────────────────────────────────────────── */} @@ -366,10 +374,10 @@ export default function CodeforcesPage() {
{profile?.avatar && ( {profile.handle} + /> )}
@@ -532,5 +540,6 @@ export default function CodeforcesPage() {
)}
+
); } diff --git a/frontend/src/pages/ContestAtCoderPage.jsx b/frontend/src/pages/ContestAtCoderPage.jsx index 512e9c7..0780571 100644 --- a/frontend/src/pages/ContestAtCoderPage.jsx +++ b/frontend/src/pages/ContestAtCoderPage.jsx @@ -34,6 +34,8 @@ export default function ContestAtCoderPage() { ]; return ( +
+ AtCoder Contests - CodeLens
{/* Hero Section */}
@@ -81,14 +83,14 @@ export default function ContestAtCoderPage() {
{["all", "ABC", "ARC", "AGC", "Heuristic"].map((type) => ( ))} @@ -106,8 +108,8 @@ export default function ContestAtCoderPage() {
{contestSolutions.map((contest) => (
@@ -140,8 +142,8 @@ export default function ContestAtCoderPage() {
{contest.tags.map((tag, idx) => ( {tag} @@ -192,5 +194,6 @@ export default function ContestAtCoderPage() {
+
); } diff --git a/frontend/src/pages/ContestCodeChefPage.jsx b/frontend/src/pages/ContestCodeChefPage.jsx index f592f4f..75f8ab1 100644 --- a/frontend/src/pages/ContestCodeChefPage.jsx +++ b/frontend/src/pages/ContestCodeChefPage.jsx @@ -34,6 +34,8 @@ export default function ContestCodeChefPage() { ]; return ( +
+ CodeChef Contests - CodeLens
{/* Hero Section */}
@@ -81,13 +83,13 @@ export default function ContestCodeChefPage() {
{["all", "Starters", "Long", "Lunchtime", "Cook-Off"].map((type) => ( @@ -106,8 +108,8 @@ export default function ContestCodeChefPage() {
{contestSolutions.map((contest) => (
@@ -142,7 +144,7 @@ export default function ContestCodeChefPage() { + > {tag} ))} @@ -192,5 +194,6 @@ export default function ContestCodeChefPage() {
+
); } diff --git a/frontend/src/pages/ContestCodeforcesPage.jsx b/frontend/src/pages/ContestCodeforcesPage.jsx index 634cfac..93a634f 100644 --- a/frontend/src/pages/ContestCodeforcesPage.jsx +++ b/frontend/src/pages/ContestCodeforcesPage.jsx @@ -34,6 +34,8 @@ export default function ContestCodeforcesPage() { ]; return ( +
+ Codeforces Contests - CodeLens
{/* Hero Section */}
@@ -81,12 +83,12 @@ export default function ContestCodeforcesPage() {
{["all", "Div. 1", "Div. 2", "Div. 3", "Div. 4", "Educational", "Global"].map((div) => (
+
); } diff --git a/frontend/src/pages/ContestLeetCodePage.jsx b/frontend/src/pages/ContestLeetCodePage.jsx index 669afa6..01c232e 100644 --- a/frontend/src/pages/ContestLeetCodePage.jsx +++ b/frontend/src/pages/ContestLeetCodePage.jsx @@ -34,6 +34,8 @@ export default function ContestLeetCodePage() { ]; return ( +
+ LeetCode Contests - CodeLens
{/* Hero Section */}
@@ -81,13 +83,13 @@ export default function ContestLeetCodePage() {
{["all", "Weekly", "Biweekly"].map((type) => ( @@ -140,9 +142,9 @@ export default function ContestLeetCodePage() {
{contest.tags.map((tag, idx) => ( + > {tag} ))} @@ -192,5 +194,6 @@ export default function ContestLeetCodePage() {
+
); } diff --git a/frontend/src/pages/DashboardPage.jsx b/frontend/src/pages/DashboardPage.jsx index 08c4a4b..2fe200b 100644 --- a/frontend/src/pages/DashboardPage.jsx +++ b/frontend/src/pages/DashboardPage.jsx @@ -33,6 +33,8 @@ export default function DashboardPage() { } return ( +
+ Dashboard - CodeLens
@@ -47,7 +49,7 @@ export default function DashboardPage() {
@@ -79,8 +81,8 @@ export default function DashboardPage() {
) : cfConnected && cfData ? (

Codeforces

@@ -131,7 +133,7 @@ export default function DashboardPage() { width: cfConnected && cfData ? `${Math.min((cfData.currentStreak / Math.max(cfData.longestStreak, 1)) * 100, 100)}%` : "0%" - }} + }} />
@@ -162,7 +164,8 @@ export default function DashboardPage() { verificationCode={verificationCode} connectLoading={connectLoading} connectError={connectError} - /> + />
+
); } diff --git a/frontend/src/pages/ExplorePage.jsx b/frontend/src/pages/ExplorePage.jsx index db1f9cf..7e1b29c 100644 --- a/frontend/src/pages/ExplorePage.jsx +++ b/frontend/src/pages/ExplorePage.jsx @@ -43,6 +43,8 @@ export default function ExplorePage() { }); }; return ( +
+ Explore - CodeLens
@@ -61,10 +63,10 @@ export default function ExplorePage() { {showScrollTop && ( )}
+
); } diff --git a/frontend/src/pages/GitHubIntelligencePage.jsx b/frontend/src/pages/GitHubIntelligencePage.jsx index 06dce10..3b2eed7 100644 --- a/frontend/src/pages/GitHubIntelligencePage.jsx +++ b/frontend/src/pages/GitHubIntelligencePage.jsx @@ -25,6 +25,8 @@ function Skeleton() { // ── Not connected ───────────────────────────────────────────────────────────── function NotConnected() { return ( +
+ GitHub Intelligence - CodeLens
GH
@@ -38,6 +40,7 @@ function NotConnected() {
+
); } @@ -177,6 +180,7 @@ function ScoresSection({ metrics }) { // ── Main ────────────────────────────────────────────────────────────────────── export default function GitHubIntelligencePage() { + const pageTitle = GitHub Intelligence - CodeLens; const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -215,9 +219,11 @@ export default function GitHubIntelligencePage() { } }; - if (loading && !data) return ; + if (loading && !data) return <>{pageTitle}; if (error?.toLowerCase().includes("not connected")) return ; if (error) return ( + <> + {pageTitle}

Failed to load GitHub data

@@ -228,6 +234,7 @@ export default function GitHubIntelligencePage() {
+ ); if (!data) return ; @@ -239,6 +246,8 @@ export default function GitHubIntelligencePage() { } = data; return ( +
+ {pageTitle}
{/* Sync Notification Banner */} {syncMsg && ( @@ -312,5 +321,6 @@ export default function GitHubIntelligencePage() {
+
); } diff --git a/frontend/src/pages/LandingPage.jsx b/frontend/src/pages/LandingPage.jsx index 605d423..c1b4128 100644 --- a/frontend/src/pages/LandingPage.jsx +++ b/frontend/src/pages/LandingPage.jsx @@ -59,6 +59,8 @@ export default function LandingPage() { const currentWord = useWordCycle(cycleWords); return ( +
+ CodeLens — Track, Analyze, Grow
{/* ───── 1. HERO SECTION ───── */} @@ -228,7 +230,7 @@ export default function LandingPage() { + > Initialize System
@@ -239,5 +241,6 @@ export default function LandingPage() {
+
); } diff --git a/frontend/src/pages/LoginPage.jsx b/frontend/src/pages/LoginPage.jsx index 530cb4a..867e9f6 100644 --- a/frontend/src/pages/LoginPage.jsx +++ b/frontend/src/pages/LoginPage.jsx @@ -64,6 +64,8 @@ export default function LoginPage() { }; return ( +
+ Login - CodeLens

@@ -109,7 +111,7 @@ export default function LoginPage() { className="w-full p-5 border-4 border-black rounded-none text-black font-bold focus:outline-none focus:border-gray-500" placeholder="YOUR@EMAIL.COM" required - /> + />

@@ -123,14 +125,14 @@ export default function LoginPage() { className="w-full p-5 border-4 border-black rounded-none text-black font-bold focus:outline-none focus:border-gray-500" placeholder="••••••••" required - /> + />
+ > Forgot Password?
@@ -139,7 +141,7 @@ export default function LoginPage() { type="submit" disabled={loading} className="w-full py-6 bg-black text-white text-xl font-black uppercase tracking-widest hover:bg-gray-900 transition-colors border-4 border-black rounded-none disabled:opacity-50 disabled:cursor-not-allowed" - > + > {loading ? 'AUTHENTICATING...' : 'SIGN IN'} @@ -154,5 +156,6 @@ export default function LoginPage() {
+
); } diff --git a/frontend/src/pages/NotFoundPage.jsx b/frontend/src/pages/NotFoundPage.jsx index cfb722b..20c7580 100644 --- a/frontend/src/pages/NotFoundPage.jsx +++ b/frontend/src/pages/NotFoundPage.jsx @@ -6,6 +6,7 @@ export default function NotFoundPage() { className="relative min-h-screen overflow-hidden border-t-4 border-black bg-white" aria-label="404 Not Found Page" > + Page Not Found - CodeLens {/* Background Grid */}
+ Practice - CodeLens
{/* ── Hero Header ─────────────────────────────────────────────────── */} @@ -439,7 +441,7 @@ export default function PracticePage() { selectedTags.length > 0 || showTagPanel ? "bg-black text-white" : "bg-white text-black hover:bg-gray-100" - }`} + }`} > Tags{selectedTags.length > 0 ? ` (${selectedTags.length})` : ""} {showTagPanel ? "▴" : "▾"} @@ -459,7 +461,7 @@ export default function PracticePage() {
{filteredTagList.map((t) => ( setSelectedTags([])} className="text-xs font-black uppercase tracking-widest text-black hover:underline" - > + > Clear Tags
@@ -504,9 +506,9 @@ export default function PracticePage() { )} {selectedTags.map((t) => ( + > {t} @@ -514,7 +516,7 @@ export default function PracticePage() {
@@ -604,11 +606,11 @@ export default function PracticePage() { {/* Rows */} {paginated.map((p, i) => ( + /> ))}
)} @@ -639,14 +641,14 @@ export default function PracticePage() { for (let pg = start; pg <= end; pg++) { pages.push( ); @@ -658,14 +660,14 @@ export default function PracticePage() { onClick={() => { setPage((p) => Math.min(totalPages, p + 1)); window.scrollTo({ top: 0 }); }} disabled={page === totalPages} className="px-4 py-2 border-[3px] border-black font-black text-xs uppercase tracking-widest hover:bg-black hover:text-white transition-colors disabled:opacity-30 disabled:cursor-not-allowed" - > + > Next › @@ -688,7 +690,7 @@ export default function PracticePage() { target="_blank" rel="noopener noreferrer" className="text-black font-black underline underline-offset-4 decoration-2 hover:opacity-60" - > + > Codeforces Problemset API

@@ -698,5 +700,6 @@ export default function PracticePage() { + ); } diff --git a/frontend/src/pages/SignupPage.jsx b/frontend/src/pages/SignupPage.jsx index b88cc24..818cf49 100644 --- a/frontend/src/pages/SignupPage.jsx +++ b/frontend/src/pages/SignupPage.jsx @@ -126,6 +126,8 @@ export default function SignupPage() { }; return ( +
+ Sign Up - CodeLens

@@ -250,7 +252,7 @@ export default function SignupPage() { type="submit" disabled={loading} className="w-full mt-4 py-6 bg-black text-white text-xl font-black uppercase tracking-widest hover:bg-gray-900 transition-colors border-4 border-black rounded-none disabled:opacity-50 disabled:cursor-not-allowed" - > + > {loading ? "VERIFYING..." : "VERIFY"} @@ -260,7 +262,7 @@ export default function SignupPage() { onClick={handleResendOtp} disabled={cooldown > 0 || loading} className="text-sm font-black uppercase tracking-widest text-black underline underline-offset-4 decoration-[3px] hover:text-gray-600 disabled:opacity-50 disabled:cursor-not-allowed disabled:no-underline" - > + > {cooldown > 0 ? `RESEND CODE (${cooldown})` : "RESEND CODE"}

@@ -277,5 +279,6 @@ export default function SignupPage() {
+
); } diff --git a/frontend/src/pages/TermsPage.jsx b/frontend/src/pages/TermsPage.jsx index df37629..db09448 100644 --- a/frontend/src/pages/TermsPage.jsx +++ b/frontend/src/pages/TermsPage.jsx @@ -1,5 +1,7 @@ export default function TermsPage() { return( +
+ Terms of Service - CodeLens

Terms of Service

@@ -8,5 +10,6 @@ export default function TermsPage() {

+
); } \ No newline at end of file