move to gitea
This commit is contained in:
201
src_backup/components/layout/Footer.tsx
Normal file
201
src_backup/components/layout/Footer.tsx
Normal file
@@ -0,0 +1,201 @@
|
||||
// src/components/layout/Footer.tsx
|
||||
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { Instagram, Facebook, Twitter, Youtube } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { useState } from 'react';
|
||||
|
||||
interface FooterSection {
|
||||
title: string;
|
||||
links: Array<{
|
||||
name: string;
|
||||
href: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
const footerSections: FooterSection[] = [
|
||||
{
|
||||
title: 'Produits',
|
||||
links: [
|
||||
{ name: 'Nouvelles Arrivées', href: '/boutique?filter=new' },
|
||||
{ name: 'Collections Premium', href: '/collections/premium' },
|
||||
{ name: 'Melhfa Traditionnelles', href: '/collections/traditionnelles' },
|
||||
{ name: 'Accessoires', href: '/accessoires' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Aide',
|
||||
links: [
|
||||
{ name: 'Guide des tailles', href: '/aide/tailles' },
|
||||
{ name: 'Livraison', href: '/aide/livraison' },
|
||||
{ name: 'Retours', href: '/aide/retours' },
|
||||
{ name: 'FAQ', href: '/aide/faq' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Entreprise',
|
||||
links: [
|
||||
{ name: 'À propos', href: '/a-propos' },
|
||||
{ name: 'Carrières', href: '/carrieres' },
|
||||
{ name: 'Presse', href: '/presse' },
|
||||
{ name: 'Contact', href: '/contact' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const socialLinks = [
|
||||
{ name: 'Instagram', href: '#', icon: Instagram },
|
||||
{ name: 'Facebook', href: '#', icon: Facebook },
|
||||
{ name: 'Twitter', href: '#', icon: Twitter },
|
||||
{ name: 'YouTube', href: '#', icon: Youtube },
|
||||
];
|
||||
|
||||
export default function Footer(): JSX.Element {
|
||||
const [email, setEmail] = useState('');
|
||||
const [isSubscribed, setIsSubscribed] = useState(false);
|
||||
|
||||
const handleNewsletterSubmit = (e: React.FormEvent): void => {
|
||||
e.preventDefault();
|
||||
if (!email) return;
|
||||
|
||||
// Simuler l'inscription à la newsletter
|
||||
setIsSubscribed(true);
|
||||
setEmail('');
|
||||
|
||||
setTimeout(() => {
|
||||
setIsSubscribed(false);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
return (
|
||||
<footer className="bg-white border-t border-black/5">
|
||||
{/* Newsletter Section */}
|
||||
<div className="bg-gray-50 py-16">
|
||||
<div className="max-w-[1400px] mx-auto px-6 text-center">
|
||||
<h2 className="text-2xl font-light mb-4 tracking-wide">
|
||||
Restez informé
|
||||
</h2>
|
||||
<p className="text-gray-600 mb-8 text-sm">
|
||||
Recevez nos dernières collections et offres exclusives
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleNewsletterSubmit} className="max-w-md mx-auto">
|
||||
<div className="flex gap-0">
|
||||
<Input
|
||||
type="email"
|
||||
placeholder="Votre adresse email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
className="flex-1 rounded-r-none border-r-0 focus:ring-0 focus:border-black text-sm"
|
||||
required
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
className="bg-black text-white hover:bg-gray-800 px-6 rounded-l-none text-xs uppercase tracking-wide"
|
||||
disabled={isSubscribed}
|
||||
>
|
||||
{isSubscribed ? 'Merci !' : "S'abonner"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Footer Content */}
|
||||
<div className="max-w-[1400px] mx-auto px-6 py-16">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 lg:gap-12">
|
||||
{/* Sections de liens */}
|
||||
{footerSections.map((section) => (
|
||||
<div key={section.title}>
|
||||
<h3 className="text-xs font-semibold uppercase tracking-widest mb-6 text-black">
|
||||
{section.title}
|
||||
</h3>
|
||||
<ul className="space-y-3">
|
||||
{section.links.map((link) => (
|
||||
<li key={link.name}>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="text-sm text-gray-600 hover:text-black transition-colors"
|
||||
>
|
||||
{link.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Réseaux sociaux */}
|
||||
<div>
|
||||
<h3 className="text-xs font-semibold uppercase tracking-widest mb-6 text-black">
|
||||
Suivez-nous
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
{socialLinks.map((social) => {
|
||||
const IconComponent = social.icon;
|
||||
return (
|
||||
<Link
|
||||
key={social.name}
|
||||
href={social.href}
|
||||
className="flex items-center text-sm text-gray-600 hover:text-black transition-colors group"
|
||||
>
|
||||
<IconComponent className="w-4 h-4 mr-3 group-hover:scale-110 transition-transform" />
|
||||
{social.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Section */}
|
||||
<div className="mt-16 pt-8 border-t border-gray-200 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
|
||||
<div className="flex flex-col md:flex-row items-center space-y-2 md:space-y-0 md:space-x-6">
|
||||
<p className="text-xs text-gray-500">
|
||||
© 2024 MELHFA. Tous droits réservés.
|
||||
</p>
|
||||
<div className="flex space-x-6">
|
||||
<Link
|
||||
href="/mentions-legales"
|
||||
className="text-xs text-gray-500 hover:text-black transition-colors"
|
||||
>
|
||||
Mentions légales
|
||||
</Link>
|
||||
<Link
|
||||
href="/politique-confidentialite"
|
||||
className="text-xs text-gray-500 hover:text-black transition-colors"
|
||||
>
|
||||
Confidentialité
|
||||
</Link>
|
||||
<Link
|
||||
href="/cookies"
|
||||
className="text-xs text-gray-500 hover:text-black transition-colors"
|
||||
>
|
||||
Cookies
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<span className="text-xs text-gray-500">Paiement sécurisé</span>
|
||||
<div className="flex space-x-2">
|
||||
{/* Logos des méthodes de paiement - vous pouvez remplacer par de vraies images */}
|
||||
<div className="w-8 h-5 bg-gray-200 rounded-sm flex items-center justify-center">
|
||||
<span className="text-[8px] font-bold text-gray-600">VISA</span>
|
||||
</div>
|
||||
<div className="w-8 h-5 bg-gray-200 rounded-sm flex items-center justify-center">
|
||||
<span className="text-[8px] font-bold text-gray-600">MC</span>
|
||||
</div>
|
||||
<div className="w-8 h-5 bg-gray-200 rounded-sm flex items-center justify-center">
|
||||
<span className="text-[8px] font-bold text-gray-600">PP</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
213
src_backup/components/layout/Header.tsx
Normal file
213
src_backup/components/layout/Header.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
// src/components/layout/Header.tsx
|
||||
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useCartActions } from '@/hooks/useCartSync';import { ShoppingBag, Menu, X, Search, User } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetTrigger,
|
||||
} from '@/components/ui/sheet';
|
||||
|
||||
interface NavigationItem {
|
||||
name: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const navigation: NavigationItem[] = [
|
||||
{ name: 'Nouvelles Arrivées', href: '/boutique?filter=new' },
|
||||
{ name: 'Collections', href: '/collections' },
|
||||
{ name: 'Promotions', href: '/boutique?filter=sale' },
|
||||
{ name: 'Accessoires', href: '/accessoires' },
|
||||
];
|
||||
|
||||
export default function Header(): JSX.Element {
|
||||
const { getItemCount } = useCart();
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const itemCount = getItemCount();
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = (): void => {
|
||||
setIsScrolled(window.scrollY > 100);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`fixed top-0 w-full z-50 transition-all duration-300 ${isScrolled
|
||||
? 'bg-white/98 backdrop-blur-xl shadow-sm border-b border-black/5'
|
||||
: 'bg-white/95 backdrop-blur-xl border-b border-black/5'
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-[1400px] mx-auto px-6">
|
||||
<div className="flex items-center justify-between py-3">
|
||||
{/* Logo */}
|
||||
<Link
|
||||
href="/"
|
||||
className="text-2xl font-semibold tracking-[3px] text-black hover:opacity-70 transition-opacity"
|
||||
>
|
||||
MELHFA
|
||||
</Link>
|
||||
|
||||
{/* Navigation Desktop */}
|
||||
<nav className="hidden lg:flex items-center space-x-10">
|
||||
{navigation.map((item) => (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
className="text-sm font-normal text-black hover:opacity-60 transition-opacity tracking-wide uppercase"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Actions Desktop */}
|
||||
<div className="hidden lg:flex items-center space-x-6">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<Search className="w-4 h-4 mr-2" />
|
||||
Recherche
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<User className="w-4 h-4 mr-2" />
|
||||
Connexion
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
Aide
|
||||
</Button>
|
||||
|
||||
<Link href="/panier" className="relative">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="p-2 hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<ShoppingBag className="w-5 h-5" />
|
||||
{itemCount > 0 && (
|
||||
<Badge
|
||||
variant="destructive"
|
||||
className="absolute -top-2 -right-2 w-5 h-5 rounded-full text-xs flex items-center justify-center p-0"
|
||||
>
|
||||
{itemCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Menu Mobile */}
|
||||
<div className="lg:hidden flex items-center space-x-4">
|
||||
<Link href="/panier" className="relative">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="p-2 hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<ShoppingBag className="w-5 h-5" />
|
||||
{itemCount > 0 && (
|
||||
<Badge
|
||||
variant="destructive"
|
||||
className="absolute -top-2 -right-2 w-5 h-5 rounded-full text-xs flex items-center justify-center p-0"
|
||||
>
|
||||
{itemCount}
|
||||
</Badge>
|
||||
)}
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
<Sheet open={isMobileMenuOpen} onOpenChange={setIsMobileMenuOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="p-2 hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<Menu className="w-5 h-5" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right" className="w-80 p-0">
|
||||
<div className="flex flex-col h-full">
|
||||
{/* Header du menu mobile */}
|
||||
<div className="flex items-center justify-between p-6 border-b border-gray-200">
|
||||
<span className="text-lg font-semibold tracking-wide">Menu</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="p-2"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Navigation mobile */}
|
||||
<nav className="flex-1 p-6">
|
||||
<div className="space-y-6">
|
||||
{navigation.map((item) => (
|
||||
<Link
|
||||
key={item.name}
|
||||
href={item.href}
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
className="block text-base font-normal text-black hover:opacity-60 transition-opacity tracking-wide uppercase"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-8 border-t border-gray-200 space-y-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-start text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<Search className="w-4 h-4 mr-3" />
|
||||
Recherche
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-start text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
<User className="w-4 h-4 mr-3" />
|
||||
Connexion
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="w-full justify-start text-sm font-normal tracking-wide uppercase text-black hover:bg-transparent hover:opacity-60"
|
||||
>
|
||||
Aide
|
||||
</Button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user