import { useEffect, useState } from "react"; import { Box, Typography, Button, FormControl, Select, MenuItem, InputBase, } from "@mui/material"; import Grid from "@mui/material/Grid2"; import { styled } from "@mui/material"; //REDUX import { useSelector, useDispatch } from "react-redux"; import { fetchProducts } from "../../redux/slices/productSlice"; import { useNavigate } from "react-router-dom"; //UTIL FUNCTION function getAllTags(data) { const products = data || []; const allTags = products.flatMap((product) => product.tags); const uniqueTags = [...new Set(allTags)]; return uniqueTags; } function getAllCollection(data) { const products = data || []; const allCollection = products.flatMap((product) => product.collections); const uniqueCollection = Array.from( new Map(allCollection.map((item) => [item?.title, item])).values() ); return uniqueCollection; } const BootstrapInput = styled(InputBase)(({ theme }) => ({ "label + &": { marginTop: theme.spacing(3), }, "& .MuiInputBase-input": { position: "relative", backgroundColor: "#2E2E2E", border: "1px solid #ced4da", color: "#FFF", fontSize: 13, padding: "5px 0", paddingRight: "50px !important", paddingLeft: "10px", transition: theme.transitions.create(["border-color", "box-shadow"]), "&:focus": { borderRadius: 4, borderColor: "#80bdff", boxShadow: "0 0 0 0.2rem rgba(0,123,255,.25)", }, }, "& .MuiSvgIcon-root": { color: "#FFF !important", }, })); const ProductList = ({ size = 99999 }) => { const products = useSelector((state) => state.products.products.data); // only used as referenced const [filteredProducts, setFilteredProducts] = useState([]); // this one is the actual data to be rendered const [tagFilterOption, setTagFilterOption] = useState([]); const [collectionFilterOption, setCollectionFilterOption] = useState([]); const dispatch = useDispatch(); const navigate = useNavigate(); //filter const [tags, setTags] = useState("all"); const [collection, setCollection] = useState("all"); const [sort, setSort] = useState("new"); useEffect(() => { dispatch(fetchProducts()); }, []); useEffect(() => { console.log("Products: ", products); if (products.length > 0) { let newFilteredProducts = filterProducts(); setFilteredProducts([]); setTimeout(() => { setFilteredProducts(newFilteredProducts); }, 100); const tagList = getAllTags(newFilteredProducts); setTagFilterOption(tagList); // Filter will only exist if the user haven't click on collection if (!sessionStorage.getItem("amber-select-collection")) { const collectionList = getAllCollection(newFilteredProducts); setCollectionFilterOption(collectionList); } else { const selectedColletion = JSON.parse( sessionStorage.getItem("amber-select-collection") ); setCollection(selectedColletion?.title); } } }, [products]); useEffect(() => { let newFilteredProducts = filterProducts(); setFilteredProducts([]); setTimeout(() => { setFilteredProducts(newFilteredProducts); }, 100); }, [tags, collection, sort]); const filterProducts = () => { if (products?.length > 0) { let productType = sessionStorage.getItem("amber-select-product-type"); let newFilteredProducts = products.filter( (product) => product.productType === productType ); // Tags newFilteredProducts = newFilteredProducts.filter((product) => { if (tags == "all") { return product.productType === productType; } else { return ( product.productType === productType && product.tags.includes(tags) ); } }); // Collection newFilteredProducts = newFilteredProducts.filter((product) => { if (collection == "all") { return product.productType === productType; } else { return ( product.productType === productType && product.collections.some((data) => data?.title === collection) ); } }); if (sort === "title") { newFilteredProducts = newFilteredProducts.sort((a, b) => a.title.localeCompare(b.title) ); } else if (sort === "new") { newFilteredProducts = newFilteredProducts.sort( (a, b) => new Date(b.createdAt) - new Date(a.createdAt) ); } else if (sort === "old") { newFilteredProducts = newFilteredProducts.sort( (a, b) => new Date(a.createdAt) - new Date(b.createdAt) ); } return newFilteredProducts; } return []; }; const handleChange = (event) => { //setInput({ ...input, [event.target.name]: event.target.value }); }; const renderProduct = ( handle, img_url, title, collection_name, minPrice, minPriceCurrency, maxPrice, maxPriceCurrency, extra_desc, selected = false ) => { return ( { navigate(`/products/${handle}`) }} > {title} {selected && ( )} {collection_name} {title} {`${minPriceCurrency} ${parseFloat(minPrice).toFixed(2)}`} ); }; return ( <> {/* FILTER */} {/* Left Side: Page Title */} {`${filteredProducts.length} Item`} {/* Right Side: Option Inputs */} {tagFilterOption.length > 0 && ( Tag )} {collectionFilterOption.length > 0 && ( Collection )} Sort {/* LIST */} {filteredProducts.map((product, index) => { let { handle, title, images, collections, minVariantPrice, maxVariantPrice, productType, variants, selected, } = product; let minPrice = minVariantPrice.amount; let minPriceCurrency = minVariantPrice.currencyCode; let maxPrice = maxVariantPrice.amount; let maxPriceCurrency = maxVariantPrice.currencyCode; let img_url = images[0]?.url; let collection_name = collections[0]?.title; if (index < size) { return renderProduct( handle, img_url, title, collection_name, minPrice, minPriceCurrency, maxPrice, maxPriceCurrency, "", selected ); } })} ); }; export default ProductList;