error-handling #1

Merged
stwhite merged 24 commits from error-handling into main 2024-10-30 15:19:49 +00:00
3 changed files with 96 additions and 64 deletions
Showing only changes of commit 88a90e39b7 - Show all commits

View File

@ -1,6 +1,6 @@
// src/components/Boxes.js // src/components/Boxes.js
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Container, Button, TextField, List, ListItem, ListItemText, IconButton } from '@mui/material'; import { Container, Button, TextField, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
import { Delete as DeleteIcon } from '@mui/icons-material'; import { Delete as DeleteIcon } from '@mui/icons-material';
import { Link as RouterLink } from 'react-router-dom'; // Import Link from react-router-dom import { Link as RouterLink } from 'react-router-dom'; // Import Link from react-router-dom
import axios from 'axios'; import axios from 'axios';
@ -51,6 +51,33 @@ export default function Boxes({ token }) {
return ( return (
<Container> <Container>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Box Name</TableCell>
<TableCell>Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{boxes.map((box) => (
<TableRow key={box.ID}>
<TableCell>
<RouterLink to={`/boxes/${box.ID}/items`} state={{ boxName: box.name, boxID: box.ID }}>
{box.name}
</RouterLink>
</TableCell>
<TableCell>
<Button onClick={() => handleDeleteBox(box.ID)} startIcon={<DeleteIcon />}>
Delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TextField <TextField
label="New Box" label="New Box"
variant="outlined" variant="outlined"
@ -61,23 +88,6 @@ export default function Boxes({ token }) {
<Button sx={{ backgroundColor: PRIMARY_COLOR, borderBottom: '1px solid', borderColor: '#444', color: SECONDARY_COLOR }} variant="contained" color="primary" onClick={handleCreateBox}> <Button sx={{ backgroundColor: PRIMARY_COLOR, borderBottom: '1px solid', borderColor: '#444', color: SECONDARY_COLOR }} variant="contained" color="primary" onClick={handleCreateBox}>
Add Box Add Box
</Button> </Button>
<List>
{boxes.map((box) => (
<ListItem key={box.ID} secondaryAction={
<IconButton edge="end" onClick={() => handleDeleteBox(box.ID)}>
<DeleteIcon />
</IconButton>
}>
<ListItemText
primary={
<RouterLink to={`/boxes/${box.ID}/items`} state={{ boxName: box.name, boxID: box.ID }}> {/* Use Link component */}
{box.name}
</RouterLink>
}
/>
</ListItem>
))}
</List>
</Container> </Container>
); );
} }

View File

@ -1,6 +1,6 @@
// src/components/ItemDetails.js // src/components/ItemDetails.js
import React, { useState, useEffect, useRef, useCallback } from 'react'; import React, { useState, useEffect, useRef, useCallback } from 'react';
import { TextField, Button, Container, Avatar } from '@mui/material'; import { TextField, Button, Container, Avatar, Tooltip } from '@mui/material';
import axios from 'axios'; import axios from 'axios';
import { PRIMARY_COLOR, SECONDARY_COLOR } from '../App'; import { PRIMARY_COLOR, SECONDARY_COLOR } from '../App';
//import { useNavigate } from 'react-router-dom'; // Import useNavigate //import { useNavigate } from 'react-router-dom'; // Import useNavigate
@ -195,13 +195,15 @@ export default function ItemDetails({ item, token, onSave, onClose, boxId }) {
<h3>Edit Item: {item.name}</h3> <h3>Edit Item: {item.name}</h3>
{/* Display the item image as an avatar */} {/* Display the item image as an avatar */}
<Avatar <Tooltip title="Click to enlarge">
src={imageSrc} <Avatar
alt={name} src={imageSrc}
onError={handleImageError} alt={name}
sx={{ width: 100, height: 100, marginBottom: '16px' }} // Style the Avatar onError={handleImageError}
onClick={handleAvatarClick} sx={{ width: 200, height: 200, marginBottom: '16px' }} // Style the Avatar
/> onClick={handleAvatarClick}
/>
</Tooltip>
{imageOverlayVisible && ( {imageOverlayVisible && (
<div className="image-overlay"> <div className="image-overlay">
<img src={imageSrc} alt={name} /> <img src={imageSrc} alt={name} />
@ -233,6 +235,7 @@ export default function ItemDetails({ item, token, onSave, onClose, boxId }) {
margin="normal" margin="normal"
value={imagePath} value={imagePath}
onChange={(e) => setImagePath(e.target.value)} onChange={(e) => setImagePath(e.target.value)}
sx={{ display: 'none' }}
/> />
<input <input
type="file" type="file"

View File

@ -14,7 +14,16 @@ import {
DialogTitle, DialogTitle,
DialogContent, DialogContent,
DialogActions, DialogActions,
TableContainer,
Table,
TableHead,
TableRow,
TableCell,
TableBody,
Box,
Tooltip
} from '@mui/material'; } from '@mui/material';
import { Delete as DeleteIcon, Edit as EditIcon } from '@mui/icons-material'; import { Delete as DeleteIcon, Edit as EditIcon } from '@mui/icons-material';
import axios from 'axios'; import axios from 'axios';
import { useParams, useLocation } from 'react-router-dom'; import { useParams, useLocation } from 'react-router-dom';
@ -377,44 +386,54 @@ export default function Items({ token }) {
boxId={boxId} boxId={boxId}
/> />
) : ( ) : (
<List> <TableContainer>
{items <Table>
.filter(item => <TableHead>
item.name.toLowerCase().includes(searchQuery.toLowerCase()) || <TableRow>
item.description.toLowerCase().includes(searchQuery.toLowerCase()) <TableCell style={{ width: '40px' }}>Image</TableCell>
) <TableCell style={{ width: '100px' }}>Name</TableCell>
.map((item) => ( <TableCell>Description</TableCell>
<ListItem key={item.ID} secondaryAction={ <TableCell>Actions</TableCell>
<> </TableRow>
<IconButton edge="end" onClick={() => handleEditItem(item)}> </TableHead>
<EditIcon /> <TableBody>
</IconButton> {items
<IconButton edge="end" sx={{ marginLeft: 4 }} onClick={() => handleDeleteItem(item.ID)}> .filter(item =>
<DeleteIcon /> item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
</IconButton> item.description.toLowerCase().includes(searchQuery.toLowerCase())
</> )
}> .map((item) => (
<ListItemAvatar> <TableRow key={item.ID}>
<Avatar <TableCell>
src={itemImages[item.ID]} <Avatar src={itemImages[item.ID] || '/images/default.jpg'} />
alt={item.name} </TableCell>
onError={handleImageError} <TableCell>{item.name}</TableCell>
/> <TableCell>{item.description}</TableCell>
</ListItemAvatar> <Box display="flex" justifyContent="space-between" width="100%">
<ListItemText <Tooltip title="Edit Item">
primary={item.name} <IconButton
secondary={ onClick={() => handleEditItem(item)}
<> size="large"
<Typography variant="body2">{item.description}</Typography> sx={{ mr: 1 }}
{item.image_path && ( >
<Typography variant="caption">Image: {item.image_path}</Typography> <EditIcon />
)} </IconButton>
</> </Tooltip>
} <Tooltip title="Delete Item">
/> <IconButton
</ListItem> onClick={() => handleDeleteItem(item.ID)}
))} size="large"
</List> color="error"
>
<DeleteIcon />
</IconButton>
</Tooltip>
</Box>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)} )}
</Container> </Container>
); );