fashionAvenue / client / src / pages / Products.jsx
Products.jsx
Raw
import {
  Pagination,
  CircularProgress,
  Grid,
  Typography,
  IconButton,
} from '@mui/material';
import { makeStyles } from '@mui/styles';
import { useContext, useEffect, useRef, useState } from 'react';
import axios from 'axios';
import { useParams } from 'react-router-dom';
import ShoppingCartOutlinedIcon from '@mui/icons-material/ShoppingCartOutlined';
import { styled } from '@mui/system';
import AuthContext from '../context/AuthContext';

const CartButton = styled(IconButton)(({ theme }) => ({
  position: 'absolute',
  zIndex: 3,
  bottom: 35,
  right: 10,
  backgroundColor: 'white',
  '&:hover': {
    backgroundColor: theme.palette.primary.main,
    cursor: 'pointer',
    color: 'white',
  },
}));

const useStyles = makeStyles({
  root: {
    padding: '0 15%',
    fontFamily: 'Noto Sans KR',
  },
  image: {
    width: '100%',
    height: '20rem',
    objectFit: 'cover',
    padding: '20px 0',
  },
  description: {
    fontSize: '18px',
    maxWidth: '20em',
  },
  productWrapper: {
    margin: '6em 0',
  },
  productLabel: {
    fontFamily: 'BAEMIN',
  },
  cartButton: { position: 'relative', top: 0, left: 0 },
});

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

const Products = () => {
  const classes = useStyles();
  const { category } = useParams();
  const prevCategory = usePrevious(category);
  const [isLoading, setIsLoading] = useState(true);
  const [products, setProducts] = useState([]);
  const [page, setPage] = useState(1);
  const [totalPage, setTotalPage] = useState(1);
  const { addToCart } = useContext(AuthContext);

  const handleChange = (event, value) => {
    setPage(value);
  };

  useEffect(() => {
    setIsLoading(true);
    if (prevCategory !== category) {
      axios
        .get(`http://localhost:4000/count/${category}`)
        .then((res) => {
          setTotalPage(res.data);
          setPage(1);
        })
        .catch((err) => console.log(err));
    }
    axios
      .get(`http://localhost:4000/products/${category}/${page - 1}`)
      .then((res) => {
        setProducts(res.data);
        setIsLoading(false);
      })
      .catch((err) => console.log(err));
  }, [page, category, totalPage, prevCategory]);

  return (
    <div className={classes.root}>
      <div className={classes.productWrapper}>
        <Typography variant="h4" className={classes.productLabel}>
          {category}
        </Typography>
        <Grid
          container
          direction="row"
          spacing={1}
          justify="center"
          alignItems="flex-start"
        >
          {isLoading === true && <CircularProgress />}
          {isLoading === false &&
            products.length > 0 &&
            products.map((p) => {
              return (
                <Grid key={p.id} item xs={6} md={4} lg={3}>
                  <div className={classes.CartButton}>
                    <img className={classes.image} src={p.image} alt={p.name} />
                    <CartButton
                      id={p.id}
                      onClick={(e) => addToCart(e.currentTarget.id)}
                    >
                      <ShoppingCartOutlinedIcon />
                    </CartButton>
                  </div>
                  <Typography className={classes.description}>
                    {p.name}
                  </Typography>
                  <strong className={classes.price}>{'$ ' + p.price}</strong>
                </Grid>
              );
            })}
        </Grid>
      </div>
      <Pagination
        count={totalPage}
        page={page}
        shape="rounded"
        onChange={handleChange}
      />
    </div>
  );
};

export default Products;