Fix menu for mobile and small screens

This commit is contained in:
TheMaddax 2024-12-02 10:26:09 -06:00
parent db358e48bf
commit 62433173eb
3 changed files with 243 additions and 876 deletions

View file

@ -10,21 +10,22 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@emotion/is-prop-valid": "^1.3.1",
"@headlessui/react": "^2.2.0", "@headlessui/react": "^2.2.0",
"framer-motion": "11.12.0",
"lucide-react": "^0.462.0", "lucide-react": "^0.462.0",
"next": "15.0.3", "next": "15.0.3",
"react": "19.0.0-rc-66855b96-20241106", "react": "18.3.1",
"react-dom": "19.0.0-rc-66855b96-20241106", "react-dom": "18.3.1",
"react-icons": "^5.0.1" "react-icons": "^5.3.0"
}, },
"devDependencies": { "devDependencies": {
"@types/next": "^8.0.7", "@types/node": "^22.10.1",
"@types/node": "^22.10.0",
"@types/react": "^18.3.12", "@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.1",
"@typescript-eslint/parser": "^8.16.0", "@typescript-eslint/parser": "^8.16.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"eslint": "^9.15.0", "eslint": "^9.16.0",
"eslint-config-next": "15.0.3", "eslint-config-next": "15.0.3",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"postcss": "^8.4.49", "postcss": "^8.4.49",

944
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,18 @@
'use client' 'use client'
import { useState } from 'react'; import { useState, useEffect } from 'react';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { Menu, X } from 'lucide-react'; import { Menu, X } from 'lucide-react';
import dynamic from 'next/dynamic';
const MotionDiv = dynamic(() => import('framer-motion').then(mod => mod.motion.div), {
ssr: false
});
const AnimatePresence = dynamic(() => import('framer-motion').then(mod => mod.AnimatePresence), {
ssr: false
});
const navigation = [ const navigation = [
{ name: 'Home', href: '/' }, { name: 'Home', href: '/' },
@ -21,108 +30,101 @@ export default function Header() {
<div className="flex lg:flex-1"> <div className="flex lg:flex-1">
<Link href="/" className="-m-1.5 p-1.5"> <Link href="/" className="-m-1.5 p-1.5">
<span className="sr-only">FINLION</span> <span className="sr-only">FINLION</span>
<Image <MotionDiv whileHover={{ scale: 1.05 }}>
className="h-12 w-auto" <Image
src="/images/logo.jpg" className="h-12 w-auto"
alt="FINLION Logo" src="/images/logo.jpg"
width={180} alt="FINLION Logo"
height={48} width={180}
priority height={48}
/> priority
/>
</MotionDiv>
</Link> </Link>
</div> </div>
{/* Mobile menu button */}
<div className="flex lg:hidden"> <div className="flex lg:hidden">
<button <MotionDiv
type="button" whileTap={{ scale: 0.95 }}
className="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700" className="inline-flex items-center justify-center rounded-md p-2.5 text-gray-700 hover:bg-gray-100 transition-colors"
onClick={() => setMobileMenuOpen(true)} onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
> >
<span className="sr-only">Open main menu</span> <span className="sr-only">Toggle menu</span>
<Menu className="h-6 w-6" aria-hidden="true" /> {mobileMenuOpen ? (
</button> <X className="h-6 w-6" aria-hidden="true" />
) : (
<Menu className="h-6 w-6" aria-hidden="true" />
)}
</MotionDiv>
</div> </div>
{/* Desktop navigation */} {/* Desktop Navigation */}
<div className="hidden lg:flex lg:gap-x-12"> <div className="hidden lg:flex lg:gap-x-12">
{navigation.map((item) => ( {navigation.map((item) => (
<Link <MotionDiv key={item.name} whileHover={{ scale: 1.05 }}>
key={item.name} <Link
href={item.href} href={item.href}
className="text-sm font-semibold leading-6 text-gray-900 hover:text-blue-800 transition-colors" className="text-sm font-semibold leading-6 text-gray-900 hover:text-blue-800 transition-colors"
> >
{item.name} {item.name}
</Link> </Link>
</MotionDiv>
))} ))}
</div> </div>
{/* CTA Button */}
<div className="hidden lg:flex lg:flex-1 lg:justify-end"> <div className="hidden lg:flex lg:flex-1 lg:justify-end">
<Link <MotionDiv whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
href="/contact" <Link
className="rounded-md bg-blue-800 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 transition-colors" href="/contact"
> className="rounded-md bg-blue-800 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 transition-colors"
Get Started >
</Link> Get Started
</Link>
</MotionDiv>
</div> </div>
</nav> </nav>
{/* Mobile menu */} {/* Mobile Navigation Menu */}
{mobileMenuOpen && ( <AnimatePresence>
<div className="lg:hidden"> {mobileMenuOpen && (
<div className="fixed inset-0 z-50"> <>
<div className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10"> <MotionDiv
<div className="flex items-center justify-between"> initial={{ opacity: 0 }}
<Link href="/" className="-m-1.5 p-1.5"> animate={{ opacity: 1 }}
<span className="sr-only">FINLION</span> exit={{ opacity: 0 }}
<Image className="fixed inset-0 bg-black/20 backdrop-blur-sm z-40"
className="h-8 w-auto" onClick={() => setMobileMenuOpen(false)}
src="/images/logo.jpg" />
alt="FINLION Logo" <MotionDiv
width={120} className="fixed inset-0 z-50"
height={32} initial={{ x: '-100%' }}
priority animate={{ x: 0 }}
/> exit={{ x: '-100%' }}
</Link> transition={{ type: 'tween', duration: 0.3 }}
<button >
type="button" <div className="fixed inset-y-0 w-full bg-white pt-24">
className="-m-2.5 rounded-md p-2.5 text-gray-700" <nav className="flex flex-col items-center space-y-8 bg-white pb-8">
onClick={() => setMobileMenuOpen(false)} {navigation.map((item) => (
> <MotionDiv
<span className="sr-only">Close menu</span> key={item.name}
<X className="h-6 w-6" aria-hidden="true" /> whileHover={{ scale: 1.05 }}
</button> whileTap={{ scale: 0.95 }}
</div> >
<div className="mt-6 flow-root">
<div className="-my-6 divide-y divide-gray-500/10">
<div className="space-y-2 py-6">
{navigation.map((item) => (
<Link <Link
key={item.name}
href={item.href} href={item.href}
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50" className="text-xl font-semibold text-blue-800 transition-colors px-4 py-2 w-full text-center"
onClick={() => setMobileMenuOpen(false)} onClick={() => setMobileMenuOpen(false)}
> >
{item.name} {item.name}
</Link> </Link>
))} </MotionDiv>
</div> ))}
<div className="py-6"> </nav>
<Link
href="/contact"
className="-mx-3 block rounded-lg px-3 py-2.5 text-base font-semibold leading-7 text-white bg-blue-800 hover:bg-blue-700 text-center"
onClick={() => setMobileMenuOpen(false)}
>
Get Started
</Link>
</div>
</div>
</div> </div>
</div> </MotionDiv>
</div> </>
</div> )}
)} </AnimatePresence>
</header> </header>
); );
} }