feat: Add core application and marketing layouts, including navigation, user management, and a shared footer component.

This commit is contained in:
Timo 2026-01-07 14:33:06 +01:00
parent 9573a2eea9
commit b217e50d9f
3 changed files with 45 additions and 43 deletions

View File

@ -161,9 +161,8 @@ export default function AppLayout({
{/* Sidebar */} {/* Sidebar */}
<aside <aside
className={`fixed top-0 left-0 z-50 h-full w-64 bg-white border-r border-gray-200 transform transition-transform lg:translate-x-0 ${ className={`fixed top-0 left-0 z-50 h-full w-64 bg-white border-r border-gray-200 transform transition-transform lg:translate-x-0 ${sidebarOpen ? 'translate-x-0' : '-translate-x-full'
sidebarOpen ? 'translate-x-0' : '-translate-x-full' }`}
}`}
> >
<div className="flex items-center justify-between p-4 border-b border-gray-200"> <div className="flex items-center justify-between p-4 border-b border-gray-200">
<Link href="/" className="flex items-center space-x-2"> <Link href="/" className="flex items-center space-x-2">
@ -187,11 +186,10 @@ export default function AppLayout({
<Link <Link
key={item.name} key={item.name}
href={item.href} href={item.href}
className={`flex items-center space-x-3 px-3 py-2 rounded-lg transition-colors ${ className={`flex items-center space-x-3 px-3 py-2 rounded-lg transition-colors ${isActive
isActive ? 'bg-primary-50 text-primary-600'
? 'bg-primary-50 text-primary-600' : 'text-gray-700 hover:bg-gray-100'
: 'text-gray-700 hover:bg-gray-100' }`}
}`}
> >
{item.icon} {item.icon}
<span className="font-medium">{item.name}</span> <span className="font-medium">{item.name}</span>
@ -249,7 +247,7 @@ export default function AppLayout({
</main> </main>
{/* Footer */} {/* Footer */}
<Footer /> <Footer variant="dashboard" />
</div> </div>
</div> </div>
); );

View File

@ -150,12 +150,9 @@ export default function MarketingLayout({
<div className="border-t border-gray-800 mt-8 pt-8 flex items-center justify-between text-gray-400"> <div className="border-t border-gray-800 mt-8 pt-8 flex items-center justify-between text-gray-400">
<Link <Link
href="/newsletter" href="/newsletter"
className="text-xs hover:text-white transition-colors flex items-center gap-1.5 opacity-50 hover:opacity-100" className="text-[6px] text-gray-700 opacity-[0.25] hover:opacity-100 hover:text-white transition-opacity duration-300"
> >
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg>
Admin
</Link> </Link>
<p>&copy; 2025 QR Master. All rights reserved.</p> <p>&copy; 2025 QR Master. All rights reserved.</p>
<div className="w-12"></div> <div className="w-12"></div>

View File

@ -1,59 +1,66 @@
import Link from 'next/link'; import Link from 'next/link';
export function Footer() { interface FooterProps {
variant?: 'marketing' | 'dashboard';
}
export function Footer({ variant = 'marketing' }: FooterProps) {
const isDashboard = variant === 'dashboard';
return ( return (
<footer className="bg-gray-900 text-white py-12 mt-20"> <footer className={`${isDashboard ? 'bg-gray-50 text-gray-600 border-t border-gray-200 mt-12' : 'bg-gray-900 text-white mt-20'} py-12`}>
<div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl"> <div className="container mx-auto px-4 sm:px-6 lg:px-8 max-w-7xl">
<div className="grid md:grid-cols-4 gap-8"> <div className="grid md:grid-cols-4 gap-8">
<div> <div>
<Link href="/" className="flex items-center space-x-2 mb-4 hover:opacity-80 transition-opacity"> <Link href="/" className="flex items-center space-x-2 mb-4 hover:opacity-80 transition-opacity">
<img src="/logo.svg" alt="QR Master" className="w-10 h-10" /> <img src="/logo.svg" alt="QR Master" className="w-10 h-10" />
<span className="text-xl font-bold">QR Master</span> <span className={`text-xl font-bold ${isDashboard ? 'text-gray-900' : ''}`}>QR Master</span>
</Link> </Link>
<p className="text-gray-400"> <p className={isDashboard ? 'text-gray-500' : 'text-gray-400'}>
Create custom QR codes in seconds with advanced tracking and analytics. Create custom QR codes in seconds with advanced tracking and analytics.
</p> </p>
</div> </div>
<div> <div>
<h3 className="font-semibold mb-4">Product</h3> <h3 className={`font-semibold mb-4 ${isDashboard ? 'text-gray-900' : ''}`}>Product</h3>
<ul className="space-y-2 text-gray-400"> <ul className={`space-y-2 ${isDashboard ? 'text-gray-500' : 'text-gray-400'}`}>
<li><Link href="/#features" className="hover:text-white">Features</Link></li> <li><Link href="/#features" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Features</Link></li>
<li><Link href="/#pricing" className="hover:text-white">Pricing</Link></li> <li><Link href="/#pricing" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Pricing</Link></li>
<li><Link href="/#faq" className="hover:text-white">FAQ</Link></li> <li><Link href="/#faq" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>FAQ</Link></li>
<li><Link href="/blog" className="hover:text-white">Blog</Link></li> <li><Link href="/blog" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Blog</Link></li>
</ul> </ul>
</div> </div>
<div> <div>
<h3 className="font-semibold mb-4">Resources</h3> <h3 className={`font-semibold mb-4 ${isDashboard ? 'text-gray-900' : ''}`}>Resources</h3>
<ul className="space-y-2 text-gray-400"> <ul className={`space-y-2 ${isDashboard ? 'text-gray-500' : 'text-gray-400'}`}>
<li><Link href="/pricing" className="hover:text-white">Full Pricing</Link></li> <li><Link href="/pricing" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Full Pricing</Link></li>
<li><Link href="/faq" className="hover:text-white">All Questions</Link></li> <li><Link href="/faq" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>All Questions</Link></li>
<li><Link href="/blog" className="hover:text-white">Blog</Link></li> <li><Link href="/blog" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Blog</Link></li>
<li><Link href="/signup" className="hover:text-white">Get Started</Link></li> <li><Link href="/signup" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Get Started</Link></li>
</ul> </ul>
</div> </div>
<div> <div>
<h3 className="font-semibold mb-4">Legal</h3> <h3 className={`font-semibold mb-4 ${isDashboard ? 'text-gray-900' : ''}`}>Legal</h3>
<ul className="space-y-2 text-gray-400"> <ul className={`space-y-2 ${isDashboard ? 'text-gray-500' : 'text-gray-400'}`}>
<li><Link href="/privacy" className="hover:text-white">Privacy Policy</Link></li> <li><Link href="/privacy" className={isDashboard ? 'hover:text-primary-600' : 'hover:text-white'}>Privacy Policy</Link></li>
</ul> </ul>
</div> </div>
</div> </div>
<div className="border-t border-gray-800 mt-8 pt-8 flex items-center justify-between text-gray-400"> <div className={`border-t mt-8 pt-8 flex items-center justify-between ${isDashboard ? 'border-gray-200 text-gray-500' : 'border-gray-800 text-gray-400'}`}>
<Link {!isDashboard ? (
href="/newsletter" <Link
className="text-xs hover:text-white transition-colors flex items-center gap-1.5 opacity-50 hover:opacity-100" href="/newsletter"
> className="text-[6px] text-gray-700 opacity-[0.03] hover:opacity-100 hover:text-white transition-opacity duration-300"
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"> >
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
</svg> </Link>
Admin ) : (
</Link> <div></div>
)}
<p>&copy; 2025 QR Master. All rights reserved.</p> <p>&copy; 2025 QR Master. All rights reserved.</p>
<div className="w-12"></div> <div className="w-12"></div>
</div> </div>