|
|
|
@ -2,36 +2,253 @@ |
|
|
|
|
* テストページコンポーネント |
|
|
|
|
* 白紙の状態で表示されるテスト用のページ |
|
|
|
|
*/ |
|
|
|
|
import React from 'react'; |
|
|
|
|
import { useLocation } from "react-router-dom"; |
|
|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
|
import { taskApi } from '../services/api'; |
|
|
|
|
import {
|
|
|
|
|
AppBar,
|
|
|
|
|
Toolbar,
|
|
|
|
|
Typography,
|
|
|
|
|
Container,
|
|
|
|
|
Box,
|
|
|
|
|
Button,
|
|
|
|
|
Drawer, |
|
|
|
|
Container, |
|
|
|
|
Typography, |
|
|
|
|
Tooltip, |
|
|
|
|
List, |
|
|
|
|
ListItem, |
|
|
|
|
ListItemText, |
|
|
|
|
ListItemIcon, |
|
|
|
|
ListItemButton, |
|
|
|
|
Divider, |
|
|
|
|
ListItemSecondaryAction, |
|
|
|
|
IconButton, |
|
|
|
|
Checkbox, |
|
|
|
|
Fab, |
|
|
|
|
Dialog, |
|
|
|
|
DialogTitle, |
|
|
|
|
DialogContent, |
|
|
|
|
DialogActions, |
|
|
|
|
TextField, |
|
|
|
|
Paper, |
|
|
|
|
Alert, |
|
|
|
|
Link, |
|
|
|
|
Grid, |
|
|
|
|
Button, |
|
|
|
|
Box, |
|
|
|
|
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 } from '../types/types'; |
|
|
|
|
import { TASK_ERRORS } from '../constants/errorMessages'; |
|
|
|
|
import { GENERAL_ERRORS } from '../constants/errorMessages'; |
|
|
|
|
import CategoryDropDown from "../components/CategoryDropDown"; |
|
|
|
|
|
|
|
|
|
// 新規タスクの初期状態
|
|
|
|
|
const EMPTY_TASK = { title: '', amount: 0, completed: false }; |
|
|
|
|
|
|
|
|
|
interface Empty_Task { |
|
|
|
|
title: string; // 食材名
|
|
|
|
|
amount: number; // 食材の個数
|
|
|
|
|
completed: boolean; //
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const AddDishes2: React.FC = () => { |
|
|
|
|
const receivedData = localStorage.getItem("dishName"); |
|
|
|
|
// タスク一覧の状態管理
|
|
|
|
|
const [tasks, setTasks] = useState<Task[]>([]); |
|
|
|
|
const [addtasks, setAddTasks] = useState<Empty_Task[]>([]); |
|
|
|
|
// エラーメッセージの状態管理
|
|
|
|
|
const [error, setError] = useState(false); |
|
|
|
|
// 新規タスク作成ダイアログの表示状態
|
|
|
|
|
const [openDialog, setOpenDialog] = useState(false); |
|
|
|
|
// 新規タスクの入力内容
|
|
|
|
|
const [newTask, setNewTask] = useState(EMPTY_TASK); |
|
|
|
|
|
|
|
|
|
// const fetchTasks = async () => {
|
|
|
|
|
// try {
|
|
|
|
|
// const tasks = await taskApi.getTasks();
|
|
|
|
|
// setTasks(tasks);
|
|
|
|
|
// } catch (error) {
|
|
|
|
|
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
|
|
|
|
|
// }
|
|
|
|
|
// };
|
|
|
|
|
|
|
|
|
|
// コンポーネントマウント時にタスク一覧を取得
|
|
|
|
|
// useEffect(() => {
|
|
|
|
|
// fetchTasks();
|
|
|
|
|
// }, []);
|
|
|
|
|
/** |
|
|
|
|
* タスクを削除するハンドラー |
|
|
|
|
* 指定されたIDのタスクをAPIを通じて削除 |
|
|
|
|
*/ |
|
|
|
|
const handleDeleteTask = async (index: number) => { |
|
|
|
|
try { |
|
|
|
|
let newAddTasks = [...addtasks]; // 配列をコピー
|
|
|
|
|
newAddTasks.splice(index, 1); |
|
|
|
|
setAddTasks(newAddTasks); |
|
|
|
|
// fetchTasks(); // 削除後のタスク一覧を再取得
|
|
|
|
|
} catch (error) { |
|
|
|
|
console.error(`${TASK_ERRORS.DELETE_FAILED}:`, error); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 新規タスクを作成するハンドラー |
|
|
|
|
* 入力されたタスク情報をAPIに送信して新規作成 |
|
|
|
|
* 作成後はダイアログを閉じ、入力内容をリセット |
|
|
|
|
*/ |
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => { |
|
|
|
|
e.preventDefault(); // フォームのデフォルト送信動作を防止
|
|
|
|
|
if (addtasks[0] == null) { |
|
|
|
|
setError(true); |
|
|
|
|
alert("食材を追加してください") |
|
|
|
|
} else { |
|
|
|
|
alert("送信成功!"); |
|
|
|
|
// localStorage.setItem("dishName", dish); // ローカルストレージにフォームに入力された料理名を保存
|
|
|
|
|
// navigate('/add2', { state: dish }); // 料理名から材料名追加ページにリダイレクト
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
const handleCreateTask = async () => { |
|
|
|
|
try { |
|
|
|
|
// await taskApi.createTask(newTask);
|
|
|
|
|
let newAddTasks = [...addtasks]; // 配列をコピー
|
|
|
|
|
newAddTasks.push(newTask); |
|
|
|
|
setAddTasks(newAddTasks); |
|
|
|
|
setOpenDialog(false); // ダイアログを閉じる
|
|
|
|
|
setNewTask(EMPTY_TASK); // 入力内容をリセット
|
|
|
|
|
// fetchTasks(); // 作成後のタスク一覧を再取得
|
|
|
|
|
} catch (error) { |
|
|
|
|
console.error(`${TASK_ERRORS.CREATE_FAILED}:`, error); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
return ( |
|
|
|
|
<div> |
|
|
|
|
<h1>追加する料理名</h1> |
|
|
|
|
<p style={{fontSize: "40px"}}>{receivedData}</p> |
|
|
|
|
</div> |
|
|
|
|
<Box> |
|
|
|
|
<div> |
|
|
|
|
<h1>追加する料理名</h1> |
|
|
|
|
<p style={{fontSize: "40px"}}>{receivedData}</p> |
|
|
|
|
</div> |
|
|
|
|
<List> |
|
|
|
|
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} |
|
|
|
|
{addtasks.map((task, index) => ( |
|
|
|
|
<ListItem |
|
|
|
|
key={index} |
|
|
|
|
sx={{ |
|
|
|
|
bgcolor: 'background.paper', |
|
|
|
|
mb: 1, |
|
|
|
|
borderRadius: 1, |
|
|
|
|
boxShadow: 1, |
|
|
|
|
}} |
|
|
|
|
> |
|
|
|
|
{/* タスク完了状態を切り替えるチェックボックス |
|
|
|
|
<Checkbox |
|
|
|
|
checked={task.completed} |
|
|
|
|
onChange={() => handleToggleComplete(task.id)} |
|
|
|
|
/> */} |
|
|
|
|
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} |
|
|
|
|
<ListItemText |
|
|
|
|
primary={task.title} |
|
|
|
|
// secondary={task.description}
|
|
|
|
|
sx={{ |
|
|
|
|
textDecoration: task.completed ? 'line-through' : 'none', |
|
|
|
|
}} |
|
|
|
|
/> |
|
|
|
|
{/* 食材の個数を表示 */} |
|
|
|
|
<ListItemText |
|
|
|
|
primary={<Typography style={{textAlign:"center"}}>個数<br /> |
|
|
|
|
{task.amount} |
|
|
|
|
</Typography> |
|
|
|
|
} |
|
|
|
|
// secondary={task.description}
|
|
|
|
|
primaryTypographyProps={{ align: "right", marginRight: "20%", 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={() => handleDeleteTask(index)} |
|
|
|
|
> |
|
|
|
|
<DeleteIcon /> |
|
|
|
|
</IconButton> |
|
|
|
|
</Tooltip> |
|
|
|
|
</ListItemSecondaryAction> |
|
|
|
|
|
|
|
|
|
</ListItem> |
|
|
|
|
))} |
|
|
|
|
</List> |
|
|
|
|
<div style={{position: "fixed", left: "75%", transform: 'translateX(-50%)', bottom: "20%"}}> |
|
|
|
|
<Button variant='contained' sx={{ width: "250px", height: "60px", fontSize: "40px" }}
|
|
|
|
|
color="primary" onClick={() => setOpenDialog(true)}> |
|
|
|
|
食材の追加 |
|
|
|
|
</Button> |
|
|
|
|
</div> |
|
|
|
|
<div style={{position: "fixed", width: "60%", left: "50%", transform: 'translateX(-50%)', bottom: "2%"}}> |
|
|
|
|
<Button variant='contained' sx={{ width: "100%", height: "100px", fontSize: "40px" }}
|
|
|
|
|
color="primary" onClick={handleSubmit}> |
|
|
|
|
料理リストへ追加 |
|
|
|
|
</Button> |
|
|
|
|
</div> |
|
|
|
|
{/* 新規タスク作成ダイアログ */} |
|
|
|
|
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true}> |
|
|
|
|
<DialogTitle>材料の追加</DialogTitle> |
|
|
|
|
<DialogContent> |
|
|
|
|
<Box sx={{ pt: 1 }}> |
|
|
|
|
{/*材料カテゴリ選択 */} |
|
|
|
|
<CategoryDropDown></CategoryDropDown> |
|
|
|
|
{/* タスクタイトル入力フィールド */} |
|
|
|
|
<TextField |
|
|
|
|
autoFocus |
|
|
|
|
margin="dense" |
|
|
|
|
label="材料名" |
|
|
|
|
fullWidth |
|
|
|
|
value={newTask.title} |
|
|
|
|
onChange={(e) => setNewTask({ ...newTask, title: e.target.value })} |
|
|
|
|
sx={{ marginBottom: 2 }} |
|
|
|
|
/> |
|
|
|
|
{/* 数量入力フィールド */} |
|
|
|
|
<TextField |
|
|
|
|
margin="dense" |
|
|
|
|
label="数量" |
|
|
|
|
fullWidth |
|
|
|
|
value={newTask.amount} |
|
|
|
|
onChange={(e) => { |
|
|
|
|
const value = e.target.value; |
|
|
|
|
const parsedValue = parseInt(value, 10); // 数値に変換
|
|
|
|
|
if (!isNaN(parsedValue)) { |
|
|
|
|
setNewTask({ ...newTask, amount: parsedValue }); // number型で保存
|
|
|
|
|
} |
|
|
|
|
}} |
|
|
|
|
sx={{ width: "20%" }} |
|
|
|
|
type="number" |
|
|
|
|
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可
|
|
|
|
|
/> |
|
|
|
|
</Box> |
|
|
|
|
</DialogContent> |
|
|
|
|
<DialogActions> |
|
|
|
|
<Button onClick={() => setOpenDialog(false)}>キャンセル</Button> |
|
|
|
|
<Button onClick={handleCreateTask} variant="contained"> |
|
|
|
|
追加 |
|
|
|
|
</Button> |
|
|
|
|
</DialogActions> |
|
|
|
|
</Dialog> |
|
|
|
|
</Box> |
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|