| import { Box, Button, ButtonGroup, Paper, Typography } from '@mui/material'; | |||||
| import { Box, Button, ButtonGroup, Card, Typography } from '@mui/material'; | |||||
| import Image from 'next/image'; | import Image from 'next/image'; | ||||
| import PropType from 'prop-types'; | import PropType from 'prop-types'; | ||||
| import { useState } from 'react'; | import { useState } from 'react'; | ||||
| // }, [quantity]); | // }, [quantity]); | ||||
| return ( | return ( | ||||
| <Paper | |||||
| <Card | |||||
| sx={{ | sx={{ | ||||
| p: 1, | |||||
| width: { lg: '88%', xs: '73%', md: '80%' }, | |||||
| mb: 2, | |||||
| ml: 12, | |||||
| ml: 10, | |||||
| mr: { sm: 10, lg: 1 }, | |||||
| backgroundColor: '#f2f2f2', | backgroundColor: '#f2f2f2', | ||||
| display: 'flex', | |||||
| justifyContent: { xs: 'center', md: 'none' }, | |||||
| p: 2, | |||||
| mb: 2, | |||||
| }} | }} | ||||
| elevation={3} | |||||
| > | > | ||||
| <Box sx={{ width: '30%', display: { xs: 'none', md: 'block' } }}> | |||||
| <Image | |||||
| src="/images/coffee-mug.svg" | |||||
| alt="profile" | |||||
| width={500} | |||||
| height={300} | |||||
| /> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | |||||
| ml: -4, | |||||
| mr: 2, | |||||
| display: 'flex', | |||||
| alignItems: 'center', | |||||
| width: '30%', | |||||
| }} | |||||
| > | |||||
| <Typography | |||||
| sx={{ | |||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| height: 25, | |||||
| fontWeight: 600, | |||||
| ml: { xs: -1, sm: 0 }, | |||||
| fontSize: { xs: 16, sm: 20 }, | |||||
| }} | |||||
| > | |||||
| {product?.name} | |||||
| </Typography> | |||||
| </Box> | |||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| display: 'flex', | display: 'flex', | ||||
| flexDirection: 'column', | |||||
| width: '20%', | |||||
| justifyContent: 'center', | |||||
| alignItems: 'center', | |||||
| ml: { xs: 2, sm: 0 }, | |||||
| flexDirection: { xs: 'column', md: 'row' }, | |||||
| justifyContent: { xs: 'center' }, | |||||
| }} | }} | ||||
| > | > | ||||
| <Typography | |||||
| <Box sx={{ display: { xs: 'none', md: 'flex', width: '20%' } }}> | |||||
| <Image | |||||
| src="/images/coffee-mug.svg" | |||||
| alt="profile" | |||||
| width={500} | |||||
| height={300} | |||||
| /> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | sx={{ | ||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| height: 16, | |||||
| fontSize: 14, | |||||
| display: 'flex', | |||||
| alignItems: 'center', | |||||
| justifyItems: 'center', | |||||
| width: { md: '40%' }, | |||||
| }} | }} | ||||
| > | > | ||||
| Quantity | |||||
| </Typography> | |||||
| <ButtonGroup | |||||
| size="small" | |||||
| aria-label="small outlined button group" | |||||
| <Typography | |||||
| align="center" | |||||
| sx={{ | |||||
| mb: { xs: 10, sm: 5, md: 0 }, | |||||
| mr: { md: 5 }, | |||||
| width: '100%', | |||||
| fontWeight: 600, | |||||
| fontSize: { xs: 16, sm: 20 }, | |||||
| }} | |||||
| > | |||||
| {product?.name} | |||||
| </Typography> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | sx={{ | ||||
| height: 35, | |||||
| width: 125, | |||||
| mt: 1, | |||||
| backgroundColor: 'primary.main', | |||||
| color: 'white', | |||||
| border: 0, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| justifyContent: 'center', | |||||
| alignItems: 'center', | |||||
| mb: { xs: 10, sm: 5, md: 0 }, | |||||
| mr: { md: 5 }, | |||||
| }} | }} | ||||
| > | > | ||||
| <Button | |||||
| <Typography | |||||
| sx={{ | sx={{ | ||||
| color: 'white', | |||||
| fontSize: 17, | |||||
| width: 25, | |||||
| }} | |||||
| onClick={() => { | |||||
| if (quantity > 0) { | |||||
| updateQuantity(product?.customID, quantity - 1); | |||||
| setQuantity((prevState) => prevState - 1); | |||||
| } | |||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| height: 16, | |||||
| fontSize: 14, | |||||
| }} | }} | ||||
| > | > | ||||
| - | |||||
| </Button> | |||||
| <Button | |||||
| Quantity | |||||
| </Typography> | |||||
| <ButtonGroup | |||||
| size="small" | |||||
| aria-label="small outlined button group" | |||||
| sx={{ | sx={{ | ||||
| height: 35, | |||||
| mt: 1, | |||||
| backgroundColor: 'primary.main', | |||||
| color: 'white', | color: 'white', | ||||
| fontSize: 15, | |||||
| width: 25, | |||||
| border: 0, | |||||
| }} | }} | ||||
| > | > | ||||
| {quantity} | |||||
| </Button> | |||||
| <Button | |||||
| sx={{ | |||||
| color: 'white', | |||||
| fontSize: 17, | |||||
| width: 25, | |||||
| }} | |||||
| onClick={() => { | |||||
| if (quantity > 0) { | |||||
| updateQuantity(product?.customID, quantity - 1); | |||||
| setQuantity((prevState) => prevState - 1); | |||||
| } | |||||
| }} | |||||
| > | |||||
| - | |||||
| </Button> | |||||
| <Button | |||||
| sx={{ | |||||
| color: 'white', | |||||
| fontSize: 15, | |||||
| width: 25, | |||||
| }} | |||||
| > | |||||
| {quantity} | |||||
| </Button> | |||||
| <Button | |||||
| sx={{ | |||||
| color: 'white', | |||||
| fontSize: 17, | |||||
| width: 25, | |||||
| }} | |||||
| onClick={() => { | |||||
| updateQuantity(product?.customID, quantity + 1); | |||||
| setQuantity((prevState) => prevState + 1); | |||||
| }} | |||||
| > | |||||
| + | |||||
| </Button> | |||||
| </ButtonGroup> | |||||
| <Button | <Button | ||||
| sx={{ | sx={{ | ||||
| height: 35, | |||||
| mt: 1, | |||||
| width: 125, | |||||
| fontSize: 15, | |||||
| textTransform: 'none', | |||||
| backgroundColor: '#C6453E', | |||||
| color: 'white', | color: 'white', | ||||
| fontSize: 17, | |||||
| width: 25, | |||||
| }} | |||||
| onClick={() => { | |||||
| updateQuantity(product?.customID, quantity + 1); | |||||
| setQuantity((prevState) => prevState + 1); | |||||
| }} | }} | ||||
| startIcon={ | |||||
| <Image src="/images/x.svg" alt="remove" width={15} height={15} /> | |||||
| } | |||||
| onClick={() => remove(product.customID)} | |||||
| > | > | ||||
| + | |||||
| Remove | |||||
| </Button> | </Button> | ||||
| </ButtonGroup> | |||||
| <Button | |||||
| sx={{ | |||||
| height: 35, | |||||
| mt: 1, | |||||
| width: 125, | |||||
| fontSize: 15, | |||||
| textTransform: 'none', | |||||
| backgroundColor: '#C6453E', | |||||
| color: 'white', | |||||
| }} | |||||
| startIcon={ | |||||
| <Image src="/images/x.svg" alt="remove" width={15} height={15} /> | |||||
| } | |||||
| onClick={() => remove(product.customID)} | |||||
| > | |||||
| Remove | |||||
| </Button> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | |||||
| ml: { xs: 5, sm: 3 }, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| width: '20%', | |||||
| justifyContent: 'center', | |||||
| alignItems: 'center', | |||||
| }} | |||||
| > | |||||
| <Typography | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | sx={{ | ||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| height: 25, | |||||
| fontSize: { xs: 15, md: 18 }, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| justifyContent: 'center', | |||||
| alignItems: 'center', | |||||
| }} | }} | ||||
| > | > | ||||
| Price: ${product?.price} | |||||
| </Typography> | |||||
| <Typography | |||||
| sx={{ | |||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| height: 25, | |||||
| fontSize: { xs: 15, md: 18 }, | |||||
| }} | |||||
| > | |||||
| Price: ${product?.price} | |||||
| </Typography> | |||||
| </Box> | |||||
| </Box> | </Box> | ||||
| </Paper> | |||||
| </Card> | |||||
| ); | ); | ||||
| }; | }; | ||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| width: '30%', | width: '30%', | ||||
| borderRadius: 4, | |||||
| overflow: 'hidden', | |||||
| display: { xs: 'none', lg: 'block' }, | |||||
| display: { xs: 'none', lg: 'flex' }, | |||||
| }} | }} | ||||
| > | > | ||||
| <Image | <Image | ||||
| </Box> | </Box> | ||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| ml: 3, | |||||
| ml: { xs: 0, md: 3 }, | |||||
| display: 'flex', | display: 'flex', | ||||
| flexDirection: 'column', | flexDirection: 'column', | ||||
| width: { lg: '60%', sx: '100%' }, | |||||
| }} | }} | ||||
| > | > | ||||
| <Typography | <Typography | ||||
| sx={{ | sx={{ | ||||
| width: '100%', | width: '100%', | ||||
| textAlign: 'center', | textAlign: 'center', | ||||
| height: 25, | |||||
| fontWeight: 600, | fontWeight: 600, | ||||
| fontSize: { md: 20, xs: 16 }, | fontSize: { md: 20, xs: 16 }, | ||||
| }} | }} | ||||
| > | > | ||||
| {data.name} - x{quantity} | |||||
| {data.name} | |||||
| </Typography> | </Typography> | ||||
| <Typography | <Typography | ||||
| sx={{ | sx={{ | ||||
| mt: { sm: 3, xs: 6 }, | |||||
| fontSize: 14, | |||||
| width: '100%', | |||||
| textAlign: 'center', | |||||
| fontWeight: 600, | |||||
| fontSize: { md: 20, xs: 16 }, | |||||
| }} | }} | ||||
| > | > | ||||
| {data.description} | |||||
| x{quantity} | |||||
| </Typography> | </Typography> | ||||
| <Typography | <Typography | ||||
| sx={{ | sx={{ | ||||
| mt: { lg: 3, xs: 1 }, | mt: { lg: 3, xs: 1 }, | ||||
| textAlign: 'right', | |||||
| textAlign: 'center', | |||||
| fontSize: 14, | fontSize: 14, | ||||
| }} | }} | ||||
| > | > |
| return ( | return ( | ||||
| <Typography | <Typography | ||||
| sx={{ | sx={{ | ||||
| mr: { sm: 10, lg: 1 }, | |||||
| pl: 12, | pl: 12, | ||||
| mt: 6, | mt: 6, | ||||
| height: '100%', | height: '100%', | ||||
| {mapProductsToDom()} | {mapProductsToDom()} | ||||
| </Grid> | </Grid> | ||||
| <Grid item lg={4} xs={12}> | <Grid item lg={4} xs={12}> | ||||
| <Box | |||||
| sx={{ width: { xs: '90%', lg: '80%' }, mt: 2, pl: { xs: 12, lg: 0 } }} | |||||
| > | |||||
| <Box sx={{ mr: { xs: 10 }, mt: 2, pl: { xs: 10, lg: 0 } }}> | |||||
| <OrderSummaryCard | <OrderSummaryCard | ||||
| data={{ totalPrice: totalPrice, totalQuantity: totalQuantity }} | data={{ totalPrice: totalPrice, totalQuantity: totalQuantity }} | ||||
| ></OrderSummaryCard> | ></OrderSummaryCard> |
| import NavigateNextIcon from '@mui/icons-material/NavigateNext'; | |||||
| import { Breadcrumbs, Divider, Grid, Typography } from '@mui/material'; | import { Breadcrumbs, Divider, Grid, Typography } from '@mui/material'; | ||||
| import PropType from 'prop-types'; | import PropType from 'prop-types'; | ||||
| <Grid item xs={12} sx={{ mt: 4 }}> | <Grid item xs={12} sx={{ mt: 4 }}> | ||||
| <Breadcrumbs | <Breadcrumbs | ||||
| aria-label="breadcrumb" | aria-label="breadcrumb" | ||||
| separator="›" | |||||
| separator={<NavigateNextIcon fontSize="small" />} | |||||
| sx={{ pl: 12, fontSize: 20 }} | sx={{ pl: 12, fontSize: 20 }} | ||||
| > | > | ||||
| {breadcrumbsArray.map((entry, index) => { | {breadcrumbsArray.map((entry, index) => { | ||||
| return ( | return ( | ||||
| <Typography | <Typography | ||||
| fontSize="20px" | |||||
| key={index} | key={index} | ||||
| color={index === breadcrumbsArray.length - 1 ? 'red' : 'black'} | color={index === breadcrumbsArray.length - 1 ? 'red' : 'black'} | ||||
| > | > |
| const { CircularProgress } = require('@mui/material'); | |||||
| const { CircularProgress, Box } = require('@mui/material'); | |||||
| const LoadingSpinner = () => { | const LoadingSpinner = () => { | ||||
| return <CircularProgress />; | |||||
| return ( | |||||
| <Box display="flex" justifyContent="center" sx={{ mt: 5 }}> | |||||
| <CircularProgress /> | |||||
| </Box> | |||||
| ); | |||||
| }; | }; | ||||
| export default LoadingSpinner; | export default LoadingSpinner; |
| width: '100%', | width: '100%', | ||||
| height: '100%', | height: '100%', | ||||
| border: 'none', | border: 'none', | ||||
| mb: '75px', | |||||
| mb: '15px', | |||||
| backgroundColor: '#F5ECD4', | backgroundColor: '#F5ECD4', | ||||
| }} | }} | ||||
| > | > | ||||
| flexDirection: 'column', | flexDirection: 'column', | ||||
| }} | }} | ||||
| > | > | ||||
| <Typography fontSize="24px" align="center" pt={1} pb={3}> | |||||
| <Typography | |||||
| sx={{ height: '100px' }} | |||||
| fontSize="24px" | |||||
| align="center" | |||||
| pt={1} | |||||
| pb={3} | |||||
| > | |||||
| {product.name} | {product.name} | ||||
| </Typography> | </Typography> | ||||
| <Typography align="center" fontSize="18px" m={2}> | |||||
| {product.description} | |||||
| <Typography | |||||
| sx={{ height: '200px' }} | |||||
| align="center" | |||||
| fontSize="18px" | |||||
| m={2} | |||||
| > | |||||
| {product.description.length > 250 | |||||
| ? product.description.slice(0, 250) + '...' | |||||
| : product.description} | |||||
| </Typography> | </Typography> | ||||
| <Typography fontSize="24px" align="center" pt={4}> | <Typography fontSize="24px" align="center" pt={4}> | ||||
| ${product.price} | ${product.price} | ||||
| </Typography> | </Typography> | ||||
| <Box textAlign="center" mt={1}> | <Box textAlign="center" mt={1}> | ||||
| <Button | <Button | ||||
| disableRipple | |||||
| disableFocusRipple | |||||
| disabled={inCart} | disabled={inCart} | ||||
| onClick={() => addProductToCart(1)} | onClick={() => addProductToCart(1)} | ||||
| sx={{ | sx={{ |
| import ProductCard from '../product-card/ProductCard'; | import ProductCard from '../product-card/ProductCard'; | ||||
| const ProductsGrid = ({ allProducts, hasNextPage, fetchNextPage }) => { | const ProductsGrid = ({ allProducts, hasNextPage, fetchNextPage }) => { | ||||
| // const allItems = useMemo( | |||||
| // () => allProducts?.pages?.flatMap((page) => page.product), | |||||
| // [allProducts] | |||||
| // ); | |||||
| const dataToDisplay = allProducts.pages.map((page) => | const dataToDisplay = allProducts.pages.map((page) => | ||||
| page.product.map((item) => ( | page.product.map((item) => ( | ||||
| <Grid key={item._id} item md={4} sm={6} xs={12} sx={{ mb: '100px' }}> | <Grid key={item._id} item md={4} sm={6} xs={12} sx={{ mb: '100px' }}> | ||||
| )) | )) | ||||
| ); | ); | ||||
| // const dataToDisplay = allProducts.map((item) => ( | |||||
| // <Grid key={item._id} item md={4} sm={6} xs={12} sx={{ mb: '100px' }}> | |||||
| // <ProductCard product={item} /> | |||||
| // </Grid> | |||||
| // )); | |||||
| return ( | return ( | ||||
| <Container | <Container | ||||
| sx={{ | sx={{ |
| sx={{ | sx={{ | ||||
| display: 'flex', | display: 'flex', | ||||
| flexDirection: 'column', | flexDirection: 'column', | ||||
| alignItems: { xs: 'center' }, | |||||
| alignItems: { xs: 'center', md: 'flex-start' }, | |||||
| width: { xs: '100%', md: '50%' }, | width: { xs: '100%', md: '50%' }, | ||||
| height: '100%', | height: '100%', | ||||
| }} | }} | ||||
| > | > | ||||
| <Typography | |||||
| variant="h3" | |||||
| sx={{ height: 60, mt: { xs: 5 }, color: 'white' }} | |||||
| > | |||||
| <Typography variant="h3" sx={{ mt: { xs: 5 }, color: 'white' }}> | |||||
| {data.name} | {data.name} | ||||
| </Typography> | </Typography> | ||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| width: 100, | |||||
| maxWidth: 100, | |||||
| height: 60, | |||||
| display: 'flex', | |||||
| alignItems: { xs: 'center', md: 'flex-start' }, | |||||
| justifyContent: { xs: 'center', md: 'flex-start' }, | |||||
| width: '100%', | |||||
| py: { xs: 2 }, | |||||
| }} | }} | ||||
| > | > | ||||
| <Image | <Image | ||||
| mt: 4, | mt: 4, | ||||
| flexDirection: { xs: 'column', md: 'row' }, | flexDirection: { xs: 'column', md: 'row' }, | ||||
| alignItems: { xs: 'center' }, | alignItems: { xs: 'center' }, | ||||
| justifyContent: { md: 'center' }, | |||||
| justifyContent: { md: 'flex-start' }, | |||||
| }} | }} | ||||
| > | > | ||||
| <ButtonGroup | <ButtonGroup |
| mt: 2, | mt: 2, | ||||
| ml: 12, | ml: 12, | ||||
| mb: 2, | mb: 2, | ||||
| width: { lg: '90%', xs: '80%' }, | |||||
| borderRadius: 2, | borderRadius: 2, | ||||
| p: 1, | p: 1, | ||||
| }} | }} | ||||
| alignItems: 'center', | alignItems: 'center', | ||||
| ml: 12, | ml: 12, | ||||
| mb: 2, | mb: 2, | ||||
| width: { lg: '90%', xs: '80%' }, | |||||
| borderRadius: 2, | borderRadius: 2, | ||||
| p: 1, | p: 1, | ||||
| }} | }} |
| import { useRouter } from 'next/router'; | import { useRouter } from 'next/router'; | ||||
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import Loader from '../../components/loader/Loader'; | import Loader from '../../components/loader/Loader'; | ||||
| import ProductCard from '../../components/product-card/ProductCard'; | |||||
| import TabPanel from '../../components/tab-panel/TabPanel'; | import TabPanel from '../../components/tab-panel/TabPanel'; | ||||
| import { useFetchSingleProduct } from '../../hooks/useFetchProductData'; | import { useFetchSingleProduct } from '../../hooks/useFetchProductData'; | ||||
| import { getProductData } from '../../requests/products/producDataRequest'; | import { getProductData } from '../../requests/products/producDataRequest'; | ||||
| return <Loader loading={isLoading} />; | return <Loader loading={isLoading} />; | ||||
| } | } | ||||
| // const productsToShow = (id) => { | |||||
| // const filtered = shuffle(similarProducts?.productsByCategory) | |||||
| // .filter((product) => product.customID !== id) | |||||
| // .slice(0, 3) | |||||
| // .map((item) => ( | |||||
| // <Grid | |||||
| // key={item._id} | |||||
| // item | |||||
| // lg={4} | |||||
| // md={6} | |||||
| // sm={6} | |||||
| // xs={12} | |||||
| // sx={{ mb: '100px' }} | |||||
| // > | |||||
| // <ProductCard product={item} /> | |||||
| // </Grid> | |||||
| // )); | |||||
| // return filtered; | |||||
| // }; | |||||
| return ( | return ( | ||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| {data.product.name} | {data.product.name} | ||||
| </Typography> | </Typography> | ||||
| <Grid container spacing={2}> | <Grid container spacing={2}> | ||||
| <Grid item md={6} sm={12}> | |||||
| <Grid sx={{ display: 'flex' }} item md={6} sm={12}> | |||||
| <Image | <Image | ||||
| src="/images/product-card-image.jpg" | src="/images/product-card-image.jpg" | ||||
| alt="product" | alt="product" | ||||
| fontSize: '32px', | fontSize: '32px', | ||||
| }} | }} | ||||
| > | > | ||||
| Other Product You May Like | |||||
| Similar Products You May Like | |||||
| </Typography> | </Typography> | ||||
| <Grid container spacing={2}></Grid> | |||||
| <Grid container spacing={2}> | |||||
| {data.similarProducts.map((product) => ( | |||||
| <Grid | |||||
| key={product._id} | |||||
| item | |||||
| md={4} | |||||
| sm={6} | |||||
| xs={12} | |||||
| sx={{ mb: '100px' }} | |||||
| > | |||||
| <ProductCard product={product} /> | |||||
| </Grid> | |||||
| ))} | |||||
| </Grid> | |||||
| </Container> | </Container> | ||||
| </Box> | </Box> | ||||
| ); | ); |
| setSort(sort); | setSort(sort); | ||||
| }; | }; | ||||
| if (isLoading) { | |||||
| return <LoadingSpinner />; | |||||
| } | |||||
| return ( | return ( | ||||
| <Box | <Box | ||||
| sx={{ | sx={{ | ||||
| sort={sort} | sort={sort} | ||||
| handleSortChange={handleSortChange} | handleSortChange={handleSortChange} | ||||
| /> | /> | ||||
| <ProductsGrid | |||||
| allProducts={data} | |||||
| sort={sort} | |||||
| productType={filter} | |||||
| fetchNextPage={fetchNextPage} | |||||
| hasNextPage={hasNextPage} | |||||
| /> | |||||
| {isLoading ? ( | |||||
| <LoadingSpinner /> | |||||
| ) : ( | |||||
| <ProductsGrid | |||||
| allProducts={data} | |||||
| sort={sort} | |||||
| productType={filter} | |||||
| fetchNextPage={fetchNextPage} | |||||
| hasNextPage={hasNextPage} | |||||
| /> | |||||
| )} | |||||
| </Box> | </Box> | ||||
| ); | ); | ||||
| }; | }; |