料理リスト編集機能(仮)の実装の実装

feature_frontend_dishlist
masato.fujita 4 months ago
parent 7c7677e469
commit 1b7ce68438
  1. 12
      frontend/src/App.tsx
  2. 7
      frontend/src/components/Layout.tsx
  3. 459
      frontend/src/pages/DishList.tsx

@ -14,7 +14,7 @@ import './App.css';
// 必要なインポートを追加
import AddDishes1 from './pages/AddDishes1';
import AddDishes2 from './pages/AddDishes2';
import DishList from './pages/DishList';
/**
* Material UIテーマを定義
*
@ -96,7 +96,15 @@ const App: React.FC = () => {
</PrivateRoute>
}
/>
{/* テストページへのルートを追加 */}
<Route
path="dishList"
element={
<PrivateRoute>
<DishList/>
</PrivateRoute>
}
/>
{/* テストページへのルートを追加 */}
<Route
path="add1"

@ -117,6 +117,13 @@ const Layout: React.FC = () => {
<ListItemIcon><InventoryIcon /></ListItemIcon>
<ListItemText primary="在庫管理" />
</ListItemButton>
<ListItemButton
onClick={() => handleNavigate('/dishList')}
selected={isSelected('/dishList')}
>
<ListItemIcon><ScienceIcon /></ListItemIcon>
<ListItemText primary="料理リスト" />
</ListItemButton>
<Divider />
</List>
</Box>

@ -0,0 +1,459 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { taskApi, toBuyApi } from '../services/api';
import {
Container,
Typography,
Tooltip,
List,
ListItem,
ListItemText,
ListItemSecondaryAction,
IconButton,
Checkbox,
Fab,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
Button,
Box,
FormControlLabel,
FormGroup,
MenuItem,
Select,
FormControl,
InputLabel
} from '@mui/material';
import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
SoupKitchen as SoupKitchenIcon
} from '@mui/icons-material';
import { Task, ToBuy, Stuff } from '../types/types';
import { TASK_ERRORS } from '../constants/errorMessages';
import { GENERAL_ERRORS } from '../constants/errorMessages';
import CategoryDropDown from "../components/CategoryDropDown";
const DishList: React.FC = () => {
const navigate = useNavigate();
// 料理リストの料理名を格納する配列
// const dishes = ;
// タスク一覧の状態管理
const [tobuys, setToBuys] = useState<ToBuy[]>([]);
const test = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1];
// APIができるまでのテスト用の型
interface Dish {
id:number,
name:string,
amount:number
}
// APIができるまでの食材配列
const testdish : Dish[] = [
{ id: 1, name: 'ジャガイモ', amount:1 },
{ id: 2, name: '人参', amount:2 },
{ id: 3, name: '人参', amount:2 },
{ id: 4, name: '人参', amount:2 }
];
// タスク一覧の状態管理
const [tasks, setTasks] = useState<Task[]>([]);
// 画面表示用の食材情報配列
const [testDishArray, setTestDishArray] = useState<Dish[]>(testdish);
// エラーメッセージの状態管理
const [error, setError] = useState(false);
// 選択した料理の情報を表示するダイアログの表示状態
const [openDialog, setOpenDialog] = useState(false);
// 料理リスト編集ダイアログの表示状態
const [openChangeDialog, setOpenChangeDialog] = useState(false);
// 料理リストの食材の個数編集ダイアログの表示状態
const [openChangeItemDialog, setOpenChangeItemDialog] = useState(false);
const changeDialog = () => {
setOpenDialog(false);
setOpenChangeDialog(true);
setTestDishArray(testdish);
};
const cancelChange = () => {
setOpenDialog(true);
setOpenChangeDialog(false);
};
/**
*
* IDのタスクをAPIを通じて削除
*/
const handleDeleteStuffTemp = async (dish_id: number) => {
try {
let testDishArrayCopy = [...testDishArray]; // 配列をコピー
testDishArrayCopy.splice(dish_id, 1);
setTestDishArray(testDishArrayCopy);
// fetchTasks(); // 削除後のタスク一覧を再取得
} catch (error) {
console.error(`${TASK_ERRORS.DELETE_FAILED}:`, error);
}
};
// コンポーネントマウント時にタスク一覧を取得
useEffect(() => {
fetchTasks();
}, []);
/**
* APIからタスク一覧を取得する関数
* state(tasks)
*/
// const fetchTasks = async () => {
// try {
// const tasks = await taskApi.getTasks();
// setTasks(tasks);
// } catch (error) {
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
// }
// };
const fetchTasks = async () => {
try {
const tobuys = await toBuyApi.getToBuys();
setToBuys(tobuys.tobuy_array);
} catch (error) {
console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
}
};
return (
<Container>
<Box>
<div>
<h1 style={{fontSize: "40px", textAlign: "center"}}></h1>
</div>
<div style = {{border: '3px solid black', borderRadius: '8px', height: '500px',
overflowY: 'auto', padding: '20px'}}>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{test.map((test, index) => (
<FormGroup>
<Button
// <ListItem
key={index}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
fontSize: '40px'
}}
onClick={() => setOpenDialog(true)}
>
{test}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
{/* <ListItemText
primary={test}
//secondary={tobuy.amount}
sx={{
textDecoration: false ? 'line-through' : 'none',
}}
/> */}
</Button>
</FormGroup>
// </ListItem>
))}
{/* </List> */}
</div>
<div style={{width: "100%", position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "20px"}}>
<Button variant='contained' sx={{width: "60%", height: "60px",
fontSize: "40px", left: "50%", transform: 'translateX(-50%)' }}
color="primary"
onClick={() => navigate('/add1')}
>
</Button>
</div>
{/*新規料理追加ボタン - 画面下部に固定表示 */}
<Tooltip title="料理から追加">
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 106, left: '60%', transform: 'translateX(-50%)' }}
onClick={() => setOpenDialog(true)}
>
<SoupKitchenIcon />
</Fab>
</Tooltip>
</Box>
{/* 新規タスク作成ダイアログ */}
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{test.map((test, index) => (
<Button onClick={() => setOpenDialog(true)} key = {index}>
{test}
</Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => setOpenDialog(false)}></Button>
<Button onClick={() => changeDialog()} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
{/* 食材の個数の編集ダイアログ */}
<Dialog open={openChangeDialog} onClose={() => setOpenChangeDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{testDishArray.map((test, id) => (
<ListItem
key={id}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
{/*
<Checkbox
checked={task.completed}
onChange={() => handleToggleComplete(task.id)}
/> */}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
<ListItemText
primary={test.name}
// secondary={task.description}
sx={{width: '80%'}}
/>
{/* 食材の個数を表示 */}
<ListItemText
primary={<Typography style={{textAlign:"center"}}><br />
{test.amount}
</Typography>
}
// secondary={task.description}
sx={{ align: "right", fontSize: "20px" }}
/>
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Tooltip title="食材情報追加">
<IconButton
edge="end"
aria-label="食材情報追加"
//onClick={() => handleDeleteTask(task.id)}
>
<ShoppingBasketIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: {
sx: {
backgroundColor: "white",
color: "red",
fontSize: "0.8rem",
padding: "6px",
borderRadius: "6px",
},
},
}}
>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteStuffTemp(id)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
// <Button onClick={() => setOpenDialog(true)} key = {index}>
// {test}
// </Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => cancelChange()}></Button>
<Button onClick={() => setOpenDialog(false)} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
{/* 食材編集ダイアログ */}
<Dialog open={openChangeDialog} onClose={() => setOpenChangeDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{testDishArray.map((test, id) => (
<ListItem
key={id}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
{/*
<Checkbox
checked={task.completed}
onChange={() => handleToggleComplete(task.id)}
/> */}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
<ListItemText
primary={test.name}
// secondary={task.description}
sx={{width: '80%'}}
/>
{/* 食材の個数を表示 */}
<ListItemText
primary={<Typography style={{textAlign:"center"}}><br />
{test.amount}
</Typography>
}
// secondary={task.description}
sx={{ align: "right", fontSize: "20px" }}
/>
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Tooltip title="食材情報追加">
<IconButton
edge="end"
aria-label="食材情報追加"
//onClick={() => handleDeleteTask(task.id)}
>
<ShoppingBasketIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: {
sx: {
backgroundColor: "white",
color: "red",
fontSize: "0.8rem",
padding: "6px",
borderRadius: "6px",
},
},
}}
>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteStuffTemp(id)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
// <Button onClick={() => setOpenDialog(true)} key = {index}>
// {test}
// </Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => cancelChange()}></Button>
<Button onClick={() => setOpenDialog(false)} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
</Container>
);
};
export default DishList;
Loading…
Cancel
Save