CatalogPage.jsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import Header from "../components/Header";
  2. import Footer from "../components/Footer";
  3. import Breadcrumb from "../components/Breadcrumbs";
  4. import {
  5. Accordion,
  6. AccordionDetails,
  7. AccordionSummary, Box, Button,
  8. Card, CardActionArea, CardActions, CardContent, CardMedia,
  9. Container, Divider,
  10. Grid,
  11. Typography,
  12. useMediaQuery
  13. } from "@mui/material";
  14. import {connect} from "react-redux";
  15. import {actionFullCatById, actionFullRootCats} from "../actions/ActionCategory";
  16. import Link from "react-router-dom/es/Link";
  17. import Page404 from "./404Page";
  18. import Route from "react-router-dom/es/Route";
  19. import Switch from "react-router-dom/es/Switch";
  20. import {useEffect, useState} from "react";
  21. import {backURL} from "../actions/PathDB";
  22. import {actionCartAdd} from "../reducers/CartReducer";
  23. import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
  24. import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
  25. import AddShoppingCartIcon from '@mui/icons-material/AddShoppingCart';
  26. import {Pagination} from "@mui/material";
  27. const CategoryItem = ({object: {_id, name, subCategories}={}}) => {
  28. const [expanded, setExpanded] = useState(false);
  29. const handleChange = (panel) => (event, isExpanded) => {
  30. setExpanded(isExpanded ? panel : false);
  31. };
  32. return (
  33. <>
  34. {subCategories === null || !subCategories ?
  35. <li>
  36. <Link style={{textDecoration: 'none'}} to={`/catalog/category/${_id}`}>
  37. <Typography
  38. variant='body1'
  39. color='#616161'
  40. marginBottom='10px'
  41. >
  42. {name}
  43. </Typography>
  44. </Link>
  45. </li>
  46. :
  47. <li>
  48. <Accordion style={{border: 'none', borderRadius: '0',marginTop: '-10px', boxShadow: 'none'}} expanded={expanded === 'panel1'} onChange={handleChange('panel1')}>
  49. <AccordionSummary
  50. sx={{padding: '0'}}
  51. expandIcon={<ExpandMoreIcon />}
  52. aria-controls="panel1bh-content"
  53. id="panel1bh-header"
  54. >
  55. <Link style={{textDecoration: 'none'}} to={`/catalog/category/${_id}`}>
  56. <Typography
  57. variant='body1'
  58. color='#616161'
  59. padding='0'
  60. >
  61. {name}
  62. </Typography>
  63. </Link>
  64. </AccordionSummary>
  65. <AccordionDetails>
  66. <ul style={{listStyle: 'none', padding: '0 0 0 10px', marginBottom: '10px'}}>
  67. {subCategories && Object.values(subCategories).map(item =>
  68. <CategoryItem object={item}/>
  69. )}
  70. </ul>
  71. </AccordionDetails>
  72. </Accordion>
  73. </li>
  74. }
  75. </>
  76. )
  77. }
  78. const CategoryAside = ({category}) => {
  79. return (
  80. <Grid sx={{backgroundColor: '#fff', padding: '30px'}} xs={12} lg={3}>
  81. <Typography
  82. variant='h6'
  83. letterSpacing='3px'
  84. lineHeight='1.3em'
  85. marginBottom='20px'
  86. >
  87. PRODUCT CATEGORIES
  88. </Typography>
  89. <ul style={{listStyle: 'none', padding: '0'}}>
  90. {category && Object.values(category).map(item =>
  91. <CategoryItem object={item}/>
  92. )}
  93. </ul>
  94. </Grid>
  95. )
  96. }
  97. const GoodCard = ({good:{_id, name, description, price, images}={}, onCartAdd}) => {
  98. return (
  99. <Grid xs={12} lg={4} item margin='20px 0'>
  100. <Card sx={{ maxWidth: 345, height: '100%', display: 'flex', flexDirection: 'column', margin: 'auto 20px'}}>
  101. <CardActionArea sx={{padding: '0', flexGrow: '1', position: 'relative'}}>
  102. <Link to='/' style={{position: 'relative', textDecoration: 'none'}}>
  103. <CardMedia sx={{marginBottom: '20px', marginTop: '20px'}}
  104. component="img"
  105. height="230"
  106. image={`${backURL}/${images[0].url}`}
  107. alt="Good title image"
  108. />
  109. <CardContent sx={{display: 'flex', flexDirection: 'column', height: '180px', justifyContent: 'space-between'}}>
  110. <Typography
  111. textAlign='center'
  112. fontFamily='sarif'
  113. letterSpacing='2px'
  114. marginBottom='20px'
  115. fontSize='19px'
  116. sx={{textTransform: 'uppercase', flexGrow: '1'}}
  117. color='#000'
  118. >
  119. {name}
  120. </Typography>
  121. <Typography textAlign='center' variant="body2" color='#616161' marginBottom='20px' sx={{ flexGrow: '0'}}>
  122. {description.length > 60 ?
  123. 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' :
  124. description
  125. }
  126. </Typography>
  127. <Typography textAlign='center' variant="h5" color="#000" sx={{ flexGrow: '0'}}>
  128. $ {parseFloat(price).toFixed(2)}
  129. </Typography>
  130. </CardContent>
  131. </Link>
  132. </CardActionArea>
  133. <CardActions sx={{flexGrow: '0', justifyContent: 'space-between'}}>
  134. <Button onClick={() => onCartAdd({_id, name, price, images})} size="small" color="primary">
  135. <AddShoppingCartIcon />
  136. </Button>
  137. <Button onClick={() => console.log('nice')} size="small" color="primary">
  138. <FavoriteBorderIcon />
  139. </Button>
  140. </CardActions>
  141. </Card>
  142. </Grid>
  143. )
  144. }
  145. const CGoodCard = connect(null, {onCartAdd: actionCartAdd})(GoodCard)
  146. const Goods = ({_id='5dc49f4d5df9d670df48cc64', category={}}) => {
  147. // const itemsPerPage = 6
  148. // const [page, setPage] = useState(1)
  149. // const [count, setCount] = useState(1)
  150. // const handleChange = (event, value) => {
  151. // setPage(value);
  152. // }
  153. return (
  154. <>
  155. {(Object.values(category) || []).map(item => {
  156. if (item['_id'] === _id) {
  157. if(!item.goods || item['goods'] === null) {
  158. return <div>not info</div>
  159. }
  160. if (item.goods) {
  161. // setCount(item['goods'].length / itemsPerPage)
  162. return (item['goods'] || []).map((good, index) => <CGoodCard key={index} good={good}/>)
  163. }
  164. }
  165. else if(item['subCategories'] !== null) {
  166. return (item['subCategories'] || []).map(subItem => {
  167. if (subItem['_id'] === _id) {
  168. if(subItem['goods'] === null) return <div>not info</div>
  169. // setCount(subItem['goods'].length / itemsPerPage)
  170. return (subItem['goods'] || []).map(good => <CGoodCard good={good}/>)
  171. }
  172. else if(subItem['subCategories'] !== null) {
  173. return (subItem['subCategories'] || []).map(subSubItem => {
  174. if (subSubItem['_id'] === _id) {
  175. if(subSubItem['goods'] === null) return <div>not info</div>
  176. // setCount(subSubItem['goods'].length / itemsPerPage)
  177. return (subSubItem['goods'] || []).map(good => <CGoodCard good={good}/>)
  178. }
  179. })
  180. }
  181. })
  182. }
  183. })}
  184. {/*<Divider />*/}
  185. {/*<Box display='flex' justifyContent='center' width='100%'>*/}
  186. {/* <Pagination*/}
  187. {/* count={count}*/}
  188. {/* page={page}*/}
  189. {/* onChange={handleChange}*/}
  190. {/* defaultPage={1}*/}
  191. {/* color="primary"*/}
  192. {/* size="large"*/}
  193. {/* showFirstButton*/}
  194. {/* showLastButton*/}
  195. {/* />*/}
  196. {/*</Box>*/}
  197. </>
  198. )
  199. }
  200. const CGoods = connect(state => ({category: state.category}))(Goods)
  201. const BlockGood = ({match:{params:{_id}}, getData}) => {
  202. useEffect(() => {
  203. getData(_id)
  204. },[_id, getData])
  205. return(
  206. <Grid container justifyContent='space-between'>
  207. <CGoods _id={_id} />
  208. </Grid>
  209. )
  210. }
  211. export const CBlockGood= connect(null, {getData: actionFullCatById})(BlockGood)
  212. const Products = () => {
  213. return (
  214. <Grid xs={12} lg={9}>
  215. <Switch>
  216. <Route path="/catalog/category/:_id" component={CBlockGood} />
  217. <Route path="*" component={Page404} />
  218. </Switch>
  219. </Grid>
  220. )
  221. }
  222. const CatalogPage = ({category={}, actionRootCat}) => {
  223. const matches = useMediaQuery('(max-width:899px)')
  224. if(Object.entries(category).length === 0) actionRootCat()
  225. return (
  226. <>
  227. <Breadcrumb links={['catalog']}/>
  228. <main style={{backgroundColor: "#f3f3f3", padding: matches ? "20px 0" : "50px 0"}}>
  229. <Container maxWidth="lg">
  230. <Grid container justifyContent='space-between'>
  231. <CategoryAside category={category}/>
  232. <Products/>
  233. </Grid>
  234. </Container>
  235. </main>
  236. </>
  237. )
  238. }
  239. const CCatalogPage = connect(state => ({category: state.category}), {actionRootCat: actionFullRootCats})(CatalogPage)
  240. export default CCatalogPage