|
@@ -7,12 +7,8 @@ import Typography from "@mui/material/Typography";
|
|
|
import {
|
|
|
Button,
|
|
|
CircularProgress, Container,
|
|
|
- FormControl,
|
|
|
Grid, IconButton,
|
|
|
InputAdornment,
|
|
|
- InputLabel,
|
|
|
- MenuItem,
|
|
|
- Select,
|
|
|
TextField
|
|
|
} from "@mui/material";
|
|
|
import {connect} from "react-redux";
|
|
@@ -29,8 +25,8 @@ import SearchIcon from "@material-ui/icons/Search";
|
|
|
import imgNotFound from "../../img/catalog/imgNotFound.png";
|
|
|
import {actionSearchRemove} from "../../reducers/SearchReducer";
|
|
|
|
|
|
-
|
|
|
-const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, fileStatus, variant='create', categoryState, actionRootCat, goodCount, goods, actionClear, result}) => {
|
|
|
+const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, fileStatus,
|
|
|
+ categoryState, actionRootCat, goodCount, goods, actionClear, result}) => {
|
|
|
const [state, setState] = useState(entity)
|
|
|
|
|
|
const {getRootProps, getInputProps, isDragActive} = useDropzone({accept: 'image/*', onDrop: acceptedFiles => {
|
|
@@ -39,22 +35,26 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
})
|
|
|
}})
|
|
|
const SortableItem = sortableElement(({value}) => {
|
|
|
- return <div key={value?._id} style={{display: 'inline-flex', borderRadius: 2,border: '1px solid #eaeaea',marginBottom: 8, marginRight: 8, width: 200, height: 200, padding: 4, boxSizing: 'border-box'}}>
|
|
|
- <div style={{display: 'flex', justifyContent: 'center', minWidth: 0, overflow: 'hidden'}}>
|
|
|
- {value?.url ?
|
|
|
- <img src={backURL+ '/' + value?.url} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={value.name}/>
|
|
|
- :
|
|
|
- <Box sx={{ display: 'flex' }}>
|
|
|
- <CircularProgress />
|
|
|
- </Box>
|
|
|
- }
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ return (
|
|
|
+ <Box key={value?._id} sx={{display: 'flex', justifyContent: 'center', borderRadius: 2, border: '1px solid #eaeaea', marginBottom: 2, width: 200, height: 200, padding: '5px', boxSizing: 'border-box'}}>
|
|
|
+ <Box sx={{display: 'flex', justifyContent: 'center', minWidth: 0, overflow: 'hidden'}}>
|
|
|
+ {value?.url ?
|
|
|
+ <img src={backURL+ '/' + value.url} style={{display: 'block', width: 'auto', height: '100%', objectFit: 'cover', objectPosition: 'center center'}} alt={value.name}/>
|
|
|
+ :
|
|
|
+ <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center'}}>
|
|
|
+ <CircularProgress />
|
|
|
+ </Box>
|
|
|
+ }
|
|
|
+ </Box>
|
|
|
+ </Box>
|
|
|
+ )
|
|
|
});
|
|
|
const SortableContainer = sortableContainer(({children}) => {
|
|
|
- return <aside style={{display:'flex', justifyContent: 'space-between', flexWrap: 'wrap'}}>
|
|
|
- {children}
|
|
|
- </aside>
|
|
|
+ return (
|
|
|
+ <aside style={{display:'flex', justifyContent: 'space-between', flexWrap: 'wrap'}}>
|
|
|
+ {children}
|
|
|
+ </aside>
|
|
|
+ )
|
|
|
})
|
|
|
const onSortEnd = ({oldIndex, newIndex}) => {
|
|
|
setState(({images}) => ({
|
|
@@ -68,8 +68,8 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
}
|
|
|
const handleOnSave = () => {
|
|
|
let query = {...state}
|
|
|
- state.images.length > 0 ? query.images = state.images.map(item => {return {'_id': item['_id']}}) : delete query.images
|
|
|
- state.categories.length > 0 ? query.categories = state.categories.map(item => {return {'_id': item['_id'], 'name': item['name']}}) : delete query.categories
|
|
|
+ state.images?.length > 0 ? query.images = state.images.map(item => {return {'_id': item['_id']}}) : delete query.images
|
|
|
+ state.categories?.length > 0 ? query.categories = state.categories.map(item => {return {'_id': item['_id'], 'name': item['name']}}) : delete query.categories
|
|
|
onSave(query)
|
|
|
goodCount()
|
|
|
}
|
|
@@ -82,7 +82,9 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
if(!categoryState || Object.entries(categoryState).length === 0) actionRootCat()
|
|
|
if(!goods) goodCount()
|
|
|
if(fileStatus?.status === 'RESOLVED'){
|
|
|
- setState({...state, images: [...state.images, fileStatus?.payload]})
|
|
|
+ state.images?.length > 0 ?
|
|
|
+ setState({...state, images: [...state.images, fileStatus?.payload]}) :
|
|
|
+ setState({...state, images: [fileStatus?.payload]})
|
|
|
}
|
|
|
},[categoryState, goods, fileStatus])
|
|
|
|
|
@@ -98,8 +100,8 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
<Typography variant='body1' textAlign='center' color='#616161' marginBottom='20px'>Drag 'n' drop image files here, or click to select file</Typography>
|
|
|
}
|
|
|
<SortableContainer axis="xy" onSortEnd={onSortEnd}>
|
|
|
- {state.images.length > 0 && state.images.map((value, index) => (
|
|
|
- <SortableItem key={`item-${value?._id}`} index={index} value={value} />
|
|
|
+ {state.images?.length > 0 && state.images.map((value, index) => (
|
|
|
+ <SortableItem key={`item-${value?._id || index}`} index={index} value={value} />
|
|
|
))}
|
|
|
</SortableContainer>
|
|
|
</Box>
|
|
@@ -109,6 +111,26 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
</Grid>
|
|
|
<Grid item xs={5.5}>
|
|
|
{categoryState &&
|
|
|
+ state.categories?.length > 0 ?
|
|
|
+ <Autocomplete
|
|
|
+ multiple
|
|
|
+ id="tags-standard"
|
|
|
+ options={Object.values(categoryState)}
|
|
|
+ defaultValue={state.categories}
|
|
|
+ onChange={(event, newValue) => {
|
|
|
+ setState({...state, categories: [...newValue]})
|
|
|
+ }}
|
|
|
+ getOptionLabel={(option) => option?.name || 'no name'}
|
|
|
+ key={option => option?.id}
|
|
|
+ renderInput={(params) => (
|
|
|
+ <TextField
|
|
|
+ {...params}
|
|
|
+ variant="standard"
|
|
|
+ label="Select categories"
|
|
|
+ placeholder="categories"
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ />:
|
|
|
<Autocomplete
|
|
|
multiple
|
|
|
id="tags-standard"
|
|
@@ -116,7 +138,7 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
onChange={(event, newValue) => {
|
|
|
setState({...state, categories: [...newValue]})
|
|
|
}}
|
|
|
- getOptionLabel={(option) => state?.categories ? [...state.categories] : option?.name || 'no name'}
|
|
|
+ getOptionLabel={(option) => option?.name || 'no name'}
|
|
|
key={option => option?.id}
|
|
|
renderInput={(params) => (
|
|
|
<TextField
|
|
@@ -180,7 +202,7 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
<Box display='flex' alignItems='center' flexDirection='column'>
|
|
|
<Typography variant='h5' letterSpacing='2px' textAlign='center' color='#616161' marginBottom='20px'>Product successfully created!</Typography>
|
|
|
<CheckCircleOutlineIcon sx={{marginBottom: '20px'}}/>
|
|
|
- <Link to={`/good/${result?.payload?._id}`} style={{color:'#616161', marginBottom:'20px'}}>
|
|
|
+ <Link to={`/good/${result.payload._id}`} style={{color:'#616161', marginBottom:'20px'}}>
|
|
|
<Typography variant='h5' letterSpacing='2px' textAlign='center' color='#616161'>View results</Typography>
|
|
|
</Link>
|
|
|
<Button variant='outlined' onClick={handleFullClear}>Add more</Button>
|
|
@@ -199,62 +221,72 @@ const GoodEdit = ({entity={images: [], categories: []}, onSave, onFileDrop, file
|
|
|
</>
|
|
|
)
|
|
|
}
|
|
|
-export const CGoodEdit = connect(state => ({fileStatus: state.promise['uploadFile'], categoryState: state.category, goods: state.promise['goodCount'], result: state.promise['goodUpsert']}), {actionRootCat: actionFullRootCats, onSave: actionGoodUpsert, goodCount: actionGoodCount, onFileDrop: actionUploadFile, actionClear: actionClearPromise})(GoodEdit)
|
|
|
+
|
|
|
+export const CGoodEdit = connect(state => ({fileStatus: state.promise['uploadFile'],
|
|
|
+ categoryState: state.category, goods: state.promise['goodCount'], result: state.promise['goodUpsert']}),
|
|
|
+ {actionRootCat: actionFullRootCats, onSave: actionGoodUpsert, goodCount: actionGoodCount,
|
|
|
+ onFileDrop: actionUploadFile, actionClear: actionClearPromise})(GoodEdit)
|
|
|
|
|
|
const ItemFound = ({item:{_id, name, price, images, description, categories}}) => {
|
|
|
let [state, setState] = useState(false)
|
|
|
|
|
|
return (
|
|
|
!state ?
|
|
|
- <Button style={{textDecoration: 'none', display: 'flex', alignItems: 'center', marginBottom: '30px'}} onClick={() => setState(true)}>
|
|
|
- <Box width='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='60px'
|
|
|
- position='relative'>
|
|
|
- <img style={{
|
|
|
- position: 'absolute',
|
|
|
- top: '0',
|
|
|
- left: '0',
|
|
|
- width: '100%',
|
|
|
- height: '100%',
|
|
|
- objectFit: 'cover'
|
|
|
- }} src={images && Array.isArray(images) && images[0]?.url ? backURL + '/' + images[0].url : imgNotFound}
|
|
|
- alt={name}/>
|
|
|
- </Box>
|
|
|
- <Box sx={{
|
|
|
- display: 'flex',
|
|
|
- flexDirection: 'column',
|
|
|
- justifyContent: 'space-between',
|
|
|
- alignItems: 'flex-start'
|
|
|
- }}>
|
|
|
- <Typography
|
|
|
- color='#000'
|
|
|
- letterSpacing='1px'
|
|
|
- fontFamily='sarif'
|
|
|
- fontWeight='600'
|
|
|
- variant='h6'
|
|
|
- >
|
|
|
- {name}
|
|
|
- </Typography>
|
|
|
- <Typography
|
|
|
- letterSpacing='1px'
|
|
|
- variant='body1'
|
|
|
- fontWeight='300'
|
|
|
- color='#616161'
|
|
|
- margin='10px 0'
|
|
|
- >
|
|
|
- {description?.length > 60 ? 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' : description}
|
|
|
- </Typography>
|
|
|
- <Typography
|
|
|
- color='#000'
|
|
|
- letterSpacing='1px'
|
|
|
- variant='body1'
|
|
|
- fontWeight='600'
|
|
|
- >
|
|
|
- ${parseFloat(price).toFixed(2)}
|
|
|
- </Typography>
|
|
|
+ <Button fullWidth sx={{display: 'flex', justifyContent:'flex-start'}} onClick={() => setState(true)}>
|
|
|
+ <Box style={{display: 'flex', alignItems: 'center', marginBottom: '30px'}}>
|
|
|
+ <Box width='60px' height='60px' borderRadius='10px' overflow='hidden' marginRight='60px'
|
|
|
+ position='relative'>
|
|
|
+ <img style={{
|
|
|
+ position: 'absolute',
|
|
|
+ top: '0',
|
|
|
+ left: '0',
|
|
|
+ width: '100%',
|
|
|
+ height: '100%',
|
|
|
+ objectFit: 'cover'
|
|
|
+ }} src={images && Array.isArray(images) && images[0]?.url ? backURL + '/' + images[0].url : imgNotFound}
|
|
|
+ alt={name}/>
|
|
|
+ </Box>
|
|
|
+ <Box sx={{
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection: 'column',
|
|
|
+ justifyContent: 'space-between',
|
|
|
+ alignItems: 'flex-start'
|
|
|
+ }}>
|
|
|
+ <Typography
|
|
|
+ color='#000'
|
|
|
+ letterSpacing='1px'
|
|
|
+ fontFamily='sarif'
|
|
|
+ fontWeight='600'
|
|
|
+ variant='h6'
|
|
|
+ >
|
|
|
+ {name || 'no name'}
|
|
|
+ </Typography>
|
|
|
+ <Typography
|
|
|
+ letterSpacing='1px'
|
|
|
+ variant='body1'
|
|
|
+ fontWeight='300'
|
|
|
+ color='#616161'
|
|
|
+ margin='10px 0'
|
|
|
+ sx={{textTransform: 'capitalize'}}
|
|
|
+ >
|
|
|
+ {description?.length > 60 ? 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' : description}
|
|
|
+ </Typography>
|
|
|
+ <Typography
|
|
|
+ color='#000'
|
|
|
+ letterSpacing='1px'
|
|
|
+ variant='body1'
|
|
|
+ fontWeight='600'
|
|
|
+ >
|
|
|
+ ${parseFloat(price).toFixed(2)}
|
|
|
+ </Typography>
|
|
|
+ </Box>
|
|
|
</Box>
|
|
|
</Button>
|
|
|
:
|
|
|
- <CGoodEdit entity={{_id, name, price, images, description, categories}}/>
|
|
|
+ <Box sx={{marginBottom: '30px', border: '1px solid #616161', borderRadius: '10px', padding: '30px 20px'}}>
|
|
|
+ <CGoodEdit entity={{_id, name, price, images, description, categories}}/>
|
|
|
+ <Button variant='outlined' sx={{marginTop: '30px'}} fullWidth onClick={() => setState(false)}>Cansel</Button>
|
|
|
+ </Box>
|
|
|
)
|
|
|
}
|
|
|
const NotFound = () => {
|
|
@@ -275,7 +307,7 @@ const FindGoodEdit = ({searchResult, onSearch, onSearchRemove}) => {
|
|
|
|
|
|
return (
|
|
|
<>
|
|
|
- <Container maxWidth="sm">
|
|
|
+ <Container maxWidth="md">
|
|
|
<Typography
|
|
|
variant='h5'
|
|
|
fontFamily='sarif'
|
|
@@ -306,12 +338,13 @@ const FindGoodEdit = ({searchResult, onSearch, onSearchRemove}) => {
|
|
|
/>
|
|
|
{(value !== '' && click) && (searchResult?.searchResult ?
|
|
|
Object.values(searchResult.searchResult).length > 0 ?
|
|
|
- Object.values(searchResult.searchResult).map(item => <ItemFound item={item}/>) : <NotFound/> :
|
|
|
+ Object.values(searchResult.searchResult).map(item => <ItemFound key={item?._id} item={item}/>) : <NotFound/> :
|
|
|
<CircularProgress color="inherit"/>
|
|
|
)}
|
|
|
</Container>
|
|
|
</>
|
|
|
)
|
|
|
}
|
|
|
-export const CFindGoodEdit = connect(state=>({searchResult: state.search}), {onSearch: actionFullGoodFind, onSearchRemove: actionSearchRemove})(FindGoodEdit)
|
|
|
|
|
|
+export const CFindGoodEdit = connect(state=>({searchResult: state.search}),
|
|
|
+ {onSearch: actionFullGoodFind, onSearchRemove: actionSearchRemove})(FindGoodEdit)
|