parent
7c7677e469
commit
1b7ce68438
@ -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…
Reference in new issue