| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- import { useState, useEffect } from 'react';
- import { Box, Typography, Button } from '@mui/material';
- import { useSelector } from 'react-redux';
- import Grid from '@mui/material/Grid2';
- import { useNavigate } from "react-router-dom";
- import defaultImage from "../../assets/images/default.png"
- import { getMenuCollectionTitlesByProductType } from '../../config/menuCollections';
-
- const normalizeTitle = (title = "") => title.trim().toUpperCase();
-
- const allowedSuggestionCollections = getMenuCollectionTitlesByProductType();
-
- // Function to check if a product is allowed in the suggestion based on its collections
- const isProductAllowedInSuggestion = (product) => {
- const allowedCollections = allowedSuggestionCollections[product?.productType] || [];
- const normalizedAllowedCollections = allowedCollections.map(normalizeTitle);
-
- return product?.collections?.some((collection) =>
- normalizedAllowedCollections.includes(normalizeTitle(collection?.title))
- );
- };
-
- const ProductSuggestion = () => {
-
- const [suggestProducts, setSuggestProducts] = useState([]);
- const products = useSelector((state) => state.products.products.data);
-
- const navigate = useNavigate();
-
- useEffect(() => {
- if (products.length > 0) {
- const getRandomProducts = (arr, num) => {
- const shuffled = [...arr].sort(() => 0.5 - Math.random());
- return shuffled.slice(0, num);
- };
-
- const visibleProducts = products.filter(isProductAllowedInSuggestion);
- // const randomProducts = getRandomProducts(products, 4);
- const randomProducts = getRandomProducts(visibleProducts, 4); // Select 4 random visible products
- setSuggestProducts(randomProducts);
- }
- }, [products]);
-
- const renderProduct = (
- handle,
- img_url,
- title,
- collection_name,
- minPrice,
- minPriceCurrency,
- maxPrice,
- maxPriceCurrency,
- minDiscountPrice,
- minDiscountPriceCurrency,
- maxDiscountPrice,
- maxDiscountPriceCurrency,
- extra_desc,
- selected = false
- ) => {
- return (
- <Grid
- className="animate__animated animate__fadeIn"
- item
- size={{ xs: 6, sm: 6, md: 3 }}
- >
- <a href={`/products/${handle}`} style={{ textDecoration: "none", color: "#000" }}>
- <Box
- sx={{
- overflow: "hidden",
- position: "relative",
- cursor: "pointer",
- }}
- onClick={() => {
- navigate(`/products/${handle}`)
- }}
- >
- <img
- src={img_url}
- alt={title}
- style={{
- width: "100%",
- aspectRatio: "3 / 4",
- objectFit: "cover",
- objectPosition: "top center",
- }}
- />
-
- {selected && (
- <Button
- sx={{
- position: "absolute",
- top: {
- xs: 0,
- sm: 0,
- md: 10,
- lg: 20,
- },
- left: {
- xs: 0,
- sm: 0,
- md: 10,
- lg: 20,
- },
- boxShadow: 0,
- fontSize: 10,
- }}
- variant="contained"
- >
- NEW
- </Button>
- )}
-
- <Box sx={{ pb: 3, pt: 1, width: "90%" }}>
- <Typography
- variant="body2"
- sx={{
- fontWeight: "100",
- fontSize: {
- xs: "0.65rem",
- sm: "0.65rem",
- md: "0.75rem",
- },
- }}
- >
- {collection_name}
- </Typography>
- <Typography
- variant="body2"
- sx={{
- fontWeight: "400",
- fontSize: {
- xs: "0.73rem",
- sm: "0.73rem",
- md: "0.875rem",
- },
- }}
- >
- {title}
- </Typography>
- <Typography
- variant="body2"
- sx={{
- fontWeight: "100",
- fontSize: {
- xs: "0.73rem",
- sm: "0.73rem",
- md: "0.875rem",
- },
- textDecoration: (minDiscountPrice > 0) ? "line-through" : "none"
- }}
- >
- {`${minPriceCurrency} ${parseFloat(minPrice).toFixed(2)}`}
- </Typography>
-
- {(minDiscountPrice > 0) && <Typography
- variant="body2"
- sx={{
- fontWeight: "100",
- fontSize: {
- xs: "0.73rem",
- sm: "0.73rem",
- md: "0.875rem",
- },
- }}
- >
- {`${minDiscountPriceCurrency} ${parseFloat(minDiscountPrice).toFixed(2)}`}
- </Typography>}
- </Box>
- </Box>
- </a>
- </Grid>
- );
- };
-
-
- return (
- <Box sx={{ mb: 5 }}>
- <Grid container spacing={1} columns={12}>
- {suggestProducts.map((product, index) => {
-
- let {
- handle,
- title,
- images,
- collections,
- minVariantPrice,
- maxVariantPrice,
- compareAtPriceRangeMinVariantPrice,
- compareAtPriceRangeMaxVariantPrice,
- // productType and variants are not needed here because filtering already happens before rendering.
- // productType,
- // variants,
- selected,
- } = product;
-
- let minPrice = minVariantPrice.amount;
- let minPriceCurrency = minVariantPrice.currencyCode;
- let maxPrice = maxVariantPrice.amount;
- let maxPriceCurrency = maxVariantPrice.currencyCode;
- // SHOULD BE THE DISCOUNTED PRICE
- let minDiscountPrice = compareAtPriceRangeMinVariantPrice.amount;
- let minDiscountPriceCurrency = compareAtPriceRangeMinVariantPrice.currencyCode;
- let maxDiscountPrice = compareAtPriceRangeMaxVariantPrice.amount;
- let maxDiscountPriceCurrency = compareAtPriceRangeMaxVariantPrice.currencyCode;
-
- let img_url = images[0]?.url || defaultImage
- let collection_name = collections[0]?.title;
-
- return renderProduct(
- handle,
- img_url,
- title,
- collection_name,
- minPrice,
- minPriceCurrency,
- maxPrice,
- maxPriceCurrency,
- minDiscountPrice,
- minDiscountPriceCurrency,
- maxDiscountPrice,
- maxDiscountPriceCurrency,
- "",
- selected
- );
- })}
- </Grid>
- </Box>
- );
- };
-
- export default ProductSuggestion;
|