| import { Button } from '@mui/material'; | |||||
| import CircularProgress from '@mui/material/CircularProgress'; | |||||
| import Image from 'next/image'; | |||||
| const LoadMore = ({ fetchNextPage, isFetchingNextPage, hasNextPage }) => { | |||||
| return ( | |||||
| <Button | |||||
| onClick={fetchNextPage} | |||||
| startIcon={ | |||||
| !isFetchingNextPage && ( | |||||
| <Image | |||||
| src="/images/arrow.svg" | |||||
| alt="arrow down" | |||||
| width={29} | |||||
| height={29} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| sx={{ | |||||
| backgroundColor: 'primary.main', | |||||
| height: 50, | |||||
| width: 150, | |||||
| color: 'white', | |||||
| ':hover': { | |||||
| bgcolor: 'primary.main', | |||||
| color: 'white', | |||||
| }, | |||||
| }} | |||||
| > | |||||
| {isFetchingNextPage && ( | |||||
| <CircularProgress | |||||
| style={{ | |||||
| color: '#fff', | |||||
| width: '29px', | |||||
| height: '29px', | |||||
| marginRight: '20px', | |||||
| }} | |||||
| /> | |||||
| )} | |||||
| {isFetchingNextPage | |||||
| ? 'Loading...' | |||||
| : hasNextPage | |||||
| ? 'Load More' | |||||
| : 'Nothing more to load'} | |||||
| </Button> | |||||
| ); | |||||
| }; | |||||
| export default LoadMore; |
| sm: 'row', | sm: 'row', | ||||
| lg: 'column', | lg: 'column', | ||||
| }, | }, | ||||
| justifyContent: { sm: 'space-between' }, | |||||
| justifyContent: { sm: 'flex-start' }, | |||||
| flexWrap: 'wrap', | flexWrap: 'wrap', | ||||
| }} | }} | ||||
| > | > |
| import { Grid } from '@mui/material'; | |||||
| const GridItem = ({ children }) => { | const GridItem = ({ children }) => { | ||||
| return <p>Hello</p>; | |||||
| return ( | |||||
| <Grid item md={4} sm={6} xs={12} sx={{ mb: '100px' }}> | |||||
| {children} | |||||
| </Grid> | |||||
| ); | |||||
| }; | }; | ||||
| export default GridItem; | export default GridItem; |
| import { Button, Container, Grid } from '@mui/material'; | |||||
| import CircularProgress from '@mui/material/CircularProgress'; | |||||
| import { Container, Grid } from '@mui/material'; | |||||
| import { Box } from '@mui/system'; | import { Box } from '@mui/system'; | ||||
| import Image from 'next/image'; | |||||
| import LoadMore from '../buttons/load-more/LoadMore'; | |||||
| import GridItem from '../grid-item/GridItem'; | |||||
| import ProductCard from '../product-card/ProductCard'; | import ProductCard from '../product-card/ProductCard'; | ||||
| const ProductsGrid = ({ | const ProductsGrid = ({ | ||||
| }) => { | }) => { | ||||
| 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' }}> | |||||
| <GridItem key={item._id}> | |||||
| <ProductCard product={item} /> | <ProductCard product={item} /> | ||||
| </Grid> | |||||
| </GridItem> | |||||
| )) | )) | ||||
| ); | ); | ||||
| </Grid> | </Grid> | ||||
| <Box textAlign="center" mt={-5} mb={5}> | <Box textAlign="center" mt={-5} mb={5}> | ||||
| {hasNextPage && ( | {hasNextPage && ( | ||||
| <Button | |||||
| onClick={fetchNextPage} | |||||
| startIcon={ | |||||
| !isFetchingNextPage && ( | |||||
| <Image | |||||
| src="/images/arrow.svg" | |||||
| alt="arrow down" | |||||
| width={29} | |||||
| height={29} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| sx={{ | |||||
| backgroundColor: 'primary.main', | |||||
| height: 50, | |||||
| width: 150, | |||||
| color: 'white', | |||||
| ':hover': { | |||||
| bgcolor: 'primary.main', | |||||
| color: 'white', | |||||
| }, | |||||
| }} | |||||
| > | |||||
| {isFetchingNextPage && ( | |||||
| <CircularProgress | |||||
| style={{ | |||||
| color: '#fff', | |||||
| width: '29px', | |||||
| height: '29px', | |||||
| marginRight: '20px', | |||||
| }} | |||||
| /> | |||||
| )} | |||||
| {isFetchingNextPage | |||||
| ? 'Loading...' | |||||
| : hasNextPage | |||||
| ? 'Load More' | |||||
| : 'Nothing more to load'} | |||||
| </Button> | |||||
| <LoadMore | |||||
| fetchNextPage={fetchNextPage} | |||||
| isFetchingNextPage={isFetchingNextPage} | |||||
| hasNextPage={hasNextPage} | |||||
| /> | |||||
| )} | )} | ||||
| </Box> | </Box> | ||||
| </Container> | </Container> |
| import { Button, Grid, Tab, Tabs, Typography } from '@mui/material'; | |||||
| import { Box } from '@mui/system'; | |||||
| import { useState } from 'react'; | |||||
| import TabPanel from '../tab-panel/TabPanel'; | |||||
| const TabContent = ({ | |||||
| description, | |||||
| inCart, | |||||
| price, | |||||
| category, | |||||
| addProductToCart, | |||||
| }) => { | |||||
| const [value, setValue] = useState(0); | |||||
| const handleChange = (event, newValue) => { | |||||
| setValue(newValue); | |||||
| }; | |||||
| function a11yProps(index) { | |||||
| return { | |||||
| id: `simple-tab-${index}`, | |||||
| 'aria-controls': `simple-tabpanel-${index}`, | |||||
| }; | |||||
| } | |||||
| return ( | |||||
| <Grid item xs={12} md={6}> | |||||
| <Tabs | |||||
| sx={{ | |||||
| '& button:focus': { | |||||
| borderTop: '1px solid black', | |||||
| borderLeft: '1px solid black', | |||||
| borderRight: '1px solid black', | |||||
| borderRadius: '5px 5px 0 0', | |||||
| borderBottom: 'none', | |||||
| }, | |||||
| }} | |||||
| value={value} | |||||
| onChange={handleChange} | |||||
| aria-label="basic tabs example" | |||||
| > | |||||
| <Tab | |||||
| sx={{ | |||||
| width: '50%', | |||||
| }} | |||||
| label="Purchase" | |||||
| {...a11yProps(0)} | |||||
| /> | |||||
| <Tab sx={{ width: '50%' }} label="Category" {...a11yProps(1)} /> | |||||
| </Tabs> | |||||
| <TabPanel value={value} index={0}> | |||||
| <Box flexGrow={2} sx={{ pb: { xs: '70px' } }}> | |||||
| <Typography>{description}</Typography> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | |||||
| display: { xs: 'flex' }, | |||||
| flexDirection: { xs: 'column' }, | |||||
| justifyContent: { xs: 'center' }, | |||||
| alignItems: { xs: 'center', md: 'flex-end' }, | |||||
| }} | |||||
| > | |||||
| <Typography mb={2}>${price}</Typography> | |||||
| <Button | |||||
| disabled={inCart} | |||||
| onClick={() => addProductToCart(1)} | |||||
| sx={{ | |||||
| backgroundColor: '#CBA213', | |||||
| height: 50, | |||||
| width: { xs: '300px', md: '150px' }, | |||||
| color: 'white', | |||||
| }} | |||||
| > | |||||
| {inCart ? 'In Cart' : 'Add to cart'} | |||||
| </Button> | |||||
| </Box> | |||||
| </TabPanel> | |||||
| <TabPanel value={value} index={1}> | |||||
| <Box sx={{ mb: { xs: '60px' } }}>{category}</Box> | |||||
| </TabPanel>{' '} | |||||
| </Grid> | |||||
| ); | |||||
| }; | |||||
| export default TabContent; |
| import { Button, Grid, Tab, Tabs, Typography } from '@mui/material'; | |||||
| import { Grid, Typography } from '@mui/material'; | |||||
| import { Box, Container } from '@mui/system'; | import { Box, Container } from '@mui/system'; | ||||
| import { dehydrate, QueryClient } from '@tanstack/react-query'; | import { dehydrate, QueryClient } from '@tanstack/react-query'; | ||||
| import Image from 'next/image'; | import Image from 'next/image'; | ||||
| import { useRouter } from 'next/router'; | import { useRouter } from 'next/router'; | ||||
| import React, { useState } from 'react'; | |||||
| import React from 'react'; | |||||
| import GridItem from '../../components/grid-item/GridItem'; | |||||
| import Loader from '../../components/loader/Loader'; | import Loader from '../../components/loader/Loader'; | ||||
| import ProductCard from '../../components/product-card/ProductCard'; | import ProductCard from '../../components/product-card/ProductCard'; | ||||
| import TabPanel from '../../components/tab-panel/TabPanel'; | |||||
| import TabContent from '../../components/tab-content/TabContent'; | |||||
| import { useFetchSingleProduct } from '../../hooks/useFetchProductData'; | import { useFetchSingleProduct } from '../../hooks/useFetchProductData'; | ||||
| import { getProductData } from '../../requests/products/producDataRequest'; | import { getProductData } from '../../requests/products/producDataRequest'; | ||||
| import { useStore, useStoreUpdate } from '../../store/cart-context'; | import { useStore, useStoreUpdate } from '../../store/cart-context'; | ||||
| const { data, isLoading } = useFetchSingleProduct(customId); | const { data, isLoading } = useFetchSingleProduct(customId); | ||||
| // const productCategory = data?.product.category; | |||||
| const [value, setValue] = useState(0); | |||||
| const addProductToCart = (quantity) => addCartValue(data.product, quantity); | const addProductToCart = (quantity) => addCartValue(data.product, quantity); | ||||
| const inCart = cartStorage?.some( | const inCart = cartStorage?.some( | ||||
| (item) => item.product.customID === data?.product.customID | (item) => item.product.customID === data?.product.customID | ||||
| ? true | ? true | ||||
| : false; | : false; | ||||
| const handleChange = (event, newValue) => { | |||||
| setValue(newValue); | |||||
| }; | |||||
| function a11yProps(index) { | |||||
| return { | |||||
| id: `simple-tab-${index}`, | |||||
| 'aria-controls': `simple-tabpanel-${index}`, | |||||
| }; | |||||
| } | |||||
| if (isLoading) { | if (isLoading) { | ||||
| return <Loader loading={isLoading} />; | return <Loader loading={isLoading} />; | ||||
| } | } | ||||
| height={700} | height={700} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={6}> | |||||
| <Tabs | |||||
| sx={{ | |||||
| '& button:focus': { | |||||
| borderTop: '1px solid black', | |||||
| borderLeft: '1px solid black', | |||||
| borderRight: '1px solid black', | |||||
| borderRadius: '5px 5px 0 0', | |||||
| borderBottom: 'none', | |||||
| }, | |||||
| }} | |||||
| value={value} | |||||
| onChange={handleChange} | |||||
| aria-label="basic tabs example" | |||||
| > | |||||
| <Tab | |||||
| sx={{ | |||||
| width: '50%', | |||||
| }} | |||||
| label="Purchase" | |||||
| {...a11yProps(0)} | |||||
| /> | |||||
| <Tab sx={{ width: '50%' }} label="Category" {...a11yProps(1)} /> | |||||
| </Tabs> | |||||
| <TabPanel value={value} index={0}> | |||||
| <Box flexGrow={2} sx={{ pb: { xs: '70px' } }}> | |||||
| <Typography>{data.product.description}</Typography> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | |||||
| display: { xs: 'flex' }, | |||||
| flexDirection: { xs: 'column' }, | |||||
| justifyContent: { xs: 'center' }, | |||||
| alignItems: { xs: 'center', md: 'flex-end' }, | |||||
| }} | |||||
| > | |||||
| <Typography mb={2}>${data.product.price}</Typography> | |||||
| <Button | |||||
| disabled={inCart} | |||||
| onClick={() => addProductToCart(1)} | |||||
| sx={{ | |||||
| backgroundColor: '#CBA213', | |||||
| height: 50, | |||||
| width: { xs: '300px', md: '150px' }, | |||||
| color: 'white', | |||||
| }} | |||||
| > | |||||
| {inCart ? 'In Cart' : 'Add to cart'} | |||||
| </Button> | |||||
| </Box> | |||||
| </TabPanel> | |||||
| <TabPanel value={value} index={1}> | |||||
| <Box sx={{ mb: { xs: '60px' } }}>{data.product.category}</Box> | |||||
| </TabPanel> | |||||
| </Grid> | |||||
| <TabContent | |||||
| description={data?.product.description} | |||||
| inCart={inCart} | |||||
| price={data?.product.price} | |||||
| category={data?.product.category} | |||||
| addProductToCart={addProductToCart} | |||||
| /> | |||||
| </Grid> | </Grid> | ||||
| <Typography | <Typography | ||||
| </Typography> | </Typography> | ||||
| <Grid container spacing={2}> | <Grid container spacing={2}> | ||||
| {data.similarProducts.map((product) => ( | {data.similarProducts.map((product) => ( | ||||
| <Grid | |||||
| key={product._id} | |||||
| item | |||||
| md={4} | |||||
| sm={6} | |||||
| xs={12} | |||||
| sx={{ mb: '100px' }} | |||||
| > | |||||
| <GridItem key={product._id}> | |||||
| <ProductCard product={product} /> | <ProductCard product={product} /> | ||||
| </Grid> | |||||
| </GridItem> | |||||
| ))} | ))} | ||||
| </Grid> | </Grid> | ||||
| </Container> | </Container> |
| import ProductsContent from '../../components/products-content/ProductsContent'; | import ProductsContent from '../../components/products-content/ProductsContent'; | ||||
| const Products = () => { | const Products = () => { | ||||
| return <ProductsContent />; | |||||
| return <ProductsContent></ProductsContent>; | |||||
| }; | }; | ||||
| export default Products; | export default Products; |