From 051c12725bea7c503e77f1da15875d643aa6a38c Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 22 Dec 2025 12:54:55 +0330 Subject: [PATCH] filter --- .../(Main)/components/MenuFilterDrawer.tsx | 106 +++++++++++------- src/app/[name]/(Main)/page.tsx | 33 +++++- src/locales/fa/menu.json | 2 + 3 files changed, 94 insertions(+), 47 deletions(-) diff --git a/src/app/[name]/(Main)/components/MenuFilterDrawer.tsx b/src/app/[name]/(Main)/components/MenuFilterDrawer.tsx index 782cb62..292d792 100644 --- a/src/app/[name]/(Main)/components/MenuFilterDrawer.tsx +++ b/src/app/[name]/(Main)/components/MenuFilterDrawer.tsx @@ -1,11 +1,10 @@ 'use client'; -import React from "react"; +import React, { useState, useEffect, useMemo } from "react"; import Button from "@/components/button/PrimaryButton"; import AnimatedBottomSheet from "@/components/bottomsheet/AnimatedBottomSheet"; import ComboBox, { ComboboxOption } from "@/components/combobox/Combobox"; import { Switch } from "@/components/ui/switch"; -import { MedalStar } from "iconsax-react"; import { TicketPercentIcon } from "lucide-react"; type MenuFilterDrawerProps = { @@ -15,6 +14,7 @@ type MenuFilterDrawerProps = { selectedDeliveryId: string; onIngredientsChange: (value: string) => void; onDeliveryChange: (value: string) => void; + onApply: () => void; tMenu: (key: string) => string; }; @@ -25,35 +25,43 @@ const MenuFilterDrawer = ({ selectedDeliveryId, onIngredientsChange, onDeliveryChange, + onApply, tMenu, }: MenuFilterDrawerProps) => { - const contents: Array = [ - { - id: "0", - title: tMenu("MenuFilterDrawer.SelectContent.Options.Normal"), - label: "", - }, - { - id: "1", - title: tMenu("MenuFilterDrawer.SelectContent.Options.Vegan"), - label: "", - }, - ]; + const [tempIngredients, setTempIngredients] = useState(selectedIngredients); + const [tempDeliveryId, setTempDeliveryId] = useState(selectedDeliveryId); - const shippings: Array = [ - { - id: "0", - title: tMenu("MenuFilterDrawer.SelectDelivery.Options.Courier"), - label: "", - }, - ]; + useEffect(() => { + if (visible) { + setTempIngredients(selectedIngredients); + setTempDeliveryId(selectedDeliveryId); + } + }, [visible, selectedIngredients, selectedDeliveryId]); + + const serviceOptions: Array = useMemo(() => { + return [ + { + id: "0", + title: tMenu("MenuFilterDrawer.SelectDelivery.Options.All") || "همه", + label: "", + }, + { + id: "pickup", + title: "بیرون بر", + label: "", + }, + { + id: "inPlace", + title: "سرو در رستوران", + label: "", + }, + ]; + }, [tMenu]); const handleIngredientsChange = ( - e: React.MouseEvent, - index: number + e: React.ChangeEvent ) => { - e.stopPropagation(); - onIngredientsChange(contents[index]?.id ?? contents[0].id); + setTempIngredients(e.target.value); }; const handleDeliveryChange = ( @@ -61,7 +69,20 @@ const MenuFilterDrawer = ({ index: number ) => { e.stopPropagation(); - onDeliveryChange(shippings[index]?.id ?? shippings[0].id); + setTempDeliveryId(serviceOptions[index]?.id ?? serviceOptions[0].id); + }; + + const handleApply = () => { + onIngredientsChange(tempIngredients); + onDeliveryChange(tempDeliveryId); + onApply(); + onClose(); + }; + + const handleCancel = () => { + setTempIngredients(selectedIngredients); + setTempDeliveryId(selectedDeliveryId); + onClose(); }; return ( @@ -72,26 +93,25 @@ const MenuFilterDrawer = ({ onClick={onClose} >
- +
+ + +
-
- - - {tMenu("MenuFilterDrawer.PlusPoint")} - - -
@@ -103,10 +123,10 @@ const MenuFilterDrawer = ({
- +
-
diff --git a/src/app/[name]/(Main)/page.tsx b/src/app/[name]/(Main)/page.tsx index 0168696..233d43b 100644 --- a/src/app/[name]/(Main)/page.tsx +++ b/src/app/[name]/(Main)/page.tsx @@ -31,11 +31,23 @@ const MenuIndex = () => { const [sorting, setSorting] = useQueryState('sortBy', { defaultValue: '0' }); const [search, setSearch] = useQueryState("q", { defaultValue: '' }); const [selectedCategory, setSelectedCategory] = useQueryState('category', { defaultValue: '0' }); - const [selectedIngredients, setSelectedIngredients] = useQueryState('ingredients', { defaultValue: '0' }); + const [selectedIngredients, setSelectedIngredients] = useQueryState('ingredients', { defaultValue: '' }); const [selectedDeliveryId, setSelectedDeliveryId] = useQueryState('delivery', { defaultValue: '0' }); const smallCategoriesRef: React.RefObject = useRef(null); const wrapperRef: React.RefObject = useRef(null); const [smallCategoriesVisible, setSmallCategoriesVisibility] = useState(false); + const [isInitialMount, setIsInitialMount] = useState(true); + + useEffect(() => { + if (isInitialMount) { + setSearch(null); + setSelectedCategory(null); + setSelectedIngredients(null); + setSelectedDeliveryId(null); + setSorting(null); + setIsInitialMount(false); + } + }, [isInitialMount, setSearch, setSelectedCategory, setSelectedIngredients, setSelectedDeliveryId, setSorting]); const onScroll = useCallback(() => { if (!wrapperRef?.current?.parentElement?.parentElement?.scrollTop || !smallCategoriesRef.current?.offsetTop) return; @@ -80,7 +92,7 @@ const MenuIndex = () => { }; const changeSelectedIngredients = useCallback((value: string) => { - setSelectedIngredients(() => value); + setSelectedIngredients(value); }, [setSelectedIngredients]); const changeSelectedDelivery = useCallback((value: string) => { @@ -90,6 +102,7 @@ const MenuIndex = () => { const filteredReceiptItems = useMemo(() => { if (!foods.length) return []; const lowerSearch = search.toLowerCase(); + const lowerIngredients = selectedIngredients ? selectedIngredients.toLowerCase() : ""; const selectedCatId = selectedCategory === "0" ? null : categories[+selectedCategory - 1]?.id; @@ -99,7 +112,18 @@ const MenuIndex = () => { const itemName = item.name || item.title || item.foodName || ""; const matchesSearch = !search || itemName.toLowerCase().includes(lowerSearch); - return matchesCategory && matchesSearch; + + const matchesIngredients = !selectedIngredients || + (item.content && Array.isArray(item.content) && + item.content.some((content: string) => + content.toLowerCase().includes(lowerIngredients) + )); + + const matchesDelivery = selectedDeliveryId === "0" || + (selectedDeliveryId === "pickup" && item.pickupServe) || + (selectedDeliveryId === "inPlace" && item.inPlaceServe); + + return matchesCategory && matchesSearch && matchesIngredients && matchesDelivery; }); const sortingKey = sortings[Number(sorting)] || sortings[0]; @@ -118,7 +142,7 @@ const MenuIndex = () => { return 0; } }); - }, [selectedCategory, search, foods, categories, sorting]); + }, [selectedCategory, search, selectedIngredients, selectedDeliveryId, foods, categories, sorting]); return (
@@ -188,6 +212,7 @@ const MenuIndex = () => { selectedDeliveryId={selectedDeliveryId} onIngredientsChange={changeSelectedIngredients} onDeliveryChange={changeSelectedDelivery} + onApply={() => { }} tMenu={tMenu} /> diff --git a/src/locales/fa/menu.json b/src/locales/fa/menu.json index 016237e..13c0159 100644 --- a/src/locales/fa/menu.json +++ b/src/locales/fa/menu.json @@ -6,6 +6,7 @@ "SelectContent": { "Label": "محتویات", "SearchLabel": "جستجو ...", + "Placeholder": "محتویات را وارد کنید...", "Options": { "Normal": "معمولی", "Vegan": "گیاهی" @@ -15,6 +16,7 @@ "Label": "روش ارسال", "SearchLabel": "جستجو ...", "Options": { + "All": "همه", "Courier": "ارسال با پیک" } },