Successful image upload now

This commit is contained in:
Steve White 2024-10-10 21:17:21 -05:00
parent 3a54c5da58
commit 0fbc5721b9
2 changed files with 95 additions and 23 deletions

View File

@ -1,5 +1,5 @@
// src/components/ItemDetails.js
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { TextField, Button, Container, Avatar } from '@mui/material';
import axios from 'axios';
@ -8,6 +8,7 @@ export default function ItemDetails({ item, token, onSave }) {
const [description, setDescription] = useState(item.description);
const [imagePath, setImagePath] = useState(item.image_path || '');
const [imageSrc, setImageSrc] = useState('/images/default.jpg'); // Initial default image
const fileInputRef = useRef(null); // Add this line to define fileInputRef
useEffect(() => {
// Function to fetch image similar to getImageSrc in Items.js
@ -51,15 +52,44 @@ export default function ItemDetails({ item, token, onSave }) {
getImageSrc(item.ID).then(dataUrl => setImageSrc(dataUrl));
}, [item.ID, token]);
const handleSave = () => {
axios.put(`${process.env.REACT_APP_API_URL}/items/${item.ID}`,
{ name, description, image_path: imagePath },
const handleImageUpload = async () => {
const formData = new FormData();
formData.append('image', fileInputRef.current.files[0]);
try {
await axios.post(`${process.env.REACT_APP_API_URL}/items/${item.ID}/upload`, formData, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/form-data'
}
});
// Handle successful upload (e.g., show a success message)
console.log('Image uploaded successfully!');
} catch (error) {
// Handle upload error (e.g., show an error message)
console.error('Image upload failed:', error);
}
};
const handleSave = async () => {
// 1. Handle image upload first if a new image is selected
if (fileInputRef.current.files[0]) {
await handleImageUpload();
}
// 2. Update item details (name, description, etc.)
try {
await axios.put(`${process.env.REACT_APP_API_URL}/items/${item.ID}`,
{ name, description, image_path: imagePath }, // You might remove image_path here
{
headers: { Authorization: `Bearer ${token}` }
}
).then(() => {
);
onSave(); // Notify parent to refresh items
});
} catch (error) {
// Handle update error
console.error('Item update failed:', error);
}
};
const handleImageError = (e) => {
@ -102,6 +132,27 @@ export default function ItemDetails({ item, token, onSave }) {
value={imagePath}
onChange={(e) => setImagePath(e.target.value)}
/>
<input
type="file"
accept="image/*"
ref={fileInputRef}
style={{ display: 'none' }}
id="editItemImageUpload" // Unique ID
/>
<Button variant="contained" component="label" htmlFor="editItemImageUpload">
Upload Image
<input
type="file"
accept="image/*"
id="image-upload"
style={{ display: 'none' }}
onChange={(e) => {
// You can handle image preview here if needed
setImagePath(e.target.files[0].name);
}}
/>
</Button>
<Button variant="contained" color="primary" onClick={handleSave}>
Save Changes
</Button>

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState, useCallback } from 'react';
import React, { useEffect, useState, useCallback, useRef } from 'react';
import {
Container,
List,
@ -26,6 +26,7 @@ export default function Items({ token }) {
const location = useLocation();
const boxName = location.state?.boxName || 'Unknown Box';
const [itemImages, setItemImages] = useState({});
const fileInputRef = useRef(null);
const handleImageError = (e) => {
if (e.target.src.startsWith('data:image/')) {
@ -43,7 +44,7 @@ export default function Items({ token }) {
.catch(error => console.error("Error loading default image:", error));
};
const getImageSrc = (itemId) => {
const getImageSrc = useCallback((itemId) => {
return axios.get(`${process.env.REACT_APP_API_URL}/items/${itemId}/image`, {
headers: { Authorization: `Bearer ${token}` },
responseType: 'blob'
@ -75,7 +76,7 @@ export default function Items({ token }) {
img.onerror = reject;
});
});
};
}, [token]);
const fetchItems = useCallback(() => {
axios.get(`${process.env.REACT_APP_API_URL}/boxes/${boxId}/items`, {
@ -93,26 +94,35 @@ export default function Items({ token }) {
});
});
});
}, [boxId, token]);
}, [boxId, token, getImageSrc]);
useEffect(() => {
fetchItems();
}, [boxId, token, fetchItems]);
const handleAddItem = () => {
axios.post(`${process.env.REACT_APP_API_URL}/items`,
{
name: newItemName,
description: newItemDescription,
box_id: parseInt(boxId, 10),
},
{
headers: { Authorization: `Bearer ${token}` }
const formData = new FormData();
formData.append('name', newItemName);
formData.append('description', newItemDescription);
formData.append('box_id', parseInt(boxId, 10));
// Append image only if a new one is selected
if (fileInputRef.current.files[0]) {
formData.append('image', fileInputRef.current.files[0]);
}
).then(() => {
axios.post(`${process.env.REACT_APP_API_URL}/items`, formData, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/form-data' // Important for file uploads
}
}).then(() => {
setNewItemName('');
setNewItemDescription('');
setNewItemImagePath('');
// Clear the file input
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
fetchItems();
});
};
@ -160,8 +170,19 @@ export default function Items({ token }) {
fullWidth
margin="normal"
value={newItemImagePath}
onChange={(e) => setNewItemImagePath(e.target.value)}
onChange={(e) => setNewItemImagePath(e.target.files[0].name)}
/>
<input
type="file"
accept="image/*"
ref={fileInputRef}
style={{ display: 'none' }}
id="newItemImageUpload" // Unique ID
/>
<Button variant="contained" component="label" htmlFor="newItemImageUpload">
Upload Image
{/* ... rest of your button code ... */}
</Button>
<Button variant="contained" color="primary" onClick={handleAddItem}>
Add Item
</Button>