Update May 12 by Elvis

This commit is contained in:
belviskhoremk
2026-05-12 00:28:37 +00:00
parent b32a70cd0e
commit c4450c993b
37 changed files with 3749 additions and 600 deletions

View File

@@ -14,10 +14,7 @@ export default function Footer() {
{/* Brand */}
<div>
<h3 className="font-serif text-xl font-semibold mb-4">BADO HAIR</h3>
<p className="text-sm opacity-70 leading-relaxed">
Extensions de cheveux 100% naturels. Qualité premium pour sublimer
votre beauté.
</p>
<p className="text-sm opacity-70 leading-relaxed">{t("footer.tagline")}</p>
</div>
{/* Navigation */}
@@ -76,7 +73,7 @@ export default function Footer() {
{/* Social */}
<div>
<h4 className="text-sm font-semibold uppercase tracking-wider mb-4">
Suivez-nous
{t("footer.follow_us")}
</h4>
<div className="flex gap-4">
{/* Instagram */}

View File

@@ -1,9 +1,10 @@
"use client";
import { ShoppingBag, User, Menu, X } from "lucide-react";
import { ShoppingBag, User, Menu, X, LogOut } from "lucide-react";
import { useState } from "react";
import { useCart } from "@/contexts/CartContext";
import { useLanguage } from "@/contexts/LanguageContext";
import { useAuth } from "@/contexts/AuthContext";
import LanguageSwitcher from "./LanguageSwitcher";
import Link from "next/link";
import { usePathname } from "next/navigation";
@@ -12,6 +13,7 @@ export default function Header() {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const { totalItems, setIsCartOpen } = useCart();
const { t } = useLanguage();
const { user, logout } = useAuth();
const currentPath = usePathname();
const navLinks = [
@@ -58,9 +60,36 @@ export default function Header() {
{/* Right icons */}
<div className="flex items-center gap-3">
<LanguageSwitcher />
<Link href="/connexion" className="p-2 text-muted-foreground hover:text-foreground transition-colors">
<User className="h-5 w-5" />
</Link>
{user ? (
<div className="flex items-center gap-2">
<Link
href="/mon-compte"
className="hidden lg:flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors"
title={t("nav.account")}
>
<User className="h-4 w-4" />
{user.full_name ?? user.email}
</Link>
<Link
href="/mon-compte"
className="lg:hidden p-2 text-muted-foreground hover:text-foreground transition-colors"
title={t("nav.account")}
>
<User className="h-5 w-5" />
</Link>
<button
onClick={logout}
className="p-2 text-muted-foreground hover:text-foreground transition-colors"
title={t("auth.logout")}
>
<LogOut className="h-5 w-5" />
</button>
</div>
) : (
<Link href="/connexion" className="p-2 text-muted-foreground hover:text-foreground transition-colors">
<User className="h-5 w-5" />
</Link>
)}
<button
onClick={() => setIsCartOpen(true)}
className="p-2 text-muted-foreground hover:text-foreground transition-colors relative cursor-pointer"

View File

@@ -9,10 +9,8 @@ import {
const languages: { code: Language; label: string; flag: string }[] = [
{ code: "fr", label: "Français", flag: "🇫🇷" },
{ code: "de", label: "Deutsch", flag: "🇩🇪" },
{ code: "en", label: "English", flag: "🇬🇧" },
{ code: "ar", label: "العربية", flag: "🇸🇦" },
{ code: "tr", label: "Türkçe", flag: "🇹🇷" },
{ code: "de", label: "Deutsch", flag: "🇩🇪" },
{ code: "en", label: "English", flag: "🇬🇧" },
];
export default function LanguageSwitcher() {
@@ -39,4 +37,4 @@ export default function LanguageSwitcher() {
</DropdownMenuContent>
</DropdownMenu>
);
};
}

View File

@@ -1,26 +1,35 @@
"use client";
import { Star } from "lucide-react";
import { Product } from "@/data/products";
import { Badge } from "@/components/ui/badge";
import Link from "next/link";
import { useLanguage } from "@/contexts/LanguageContext";
interface ProductCardProps {
product: Product;
}
export default function ProductCard({ product }: ProductCardProps) {
const { t } = useLanguage();
return (
<Link href={`/produit/${product.id}`} className="group block">
<div className="relative overflow-hidden rounded-lg bg-muted aspect-[3/4] mb-3">
<img
src={product.image}
alt={product.name}
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
loading="lazy"
/>
{product.image ? (
<img
src={product.image}
alt={product.name}
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
loading="lazy"
/>
) : (
<div className="w-full h-full bg-muted" />
)}
<div className="absolute top-3 left-3 flex gap-2">
{product.isNew && (
<Badge className="bg-primary text-primary-foreground text-[10px] uppercase tracking-wider">
Nouveau
{t("product.badge_new")}
</Badge>
)}
{product.isBestseller && (
@@ -42,7 +51,7 @@ export default function ProductCard({ product }: ProductCardProps) {
<div className="flex items-center gap-1">
<Star className="h-3 w-3 fill-primary text-primary" />
<span className="text-xs text-muted-foreground">
{product.rating} ({product.reviewCount})
{product.rating} ({product.reviewCount} {t("product.reviews")})
</span>
</div>
<div className="flex items-center gap-2">
@@ -54,4 +63,4 @@ export default function ProductCard({ product }: ProductCardProps) {
</div>
</Link>
);
};
}

View File

@@ -1,6 +1,6 @@
"use client";
import { LayoutDashboard, Package, CalendarCheck, LogOut, Home } from "lucide-react";
import { LayoutDashboard, Package, CalendarCheck, CalendarDays, ShoppingBag, Users, Settings, Scissors, LogOut, Home } from "lucide-react";
import {
Sidebar,
SidebarContent,
@@ -14,26 +14,33 @@ import {
SidebarHeader,
useSidebar,
} from "@/components/ui/sidebar";
import { useAdmin } from "@/contexts/AdminContext";
import { useAuth } from "@/contexts/AuthContext";
import { useLanguage } from "@/contexts/LanguageContext";
import { Button } from "@/components/ui/button";
import { usePathname, useRouter } from "next/navigation";
import Link from "next/link";
import { useState } from "react";
const items = [
{ title: "Vue d'ensemble", url: "/admin", icon: LayoutDashboard, end: true },
{ title: "Produits", url: "/admin/produits", icon: Package },
{ title: "Réservations", url: "/admin/reservations", icon: CalendarCheck },
];
export const AdminSidebar = () => {
const { state } = useSidebar();
const collapsed = state === "collapsed";
const { logout } = useAdmin();
const { logout } = useAuth();
const { t } = useLanguage();
const route = useRouter();
const pathname = usePathname();
const [isActive, setIsActive] = useState("");
const items = [
{ title: t("admin.nav.overview"), url: "/admin", icon: LayoutDashboard, exact: true },
{ title: t("admin.nav.products"), url: "/admin/produits", icon: Package },
{ title: t("admin.nav.orders"), url: "/admin/commandes", icon: ShoppingBag },
{ title: t("admin.nav.bookings"), url: "/admin/reservations", icon: CalendarCheck },
{ title: t("admin.nav.planning"), url: "/admin/planning", icon: CalendarDays },
{ title: t("admin.nav.services"), url: "/admin/services", icon: Scissors },
{ title: t("admin.nav.customers"), url: "/admin/clients", icon: Users },
{ title: t("admin.nav.settings"), url: "/admin/parametres", icon: Settings },
];
const isActive = (item: typeof items[0]) =>
item.exact ? pathname === item.url : pathname.startsWith(item.url);
const handleLogout = () => {
logout();
@@ -53,15 +60,15 @@ export const AdminSidebar = () => {
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Gestion</SidebarGroupLabel>
<SidebarGroupLabel>{t("admin.nav.management")}</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuItem key={item.url}>
<SidebarMenuButton asChild>
<Link
href={item.url}
className={`flex items-center gap-2 ${isActive === item.url ? "bg-sidebar-accent text-sidebar-accent-foreground font-medium" : ""}`}
className={`flex items-center gap-2 ${isActive(item) ? "bg-sidebar-accent text-sidebar-accent-foreground font-medium" : ""}`}
>
<item.icon className="h-4 w-4" />
{!collapsed && <span>{item.title}</span>}
@@ -78,7 +85,7 @@ export const AdminSidebar = () => {
<SidebarMenuButton asChild>
<Link href="/" className="flex items-center gap-2">
<Home className="h-4 w-4" />
{!collapsed && <span>Voir le site</span>}
{!collapsed && <span>{t("admin.nav.view_site")}</span>}
</Link>
</SidebarMenuButton>
<Button
@@ -88,7 +95,7 @@ export const AdminSidebar = () => {
className="w-full justify-start gap-2"
>
<LogOut className="h-4 w-4" />
{!collapsed && <span>Déconnexion</span>}
{!collapsed && <span>{t("admin.logout")}</span>}
</Button>
</SidebarFooter>
</Sidebar>