Merge pull request #2 from AshwaniNITR/Shoaib's-branch

extension of resources navbar
This commit is contained in:
Shoaib1M
2025-10-18 12:33:08 +05:30
committed by GitHub
3 changed files with 115 additions and 31 deletions

3
src/app/books/page.jsx Normal file
View File

@@ -0,0 +1,3 @@
export default function BooksPage() {
return <h1 className="text-center text-black mt-20">Books Page</h1>;
}

View File

@@ -3,7 +3,6 @@
import { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
// Animation variants
const ANIMATIONS = {
overlay: {
hidden: { opacity: 0 },
@@ -30,15 +29,14 @@ const ANIMATIONS = {
export default function Navbar() {
const [isOpen, setIsOpen] = useState(false);
const [showDropdown, setShowDropdown] = useState(false);
// Close on Esc
useEffect(() => {
const onKey = (e) => e.key === "Escape" && setIsOpen(false);
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, []);
// Lock body scroll when open
useEffect(() => {
document.documentElement.classList.toggle("overflow-hidden", isOpen);
return () => document.documentElement.classList.remove("overflow-hidden");
@@ -46,6 +44,15 @@ export default function Navbar() {
const toggleMenu = () => setIsOpen((v) => !v);
const mainLinks = [
"Home",
"Events",
"Projects",
"Team",
"Resources",
"Contact",
];
return (
<>
{/* ---------------- MOBILE NAV ---------------- */}
@@ -54,7 +61,7 @@ export default function Navbar() {
{/* Logo */}
<div className="text-blue-500 text-2xl font-bold">ML4E</div>
{/* Hamburger / Cross button (moves to top-right & higher z when open) */}
{/* Hamburger Button */}
<button
onClick={toggleMenu}
aria-label="Toggle menu"
@@ -84,7 +91,6 @@ export default function Navbar() {
<AnimatePresence>
{isOpen && (
<>
{/* Dark overlay behind button */}
<motion.div
className="fixed inset-0 bg-gray-900/95 z-40"
variants={ANIMATIONS.overlay}
@@ -93,7 +99,6 @@ export default function Navbar() {
exit="exit"
onClick={() => setIsOpen(false)}
/>
{/* Menu layer (below the floating button) */}
<motion.div
className="fixed inset-0 z-50 flex flex-col justify-center items-center"
variants={ANIMATIONS.menuContainer}
@@ -105,8 +110,40 @@ export default function Navbar() {
className="flex flex-col items-center gap-6 px-4"
variants={ANIMATIONS.menuContainer}
>
{["Home", "Events", "Projects", "Team", "Resources", "Contact"].map(
(item) => (
{mainLinks.map((item) => {
if (item === "Resources") {
return (
<div
key="resources"
className="flex flex-col items-center"
>
<motion.button
onClick={() => setShowDropdown(!showDropdown)}
className="text-xl text-white hover:text-blue-300 transition-colors py-2 px-4 rounded-lg hover:bg-white/5"
>
Resources
</motion.button>
{showDropdown && (
<div className="flex flex-col items-center gap-2 mt-2">
<a
href="/onlineresources"
className="text-white text-base hover:text-blue-300"
>
Online Resources
</a>
<a
href="/books"
className="text-white text-base hover:text-blue-300"
>
Books
</a>
</div>
)}
</div>
);
}
return (
<motion.a
key={item}
href={`#${item.toLowerCase()}`}
@@ -116,8 +153,8 @@ export default function Navbar() {
>
{item}
</motion.a>
)
)}
);
})}
</motion.div>
</motion.div>
</>
@@ -125,7 +162,7 @@ export default function Navbar() {
</AnimatePresence>
</nav>
{/* ---------------- DESKTOP SIDEBAR ---------------- */}
{/* ---------------- DESKTOP NAV ---------------- */}
<div className="hidden md:block">
<div
className={`fixed top-0 left-0 h-screen w-20 flex flex-col justify-between items-center py-6 z-50
@@ -138,20 +175,18 @@ export default function Navbar() {
{/* Logo */}
<div className="text-white text-2xl font-bold">ML4E</div>
{/* Desktop hamburger (does NOT turn into cross; cross is at top-right) */}
{!isOpen?(
{!isOpen && (
<button
onClick={toggleMenu}
aria-label="Open menu"
aria-expanded={isOpen}
className="flex flex-col justify-center items-center w-12 h-12 rounded-full bg-blue-500/10 backdrop-blur-sm border border-blue-500/20"
>
<span className="block w-6 h-0.5 bg-blue-400 mb-1.5" />
<span className="block w-6 h-0.5 bg-blue-400" />
<span className="block w-6 h-0.5 bg-blue-400 mt-1.5" />
</button>
):(null)}
onClick={toggleMenu}
aria-label="Open menu"
aria-expanded={isOpen}
className="flex flex-col justify-center items-center w-12 h-12 rounded-full bg-blue-500/10 backdrop-blur-sm border border-blue-500/20"
>
<span className="block w-6 h-0.5 bg-blue-400 mb-1.5" />
<span className="block w-6 h-0.5 bg-blue-400" />
<span className="block w-6 h-0.5 bg-blue-400 mt-1.5" />
</button>
)}
<div className="h-6" />
</div>
@@ -176,7 +211,6 @@ export default function Navbar() {
animate="visible"
exit="exit"
>
{/* Desktop cross at top-right only */}
<button
onClick={() => setIsOpen(false)}
aria-label="Close menu"
@@ -189,19 +223,61 @@ export default function Navbar() {
className="flex flex-col md:flex-row md:flex-wrap items-center justify-center gap-6 max-w-4xl px-4"
variants={ANIMATIONS.menuContainer}
>
{["Home", "Events", "Projects", "Team", "Resources", "Contact"].map(
(item) => (
{mainLinks.map((item) => {
if (item === "Resources") {
return (
<div
key="resources-desktop"
className="relative group"
onMouseEnter={() => setShowDropdown(true)}
onMouseLeave={() => setShowDropdown(false)}
>
<motion.span
className="text-2xl text-white hover:text-blue-300 transition-colors py-2 px-6 rounded-lg hover:bg-white/5"
variants={ANIMATIONS.menuItem}
>
Resources
</motion.span>
<AnimatePresence>
{showDropdown && (
<motion.div
className="absolute top-full left-0 mt-2 flex flex-col bg-white/10 border border-white/20 rounded-lg shadow-lg"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
>
<a
href="/onlineresources"
className="px-4 py-2 text-white hover:bg-blue-500/20"
>
Online Resources
</a>
<a
href="/books"
className="px-4 py-2 text-white hover:bg-blue-500/20"
>
Books
</a>
</motion.div>
)}
</AnimatePresence>
</div>
);
}
return (
<motion.a
key={item}
href={`#${item.toLowerCase()}`}
variants={ANIMATIONS.menuItem}
className="text-xl md:text-2xl text-white hover:text-blue-300 transition-colors py-2 px-6 rounded-lg hover:bg-white/5"
className="text-2xl text-white hover:text-blue-300 transition-colors py-2 px-6 rounded-lg hover:bg-white/5"
onClick={() => setIsOpen(false)}
>
{item}
</motion.a>
)
)}
);
})}
</motion.div>
</motion.div>
</>
@@ -210,4 +286,4 @@ export default function Navbar() {
</div>
</>
);
}
}

View File

@@ -0,0 +1,5 @@
export default function OnlineResourcesPage() {
return (
<h1 className="text-center text-black mt-20">Online Resources Page</h1>
);
}