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
+8
View File
@@ -0,0 +1,8 @@
import type {Metadata} from 'next';
import CartPage from '@/components/CartPage';
export const metadata: Metadata = {title: 'سبد خرید | روبات مارکت'};
export default function Page() {
return <CartPage/>;
}
+9 -1
View File
@@ -3,6 +3,9 @@ import type {ReactNode} from 'react';
import {Vazirmatn} from 'next/font/google';
import './globals.css';
import Providers from './providers';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import DevelopmentNotice from '@/components/DevelopmentNotice';
const vazirmatn = Vazirmatn({
subsets: ['arabic'],
@@ -28,7 +31,12 @@ export default function RootLayout({children}: {children: ReactNode}) {
return (
<html lang="fa" dir="rtl" className={`${vazirmatn.variable} light`} suppressHydrationWarning>
<body className="bg-page text-primary antialiased transition-colors duration-300">
<Providers>{children}</Providers>
<Providers>
<Header/>
{children}
<Footer/>
<DevelopmentNotice/>
</Providers>
</body>
</html>
);
-6
View File
@@ -3,22 +3,16 @@ import ShowcaseSection from "@/components/ShowcaseSection";
import FeaturesSection from '@/components/FeaturesSection';
import AboutSection from '@/components/AboutSection';
import HeroSection from '@/components/HeroSection';
import CartDrawer from '@/components/CartDrawer';
import Footer from '@/components/Footer';
import Header from '@/components/Header';
export default function HomePage() {
return (
<main className="relative bg-page">
<Header/>
<CartDrawer/>
<HeroSection/>
<ShowcaseSection/>
<FeaturesSection/>
<AboutSection/>
<LocationsSection/>
<Footer/>
</main>
);
}
+21
View File
@@ -0,0 +1,21 @@
import type {Metadata} from 'next';
import {notFound} from 'next/navigation';
import {content} from '@/data/content';
import ProductDetails from '@/components/ProductDetails';
type Props = {params: {id: string}};
export function generateStaticParams() {
return content.fa.machines.map(machine => ({id: machine.id}));
}
export function generateMetadata({params}: Props): Metadata {
const machine = content.fa.machines.find(item => item.id === params.id);
if (!machine) return {};
return {title: `${machine.name} | روبات مارکت`, description: machine.description};
}
export default function ProductPage({params}: Props) {
if (!content.fa.machines.some(machine => machine.id === params.id)) notFound();
return <ProductDetails id={params.id}/>;
}
+2 -3
View File
@@ -11,6 +11,7 @@ import enUS from 'antd/locale/en_US';
import {store} from '@/store/store';
import {ThemeProvider, useTheme} from './context/ThemeContext';
import {LanguageProvider, useLanguage} from './context/LanguageContext';
import CartPersistence from '@/components/CartPersistence';
function AntdBridge({children}: {children: ReactNode}) {
const {theme} = useTheme();
@@ -37,9 +38,6 @@ function AntdBridge({children}: {children: ReactNode}) {
headerBg: theme === 'dark' ? '#0c2b24' : '#ffffff',
titleColor: theme === 'dark' ? '#e6f7f4' : '#04231f',
},
Drawer: {
colorBgElevated: theme === 'dark' ? '#0c2b24' : '#ffffff',
},
},
};
@@ -53,6 +51,7 @@ function AntdBridge({children}: {children: ReactNode}) {
export default function Providers({children}: {children: ReactNode}) {
return (
<ReduxProvider store={store}>
<CartPersistence/>
<ThemeProvider>
<LanguageProvider>
<AntdBridge>{children}</AntdBridge>