diff --git a/public/default.jpg b/public/default.jpg new file mode 100644 index 0000000..39873a8 Binary files /dev/null and b/public/default.jpg differ diff --git a/src/components/ItemDetails.js b/src/components/ItemDetails.js index 0c9b44b..fb7b99f 100644 --- a/src/components/ItemDetails.js +++ b/src/components/ItemDetails.js @@ -1,12 +1,55 @@ // src/components/ItemDetails.js -import React, { useState } from 'react'; -import { TextField, Button, Container } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { TextField, Button, Container, Avatar } from '@mui/material'; import axios from 'axios'; export default function ItemDetails({ item, token, onSave }) { const [name, setName] = useState(item.name); const [description, setDescription] = useState(item.description); const [imagePath, setImagePath] = useState(item.image_path || ''); + const [imageSrc, setImageSrc] = useState('/images/default.jpg'); // Initial default image + + useEffect(() => { + // Function to fetch image similar to getImageSrc in Items.js + const getImageSrc = (itemId) => { + return axios.get(`${process.env.REACT_APP_API_URL}/items/${itemId}/image`, { + headers: { Authorization: `Bearer ${token}` }, + responseType: 'blob' + }) + .then(response => { + if (response.status === 200) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(response.data); + }); + } else { + throw new Error('Image fetch failed'); + } + }) + .catch(() => { + // Return the data URL of the default image if image fetch fails + return new Promise((resolve, reject) => { + const img = new Image(); + img.src = '/default.jpg'; + img.onload = () => { + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + const dataURL = canvas.toDataURL(); + resolve(dataURL); + }; + img.onerror = reject; + }); + }); + }; + + // Fetch the image when the component mounts or the item changes + getImageSrc(item.ID).then(dataUrl => setImageSrc(dataUrl)); + }, [item.ID, token]); const handleSave = () => { axios.put(`${process.env.REACT_APP_API_URL}/items/${item.ID}`, @@ -19,9 +62,22 @@ export default function ItemDetails({ item, token, onSave }) { }); }; + const handleImageError = (e) => { + e.target.src = '/images/default.jpg'; // Fallback to default image on error + }; + return (

Edit Item: {item.name}

+ + {/* Display the item image as an avatar */} + + { + if (e.target.src.startsWith('data:image/')) { + console.error("Default image failed to load. Check the file path."); + return; + } + const reader = new FileReader(); + reader.onload = () => { + e.target.onerror = null; + e.target.src = reader.result; + }; + fetch('/default.jpg') + .then(res => res.blob()) + .then(blob => reader.readAsDataURL(blob)) + .catch(error => console.error("Error loading default image:", error)); + }; + + const getImageSrc = (itemId) => { + return axios.get(`${process.env.REACT_APP_API_URL}/items/${itemId}/image`, { + headers: { Authorization: `Bearer ${token}` }, + responseType: 'blob' + }) + .then(response => { + if (response.status === 200) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(response.data); + }); + } else { + throw new Error('Image fetch failed'); + } + }) + .catch(() => { + return new Promise((resolve, reject) => { + const img = new Image(); + img.src = '/default.jpg'; + img.onload = () => { + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + resolve(canvas.toDataURL()); + }; + img.onerror = reject; + }); + }); + }; const fetchItems = useCallback(() => { axios.get(`${process.env.REACT_APP_API_URL}/boxes/${boxId}/items`, { headers: { Authorization: `Bearer ${token}` } }).then(response => { setItems(response.data); + + // Fetch images for each item + response.data.forEach(item => { + getImageSrc(item.ID).then(imageDataUrl => { + setItemImages(prevItemImages => ({ + ...prevItemImages, + [item.ID]: imageDataUrl + })); + }); + }); }); }, [boxId, token]); @@ -66,19 +126,18 @@ export default function Items({ token }) { }; const handleEditItem = (item) => { - setEditingItem(item); // Set the item to be edited + setEditingItem(item); }; const handleSaveEdit = () => { - setEditingItem(null); // Clear the editing state after saving - fetchItems(); // Refresh the list after edit + setEditingItem(null); + fetchItems(); }; return (

Items in Box: {boxName}

- {/* Add Item Form */} - {/* Conditionally render the ItemDetails component if editingItem is not null */} {editingItem ? ( ) : ( @@ -123,13 +181,13 @@ export default function Items({ token }) { }> - - - + + +