diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d4d6caf..82bce23 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -93,6 +93,7 @@ const App: React.FC = () => { } /> + }> {/* ルートパスへのアクセスはタスク一覧にリダイレクト */} diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index eb3612f..4ac785b 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -22,6 +22,7 @@ import { Menu as MenuIcon, ListAlt as ListAltIcon, Inventory as InventoryIcon, // テストページ用のアイコン + Science as ScienceIcon, // 鈴木 } from '@mui/icons-material'; import { useNavigate, Outlet, useLocation } from 'react-router-dom'; @@ -100,6 +101,8 @@ const Layout: React.FC = () => { {/* テストページへのリンクを追加 */} + + {/* 在庫リストへのリンクを追加 */} handleNavigate('/stock')} selected={isSelected('/stock')} diff --git a/frontend/src/pages/StockPage.tsx b/frontend/src/pages/StockPage.tsx index 8de8bd9..1c8ee61 100644 --- a/frontend/src/pages/StockPage.tsx +++ b/frontend/src/pages/StockPage.tsx @@ -2,15 +2,315 @@ * テストページコンポーネント * 白紙の状態で表示されるテスト用のページ */ -import React from 'react'; -import { Box } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { stockApi } from '../services/api'; +import { Stock } from '../types/types'; +import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from "@mui/material"; +import { + Container, + Typography, + Tooltip, + Fab, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + TextField, + Button, + Box, + +} from '@mui/material'; +import { TASK_ERRORS } from '../constants/errorMessages'; +import CategoryDropDown from "../components/CategoryDropDown"; const StockPage: React.FC = () => { - return ( - - {/* 白紙のページ - 何も表示しない */} - - ); + + const [stocks, setStocks] = useState([]); + // 削除メッセージダイアログの表示状態 + const [open, setOpen] = useState(false); + + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + + // セル選択の表示状態 + const [selectedRow, setSelectedRow] = useState(null); + + // コンポーネントマウント時にタスク一覧を取得 + useEffect(() => { + fetchStocks(); + }, []); + + /** + * APIからタスク一覧を取得する関数 + * 取得したタスクをstate(tasks)に設定 + */ + const fetchStocks = async () => { + try { + const stocks = await stockApi.getStocks(); + setStocks(stocks.stock_array); + } catch (error) { + console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); + } + }; + + /** + * 文字列(ISO 8601形式)をyyyy/MM/ddに変換する関数 + */ + const formatDate = (isoString: string): string => { + const date = new Date(isoString); + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, "0"); // 月は0始まりなので+1 + const day = date.getDate().toString().padStart(2, "0"); + return `${year}/${month}/${day}`; + }; + /* Date型をyyyy/MM/ddに変換する関数 + const formatDate = (date: Date): string => { + const year = date.getFullYear(); + const month = (date.getMonth() + 1).toString().padStart(2, "0"); // 月は0始まりなので+1 + const day = date.getDate().toString().padStart(2, "0"); + return `${year}/${month}/${day}`; + }; + */ + + /** + * セルを選択する関数 + */ + const handleRowClick = (id: number) => { + setSelectedRow(prevSelected => (prevSelected === id ? null : id)); // クリックで選択・解除を切り替え + }; + + + return ( + + + 在庫一覧 + + + {/* タスク編集ボタン */} + + + {/* タスク削除ボタン */} + {/* */} + + + + 食材の削除 + + この操作は取り消せません。本当に削除しますか? + ⚠️ 注意: 削除すると復元できません。 + + + + + + 乳製品 + + {/* 乳製品一覧表示エリア - 青い背景のコンテナ */} +
+ + {/* 要素が無かったら表示しない */} + {stocks.filter(stock => stock.category === "乳製品").length === 0 ? null : ( + + + + + 食材名 + 数量 + 購入価格 + 賞味・消費期限 + 購入日 + + + + {stocks + .filter(stock => stock.category == "乳製品") // 乳製品だけ抽出 + .map(stock => ( + handleRowClick(stock.stock_id)} + style={{ backgroundColor: selectedRow === stock.stock_id ? "yellow" : "white", cursor: "pointer" }}> + {stock.stuff_name} + {stock.amount} + {stock.price} + {formatDate(stock.exp_date)} + {formatDate(stock.buy_date)} + + ))} + +
+
+ )} +
+ + + 肉・魚 + + {/* 肉・魚一覧表示エリア - 青い背景のコンテナ */} +
+ + {stocks.filter(stock => stock.category == "肉" || stock.category == "魚").length === 0 ? null : ( + + + + + 食材名 + 数量 + 購入価格 + 賞味・消費期限 + 購入日 + + + + {stocks + .filter(stock => stock.category == "肉" || stock.category == "魚") // 肉と魚だけ抽出 + .map(stock => ( + handleRowClick(stock.stock_id)} + style={{ backgroundColor: selectedRow === stock.stock_id ? "yellow" : "white", cursor: "pointer" }}> + {stock.stuff_name} + {stock.amount} + {stock.price} + {formatDate(stock.exp_date)} + {formatDate(stock.buy_date)} + + ))} + +
+
+ )} + +
+ + + 野菜 + + {/* 野菜一覧表示エリア - 青い背景のコンテナ */} +
+ {stocks.filter(stock => stock.category === "野菜").length === 0 ? null : ( + + + + + 食材名 + 数量 + 購入価格 + 賞味・消費期限 + 購入日 + + + + {stocks + .filter(stock => stock.category == "野菜") // 野菜だけ抽出 + .map(stock => ( + handleRowClick(stock.stock_id)} + style={{ backgroundColor: selectedRow === stock.stock_id ? "yellow" : "white", cursor: "pointer" }}> + {stock.stuff_name} + {stock.amount} + {stock.price} + {formatDate(stock.exp_date)} + {formatDate(stock.buy_date)} + + ))} + +
+
+ )} +
+ + + 調味料 + + {/* 調味料一覧表示エリア - 青い背景のコンテナ */} +
+ {stocks.filter(stock => stock.category === "調味料").length === 0 ? null : ( + + + + + 食材名 + 数量 + 購入価格 + 賞味・消費期限 + 購入日 + + + + {stocks + .filter(stock => stock.category == "調味料") // 調味料だけ抽出 + .map(stock => ( + handleRowClick(stock.stock_id)} + style={{ backgroundColor: selectedRow === stock.stock_id ? "yellow" : "white", cursor: "pointer" }}> + {stock.stuff_name} + {stock.amount} + {stock.price} + {formatDate(stock.exp_date)} + {formatDate(stock.buy_date)} + + ))} + +
+
+ )} +
+ + + その他 + + {/* その他一覧表示エリア - 青い背景のコンテナ */} +
+ {stocks.filter(stock => stock.category === "その他").length === 0 ? null : ( + + + + + 食材名 + 数量 + 購入価格 + 賞味・消費期限 + 購入日 + + + + {stocks + .filter(stock => stock.category == "その他") // その他だけ抽出 + .map(stock => ( + handleRowClick(stock.stock_id)} + style={{ backgroundColor: selectedRow === stock.stock_id ? "yellow" : "white", cursor: "pointer" }}> + {stock.stuff_name} + {stock.amount} + {stock.price} + {formatDate(stock.exp_date)} + {formatDate(stock.buy_date)} + + ))} + +
+
+ )} +
+
+ ); }; export default StockPage; \ No newline at end of file diff --git a/frontend/src/pages/TaskListPage.tsx b/frontend/src/pages/TaskListPage.tsx index e44bc7b..411b115 100644 --- a/frontend/src/pages/TaskListPage.tsx +++ b/frontend/src/pages/TaskListPage.tsx @@ -59,9 +59,8 @@ const TaskListPage: React.FC = () => { //在庫登録ダイアログの表示状態 const [openInfoDialog, setOpenInfoDialog] = useState(false); - - const [selectedTask, setSelectedTask] = useState(); - + + const [selectedTask, setSelectedTask] = useState(0); const [newToBuy, setNewToBuy] = useState(EMPTY_TASK); @@ -165,8 +164,8 @@ const TaskListPage: React.FC = () => { */} {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} { setOpenInfoDialog(true)} - //onClick={() => handleDeleteTask(task.id)} + onClick={() => { + setOpenInfoDialog(true) + setSelectedTask(tobuy.tobuy_id) + handleDeleteTask(tobuy.tobuy_id) + }} > @@ -265,7 +267,7 @@ const TaskListPage: React.FC = () => { - {!newToBuy.newAddition && + {!newToBuy.newAddition && 材料名(選択)