123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- import {useEffect, useState} from "react";
- import {connect} from "react-redux";
- import {Box, Button, CircularProgress, Container, Divider, Grid, Paper, Typography, useMediaQuery} from "@mui/material";
- import {actionGoodFindOne} from "../actions/ActionGoodFind";
- import Switch from "react-router-dom/es/Switch";
- import Route from "react-router-dom/es/Route";
- import Page404 from "./404Page";
- import Breadcrumb from "../components/Breadcrumbs";
- import {SetCount} from "../components/SetCount";
- import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
- import Link from "react-router-dom/es/Link";
- import {actionCardChange} from "../reducers/CartReducer";
- import {actionWishListAdd, actionWishListRemove} from "../reducers/WishListReducer";
- import FavoriteIcon from "@mui/icons-material/Favorite";
- import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
- import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
- import Carousel from 'react-material-ui-carousel'
- import {backURL} from "../actions/PathDB";
- import imgNotFound from "../img/catalog/imgNotFound.png";
- export const timeCalc = (createdAt) => {
- let formattedTime;
- let date = new Date(+createdAt);
- let year = date.getFullYear();
- let month = "0" + (date.getMonth()+1);
- let day = "0" + date.getDate();
- let hours = "0" + date.getHours();
- let minutes = "0" + date.getMinutes();
- let seconds = "0" + date.getSeconds();
- formattedTime = day.substr(-2) + '.' + month.substr(-2) + '.' + year +
- ' ' + hours.substr(-2) + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
- return formattedTime;
- }
- const ImageItem = ({images}) => {
- return (
- <img src={images && images.url ? backURL + '/' + images.url : imgNotFound} alt={images?.originalFileName ? images.originalFileName.split('.')[0] : 'image'}/>
- )
- }
- const CarouselItem = ({images}) => {
- return (
- <Carousel
- navButtonsProps={{
- style: {
- backgroundColor: 'transparent',
- color: '#000',
- borderRadius: 0
- }
- }}
- NextIcon={<ArrowForwardIosIcon/>}
- PrevIcon={<ArrowBackIosNewIcon/>}
- fullHeightHover={true}
- >
- {
- images.map((item, index) => <Box key={index} sx={{width: '100%', display: 'flex', justifyContent: 'center', height: '340px'}}><ImageItem key={item._id} images={item} /></Box>)
- }
- </Carousel>
- )
- }
- const ProductTitle = ({title}) => {
- return (
- <Typography
- variant='h4'
- fontFamily='sarif'
- letterSpacing='4px'
- >
- {title || 'PRODUCT TITLE'}
- </Typography>
- )
- }
- const ProductPrice = ({price}) => {
- return (
- <Typography
- variant='h5'
- margin='30px 0'
- >
- ${price ? parseFloat(price).toFixed(2) : 0 }
- </Typography>
- )
- }
- const ProductDescription = ({description}) => {
- return (
- <Typography
- fontSize='17px'
- letterSpacing='1px'
- lineHeight='1.7em'
- color='#616161'
- fontWeight='300'
- >
- {description || 'PRODUCT DESCRIPTION'}
- </Typography>
- )
- }
- const ProductTags = ({title, subtitle}) => {
- return (
- <Typography
- variant='body2'
- color='#616161'
- fontWeight='300'
- marginBottom='10px'
- >
- {title}: {Array.isArray(subtitle) ? subtitle.map((item, index) => <span key={index}>{item}{subtitle.length-1 !== index && ", " } </span>) : subtitle}
- </Typography>
- )
- }
- const AddToCart = ({cart, good, addToCart}) => {
- let [count, setCount] = useState(cart[good?._id]?.count || 1)
- useEffect(() => {
- setCount(cart[good?._id]?.count || 1)
- },[cart])
- console.log(count)
- return (
- <Box width='100%' backgroundColor='#fff' padding='30px'>
- <Grid container justifyContent='space-between'>
- <Grid xs={5} item>
- <SetCount defaultValue={count} onCount={value => setCount(value)}/>
- </Grid>
- <Grid xs={5} item>
- <Button
- sx={{height: '55px', width: '100%', borderRadius: '0', color: '#000', borderColor: '#000', fontSize: '20px', fontWeight: '300'}}
- variant="outlined"
- color={"inherit"}
- onClick={() => addToCart(good, count)}
- >
- {good._id in cart ? 'CHANGE CART' : 'ADD TO CART'}
- </Button>
- </Grid>
- </Grid>
- </Box>
- )
- }
- const CAddToCart = connect(state=>({cart: state.cart}), {addToCart: actionCardChange})(AddToCart)
- const AddToWishList = ({good={}, wishlist ,onAddToWishList, onWishListRemove}) => {
- const flag = good?._id in wishlist
- return (
- <Button size="small"
- color="inherit"
- sx={{paddingLeft: '0', margin: '30px 0'}}
- onClick={() => {flag ? onWishListRemove(good) : onAddToWishList(good)}}
- >
- <Typography
- color='#000'
- display='flex'
- alignItems='center'
- fontSize='13px'
- fontWeight='600'
- letterSpacing='2px'
- >
- {flag ?
- <><FavoriteIcon sx={{marginRight: '10px'}}/> REMOVE FROM WISHLIST</>:
- <><FavoriteBorderIcon sx={{marginRight: '10px'}}/> ADD TO WISHLIST</>
- }
- </Typography>
- </Button>
- )
- }
- const CAddToWishList = connect(state => ({wishlist: state.wishlist}), {onAddToWishList: actionWishListAdd, onWishListRemove: actionWishListRemove})(AddToWishList)
- const Goods = ({good}) => {
- const matches = useMediaQuery('(max-width:768px)');
- return (
- good && Object.values(good).length > 0 ?
- <Grid container justifyContent='space-around' padding={matches ? "20px 0" : "50px 0"}>
- <Grid xs={12} md={6} item padding='5px 70px 5px 10px'>
- {Array.isArray(good?.images) && good?.images.length > 1 ? <CarouselItem images={good?.images}/> :
- <Box sx={{width: '100%', display: 'flex', justifyContent: 'center', height: '340px'}}>
- <ImageItem images={Array.isArray(good?.images) && good?.images[0]}/>
- </Box>}
- <Divider sx={{margin: '20px 0'}}/>
- <ProductDescription description={good?.description}/>
- </Grid>
- <Grid xs={12} md={6} item padding='5px 110px 5px 10px'>
- <ProductTitle title={good?.name}/>
- <ProductPrice price={good?.price}/>
- <CAddToCart good={good}/>
- <CAddToWishList good={good}/>
- <Box>
- {good?._id && <ProductTags key={'SKU'} title={'SKU'} subtitle={good?._id}/>}
- {Array.isArray(good?.categories) &&
- <ProductTags key={'CATEGORY'} title={'CATEGORY'} subtitle={good?.categories.map(item => {
- return <Link key={item?._id} style={{color: "#000", textDecoration: 'none'}}
- to={`/catalog/category/${item?._id}`}>{item?.name}</Link>
- })}/>
- }
- {good?.createdAt && <ProductTags key={'TIMEOFCREATION'} title={'TIME OF CREATION'}
- subtitle={timeCalc(good?.createdAt)}/>}
- </Box>
- </Grid>
- </Grid>:
- <Box sx={{height: '100%', width: '100%', display: 'flex', justifyContent:'center', alignItems:'center'}}><CircularProgress color="inherit"/></Box>
- )
- }
- const CGoods = connect(state => ({good: state.promise['goodFindOne']?.payload}))(Goods)
- const BlockProduct = ({match:{params:{_id}}, getData}) => {
- useEffect(() => {
- getData(_id)
- },[_id, getData])
- return(
- <>
- <main style={{backgroundColor: "#f3f3f3", minHeight:'300px'}}>
- <Breadcrumb links={['good']}/>
- <Container maxWidth="lg">
- <CGoods key={_id} />
- </Container>
- </main>
- </>
- )
- }
- const CBlockProduct = connect(null, {getData: actionGoodFindOne})(BlockProduct)
- const ProductPage = () => {
- return (
- <Switch>
- <Route path="/good/:_id" component={CBlockProduct} />
- <Route path="*" component={Page404} />
- </Switch>
- )
- }
- export default ProductPage
- //TODO MOBILE VERSION
|