Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import ForgotPassword from "./components/auth/ForgotPassword";
import ProtectedRoute from "./components/shared/ProtectedRoute";
import PublicRoute from "./components/shared/PublicRoute";


export default function App() {
return (
<AuthProvider>
Expand Down Expand Up @@ -81,7 +82,10 @@ export default function App() {
<Route path="/terms" element={<TermsPage/>} />
<Route path="/privacy" element={<PrivacyPage/>} />
<Route path="*" element={<NotFoundPage />} />

</Routes>


</MainLayout>
</BrowserRouter>
</AuthProvider>
Expand Down
183 changes: 84 additions & 99 deletions frontend/src/components/shared/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,116 +204,101 @@ export default function Navbar() {
</button>

{/* ── Mega Menu Panel ── */}
{megaOpen && (
<div
ref={megaRef}
onMouseEnter={handleMegaMouseEnter}
onMouseLeave={handleMegaMouseLeave}
className="absolute top-full left-1/2 mt-[18px] w-[640px] bg-white border-4 border-black z-50"
style={{ transform: "translateX(-50%)" }}
>
{/* Top accent bar */}
<div className="h-[3px] w-full bg-black" />
<div
ref={megaRef}
onMouseEnter={handleMegaMouseEnter}
onMouseLeave={handleMegaMouseLeave}
aria-hidden={!megaOpen}
className={`absolute top-full left-1/2 mt-4 w-[580px] bg-white border-4 border-black z-50 transition-all duration-200 origin-top ${
megaOpen
? "opacity-100 translate-y-0 scale-100 visible"
: "opacity-0 -translate-y-2 scale-95 invisible"
}`}
style={{ transform: "translateX(-50%)" }}
Comment thread
Harkiratcodess marked this conversation as resolved.
>
{/* Top accent bar */}
<div className="h-1 w-full bg-black" />

<div className="p-6">
<p className="text-[10px] font-black uppercase tracking-[0.2em] text-gray-400 mb-4 border-b-2 border-black pb-3">
AI-Powered Tools — GSSoC '26
</p>
<div className="grid grid-cols-2 gap-0">
{MEGA_MENU_ITEMS.map((item, i) => {
const Wrapper = item.to ? Link : "div";
const hasSubmenu = item.submenu && item.submenu.length > 0;

if (hasSubmenu) {
return (
<div
key={item.label}
className={`col-span-2 border-black ${
i < MEGA_MENU_ITEMS.length - 1 ? "border-b-2" : ""
}`}
>
<div className="group p-4 bg-black text-white cursor-default">
<div className="flex items-center gap-2 mb-1">
<span className="text-base font-black leading-none">{item.icon}</span>
<span className="text-sm font-black uppercase tracking-widest">
{item.label}
</span>
{item.tag && (
<span className="text-[9px] font-black tracking-widest border-2 border-current px-[5px] py-[1px] leading-tight">
{item.tag}
</span>
)}
</div>
<p className="text-xs font-bold tracking-wide leading-snug opacity-80 pl-6">
{item.desc}
</p>
</div>
<div className="grid grid-cols-2 gap-0 bg-gray-50">
{item.submenu.map((subItem, subIdx) => (
<Link
key={subItem.label}
to={subItem.to}
onClick={closeMenu}
className={`group text-left p-4 border-black transition-colors duration-150 hover:bg-black hover:text-white ${
subIdx % 2 === 0 ? "border-r-2" : ""
} ${subIdx < item.submenu.length - 2 ? "border-b-2" : ""}`}
>
<div className="flex items-center gap-2 mb-1">
<span className="text-base font-black leading-none">{subItem.icon}</span>
<span className="text-xs font-black uppercase tracking-widest">
{subItem.label}
</span>
</div>
<p className="text-[11px] font-bold tracking-wide leading-snug opacity-60 group-hover:opacity-80 pl-6">
{subItem.desc}
</p>
</Link>
))}
</div>
</div>
);
}

<div className="p-3">


<div className="grid grid-cols-2 gap-[2px] bg-black border-2 border-black overflow-hidden">
{MEGA_MENU_ITEMS.map((item, i) => {
const Wrapper = item.to ? Link : "button";
const hasSubmenu = item.submenu && item.submenu.length > 0;

if (hasSubmenu) {
return (
<Wrapper
<div
key={item.label}
to={item.to}
onClick={closeMenu}
className={`group text-left p-4 border-black transition-colors duration-150 hover:bg-black hover:text-white ${
i % 2 === 0 ? "border-r-2" : ""
} ${i < MEGA_MENU_ITEMS.length - 2 ? "border-b-2" : ""}`}
className="col-span-2 bg-white"
>
<div className="flex items-center gap-2 mb-1">
<span className="text-base font-black leading-none">{item.icon}</span>
<span className="text-sm font-black uppercase tracking-widest">
{item.label}
</span>
<div className="p-3 bg-black text-white flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="text-sm">{item.icon}</span>
<span className="text-xs font-black uppercase tracking-widest">
{item.label}
</span>
</div>
{item.tag && (
<span className="text-[9px] font-black tracking-widest border-2 border-current px-[5px] py-[1px] leading-tight">
<span className="text-[8px] font-black tracking-widest border border-white px-1.5 py-0.5">
{item.tag}
</span>
)}
</div>
<p className="text-xs font-bold tracking-wide leading-snug opacity-60 group-hover:opacity-80 pl-6">
{item.desc}
</p>
</Wrapper>
<div className="grid grid-cols-2 gap-[2px] bg-black">
{item.submenu.map((subItem) => (
<Link
key={subItem.label}
to={subItem.to}
onClick={closeMenu}
className="group flex flex-col p-3 bg-white hover:bg-gray-50 transition-colors"
>
<div className="flex items-center gap-2 mb-0.5">
<span className="text-xs group-hover:scale-110 transition-transform">{subItem.icon}</span>
<span className="text-[11px] font-black uppercase tracking-wider group-hover:underline decoration-2">
{subItem.label}
</span>
</div>
<p className="text-[10px] font-bold text-gray-500 pl-5 leading-tight">
{subItem.desc}
</p>
</Link>
))}
</div>
</div>
);
})}
</div>

{/* Footer strip */}
<div className="mt-4 pt-3 border-t-2 border-black flex items-center justify-between">
<span className="text-[10px] font-black uppercase tracking-[0.15em] text-gray-500">
More tools shipping soon
</span>
<span className="text-[10px] font-black uppercase tracking-widest border-b-2 border-black hover:opacity-60 cursor-pointer">
View All →
</span>
</div>
}

return (
<Wrapper
key={item.label}
to={item.to}
onClick={closeMenu}
className="group flex flex-col p-4 bg-white hover:bg-black hover:text-white transition-all duration-150"
>
<div className="flex items-center gap-2 mb-1">
<span className="text-lg group-hover:scale-110 transition-transform">{item.icon}</span>
<span className="text-xs font-black uppercase tracking-widest">
{item.label}
</span>
{item.tag && (
<span className="text-[8px] font-black tracking-widest border-2 border-current px-1.5 py-0.5">
{item.tag}
</span>
)}
</div>
<p className="text-[10px] font-bold opacity-60 group-hover:opacity-100 pl-6 leading-relaxed">
{item.desc}
</p>
</Wrapper>
);
})}
</div>


</div>
)}
</div>
</div>
</div>

Expand Down Expand Up @@ -506,7 +491,7 @@ export default function Navbar() {
return (
<Wrapper
key={item.label}
to={item.to}
{...(item.to ? { to: item.to } : { type: "button" })}
onClick={closeMenu}
className="w-full text-left px-8 py-3 border-b border-black/10 hover:bg-black hover:text-white transition-colors duration-150 group"
>
Expand Down
23 changes: 10 additions & 13 deletions frontend/src/pages/DashboardPage.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useState } from "react";
import { useAuth } from "../context/AuthContext";
import { useNavigate, Link } from "react-router-dom";
import { Link,useNavigate } from "react-router-dom";
import Loader from "../components/shared/Loader";
import { useCodeforces } from "../hooks/useCodeforces";
import ConnectBanner from "../components/codeforces/ConnectBanner";
import VerifyModal from "../components/codeforces/VerifyModal";
import AIInsightPanel from "../components/ai/AIInsightPanel";

export default function DashboardPage() {
const { user, loading, logout } = useAuth();
const { user, loading, logout } = useAuth();
const navigate = useNavigate();
const [modalOpen, setModalOpen] = useState(false);

Expand All @@ -22,11 +22,13 @@ export default function DashboardPage() {
connectLoading,
connectError,
} = useCodeforces(true); // dashboard mode = lightweight summary only

const handleLogout = () => {
logout();
navigate("/");
};
logout();
navigate("/");
};



if (loading) {
return <Loader />;
Expand All @@ -35,7 +37,7 @@ export default function DashboardPage() {
return (
<div className="w-full flex-1 flex flex-col px-4 sm:px-6 md:px-8 py-12 sm:py-16 bg-white overflow-hidden">
<div className="max-w-7xl mx-auto w-full">
<header className="mb-12 sm:mb-16 border-b-4 border-black pb-6 sm:pb-8 flex flex-col md:flex-row md:items-end md:justify-between gap-4 sm:gap-6">
<header className="mb-12 sm:mb-16 border-b-4 border-black pb-6 sm:pb-8 flex flex-col md:flex-row md:items-end md:justify-between gap-4 sm:gap-6">
<div>
<h1 className="text-3xl sm:text-5xl md:text-7xl font-black uppercase tracking-tighter text-black mb-4 sm:mb-6">
Command Center
Expand All @@ -44,12 +46,7 @@ export default function DashboardPage() {
Welcome back, {user?.name || "Engineer"}. Here is your unified growth telemetry.
</p>
</div>
<button
onClick={handleLogout}
className="px-6 sm:px-8 py-3 sm:py-4 border-4 border-black bg-white text-black font-black uppercase tracking-widest hover:bg-black hover:text-white transition-colors rounded-none w-full md:w-auto"
>
Logout
</button>

</header>

<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 sm:gap-10 mb-12 sm:mb-16">
Expand Down
1 change: 0 additions & 1 deletion server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.