diff --git a/frontend/public/index.html b/frontend/public/index.html index ed1fb15..8793c25 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -23,7 +23,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + shopchop diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index c4a8739..78c0a7b 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -74,7 +74,7 @@ const Layout: React.FC = () => { - ToDoアプリ + shopchop + + + )} + + + + {/* タスク削除ダイアログ */} + + 食材の削除 + + {selectedRow && ( + <> + この操作は取り消せません。本当に削除しますか? + ⚠️ 注意: 削除すると復元できません。 + + {/* */} + + + )} + + + + + + ); }; @@ -87,227 +210,44 @@ const StockPage: React.FC = () => { 在庫一覧 - {/* タスク編集ボタン */} - {/* タスク削除ボタン */} - {/* */} + - - - 食材の削除 - - この操作は取り消せません。本当に削除しますか? - ⚠️ 注意: 削除すると復元できません。 - - - - - 乳製品 - - {/* 乳製品一覧表示エリア - 青い背景のコンテナ */} + {/* 在庫一覧リスト */} + {/* 乳製品 */} + 乳製品
- - {/* 要素が無かったら表示しない */} - {stocks.filter(stock => stock.category === "乳製品").length === 0 ? null : ( - - - - - 食材名 - 数量 - 購入価格 - 賞味・消費期限 - 購入日 - - - - {stocks - .filter(stock => stock.category == "乳製品") // 乳製品だけ抽出 - .map(stock => ( - handleRowClick(stock.stockId)} - style={{ backgroundColor: selectedRow === stock.stockId ? "yellow" : "white", cursor: "pointer" }}> - {stock.stuffName} - {stock.amount} - {stock.price} - {formatDate(stock.expDate)} - {formatDate(stock.buyDate)} - - ))} - -
-
- )} + {StockTable(stocks, ["乳製品"])}
- - 魚・肉 - - {/* 魚・肉一覧表示エリア - 青い背景のコンテナ */} + {/* 肉・魚 */} + 魚・肉
- - {stocks.filter(stock => stock.category == "魚・肉").length === 0 ? null : ( - - - - - 食材名 - 数量 - 購入価格 - 賞味・消費期限 - 購入日 - - - - {stocks - .filter(stock => stock.category == "魚・肉") // 「魚・肉」だけ抽出 - .map(stock => ( - handleRowClick(stock.stockId)} - style={{ backgroundColor: selectedRow === stock.stockId ? "yellow" : "white", cursor: "pointer" }}> - {stock.stuffName} - {stock.amount} - {stock.price} - {formatDate(stock.expDate)} - {formatDate(stock.buyDate)} - - ))} - -
-
- )} - + {StockTable(stocks, ["魚・肉"])}
- - 野菜 - - {/* 野菜一覧表示エリア - 青い背景のコンテナ */} + {/* 野菜 */} + 野菜
- {stocks.filter(stock => stock.category === "野菜").length === 0 ? null : ( - - - - - 食材名 - 数量 - 購入価格 - 賞味・消費期限 - 購入日 - - - - {stocks - .filter(stock => stock.category == "野菜") // 野菜だけ抽出 - .map(stock => ( - handleRowClick(stock.stockId)} - style={{ backgroundColor: selectedRow === stock.stockId ? "yellow" : "white", cursor: "pointer" }}> - {stock.stuffName} - {stock.amount} - {stock.price} - {formatDate(stock.expDate)} - {formatDate(stock.buyDate)} - - ))} - -
-
- )} + {StockTable(stocks, ["野菜"])}
- - 調味料 - - {/* 調味料一覧表示エリア - 青い背景のコンテナ */} + {/* 調味料 */} + 調味料
- {stocks.filter(stock => stock.category === "調味料").length === 0 ? null : ( - - - - - 食材名 - 数量 - 購入価格 - 賞味・消費期限 - 購入日 - - - - {stocks - .filter(stock => stock.category == "調味料") // 調味料だけ抽出 - .map(stock => ( - handleRowClick(stock.stockId)} - style={{ backgroundColor: selectedRow === stock.stockId ? "yellow" : "white", cursor: "pointer" }}> - {stock.stuffName} - {stock.amount} - {stock.price} - {formatDate(stock.expDate)} - {formatDate(stock.buyDate)} - - ))} - -
-
- )} + {StockTable(stocks, ["調味料"])}
- - その他 - - {/* その他一覧表示エリア - 青い背景のコンテナ */} + {/* その他 */} + その他
- {stocks.filter(stock => stock.category === "その他").length === 0 ? null : ( - - - - - 食材名 - 数量 - 購入価格 - 賞味・消費期限 - 購入日 - - - - {stocks - .filter(stock => stock.category == "その他") // その他だけ抽出 - .map(stock => ( - handleRowClick(stock.stockId)} - style={{ backgroundColor: selectedRow === stock.stockId ? "yellow" : "white", cursor: "pointer" }}> - {stock.stuffName} - {stock.amount} - {stock.price} - {formatDate(stock.expDate)} - {formatDate(stock.buyDate)} - - ))} - -
-
- )} + {StockTable(stocks, ["その他"])}
); diff --git a/frontend/src/pages/TaskListPage.tsx b/frontend/src/pages/TaskListPage.tsx index ae7eeef..f10f248 100644 --- a/frontend/src/pages/TaskListPage.tsx +++ b/frontend/src/pages/TaskListPage.tsx @@ -4,6 +4,7 @@ */ import React, { useState, useEffect } from 'react'; import { toBuyApi, stuffApi } from '../services/api'; +import { useNavigate, Outlet, useLocation } from 'react-router-dom'; import { Container, Typography, @@ -252,7 +253,12 @@ const TaskListPage: React.FC = () => { setOpenDialog(true)} + onClick={() => {setOpenDialog(true); + //handleNavigate('/AddDishies1'); + }} + //selected={isSelected('/test')} + + > diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 1477b83..a2a6967 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -140,7 +140,7 @@ export const toBuyApi = { const response = await fetch(`${API_BASE_URL}/api/tobuy/delete`, { method: 'DELETE', headers: getHeaders(), - body: JSON.stringify({tobuyId}), + body: JSON.stringify({ tobuyId }), }); if (!response.ok) { @@ -157,13 +157,13 @@ export const toBuyApi = { /** * 買うものリストの在庫登録(購入処理) */ - buy: async (req: {tobuyId: number, price: number, expDate: string, buyDate: string, lastUpdate: string}): Promise<{ result: boolean }> => { - + buy: async (req: { tobuyId: number, price: number, expDate: string, buyDate: string, lastUpdate: string }): Promise<{ result: boolean }> => { + console.log('req: ', req) req.buyDate = makeDateObject(req.buyDate)?.toISOString()?.substring(0, 10) || '' req.expDate = makeDateObject(req.expDate)?.toISOString()?.substring(0, 10) || '' - + const response = await fetch(`${API_BASE_URL}/api/tobuy/buy`, { method: 'POST', headers: getHeaders(), @@ -245,16 +245,87 @@ export const stockApi = { return response.json(); }, + + /** + * 在庫リストの編集 + */ + updateStock: async (req: {stockId: number, amount: number, price: number, lastUpdate: string, buyDate: string, expDate: string}): Promise<{ result: boolean; message: string }> => { + + + + const response = await fetch(`${API_BASE_URL}/api/stocks/update`, { + method: 'PUT', + headers: getHeaders(), + body: JSON.stringify(req), + }); + + if (!response.ok) { + throw new Error(STOCK_ERRORS.UPDATE_FAILED); + } + + return response.json() + + // return { + // "result": true + // } + }, + + /** + * 在庫リストの削除 + * @param id 削除対象の食材のID + */ + deleteStock: async (stockId: number): Promise<{ result: boolean; message: string }> => { + const response = await fetch(`${API_BASE_URL}/api/stocks/delete`, { + method: 'DELETE', + headers: getHeaders(), + body: JSON.stringify({ stockId }), + }); + + console.log("API レスポンスステータス:", response.status); + console.log("API レスポンス本文:", await response.text()); + + if (!response.ok) { + throw new Error(STOCK_ERRORS.DELETE_FAILED); + } + + return response.json() + + // return { + // "result": true + // } + }, + } +const deleteStock = async (stockId: number): Promise<{ result: boolean; message: string }> => { + console.log("API の deleteStock メソッドが呼ばれました。stockId:", stockId); + + const response = await fetch(`${API_BASE_URL}/api/stocks/delete`, { + method: "DELETE", + headers: getHeaders(), + body: JSON.stringify({ stockId }), + }); + + console.log("API レスポンスステータス:", response.status); + console.log("API レスポンス本文:", await response.text()); + + if (!response.ok) { + return { result: false, message: "削除に失敗しました。" }; + } + + // API のレスポンスから result と message を取得 + const data = await response.json(); + return { result: data.result, message: data.message }; +}; + function makeDateObject(dateStr: String) { - // 例: '2025/06/15' または '2025-06-15' を '2025-06-15' に変換 - const parts = dateStr.split(/[-\/]/); // ハイフンかスラッシュで分割 - if (parts.length === 3) { - return new Date(parts[0] + '-' + parts[1] + '-' + parts[2]); - } - return null; // 無効な日付の場合 + // 例: '2025/06/15' または '2025-06-15' を '2025-06-15' に変換 + const parts = dateStr.split(/[-\/]/); // ハイフンかスラッシュで分割 + if (parts.length === 3) { + return new Date(parts[0] + '-' + parts[1] + '-' + parts[2]); + } + return null; // 無効な日付の場合 }