refactor(products): organize product showcase into feature module

This commit is contained in:
2026-09-29 09:44:00 +03:30
parent fcded6f139
commit ae6018a1f0
13 changed files with 68 additions and 45 deletions
+57 -34
View File
@@ -5,9 +5,17 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="bb7b50a5-be9c-4cd7-a05b-979f0e91b173" name="Changes" comment="Replace desktop showcase video with scroll-driven color backgrounds"> <list default="true" id="bb7b50a5-be9c-4cd7-a05b-979f0e91b173" name="Changes" comment="Replace desktop showcase video with scroll-driven color backgrounds">
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Checkout_at_9_20_26,_11_55 AM_[Changes]/shelved.patch" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/app/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/app/page.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Checkout_at_9_20_26__11_55AM__Changes_.xml" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/app/products/[id]/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/app/products/[id]/page.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/app/products/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/app/products/page.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/FloatingItems.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/HorizontalShowcase.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/MobileShowcase.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/ProductDetails.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/ProductsPage.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/ShowcaseSection.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/components/VendingCard.tsx" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/data/products.ts" beforeDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -91,43 +99,49 @@
&quot;associatedIndex&quot;: 2 &quot;associatedIndex&quot;: 2
}</component> }</component>
<component name="ProjectId" id="3HDEfy1HyzjDcELlwvnRRXxPltq" /> <component name="ProjectId" id="3HDEfy1HyzjDcELlwvnRRXxPltq" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;ASKED_MARK_IGNORED_FILES_AS_EXCLUDED&quot;: &quot;true&quot;, "ASKED_MARK_IGNORED_FILES_AS_EXCLUDED": "true",
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;, "ModuleVcsDetector.initialDetectionPerformed": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;, "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;, "RunOnceActivity.typescript.service.memoryLimit.init": "true",
&quot;codeWithMe.voiceChat.enabledByDefault&quot;: &quot;false&quot;, "codeWithMe.voiceChat.enabledByDefault": "false",
&quot;com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1&quot;: &quot;true&quot;, "com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
&quot;git-widget-placeholder&quot;: &quot;develop&quot;, "git-widget-placeholder": "develop",
&quot;javascript.nodejs.core.library.configured.version&quot;: &quot;24.20.0&quot;, "javascript.nodejs.core.library.configured.version": "24.20.0",
&quot;javascript.nodejs.core.library.typings.version&quot;: &quot;24.13.3&quot;, "javascript.nodejs.core.library.typings.version": "24.13.3",
&quot;javascript.preferred.runtime.type.id&quot;: &quot;node&quot;, "javascript.preferred.runtime.type.id": "node",
&quot;js.debugger.nextJs.config.created.client&quot;: &quot;true&quot;, "js.debugger.nextJs.config.created.client": "true",
&quot;js.debugger.nextJs.config.created.server&quot;: &quot;true&quot;, "js.debugger.nextJs.config.created.server": "true",
&quot;junie.onboarding.icon.badge.shown&quot;: &quot;true&quot;, "junie.onboarding.icon.badge.shown": "true",
&quot;kronk.content.tree.expanded.paths&quot;: &quot;&quot;, "kronk.content.tree.expanded.paths": "",
&quot;last_opened_file_path&quot;: &quot;/home/hamed/Documents/Projects/GItLabRepo/device_web&quot;, "last_opened_file_path": "/home/hamed/Documents/Projects/GItLabRepo/device_web",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.jshint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "node.js.selected.package.jshint": "",
&quot;prettierjs.PrettierConfiguration.Package&quot;: &quot;/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/prettier&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;settings.editor.selected.configurable&quot;: &quot;settings.javascript.prettier&quot;, "nodejs_package_manager_path": "npm",
&quot;to.speed.mode.migration.done&quot;: &quot;true&quot;, "prettierjs.PrettierConfiguration.Package": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/prettier",
&quot;ts.external.directory.path&quot;: &quot;/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/typescript/lib&quot;, "settings.editor.selected.configurable": "settings.javascript.prettier",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "to.speed.mode.migration.done": "true",
"ts.external.directory.path": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/typescript/lib",
"vue.rearranger.settings.migration": "true"
} }
}</component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
<recent name="D:\Project\GitHubRepo\robot-market-landing\public\images\icons" /> <recent name="D:\Project\GitHubRepo\robot-market-landing\public\images\icons" />
<recent name="D:\Project\GitHubRepo\robot-market-landing\public\images" /> <recent name="D:\Project\GitHubRepo\robot-market-landing\public\images" />
<recent name="D:\Project\GitHubRepo\robot-market-landing\app" /> <recent name="D:\Project\GitHubRepo\robot-market-landing\app" />
@@ -220,6 +234,7 @@
<workItem from="1790568898974" duration="91000" /> <workItem from="1790568898974" duration="91000" />
<workItem from="1790569032481" duration="788000" /> <workItem from="1790569032481" duration="788000" />
<workItem from="1790573950198" duration="16000" /> <workItem from="1790573950198" duration="16000" />
<workItem from="1790660862579" duration="1055000" />
</task> </task>
<task id="LOCAL-00001" summary="update"> <task id="LOCAL-00001" summary="update">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -565,7 +580,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1790492715355</updated> <updated>1790492715355</updated>
</task> </task>
<option name="localTasksCounter" value="44" /> <task id="LOCAL-00044" summary="Replace desktop showcase video with scroll-driven color backgrounds">
<option name="closed" value="true" />
<created>1790661145102</created>
<option name="number" value="00044" />
<option name="presentableId" value="LOCAL-00044" />
<option name="project" value="LOCAL" />
<updated>1790661145102</updated>
</task>
<option name="localTasksCounter" value="45" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
+1 -1
View File
@@ -1,5 +1,5 @@
import LocationsSection from '@/components/LocationsSection'; import LocationsSection from '@/components/LocationsSection';
import ShowcaseSection from '@/components/ShowcaseSection'; import {ShowcaseSection} from '@/features/products';
import FeaturesSection from '@/components/FeaturesSection'; import FeaturesSection from '@/components/FeaturesSection';
import AboutSection from '@/components/AboutSection'; import AboutSection from '@/components/AboutSection';
import HeroSection from '@/components/HeroSection'; import HeroSection from '@/components/HeroSection';
+1 -1
View File
@@ -1,7 +1,7 @@
import type {Metadata} from 'next'; import type {Metadata} from 'next';
import {notFound} from 'next/navigation'; import {notFound} from 'next/navigation';
import {content} from '@/data/content'; import {content} from '@/data/content';
import ProductDetails from '@/components/ProductDetails'; import {ProductDetails} from '@/features/products';
import ProtectedPage from '@/components/auth/ProtectedPage'; import ProtectedPage from '@/components/auth/ProtectedPage';
type Props = {params: {id: string}}; type Props = {params: {id: string}};
+1 -1
View File
@@ -1,6 +1,6 @@
import {Suspense} from 'react'; import {Suspense} from 'react';
import type {Metadata} from 'next'; import type {Metadata} from 'next';
import ProductsPage from '@/components/ProductsPage'; import {ProductsPage} from '@/features/products';
export const metadata: Metadata = {title: 'همه محصولات | روبات مارکت'}; export const metadata: Metadata = {title: 'همه محصولات | روبات مارکت'};
@@ -4,7 +4,7 @@ import {useEffect, useRef} from 'react';
import {gsap} from 'gsap'; import {gsap} from 'gsap';
import {ScrollTrigger} from 'gsap/ScrollTrigger'; import {ScrollTrigger} from 'gsap/ScrollTrigger';
import VendingCard from './VendingCard'; import VendingCard from './VendingCard';
import {featuredMachines} from '@/data/products'; import {featuredMachines} from '@/features/products/data/catalog';
import {useLanguage} from '@/app/context/LanguageContext'; import {useLanguage} from '@/app/context/LanguageContext';
gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollTrigger);
@@ -1,7 +1,7 @@
'use client'; 'use client';
import {PhoneOutlined} from '@ant-design/icons'; import {PhoneOutlined} from '@ant-design/icons';
import {featuredMachines} from '@/data/products'; import {featuredMachines} from '@/features/products/data/catalog';
import {useLanguage} from '@/app/context/LanguageContext'; import {useLanguage} from '@/app/context/LanguageContext';
import {commerceCopy} from '@/data/commerce'; import {commerceCopy} from '@/data/commerce';
@@ -5,7 +5,7 @@ import Link from 'next/link';
import {CheckCircleOutlined} from '@ant-design/icons'; import {CheckCircleOutlined} from '@ant-design/icons';
import {useLanguage} from '@/app/context/LanguageContext'; import {useLanguage} from '@/app/context/LanguageContext';
import {commerceCopy} from '@/data/commerce'; import {commerceCopy} from '@/data/commerce';
import QuantityControl from './QuantityControl'; import QuantityControl from '@/components/QuantityControl';
export default function ProductDetails({id}: {id: string}) { export default function ProductDetails({id}: {id: string}) {
const {t, locale} = useLanguage(); const {t, locale} = useLanguage();
@@ -4,8 +4,8 @@ import Link from 'next/link';
import {usePathname, useRouter, useSearchParams} from 'next/navigation'; import {usePathname, useRouter, useSearchParams} from 'next/navigation';
import {useLanguage} from '@/app/context/LanguageContext'; import {useLanguage} from '@/app/context/LanguageContext';
import {commerceCopy} from '@/data/commerce'; import {commerceCopy} from '@/data/commerce';
import {filterMachines, productCategories} from '@/data/products'; import {filterMachines, productCategories} from '@/features/products/data/catalog';
import QuantityControl from './QuantityControl'; import QuantityControl from '@/components/QuantityControl';
export default function ProductsPage() { export default function ProductsPage() {
const {t, locale} = useLanguage(); const {t, locale} = useLanguage();
@@ -3,9 +3,6 @@
import type {Machine} from '@/types/domain'; import type {Machine} from '@/types/domain';
import type {MouseEvent} from 'react'; import type {MouseEvent} from 'react';
import {useRef} from 'react'; import {useRef} from 'react';
import QuantityControl from './QuantityControl';
import ProtectedLink from './auth/ProtectedLink';
import {commerceCopy} from '@/data/commerce';
import {useLanguage} from '@/app/context/LanguageContext'; import {useLanguage} from '@/app/context/LanguageContext';
import FloatingItems from './FloatingItems'; import FloatingItems from './FloatingItems';
import {floatingSnacks} from '@/data/content'; import {floatingSnacks} from '@/data/content';
+3
View File
@@ -0,0 +1,3 @@
export {default as ProductDetails} from './components/ProductDetails';
export {default as ProductsPage} from './components/ProductsPage';
export {default as ShowcaseSection} from './components/ShowcaseSection';