From 9874d9cfe401920ed33113718efcd2a5cda9e0f4 Mon Sep 17 00:00:00 2001 From: Mahyar Khanbolooki Date: Mon, 14 Jul 2025 22:52:38 +0330 Subject: [PATCH] add: url state for menu list --- package-lock.json | 25 ++++++++++++++++++++++--- package.json | 1 + src/app/[name]/page.tsx | 25 ++++++++++++++----------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index bd30bdc..517d50b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "iconsax-react": "^0.0.8", "lucide-react": "^0.525.0", "next": "15.3.4", + "next-usequerystate": "^1.20.0", "react": "^19.0.0", "react-dom": "^19.0.0", "tailwind-merge": "^3.3.1", @@ -1925,7 +1926,7 @@ "version": "19.1.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1935,7 +1936,7 @@ "version": "19.1.6", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", - "devOptional": true, + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.0.0" @@ -3086,7 +3087,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -5401,6 +5402,12 @@ "node": ">= 18" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, "node_modules/mkdirp": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", @@ -5534,6 +5541,18 @@ } } }, + "node_modules/next-usequerystate": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/next-usequerystate/-/next-usequerystate-1.20.0.tgz", + "integrity": "sha512-0uXOYkOHXiTwrnBwZ3E6pT2l1HWoqgCxjcJE58TRSbhYjNnpQ9MxzgwoU7z6akQuQodWQffTh+HNLZRwoh1ujQ==", + "license": "MIT", + "dependencies": { + "mitt": "^3.0.1" + }, + "peerDependencies": { + "next": ">=13.4 <14.0.2 || ^14.0.3" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", diff --git a/package.json b/package.json index b6c3f85..f9bfc6e 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "iconsax-react": "^0.0.8", "lucide-react": "^0.525.0", "next": "15.3.4", + "next-usequerystate": "^1.20.0", "react": "^19.0.0", "react-dom": "^19.0.0", "tailwind-merge": "^3.3.1", diff --git a/src/app/[name]/page.tsx b/src/app/[name]/page.tsx index 1300925..d6aa3b6 100644 --- a/src/app/[name]/page.tsx +++ b/src/app/[name]/page.tsx @@ -18,6 +18,7 @@ import { DropdownOption } from "@/components/combobox/Combobox"; import { Switch } from "@/components/ui/switch"; import { TicketPercentIcon } from "lucide-react"; import { MedalStar } from 'iconsax-react' +import { useQueryState } from 'next-usequerystate' const categories = new Array(13).fill({ title: "خوراک", icon: "" }); @@ -141,20 +142,22 @@ const shippings: Array = [ const MenuIndex = () => { - const [search, setSearch] = useState(""); - const [selectedCategory, setSelectedCategory] = useState(0); const [filterModal, setFilterModal] = useState(false); const [sortingModal, setSortingModal] = useState(false); - const [, setSorting] = useState(0); - const [selectedContentId, setSelectedContentId] = useState('0'); - const [selectedShippingId, setSelectedShippingId] = useState('0'); + const [, setSorting] = useQueryState('sortBy', { defaultValue: '0' }); + const [search, setSearch] = useQueryState("q", { defaultValue: '' }); + const [selectedCategory, setSelectedCategory] = useQueryState('category', { defaultValue: '0' }); + const [selectedContentId, setSelectedContentId] = useQueryState('contentType', { defaultValue: '0' }); + const [selectedShippingId, setSelectedShippingId] = useQueryState('shippingType', { defaultValue: '0' }); const updateSearch = useCallback((e: React.ChangeEvent) => { setSearch(e.target.value); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const updateCategory = useCallback((id: number) => { - setSelectedCategory(id); + setSelectedCategory(String(id)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const toggleFilterModal = useCallback(() => { @@ -166,7 +169,7 @@ const MenuIndex = () => { }, []); const changeSorting = (index: number) => { - setSorting(() => index); + setSorting(() => String(index)); } const changeSelectedContent = (e: React.MouseEvent, index: number) => { @@ -181,7 +184,7 @@ const MenuIndex = () => { const lowerSearch = search.toLowerCase(); return foods.filter( (item) => - item.category === selectedCategory && + item.category === +selectedCategory && item.name.toLowerCase().includes(lowerSearch) ); }, [selectedCategory, search]); @@ -194,7 +197,7 @@ const MenuIndex = () => { {categories.map((item, index) => ( updateCategory(index)} > {
- {categories[selectedCategory]?.title} + {categories[+selectedCategory]?.title}
-
+