Просмотр исходного кода

feat module 1,2,4 : modified search bar result based on menu at navbar - search bar

master
nadia 4 дней назад
Родитель
Сommit
a334300038

+ 5
- 3
src/components/Navbar/Navbar.jsx Просмотреть файл

@@ -29,6 +29,7 @@ import { Scrollbar, A11y, Navigation } from 'swiper/modules';
29 29
 
30 30
 import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
31 31
 import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
32
+import { NAV_MENU_STRUCTURE as SHARED_NAV_MENU_STRUCTURE } from "../../config/menuCollections";
32 33
 
33 34
 function calculateTotalQuantity(cartItems) {
34 35
   return cartItems.reduce((total, item) => total + item.quantity, 0);
@@ -89,6 +90,9 @@ const getProductTypeMenuLabel = (productType = "") => {
89 90
   return normalizeTitle(productType) === "BEAUTY" ? "Essentials" : productType;
90 91
 };
91 92
 
93
+const NAV_MENU_STRUCTURE = SHARED_NAV_MENU_STRUCTURE;
94
+
95
+/*
92 96
 const NAV_MENU_STRUCTURE = [
93 97
   {
94 98
     productType: "Apparel",
@@ -97,7 +101,6 @@ const NAV_MENU_STRUCTURE = [
97 101
       {
98 102
         label: "Casual",
99 103
         children: [
100
-          // Local Shopify collection title is "DENIM ND X MARII FOR AMBER"; old/reference title: "ND X MARII FOR AMBER".
101 104
           { label: "ND X Marii for Amber", titles: ["DENIM ND X MARII FOR AMBER", "ND X MARII FOR AMBER"] },
102 105
           { label: "Somewhere Somehow Someone", titles: ["SOMEWHERE SOMEHOW SOMEONE"] },
103 106
           { label: "Flower Power", titles: ["FLOWER POWER"] },
@@ -106,9 +109,7 @@ const NAV_MENU_STRUCTURE = [
106 109
       {
107 110
         label: "Traditional",
108 111
         children: [
109
-          // label is the display name, titles are the collection names that will be matched to the product collections in shopify
110 112
           { label: "Eid's Time For Love", titles: ["EID'S TIME FOR LOVE"] },
111
-          // Local Shopify collection title is "RAYA ROMANTICS"; old/reference title: "RAYA ROMANTICS COLLECTION 2025".
112 113
           { label: "Raya Romantics", titles: ["RAYA ROMANTICS", "RAYA ROMANTICS COLLECTION 2025"] },
113 114
           { label: "Atma Sari", titles: ["ATMA SARI"] },
114 115
           { label: "Oasis abaya", titles: ["OASIS ABAYA COLLECTION", "MIRAGE COLLECTION"] },
@@ -125,6 +126,7 @@ const NAV_MENU_STRUCTURE = [
125 126
     ],
126 127
   },
127 128
 ];
129
+*/
128 130
 
129 131
 const sortCollectionsByPriority = (collection = [], productType = "") => {
130 132
   const typeKey = (productType || "").trim().toLowerCase();

+ 44
- 1
src/components/SearchProduct/SearchProduct.jsx Просмотреть файл

@@ -11,6 +11,7 @@ import {
11 11
   CardMedia,
12 12
 } from "@mui/material";
13 13
 import { useSelector } from "react-redux";
14
+import { getMenuCollectionTitlesByProductType } from "../../config/menuCollections";
14 15
 
15 16
 function doesSubstringExistInArray(array, substring) {
16 17
     
@@ -22,6 +23,47 @@ function doesSubstringExistInArray(array, substring) {
22 23
     return array.some(element => element.toLowerCase().includes(lowerCaseSubstring));
23 24
 }
24 25
 
26
+// Define allowed search collections for each product type
27
+const allowedSearchCollectionsByProductType = getMenuCollectionTitlesByProductType();
28
+
29
+/*
30
+Old standalone search allow-list. Current code uses src/config/menuCollections.js
31
+so search results automatically follow the navbar menu.
32
+
33
+const allowedSearchCollectionsByProductType = {
34
+  Apparel: [
35
+    "DENIM ND X MARII FOR AMBER",
36
+    "ND X MARII FOR AMBER",
37
+    "SOMEWHERE SOMEHOW SOMEONE",
38
+    "FLOWER POWER",
39
+    "EID'S TIME FOR LOVE",
40
+    "RAYA ROMANTICS",
41
+    "RAYA ROMANTICS COLLECTION 2025",
42
+    "ATMA SARI",
43
+    "OASIS ABAYA COLLECTION",
44
+    "MIRAGE COLLECTION",
45
+  ],
46
+  BEAUTY: [
47
+    "COSMETICS",
48
+    "HAND & BODY LOTION",
49
+  ],
50
+};
51
+*/
52
+
53
+const normalizeTitle = (value = "") => value.trim().toUpperCase();
54
+
55
+const isProductAllowedInSearch = (product) => {
56
+  const allowedCollections = allowedSearchCollectionsByProductType[product?.productType];
57
+
58
+  if (!allowedCollections) return false;
59
+
60
+  const allowedCollectionSet = new Set(allowedCollections.map(normalizeTitle));
61
+
62
+  return product?.collections?.some((collection) =>
63
+    allowedCollectionSet.has(normalizeTitle(collection?.title || ""))
64
+  );
65
+}
66
+
25 67
 const SearchProduct = ({ onClose }) => {
26 68
   const products = useSelector((state) => state.products.products.data);
27 69
   const [searchedProducts, setSearchedProducts] = useState([]);
@@ -31,7 +73,8 @@ const SearchProduct = ({ onClose }) => {
31 73
 
32 74
     if(searchQuery?.length < 2) return
33 75
 
34
-    let filteredProducts = products.filter((product) => {
76
+      // let filteredProducts = products.filter((product) => {
77
+      let filteredProducts = products.filter(isProductAllowedInSearch).filter((product) => {
35 78
 
36 79
       let title = product?.title?.toLowerCase();
37 80
       let search = searchQuery.toLowerCase();

+ 59
- 0
src/config/menuCollections.js Просмотреть файл

@@ -0,0 +1,59 @@
1
+export const NAV_MENU_STRUCTURE = [
2
+  {
3
+    productType: "Apparel",
4
+    label: "APPAREL",
5
+    groups: [
6
+      {
7
+        label: "Casual",
8
+        children: [
9
+          { label: "ND X Marii for Amber", titles: ["DENIM ND X MARII FOR AMBER", "ND X MARII FOR AMBER"] },
10
+          { label: "Somewhere Somehow Someone", titles: ["SOMEWHERE SOMEHOW SOMEONE"] },
11
+          { label: "Flower Power", titles: ["FLOWER POWER"] },
12
+        ],
13
+      },
14
+      {
15
+        label: "Traditional",
16
+        children: [
17
+          // label is the display name, titles are the collection names that will be matched to the product collections in shopify
18
+          { label: "Eid's Time For Love", titles: ["EID'S TIME FOR LOVE"] },
19
+          { label: "Raya Romantics", titles: ["RAYA ROMANTICS", "RAYA ROMANTICS COLLECTION 2025"] },
20
+          { label: "Atma Sari", titles: ["ATMA SARI"] },
21
+          { label: "Oasis abaya", titles: ["OASIS ABAYA COLLECTION", "MIRAGE COLLECTION"] },
22
+        ],
23
+      },
24
+    ],
25
+  },
26
+  {
27
+    productType: "BEAUTY",
28
+    label: "Essentials",
29
+    children: [
30
+      { label: "Cosmetics", titles: ["COSMETICS"] },
31
+      { label: "Hand & Body Lotion", titles: ["HAND & BODY LOTION"] },
32
+    ],
33
+  },
34
+];
35
+
36
+export const getMenuCollectionTitlesByProductType = () => {
37
+  return NAV_MENU_STRUCTURE.reduce((allowedCollections, menu) => {
38
+    const titles = [];
39
+
40
+    if (menu.groups) {
41
+      menu.groups.forEach((group) => {
42
+        group.children.forEach((item) => {
43
+          titles.push(...(item.titles || []));
44
+        });
45
+      });
46
+    }
47
+
48
+    if (menu.children) {
49
+      menu.children.forEach((item) => {
50
+        titles.push(...(item.titles || []));
51
+      });
52
+    }
53
+
54
+    return {
55
+      ...allowedCollections,
56
+      [menu.productType]: titles,
57
+    };
58
+  }, {});
59
+};

Загрузка…
Отмена
Сохранить