# روبات مارکت — Vending Machine Showcase پروژه Next.js (App Router) صفحه معرفی محصولات «روبات مارکت»، با انیمیشن‌های GSAP/ScrollTrigger، مدیریت سبد خرید با Redux Toolkit، حالت تیره/روشن، دو زبانه (فارسی/انگلیسی)، نقشه، فرم تیکت پشتیبانی، و ویجت چت. ## اجرای پروژه ```bash npm install npm run dev ``` سپس `http://localhost:3000` را باز کنید. ## ساختار پروژه ``` app/ layout.jsx # پوسته HTML، فونت وزیرمتن page.jsx # چیدمان کامل صفحه providers.jsx # Redux + Theme + Language + AntD ConfigProvider globals.css # توکن‌های رنگ دارک/لایت، جلوه اسپات‌لایت، تایپ‌رایتر context/ ThemeContext.jsx # حالت دارک/لایت (ذخیره در localStorage) LanguageContext.jsx # زبان فا/en (ذخیره در localStorage + جهت صفحه) store/ # Redux (سبد خرید) data/ content.js # منبع واحد محتوای دوزبانه (fa/en) — همه‌ی متن‌ها اینجاست components/ Header.jsx # هدر + سوییچ زبان/تم + دکمه ورود به پنل کاربری ThemeToggle.jsx / LanguageToggle.jsx HeroSection.jsx # هدلاین تایپ‌شونده + پس‌زمینه رنگی در حال چرخش HorizontalShowcase.jsx # اسکرول افقی پین‌شده + ویدیوی پس‌زمینه VendingCard.jsx # کارت دستگاه + جلوه اسپات‌لایت FloatingItems.jsx FeaturesSection.jsx AboutSection.jsx LocationsSection.jsx MapSection.jsx # نقشه Neshan (کلید API را خودتان اضافه می‌کنید) CatalogSection.jsx # کاتالوگ محصولات قابل سفارش IntroVideoSection.jsx # ویدیوی معرفی شرکت TicketForm.jsx # فرم تیکت پشتیبانی ChatWidget.jsx # آیکون شناور چت + مودال گفتگو CartDrawer.jsx Footer.jsx public/ images/, gifs/, video/ # دارایی‌های placeholder — در پیام قبلی توضیح داده شده ``` ## ویژگی‌های اضافه‌شده در این نسخه ### نقشه (Neshan) `components/MapSection.jsx` از **Neshan Static Map API** استفاده می‌کند (یک تصویر ساده، بدون نیاز به اسکریپت/SDK جاوااسکریپت). کلید API را اینجا وارد کنید: 1. یک فایل `.env.local` در ریشه پروژه بسازید (از روی `.env.local.example` کپی کنید) 2. مقدار `NEXT_PUBLIC_NESHAN_API_KEY` را با کلید واقعی خودتان از [platform.neshan.org](https://platform.neshan.org) پر کنید تا وقتی کلید خالی باشد، به‌جای نقشه یک پیام راهنما («برای فعال شدن نقشه، کلید API نشان را در تنظیمات پروژه قرار دهید») نمایش داده می‌شود — سایت خراب نمی‌شود. نقشه در حالت تیره/روشن هم استایل متفاوتی می‌گیرد (`standard-night` / `standard-day`). لینک «مشاهده در نشان» کنار هر آدرس به نقشه تعاملی neshan.org می‌رود و نیازی به کلید ندارد. مختصات فعلی در `data/content.js` (`mapLocations`) تقریبی هستند — با پین دقیق جایگزین کنید. ### کاتالوگ محصولات `components/CatalogSection.jsx` — گرید محصولاتی (زعفران، تنقلات، نوشیدنی، قهوه، چای و ...) که مشتریان دستگاه می‌توانند با قیمت کمتر از بازار سفارش دهند. هر آیتم قیمت بازار (خط‌خورده) و قیمت ویژه را نشان می‌دهد و دکمه «افزودن به سفارش» آن را به همان سبد خرید Redux اضافه می‌کند (در کنار دستگاه‌ها). لیست محصولات، قیمت‌ها و تصاویر در `data/content.js` (کلید `catalog`) قابل ویرایش است؛ تصاویر placeholder در `public/images/catalog/` قرار دارند. ### سکشن ویدیوی معرفی شرکت `components/IntroVideoSection.jsx` — یک پلیر ویدیوی مستقل (جدا از ویدیوی پس‌زمینه اسکرول افقی) با پوستر و دکمه پخش استاندارد مرورگر. برای جایگزینی، فایل واقعی را در `public/video/company-intro-placeholder.mp4` بگذارید (یا مسیر `introVideoSrc` را در `data/content.js` عوض کنید)؛ پوستر هم از `public/images/video-poster.svg` می‌آید. ### رنگ‌بندی متناوب سکشن‌ها هر سکشن اصلی صفحه (به‌جز هیرو و بخش اسکرول افقی که پس‌زمینه مخصوص خودشان را دارند) به‌ترتیب بین سه تن رنگی برند می‌چرخد: `bg-page` → `bg-surface` → `bg-elevated` → ... به‌همراه یک خط جداکننده ظریف بالای هر بخش. این‌ها همان توکن‌های دارک/لایت هستند، پس با تغییر تم هم هماهنگ می‌مانند. برای تغییر ترتیب یا اضافه کردن سکشن جدید، کافی‌ست یکی از این سه کلاس را روی `
` بگذارید. ### حالت دارک/لایت دکمه سوییچ در هدر (آیکون خورشید/ماه). ترجیح در `localStorage` ذخیره می‌شود و در اولین بار بر اساس تنظیمات سیستم کاربر تعیین می‌شود. رنگ‌بندی از طریق متغیرهای CSS در `app/globals.css` (`--color-bg-page`, `--color-text-primary`, ...) و کلاس‌های کمکی `bg-page` / `bg-surface` / `text-primary` / `text-secondary` / `border-subtle` مدیریت می‌شود؛ برای هر رنگ جدید فقط همین‌جا را ویرایش کنید. تم Ant Design هم به‌صورت خودکار (`darkAlgorithm` / `defaultAlgorithm`) هماهنگ می‌شود. ### دو زبانه (فارسی / انگلیسی) دکمه «EN / فا» در هدر. تمام متن‌های سایت (منو، هیرو، محصولات، درباره ما، مکان‌های نصب، فرم تیکت، چت، فوتر) از `data/content.js` خوانده می‌شوند — یک آبجکت با کلیدهای `fa` و `en`. تغییر زبان همچنین جهت صفحه (`dir`) و `lang` تگ `html` را به‌روزرسانی می‌کند. برای اضافه یا اصلاح متن، فقط `data/content.js` را ویرایش کنید؛ کامپوننت‌ها نیازی به تغییر ندارند. > نکته فنی: بخش اسکرول افقی (`HorizontalShowcase`) به‌عمد همیشه `dir="ltr"` روی خود track دارد > (چون محاسبات GSAP به آن نیاز دارد)، اما هر کارت داخلش جهت متن را بر اساس زبان فعال تنظیم می‌کند. ### فرم تیکت پشتیبانی `components/TicketForm.jsx` — فرم Ant Design با اعتبارسنجی (نام، تلفن، ایمیل اختیاری، موضوع، اولویت، پیام). ارسال فعلاً فقط یک پیام موفقیت نمایش می‌دهد؛ بلوک کامنت‌شده `// TODO: Connect to the real ticketing/support API` دقیقاً نشان می‌دهد کجا باید axios را وصل کنید. ### ویجت چت دکمه شناور گوشه صفحه (`components/ChatWidget.jsx`) یک مودال گفتگوی ساده باز می‌کند. پیام‌ها فعلاً در state محلی نگه‌داری می‌شوند و یک پاسخ خودکار نمایشی می‌دهند. بلوک `// TODO: Connect to a real chat/support backend` محل اتصال به بک‌اند واقعی (یا وب‌سوکت) را مشخص کرده. ### هیرو: تایپ‌رایتر + پس‌زمینه رنگی در حال تغییر هدلاین با افکت تایپ‌رایتر بین چند جمله (`data/content.js` → `hero.typingPhrases`) می‌چرخد. پس‌زمینه به‌صورت حلقه‌ای بین سبز برند (`#00a693`)، مشکی و سفید تغییر رنگ می‌دهد (با GSAP). یک لایه scrim تیره روی آن قرار دارد تا متن در هر سه حالت خوانا بماند. وقتی ویدیوی هیرو را آماده کردید، داخل `components/HeroSection.jsx` یک بلوک `TODO` کامنت‌شده دقیقاً نشان می‌دهد چطور به‌جای پس‌زمینه رنگی، ویدیو را جایگزین کنید (فقط از حالت کامنت خارجش کنید). ### ورود به پنل کاربری دکمه «ورود به پنل کاربری» / «Sign In» در هدر اضافه شده (در `components/Header.jsx`). چون گفتید لینک‌دهی را خودتان انجام می‌دهید، فعلاً فقط یک `onClick` خالی با کامنت TODO دارد — مسیر واقعی پنل کاربری را همان‌جا وصل کنید. ## جایگزینی دارایی‌های واقعی (تصاویر/گیف/ویدیو) همان‌طور که قبلاً توضیح داده شد، فایل‌های داخل `public/images`, `public/gifs`, `public/video` placeholder هستند. برای جایگزینی، فایل جدید را با همان نام/مسیر جایگزین کنید یا مسیر را در `data/content.js` تغییر دهید. ## اتصال درگاه پرداخت در `components/CartDrawer.jsx` داخل `handleCheckout` بلوک `// TODO: Connect to payment gateway API` با نمونه‌کد axios کامنت‌شده وجود دارد.