EditableGood.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React, { useState } from 'react';
  2. import Button from '@mui/material/Button';
  3. import { Container, Grid, Card, CardContent, CardMedia, CardActions, TextField, InputAdornment, Box, Modal } from '@mui/material';
  4. import { getFullImageUrl } from "./../utills";
  5. import { useSelector } from 'react-redux';
  6. import { frontEndNames, getCurrentEntity, isCurrentUserAdmin, useGetGoodByIdQuery, useSaveGoodMutation } from '../reducers';
  7. import { useParams } from 'react-router-dom';
  8. import { CSortedFileDropZone } from './SortedFileDropZone';
  9. import { saveImage } from '../utills/utils';
  10. import { CGood } from './Good';
  11. import { ModalContainer } from './ModalContainer';
  12. import { history } from "../App";
  13. import { LackPermissions } from './LackPermissions';
  14. import { CCategoryDropDownList } from './DropDownList';
  15. import { CategoryBreadcrumbs } from './CategoryBreadcrumbs';
  16. const EditableGood = ({ good: goodExt, maxWidth = 'md', saveGood }) => {
  17. const copyGood = goodExt => ({ ...goodExt, images: [...(goodExt.images ?? [])] });
  18. let [good, setGood] = useState(copyGood(goodExt));
  19. let [showPreview, setShowPreview] = useState(false);
  20. let [imagesContainer, setImagesContainer] = useState({ images: [...(goodExt.images ?? [])] });
  21. const onSetCategory = (catItem) => {
  22. good.categories = catItem.cat ? [{ _id: catItem.cat._id }] : [];
  23. }
  24. const setGoodData = (data) => {
  25. let goodData = { ...good, ...data };
  26. setGood(goodData);
  27. return goodData;
  28. }
  29. const onChangeImages = images => {
  30. setImagesContainer({ images });
  31. good.images = images;
  32. setGood(good);
  33. }
  34. const preview = show => {
  35. setShowPreview(show);
  36. }
  37. let isExistingGood = good?._id;
  38. const saveFullGood = async () => {
  39. let addedImages = imagesContainer.images.filter(img => !img._id);
  40. let results = await Promise.all(addedImages.map(img => saveImage(img)));
  41. for (let i = 0; i < results.length; i++) {
  42. addedImages[i]._id = results[i]._id;
  43. addedImages[i].url = results[i].url;
  44. }
  45. let images = imagesContainer.images.map(img => ({ _id: img._id }));
  46. good = { ...good, images };
  47. saveGood({ good })
  48. .then(res => {
  49. let _id = res.data?.GoodUpsert?._id;
  50. if (_id && !isExistingGood) {
  51. history.push(`/editgood/${_id}`);
  52. }
  53. return res;
  54. });
  55. }
  56. if (good)
  57. good.categories ??= [];
  58. const currentCategory = good.categories?.length > 0 ? good.categories[0] : undefined;
  59. return good && (
  60. <>
  61. <Container maxWidth={maxWidth}>
  62. <CategoryBreadcrumbs category={currentCategory} showLeafAsLink={true} />
  63. <Card variant='outlined'>
  64. <Grid container spacing={maxWidth === 'xs' ? 7 : 5} rowSpacing={2}>
  65. <Grid item xs={12}>
  66. <Grid container spacing={2}>
  67. <Grid item xs={4}>
  68. <CardMedia
  69. component="img"
  70. sx={{ height: 300, padding: "1em 1em 0 1em", objectFit: "contain" }}
  71. image={good.images?.length > 0 ? getFullImageUrl(good.images[0]) : ''}
  72. title={good.name}
  73. />
  74. </Grid>
  75. <Grid item xs={8}>
  76. <CardContent>
  77. <Grid container rowSpacing={2}>
  78. <Grid item width="100%">
  79. {
  80. <CCategoryDropDownList currentCat={currentCategory} onSetCategory={onSetCategory} />
  81. }
  82. </Grid>
  83. <Grid item width="100%">
  84. <TextField
  85. required
  86. id="outlined-required"
  87. label="Name"
  88. value={good.name}
  89. onChange={event => setGoodData({ name: event.target.value })}
  90. fullWidth
  91. />
  92. </Grid>
  93. <Grid item width="100%">
  94. <TextField
  95. required
  96. id="outlined-required"
  97. label="Price"
  98. type="number"
  99. startAdornment={<InputAdornment position="start">$</InputAdornment>}
  100. value={good.price}
  101. onChange={event => setGoodData({ price: +event.target.value })}
  102. fullWidth
  103. />
  104. </Grid>
  105. <Grid item width="100%">
  106. <TextField
  107. required
  108. id="outlined-required"
  109. label="Description"
  110. value={good.description}
  111. onChange={event => setGoodData({ description: event.target.value })}
  112. multiline={true}
  113. rows={15}
  114. fullWidth
  115. />
  116. </Grid>
  117. </Grid>
  118. </CardContent>
  119. </Grid>
  120. </Grid>
  121. </Grid>
  122. </Grid>
  123. {showPreview &&
  124. <ModalContainer onCloseClick={() => preview(false)}>
  125. <CGood good={good} editable={false} />
  126. </ModalContainer>
  127. }
  128. <CardActions>
  129. <Button size='small' color='primary'
  130. onClick={() => saveFullGood(good)}
  131. >
  132. Save
  133. </Button>
  134. <Button size='small' color='primary'
  135. onClick={() => setGood(copyGood(goodExt))}
  136. >
  137. Cancel
  138. </Button>
  139. <Button size='small' color='primary'
  140. onClick={() => preview(true)}
  141. >
  142. Preview
  143. </Button>
  144. </CardActions>
  145. <CSortedFileDropZone items={good.images} sx={{ maxWidth: "15vh" }} itemProp={{ sx: { maxWidth: "15vh" } }} onChange={items => onChangeImages(items)} />
  146. </Card>
  147. </Container>
  148. </>
  149. )
  150. }
  151. const CEditableGood = ({ maxWidth = 'md' }) => {
  152. const { _id } = useParams();
  153. let { isLoading, data } = useGetGoodByIdQuery(_id || 'fwkjelnfvkjwe');
  154. isLoading = _id ? isLoading : false;
  155. let good = isLoading ? { name: 'loading', categories: [] } : data?.GoodFindOne;
  156. const [saveGoodMutation, { }] = useSaveGoodMutation();
  157. const state = useSelector(state => state);
  158. let currentCategory = getCurrentEntity(frontEndNames.category, state)
  159. let isAdmin = isCurrentUserAdmin(state);
  160. if (!isLoading && !good && isAdmin) {
  161. let categories = currentCategory ? [{ _id: currentCategory._id, name: currentCategory.name }] : [];
  162. good = { _id: undefined, categories, images: [] };
  163. }
  164. return !isLoading &&
  165. (isAdmin ? <EditableGood good={good} saveGood={saveGoodMutation} maxWidth={maxWidth} /> : <LackPermissions name="good" />)
  166. }
  167. export { CEditableGood }
  168. /*-good.categories.map(cat => (
  169. <Grid item width="100%">
  170. <TextField
  171. required
  172. id="outlined-required"
  173. label="Categories"
  174. value={cat.name}
  175. onChange={event => setGoodData({ description: event.target.value })}
  176. multiline={true}
  177. rows={1}
  178. fullWidth
  179. />
  180. </Grid>
  181. ))*/