Skip to content

Commit

Permalink
Merge pull request #112 from openfoodfacts/delete-from-nutripatrol
Browse files Browse the repository at this point in the history
feat: Delete images from image tickets in nutripatrol
  • Loading branch information
raphael0202 authored Oct 23, 2024
2 parents 385ef6d + a996b8d commit d45492e
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 69 deletions.
1 change: 1 addition & 0 deletions .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ VITE_API_URL = "http://localhost:8000/api/v1"
# PO Url
# ------
VITE_PO_URL = "https://world.openfoodfacts.org"
VITE_PO_DELETE_IMAGES_URL = "https://world.openfoodfacts.localhost/cgi/product_image_move.pl"

# PO Url for images
# ------
Expand Down
1 change: 1 addition & 0 deletions .env.preprod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ VITE_API_URL = "https://nutripatrol.openfoodfacts.net/api/v1"
# PO Url
# ------
VITE_PO_URL = "https://world.openfoodfacts.net"
VITE_PO_DELETE_IMAGES_URL = "https://world.openfoodfacts.net/cgi/product_image_move.pl"

# PO Url for images
# ------
Expand Down
1 change: 1 addition & 0 deletions .env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ VITE_API_URL = "https://nutripatrol.openfoodfacts.org/api/v1"
# PO Url
# ------
VITE_PO_URL = "https://world.openfoodfacts.org"
VITE_PO_DELETE_IMAGES_URL = "https://world.openfoodfacts.org/cgi/product_image_move.pl"

# PO Url for images
# ------
Expand Down
87 changes: 87 additions & 0 deletions src/components/DeleteButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import Button from '@mui/material/Button';
import DeleteIcon from '@mui/icons-material/Delete';
import CheckIcon from '@mui/icons-material/Check';
import LoopIcon from '@mui/icons-material/Loop';
import { useState } from 'react';
import axios from 'axios';

interface DeleteButtonProps {
barcode: string;
imgids: string;
handleImageDeleted: () => void;
}

const DeleteButton = ({ barcode, imgids, handleImageDeleted }: DeleteButtonProps) => {

const [isConfirmed, setIsConfirmed] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const deleteUrl = `${import.meta.env.VITE_PO_DELETE_IMAGES_URL}?code=${barcode}&imgids=${imgids}&move_to_override=trash`

const handleDelete = () => {
if (!isConfirmed) {
setIsConfirmed(true)
} else {
setIsLoading(true)
const data = new URLSearchParams()
data.append('code', barcode)
data.append('imgids', imgids)
data.append('move_to_override', 'trash')
try {
axios.post(
deleteUrl,
data,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
withCredentials: true
}
)
.then(response => {
console.log(response)
setIsLoading(false)
handleImageDeleted()
})
} catch (err) {
console.error(err)
setIsLoading(false)
}
}
}

return (
<Button
aria-label="delete"
color={
isConfirmed ?
'info'
:
'error'
}
startIcon={
isLoading ?
<LoopIcon />
:
(isConfirmed ?
<CheckIcon />
:
<DeleteIcon />
)
}
onClick={handleDelete}
variant='contained'
>
{ isLoading ?
'Loading'
:
(isConfirmed ?
'Confirm'
:
'Delete'
)
}
</Button>
)
}

export default DeleteButton
102 changes: 33 additions & 69 deletions src/components/InfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import DeleteButton from './DeleteButton';

const style = {
position:'absolute',
Expand Down Expand Up @@ -45,13 +46,10 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
}
const handleTicketInfo = () => {
axios.get(`${import.meta.env.VITE_PO_URL}/api/v2/product/${barcode}.json`).then((res) => {
console.log(res.data.product);

const usedData: any = {
name: res.data.product.product_name || null,
barcode: res.data.code || null,
images: {},
selectedImages: [],
brands: res.data.product.brands || null,
editors_tags: res.data.product.editors_tags || null,
categories: [],
Expand All @@ -60,26 +58,14 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
// loop through the images and build the url
if (res.data.product.images) {
Object.keys(res.data.product.images).forEach((key) => {
// if the key is not a number do nothing
if (isNaN(parseInt(key))) {
usedData.images[key] = buildUrl(barcode, key, '100', res.data.product.images[key].rev);
return;
} else {
usedData.images[key] = buildUrl(barcode, key, '100');
}
});
}
// loop through the selected images and keep only the url
const selectedImages = res.data.product.selected_images;
if (selectedImages) {
for (const key in selectedImages) {
if (selectedImages[key].thumb ) {
for (const lang in selectedImages[key].thumb) {
if (selectedImages[key].thumb[lang]) {
usedData.selectedImages.push(selectedImages[key].thumb[lang]);
}
}
}
}
}
// loop through the ingredients and keep only the text
const ingredients = res.data.product.ingredients;
if (ingredients) {
Expand All @@ -105,6 +91,9 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
setIsLoaded(true);
})
}
const handleImageDeleted = () => {
handleTicketInfo();
};
const handleOpen = () => {
handleTicketInfo();
setOpen(true);
Expand Down Expand Up @@ -139,6 +128,33 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Barcode : {ticketInfo?.barcode}
</Typography>
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Images :
</Typography>
{ticketInfo?.images ? (
<Box sx={{ display: 'flex', gap: '20px', alignItems: 'center', justifyContent: 'center', mt:2}}>
<Grid container spacing={2}>
{Object.keys(ticketInfo.images).map((key) => (
<Grid key={key} sx={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
<img
src={ticketInfo.images[key]}
alt={key}
width={160}
height={160}
style={{objectFit: 'contain'}}
/>

<DeleteButton barcode={ticketInfo.barcode} imgids={key} handleImageDeleted={handleImageDeleted} />

</Grid>
))}
</Grid>
</Box>
) : (
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
No images found
</Typography>
)}
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Brands : {ticketInfo?.brands}
</Typography>
Expand All @@ -164,32 +180,6 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
</Typography>
)}
</Box>
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Selected Images :
</Typography>
{ticketInfo?.selectedImages ? (
<Box sx={{ display: 'flex', gap: '10px', alignItems: 'center', justifyContent: 'center', mt:2}}>
<Grid container spacing={2}>
{ticketInfo.selectedImages.map((image: string, index: number) => (
<Grid key={index}>
<a href={image} target='_blank' key={index}>
<img
src={image}
alt={index.toString()}
width={120}
height={120}
style={{objectFit: 'contain'}}
/>
</a>
</Grid>
))}
</Grid>
</Box>
) : (
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
No selected images found
</Typography>
)}
<Box sx={{ border: 'solid 1px black', p: 2 }}>
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Ingredients :
Expand All @@ -212,32 +202,6 @@ export default function ModalInfo({barcode}: ModalInfoProps) {
</Typography>
)}
</Box>
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
Images :
</Typography>
{ticketInfo?.images ? (
<Box sx={{ display: 'flex', gap: '10px', alignItems: 'center', justifyContent: 'center', mt:2}}>
<Grid container spacing={2}>
{Object.keys(ticketInfo.images).map((key) => (
<Grid key={key}>
<a href={ticketInfo.images[key]} target='_blank' key={key}>
<img
src={ticketInfo.images[key]}
alt={key}
width={120}
height={120}
style={{objectFit: 'contain'}}
/>
</a>
</Grid>
))}
</Grid>
</Box>
) : (
<Typography id="modal-modal-description" sx={{ mt: 2 }}>
No images found
</Typography>
)}
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
Expand Down

0 comments on commit d45492e

Please sign in to comment.