入力した料理に必要な材料を入力し、追加ボタンを押すことで画面にその内容が表示されるよう修正

dev-frontend-add_dishes
masato.fujita 5 months ago
parent 411327ec40
commit fbc186bcc0
  1. 8
      frontend/src/pages/AddDishes1.tsx
  2. 257
      frontend/src/pages/AddDishes2.tsx

@ -36,11 +36,12 @@ const AddDishes1: React.FC = () => {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); // フォームのデフォルト送信動作を防止
if (!dish.trim()) {
alert("エラー");
setError(true);
} else {
alert("送信成功!");
localStorage.setItem("dishName", dish);
navigate('/add2', { state: dish }); // タスク一覧ページにリダイレクト
localStorage.setItem("dishName", dish); // ローカルストレージにフォームに入力された料理名を保存
navigate('/add2', { state: dish }); // 料理名から材料名追加ページにリダイレクト
}
};
@ -55,7 +56,6 @@ const AddDishes1: React.FC = () => {
required
// id="username"
label="追加・編集したい料理名を入力"
placeholder='ここに料理名を入力'
variant="outlined"
InputLabelProps={{ style: { fontSize: "40px" }}}
style={{width: "80%" }}
@ -71,7 +71,7 @@ const AddDishes1: React.FC = () => {
</div>
<div style={{position: "fixed", left: "75%", transform: 'translateX(-50%)', bottom: "10px"}}>
<Button type="submit" variant='contained' sx={{ width: "250px", height: "60px", fontSize: "40px" }} color="primary" >
{dish}
</Button>
</div>
</Box>

@ -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>
);
};

Loading…
Cancel
Save