From b6790f692647d12976c375adaf0c79b5a7fe1446 Mon Sep 17 00:00:00 2001 From: dbroqua Date: Sun, 2 Dec 2018 17:40:23 +0100 Subject: [PATCH] Added delete option for pictures --- src/Vegetable.css | 7 ++ src/Vegetable.js | 148 ++++++++++++++++++++++++-------------- src/Vegetable/Carousel.js | 68 ++++++++++++------ 3 files changed, 150 insertions(+), 73 deletions(-) diff --git a/src/Vegetable.css b/src/Vegetable.css index 9f22d80..66b9a05 100644 --- a/src/Vegetable.css +++ b/src/Vegetable.css @@ -36,3 +36,10 @@ top: 33%; .carousel-inner img { max-width: 100%; } + + +.deletePicture { + position: absolute; + right: 16px; + top: 16px; +} \ No newline at end of file diff --git a/src/Vegetable.js b/src/Vegetable.js index 7fe7831..00907b3 100644 --- a/src/Vegetable.js +++ b/src/Vegetable.js @@ -17,15 +17,15 @@ import { } from 'react-icons/fa'; import { NotificationContainer, - NotificationManager + NotificationManager, } from 'react-notifications'; import Navigation from './Navigation'; import Header from './Header'; import API from './Api'; -import VegetableMain from './Vegetable/Main' -import VegetableCarousel from './Vegetable/Carousel' -import VegetableMap from './Vegetable/Map' -import VegetablesProperties from './Vegetable/Properties' +import VegetableMain from './Vegetable/Main'; +import VegetableCarousel from './Vegetable/Carousel'; +import VegetableMap from './Vegetable/Map'; +import VegetablesProperties from './Vegetable/Properties'; import './Vegetable.css'; import 'react-notifications/lib/notifications.css'; @@ -42,10 +42,12 @@ class Vegetable extends Component { description: '', Pictures: [], }, + uploadPictures: 0, + uploadedPictures: 0, imagePreviewUrl: '', imagesPreviewUrls: [], activeTab: '1', - availableProperties: [] + availableProperties: [], }; this.handleChange = this.handleChange.bind(this); @@ -53,8 +55,8 @@ class Vegetable extends Component { this.updateVegetable = this.updateVegetable.bind(this); this.changeMainPicture = this.changeMainPicture.bind(this); this.addPicture = this.addPicture.bind(this); + this.deletePicture = this.deletePicture.bind(this); this.toggle = this.toggle.bind(this); - this.postPicture = this.postPicture.bind(this); this.updateValueFromChild = this.updateValueFromChild.bind(this); this.getVegetable(props.match.params.categoryId, props.match.params.vegetableId); @@ -102,21 +104,73 @@ class Vegetable extends Component { addPicture(file, reader) { this.setState(prevState => ({ - Vegetable: { - ...prevState.Vegetable, - Pictures: [ - ...prevState.Vegetable.Pictures, - file - ] - }, - imagesPreviewUrls: [ - ...prevState.imagesPreviewUrls, - reader.result - ], - activeIndex: prevState.imagesPreviewUrls.length - })); + uploadPictures: prevState.uploadPictures + 1, + }), () => { + const fd = new FormData(); + NotificationManager.info('Sauvegarde de l\'image en cours...'); - this.postPicture(file); + fd.append('picture', file); + + API.post(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures`, fd) + .then((res) => { + const picture = res.data; + this.setState(prevState => ({ + uploadedPictures: prevState.uploadedPictures + 1, + Vegetable: { + ...prevState.Vegetable, + Pictures: [ + ...prevState.Vegetable.Pictures, + picture, + ], + }, + imagesPreviewUrls: [ + ...prevState.imagesPreviewUrls, + picture.url, + ], + activeIndex: prevState.imagesPreviewUrls.length, + })); + NotificationManager.success('Image sauvegardée'); + }) + .catch(() => { + NotificationManager.error('Impossible d\'ajouter cette image'); + }); + }); + } + + deletePicture(id) { + API.delete(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures/${id}`) + .then(() => { + NotificationManager.success('Image supprimée'); + const Pictures = this.state.Vegetable.Pictures; + const urls = this.state.imagesPreviewUrls; + let url = null; + + for (let i = 0; i < Pictures.length; i++) { + if (Pictures[i].id === id) { + url = Pictures[i].url; + Pictures.splice(i, 1); + break; + } + } + for (let i = 0; i < urls.length; i++) { + if (urls[i] === url) { + urls.splice(i, 1); + break; + } + } + + this.setState(prevState => ({ + ...prevState, + imagesPreviewUrls: urls, + Vegetable: { + ...prevState.Vegetable, + Pictures, + }, + })); + }) + .catch(() => { + NotificationManager.error('Impossible de supprimer cette image'); + }); } updateVegetable(event) { @@ -126,12 +180,12 @@ class Vegetable extends Component { const requests = 1 + this.state.Vegetable.Properties.length; let requestsDone = 0; - let isDone = () => { + const isDone = () => { if (requests === requestsDone) { NotificationManager.success('Sauvegarde terminée'); this.getVegetable(this.props.match.params.categoryId, this.props.match.params.vegetableId); } - } + }; // Patch Vegetable const fd = new FormData(); @@ -158,7 +212,7 @@ class Vegetable extends Component { }); // Patch or create Properties - this.state.Vegetable.Properties.forEach(propertyItem => { + this.state.Vegetable.Properties.forEach((propertyItem) => { if (propertyItem.id) { API.patch(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/properties/${propertyItem.id}`, propertyItem) .then((res) => { @@ -178,35 +232,20 @@ class Vegetable extends Component { NotificationManager.error(`Impossile de sauvegarder la propriété ayant pour valeur ${propertyItem.value}`); }); } - }) - - } - - postPicture(picture) { - const fd = new FormData(); - - fd.append('picture', picture); - - API.post(`types/${this.state.Vegetable.Type.id}/vegetables/${this.state.Vegetable.id}/pictures`, fd) - .then((res) => { - // this.setState({ Category: res.data }); - }) - .catch(() => { - NotificationManager.error(`Impossible d'ajouter cette image`); - }); + }); } getVegetable(categoryId, vegetableId) { API.get('properties') - .then(res => { - //availableProperties + .then((res) => { + // availableProperties if (res.status === 200) { this.setState({ - availableProperties: res.data.rows + availableProperties: res.data.rows, }); } }) - .catch(e => { + .catch((e) => { NotificationManager.error('Erreur lors de la récupération des types de propriétés'); }); @@ -214,7 +253,7 @@ class Vegetable extends Component { .then((res) => { if (res.status === 200) { const item = res.data; - let images = []; + const images = []; if (item.description === null) { item.description = ' '; @@ -229,7 +268,7 @@ class Vegetable extends Component { this.setState(prevState => ({ ...prevState, Vegetable: item, - imagesPreviewUrls: images + imagesPreviewUrls: images, })); } }) @@ -241,7 +280,7 @@ class Vegetable extends Component { render() { return (
- +
@@ -306,18 +345,21 @@ class Vegetable extends Component { - - + {this.state.uploadPictures === this.state.uploadedPictures ? ( + + ) : (null)}
diff --git a/src/Vegetable/Carousel.js b/src/Vegetable/Carousel.js index 773a263..5152359 100644 --- a/src/Vegetable/Carousel.js +++ b/src/Vegetable/Carousel.js @@ -11,18 +11,25 @@ import { CarouselItem, CarouselControl, CarouselIndicators, + ListGroup, + ListGroupItem, + Button, } from 'reactstrap'; import { FaFileImage, + FaTrash, } from 'react-icons/fa'; +import '../Vegetable.css'; + class VegetableCarousel extends Component { constructor(props) { super(props); this.state = { imagesPreviewUrls: this.props.imagesPreviewUrls, - activeIndex: 0 + pictures: this.props.pictures, + activeIndex: 0, }; this.onPictureChange = this.onPictureChange.bind(this); @@ -34,14 +41,19 @@ class VegetableCarousel extends Component { } componentWillReceiveProps(nextProps) { - if ( nextProps.imagesPreviewUrls) { + if (nextProps.imagesPreviewUrls) { this.setState({ - imagesPreviewUrls: nextProps.imagesPreviewUrls + imagesPreviewUrls: nextProps.imagesPreviewUrls, }); } - if ( nextProps.activeIndex) { + if (nextProps.activeIndex) { this.setState({ - activeIndex: nextProps.activeIndex + activeIndex: nextProps.activeIndex, + }); + } + if (nextProps.pictures) { + this.setState({ + pictures: nextProps.pictures, }); } } @@ -110,35 +122,51 @@ class VegetableCarousel extends Component { id="Pictures" onChange={e => this.onPictureChange(e)} /> + + {this.state.pictures.map((item, key) => ( + + + {item.url} + + ))} + {this.state.imagesPreviewUrls && this.state.imagesPreviewUrls.length > 0 - ? ( + > - {this.state.imagesPreviewUrls.map( (item, key) => ( + {this.state.imagesPreviewUrls.map((item, key) => ( - Carousel - - ))} - - - ) + key={`Carousel_${key}`} + > + Carousel + + ))} + + + + ) : (null) - } - - - ) + } + + + ); } }