feat: add cart and product pages, quantity controls, and first-visit development notice
Build & Deploy (develop) / build-and-deploy (push) Successful in 1m44s

This commit is contained in:
2026-09-15 07:14:37 +02:00
parent 4cd34106b0
commit 0390a35d01
23 changed files with 528 additions and 466 deletions
+21 -21
View File
@@ -4,30 +4,33 @@
import {useState, useEffect} from 'react';
import Image from 'next/image';
import Link from 'next/link';
import {usePathname} from 'next/navigation';
import {Badge, Button} from 'antd';
import {ShoppingCartOutlined, MenuOutlined, CloseOutlined, UserOutlined} from '@ant-design/icons';
import {useAppSelector, useAppDispatch} from '@/store/hooks';
import {selectCartCount, openDrawer} from '@/store/cartSlice';
import {useAppSelector} from '@/store/hooks';
import {selectCartCount} from '@/store/cartSlice';
import {useLanguage} from '@/app/context/LanguageContext';
import ThemeToggle from './ThemeToggle';
import LanguageToggle from './LanguageToggle';
export default function Header() {
const dispatch = useAppDispatch();
const pathname = usePathname();
const cartCount = useAppSelector(selectCartCount);
const {t} = useLanguage();
const [scrolled, setScrolled] = useState(false);
const [mobileOpen, setMobileOpen] = useState(false);
const navLinks = [
{href: '#hero', label: t.nav.home},
{href: '#showcase', label: t.nav.showcase},
{href: '#about', label: t.nav.about},
{href: '#locations', label: t.nav.locations},
{href: '/#hero', label: t.nav.home},
{href: '/#showcase', label: t.nav.showcase},
{href: '/#about', label: t.nav.about},
{href: '/#locations', label: t.nav.locations},
];
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 24);
onScroll();
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
@@ -40,23 +43,23 @@ export default function Header() {
return (
<header
className={`fixed top-0 inset-x-0 z-50 transition-all duration-300 ${
scrolled ? 'bg-page-85 backdrop-blur-md shadow-[0_1px_0_0_rgba(0,166,147,0.25)]' : 'bg-transparent'
scrolled || pathname !== '/' ? 'bg-page-85 backdrop-blur-md shadow-[0_1px_0_0_rgba(0,166,147,0.25)]' : 'bg-transparent'
}`}
>
<div className="mx-auto max-w-7xl px-5 md:px-8 h-20 flex items-center justify-between gap-4">
<a href="#hero" className="flex items-center gap-2 shrink-0">
<Link href="/#hero" onClick={() => setMobileOpen(false)} className="flex items-center gap-2 shrink-0">
<Image src="/images/icons/logo.png" alt="روبات مارکت" width={150} height={42} priority/>
</a>
</Link>
<nav className="hidden xl:flex items-center gap-5 2xl:gap-7">
{navLinks.map((link) => (
<a
<Link
key={link.href}
href={link.href}
className="text-sm text-secondary hover:text-brand-300 transition-colors whitespace-nowrap"
>
{link.label}
</a>
</Link>
))}
</nav>
@@ -77,13 +80,10 @@ export default function Header() {
</Button>
<Badge count={cartCount} size="small" offset={[-2, 2]}>
<Button
shape="circle"
size="large"
icon={<ShoppingCartOutlined/>}
onClick={() => dispatch(openDrawer())}
aria-label={t.cart.title}
/>
<Link href="/cart" onClick={() => setMobileOpen(false)} aria-label={t.cart.title}
className="w-11 h-11 rounded-full border border-subtle bg-elevated inline-flex items-center justify-center text-xl text-primary hover:text-brand-400">
<ShoppingCartOutlined/>
</Link>
</Badge>
<button
@@ -100,14 +100,14 @@ export default function Header() {
<nav
className="xl:hidden bg-elevated-95 backdrop-blur-md border-t border-subtle px-5 py-4 flex flex-col gap-4 max-h-[calc(100vh-5rem)] overflow-y-auto">
{navLinks.map((link) => (
<a
<Link
key={link.href}
href={link.href}
onClick={() => setMobileOpen(false)}
className="text-secondary text-base"
>
{link.label}
</a>
</Link>
))}
<div className="flex items-center gap-3 pt-2 border-t border-subtle">
<LanguageToggle/>