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}`)
}}
>
{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;