From 31f261bf5f1b7b7a10d44c8f4264bf3d29b18e96 Mon Sep 17 00:00:00 2001 From: Hamed Date: Thu, 30 Jul 2026 10:57:49 +0400 Subject: [PATCH] update --- .env.example | 3 +- .eslintrc.json | 3 + .gitignore | 5 +- .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/modules.xml | 8 + .idea/robot-market-landing.iml | 8 + .idea/vcs.xml | 6 + .idea/workspace.xml | 53 +- README.md | 139 +- jsconfig.json | 15 +- next.config.js | 14 - next.config.mjs | 13 + package-lock.json | 6234 ++++++++++++++++- package.json | 24 +- public/icons/icon-maskable.svg | 11 + public/icons/icon.svg | 11 + public/icons/og-placeholder.svg | 12 + public/svg/floating/chip.svg | 5 + public/svg/floating/cola.svg | 4 + public/svg/floating/cookie.svg | 7 + public/svg/floating/drink.svg | 4 + public/svg/floating/juice.svg | 5 + public/svg/floating/snack.svg | 4 + public/svg/floating/water.svg | 5 + public/svg/machines/machine35/base.svg | 4 + public/svg/machines/machine35/body.svg | 4 + public/svg/machines/machine35/door.svg | 4 + public/svg/machines/machine35/panel.svg | 9 + public/svg/machines/machine35/screen.svg | 4 + public/svg/machines/machine35/shelves.svg | 1 + public/svg/machines/machine48/base.svg | 4 + public/svg/machines/machine48/body.svg | 4 + public/svg/machines/machine48/door.svg | 4 + public/svg/machines/machine48/panel.svg | 9 + public/svg/machines/machine48/screen.svg | 4 + public/svg/machines/machine48/shelves.svg | 1 + public/svg/machines/machine60/base.svg | 4 + public/svg/machines/machine60/body.svg | 4 + public/svg/machines/machine60/door.svg | 4 + public/svg/machines/machine60/panel.svg | 9 + public/svg/machines/machine60/screen.svg | 4 + public/svg/machines/machine60/shelves.svg | 1 + src/app/dashboard/page.js | 49 + src/app/globals.css | 87 +- src/app/layout.js | 93 +- src/app/loading.js | 11 + src/app/manifest.js | 22 + src/app/not-found.js | 23 + src/app/page.js | 39 +- src/app/robots.js | 10 + src/app/sitemap.js | 30 + src/components/About.js | 132 - src/components/Footer.js | 89 - src/components/Header.js | 111 - src/components/Hero.js | 216 - src/components/Icons.js | 61 - src/components/Locations.js | 64 - src/components/Products.js | 127 - src/components/ScrollRefresh.js | 35 - src/components/VendingMachineParts.js | 103 - src/components/animations/ScrollReveal.jsx | 65 + src/components/common/Container.jsx | 13 + src/components/common/GlassCard.jsx | 41 + src/components/common/MagneticButton.jsx | 129 + src/components/common/Section.jsx | 17 + src/components/hero/FloatingProducts.jsx | 113 + src/components/hero/Hero.jsx | 63 + src/components/hero/HeroBackground.jsx | 87 + src/components/hero/MachineAssembly.jsx | 141 + src/components/layout/About.jsx | 70 + src/components/layout/ContactCta.jsx | 33 + src/components/layout/Footer.jsx | 85 + src/components/layout/Navbar.jsx | 127 + src/components/products/MachineVisual.jsx | 57 + src/components/products/ProductSection.jsx | 134 + src/components/products/ProductsShowcase.jsx | 190 + .../products/SectionFloatingItems.jsx | 86 + src/components/ui/AntThemeProvider.jsx | 38 + src/constants/motion.js | 9 + src/constants/nav.js | 12 + src/constants/theme.js | 26 + src/data/content.js | 101 - src/data/floatingProducts.json | 9 + src/data/products.json | 79 + src/hooks/useIsomorphicLayoutEffect.js | 11 + src/hooks/useReducedMotion.js | 24 + src/redux/provider.jsx | 19 + src/redux/slices/authSlice.js | 45 + src/redux/slices/productsSlice.js | 44 + src/redux/slices/uiSlice.js | 44 + src/redux/store.js | 20 + src/services/auth.service.js | 31 + src/services/axios.js | 45 + src/services/dashboard.service.js | 23 + src/services/product.service.js | 30 + src/utils/api.js | 56 - src/utils/breakpoints.js | 13 + src/utils/cn.js | 9 + src/utils/formatPrice.js | 10 + src/utils/gsap.js | 20 - src/utils/gsapConfig.js | 16 + tailwind.config.js | 50 +- 102 files changed, 8782 insertions(+), 1432 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/robot-market-landing.iml create mode 100644 .idea/vcs.xml delete mode 100644 next.config.js create mode 100644 next.config.mjs create mode 100644 public/icons/icon-maskable.svg create mode 100644 public/icons/icon.svg create mode 100644 public/icons/og-placeholder.svg create mode 100644 public/svg/floating/chip.svg create mode 100644 public/svg/floating/cola.svg create mode 100644 public/svg/floating/cookie.svg create mode 100644 public/svg/floating/drink.svg create mode 100644 public/svg/floating/juice.svg create mode 100644 public/svg/floating/snack.svg create mode 100644 public/svg/floating/water.svg create mode 100644 public/svg/machines/machine35/base.svg create mode 100644 public/svg/machines/machine35/body.svg create mode 100644 public/svg/machines/machine35/door.svg create mode 100644 public/svg/machines/machine35/panel.svg create mode 100644 public/svg/machines/machine35/screen.svg create mode 100644 public/svg/machines/machine35/shelves.svg create mode 100644 public/svg/machines/machine48/base.svg create mode 100644 public/svg/machines/machine48/body.svg create mode 100644 public/svg/machines/machine48/door.svg create mode 100644 public/svg/machines/machine48/panel.svg create mode 100644 public/svg/machines/machine48/screen.svg create mode 100644 public/svg/machines/machine48/shelves.svg create mode 100644 public/svg/machines/machine60/base.svg create mode 100644 public/svg/machines/machine60/body.svg create mode 100644 public/svg/machines/machine60/door.svg create mode 100644 public/svg/machines/machine60/panel.svg create mode 100644 public/svg/machines/machine60/screen.svg create mode 100644 public/svg/machines/machine60/shelves.svg create mode 100644 src/app/dashboard/page.js create mode 100644 src/app/loading.js create mode 100644 src/app/manifest.js create mode 100644 src/app/not-found.js create mode 100644 src/app/robots.js create mode 100644 src/app/sitemap.js delete mode 100644 src/components/About.js delete mode 100644 src/components/Footer.js delete mode 100644 src/components/Header.js delete mode 100644 src/components/Hero.js delete mode 100644 src/components/Icons.js delete mode 100644 src/components/Locations.js delete mode 100644 src/components/Products.js delete mode 100644 src/components/ScrollRefresh.js delete mode 100644 src/components/VendingMachineParts.js create mode 100644 src/components/animations/ScrollReveal.jsx create mode 100644 src/components/common/Container.jsx create mode 100644 src/components/common/GlassCard.jsx create mode 100644 src/components/common/MagneticButton.jsx create mode 100644 src/components/common/Section.jsx create mode 100644 src/components/hero/FloatingProducts.jsx create mode 100644 src/components/hero/Hero.jsx create mode 100644 src/components/hero/HeroBackground.jsx create mode 100644 src/components/hero/MachineAssembly.jsx create mode 100644 src/components/layout/About.jsx create mode 100644 src/components/layout/ContactCta.jsx create mode 100644 src/components/layout/Footer.jsx create mode 100644 src/components/layout/Navbar.jsx create mode 100644 src/components/products/MachineVisual.jsx create mode 100644 src/components/products/ProductSection.jsx create mode 100644 src/components/products/ProductsShowcase.jsx create mode 100644 src/components/products/SectionFloatingItems.jsx create mode 100644 src/components/ui/AntThemeProvider.jsx create mode 100644 src/constants/motion.js create mode 100644 src/constants/nav.js create mode 100644 src/constants/theme.js delete mode 100644 src/data/content.js create mode 100644 src/data/floatingProducts.json create mode 100644 src/data/products.json create mode 100644 src/hooks/useIsomorphicLayoutEffect.js create mode 100644 src/hooks/useReducedMotion.js create mode 100644 src/redux/provider.jsx create mode 100644 src/redux/slices/authSlice.js create mode 100644 src/redux/slices/productsSlice.js create mode 100644 src/redux/slices/uiSlice.js create mode 100644 src/redux/store.js create mode 100644 src/services/auth.service.js create mode 100644 src/services/axios.js create mode 100644 src/services/dashboard.service.js create mode 100644 src/services/product.service.js delete mode 100644 src/utils/api.js create mode 100644 src/utils/breakpoints.js create mode 100644 src/utils/cn.js create mode 100644 src/utils/formatPrice.js delete mode 100644 src/utils/gsap.js create mode 100644 src/utils/gsapConfig.js diff --git a/.env.example b/.env.example index ef357eb..123f66c 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ -NEXT_PUBLIC_API_BASE_URL=https://api.robotmarket.ir/v1 +# Base URL for the future backend API +NEXT_PUBLIC_API_BASE_URL=https://api.robotmarket.example.com diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.gitignore b/.gitignore index 3f799a9..18d2aec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ node_modules .next -.env*.local -.DS_Store out -build +.env* +.DS_Store *.log diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ad9397e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/robot-market-landing.iml b/.idea/robot-market-landing.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/robot-market-landing.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index bd91bea..d7fe5dc 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,35 +1,6 @@ - - - - { - "associatedIndex": 2, - "fromUser": false -} - - - - { - "keyToString": { - "ModuleVcsDetector.initialDetectionPerformed": "true", - "RunOnceActivity.ShowReadmeOnStart": "true", - "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", - "RunOnceActivity.typescript.service.memoryLimit.init": "true", - "codeWithMe.voiceChat.enabledByDefault": "false", - "js.debugger.nextJs.config.created.client": "true", - "js.debugger.nextJs.config.created.server": "true", - "last_opened_file_path": "D:/Project/robot-market-landing/robot-market", - "nodejs_package_manager_path": "npm", - "vue.rearranger.settings.migration": "true" - } -} + {} @@ -45,26 +16,4 @@ - - - - - - - - - - 1785213528048 - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 7815471..9865636 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,138 @@ -# روبات مارکت — سایت نمایش محصولات +# روبات مارکت — Robot Market Landing -## نصب و اجرا +A cinematic, RTL, Persian-language landing page for **Robot Market**, a +smart refrigerated vending-machine brand. Built with Next.js (App Router), +Tailwind CSS, Ant Design, Redux Toolkit, Axios and GSAP + ScrollTrigger. + +The centerpiece of the page is a scroll-driven hero animation: scattered +SVG pieces fly together into a fully assembled vending machine as the user +scrolls, followed by a three-act "scroll story" introducing each of the +three product models. + +## Getting started ```bash npm install npm run dev ``` -سپس آدرس `http://localhost:3000` را در مرورگر باز کنید. +Open http://localhost:3000. -## ساختار پروژه +```bash +npm run build # production build +npm run start # serve the production build +npm run lint # eslint +``` + +## Tech stack + +| Concern | Library | +| ------------------- | -------------------------------- | +| Framework | Next.js 14 (App Router, JS only) | +| Styling | Tailwind CSS | +| Component library | Ant Design (RTL-configured) | +| State management | Redux Toolkit | +| HTTP client | Axios | +| Animation | GSAP + ScrollTrigger + @gsap/react | +| Icons | react-icons | +| Font | Vazirmatn (next/font/google) | + +## Project structure ``` src/ - app/ # layout.js و page.js (App Router) - components/ # کامپوننت‌های بخش‌های سایت - data/ # محتوای متنی و محصولات (content.js) - utils/api.js # نمونه Axios برای اتصال به API در آینده + app/ Routes (App Router): layout, page, dashboard, + robots.js, sitemap.js, manifest.js, loading, 404 + components/ + common/ Container, Section, GlassCard, MagneticButton + layout/ Navbar, Footer, About, ContactCta + hero/ Hero, HeroBackground, MachineAssembly, FloatingProducts + products/ ProductsShowcase, ProductSection, MachineVisual + animations/ ScrollReveal (shared scroll-in wrapper) + ui/ AntThemeProvider (Ant Design RTL + token bridge) + redux/ + store.js Store factory (per-request, App-Router-safe) + provider.jsx Client + slices/ auth, products, ui + services/ + axios.js Shared Axios instance + interceptors + auth.service.js // TODO: Connect Login API + product.service.js // TODO: Connect Product API + dashboard.service.js // TODO: Connect Dashboard API + hooks/ useReducedMotion, useIsomorphicLayoutEffect + utils/ cn, formatPrice, gsapConfig, breakpoints + constants/ theme tokens, nav links + data/ products.json, floatingProducts.json (mock data) +public/ + svg/machines/machine35|48|60/ Assembly pieces: base, body, door, panel, screen, shelves + svg/floating/ chip, cola, drink, cookie, snack, juice + icons/ Brand icon + OG image placeholders (SVG) ``` -## نکات +## Replacing placeholder assets -- رنگ اصلی برند در `tailwind.config.js` روی `#00a693` تنظیم شده است. -- فونت وزیرمتن به‌صورت خودکار از `next/font/google` بارگذاری می‌شود. -- برای جایگزینی عکس واقعی دستگاه به‌جای طرح SVG، فایل - `src/components/VendingMachineParts.js` را ویرایش کنید. -- برای اتصال فرم "سفارش و مشاوره" یا دکمه "افزودن به سبد" به بک‌اند واقعی، - از توابع آماده در `src/utils/api.js` استفاده کنید. +Every visual asset in `public/svg` is a deliberately simple placeholder — +swap the files in place (same filenames) and nothing else needs to change: + +- `public/svg/machines//*.svg` — the 6 pieces GSAP assembles/positions. + Keep the same `viewBox="0 0 400 700"` coordinate space so pieces still + line up when assembled, or update the piece list in `src/data/products.json`. +- `public/svg/floating/*.svg` — the floating product icons around the hero. +- `public/icons/*.svg` — brand icon and Open Graph placeholder. Replace the + OG placeholder with a real 1200×630 raster (`.png`/`.jpg`) before launch + and update the reference in `src/app/layout.js`. + +## Connecting the real API + +Nothing here talks to a real backend yet. Each service method already has +the exact call commented out — uncomment and remove the mock `Promise.resolve`: + +```js +// src/services/product.service.js +async getAll() { + // TODO: Connect Product API + return apiClient.get("/products").then((res) => res.data); +} +``` + +Set `NEXT_PUBLIC_API_BASE_URL` in `.env.local` (see `.env.example`). + +## Motion & accessibility notes + +- **Scroll-locked product story.** Each `ProductSection` reports its DOM + nodes up to `ProductsShowcase`, which builds and pins all three + machines' `ScrollTrigger` timelines together in one place (fixing a bug + where wide/desktop viewports could fail to reveal machines after the + first one — see the comment at the top of `ProductsShowcase.jsx`), then + calls `ScrollTrigger.refresh()` once every measurement has settled. + Scrolling literally cannot advance past a pinned section until its + reveal finishes — only then does the next machine begin. +- **Vivid, temperature-coded background per machine.** Each product + carries its own `bgColor` in `src/data/products.json`, and + `ProductsShowcase` cross-fades a single fixed color layer to that color + over the *exact same* scroll range the section uses to pin — so the + backdrop finishes changing exactly as the machine settles into place. + The three models deliberately alternate cool → warm → cool: a vivid icy + cyan-blue (`#12C4E0`) for the entry model, a warm coral-orange + (`#FF7A45`) for the mid-tier, and a cool emerald-teal (`#12D6A8`) for + the flagship — all bright, cheerful tones rather than muted brand + neutrals, chosen specifically for this section. +- **Floating drinks/snacks per section.** `SectionFloatingItems.jsx` + places a small set of product icons (soda, mineral water, juice, + snacks) drifting gently around each machine — which items appear is + configurable per product via `floatingItemIds` in `products.json`. +- All GSAP animations check `prefers-reduced-motion` and degrade to simple + opacity fades (or skip entirely) when it's set. +- `gsap.matchMedia()` is used in both `MachineAssembly` (hero) and + `ProductSection` to give desktop/tablet/mobile different scroll + distances/intensity. +- Focus states, semantic landmarks (`
`, `
`, `