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,6 +30,7 @@ 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>
<MotionDiv whileHover={{ scale: 1.05 }}>
<Image <Image
className="h-12 w-auto" className="h-12 w-auto"
src="/images/logo.jpg" src="/images/logo.jpg"
@ -29,100 +39,92 @@ export default function Header() {
height={48} height={48}
priority 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>
{mobileMenuOpen ? (
<X className="h-6 w-6" aria-hidden="true" />
) : (
<Menu className="h-6 w-6" aria-hidden="true" /> <Menu className="h-6 w-6" aria-hidden="true" />
</button> )}
</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) => (
<MotionDiv key={item.name} whileHover={{ scale: 1.05 }}>
<Link <Link
key={item.name}
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">
<MotionDiv whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
<Link <Link
href="/contact" 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" 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 Get Started
</Link> </Link>
</MotionDiv>
</div> </div>
</nav> </nav>
{/* Mobile menu */} {/* Mobile Navigation Menu */}
<AnimatePresence>
{mobileMenuOpen && ( {mobileMenuOpen && (
<div className="lg:hidden"> <>
<div className="fixed inset-0 z-50"> <MotionDiv
<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"> initial={{ opacity: 0 }}
<div className="flex items-center justify-between"> animate={{ opacity: 1 }}
<Link href="/" className="-m-1.5 p-1.5"> exit={{ opacity: 0 }}
<span className="sr-only">FINLION</span> className="fixed inset-0 bg-black/20 backdrop-blur-sm z-40"
<Image
className="h-8 w-auto"
src="/images/logo.jpg"
alt="FINLION Logo"
width={120}
height={32}
priority
/>
</Link>
<button
type="button"
className="-m-2.5 rounded-md p-2.5 text-gray-700"
onClick={() => setMobileMenuOpen(false)} onClick={() => setMobileMenuOpen(false)}
/>
<MotionDiv
className="fixed inset-0 z-50"
initial={{ x: '-100%' }}
animate={{ x: 0 }}
exit={{ x: '-100%' }}
transition={{ type: 'tween', duration: 0.3 }}
> >
<span className="sr-only">Close menu</span> <div className="fixed inset-y-0 w-full bg-white pt-24">
<X className="h-6 w-6" aria-hidden="true" /> <nav className="flex flex-col items-center space-y-8 bg-white pb-8">
</button>
</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) => ( {navigation.map((item) => (
<Link <MotionDiv
key={item.name} key={item.name}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<Link
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>
))} ))}
</nav>
</div> </div>
<div className="py-6"> </MotionDiv>
<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>
</div>
)} )}
</AnimatePresence>
</header> </header>
); );
} }