diff --git a/frontend/src/pages/StockPage.tsx b/frontend/src/pages/StockPage.tsx index 9caafe3..6bd440c 100644 --- a/frontend/src/pages/StockPage.tsx +++ b/frontend/src/pages/StockPage.tsx @@ -3,8 +3,8 @@ * 白紙の状態で表示されるテスト用のページ */ import React, { useState, useEffect } from 'react'; -import { stockApi } from '../services/api'; -import { Stock } from '../types/types'; +import { stockApi, stuffApi } from '../services/api'; +import { Stock, Stuff } from '../types/types'; import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from "@mui/material"; import { Container, @@ -18,15 +18,40 @@ import { TextField, Button, Box, - + Checkbox, + FormControlLabel, + FormGroup, + FormControl, + InputLabel, + Select, + MenuItem, } from '@mui/material'; import { STOCK_ERRORS } from '../constants/errorMessages'; +// 新規在庫の初期状態 +const EMPTY_STOCK: Omit & { stuffId: number | null } & { newAddition: boolean } = { + stuffId: null, + stuffName: '', + amount: 0, + price: 0, + lastUpdate: '', + buyDate: '', + expDate: '', + category: '', + newAddition: false, // 材料を新規作成するか否か + // shop '', +} + const StockPage: React.FC = () => { const [stocks, setStocks] = useState([]); // セル選択の表示状態 const [selectedRow, setSelectedRow] = useState(null); + // 追加ダイアログボックスの表示状態 + const [isAddOpen, setIsAddOpen] = useState(false); + // 在庫追加に使う状態 + const [newStock, setNewStock] = useState(EMPTY_STOCK); + const [stuffs, setStuffs] = useState([]); // 編集ダイアロボックスの表示状態 const [isEditOpen, setIsEditOpen] = useState(false); // 削除メッセージダイアログの表示状態 @@ -53,6 +78,25 @@ const StockPage: React.FC = () => { } }; + /** + * 在庫リストに新規食材を作成するハンドラー + */ + const handleCreateStock = async () => { + try { + if (newStock.newAddition) { + newStock.stuffId = null; + } + console.log(newStock) + const today = new Date().toISOString().substring(0, 10); + await stockApi.addStock(newStock); + setIsAddOpen(false); // ダイアログを閉じる + setNewStock(EMPTY_STOCK); // 入力内容をリセット + fetchStocks(); // 作成後のタスク一覧を再取得 + } catch (error) { + console.error(`${STOCK_ERRORS.CREATE_FAILED}:`, error); + } + }; + /** * 在庫リストを編集するハンドラー */ @@ -79,6 +123,15 @@ const StockPage: React.FC = () => { } }; + /** + * カテゴリー選択?? + */ + const onChangeCategory = async (category: string) => { + setNewStock({ ...newStock, category }) + const result = await stuffApi.getStuffs(category) + setStuffs(result) + } + /** * 文字列(ISO 8601形式)をyyyy/MM/ddに変換する関数 */ @@ -98,6 +151,15 @@ const StockPage: React.FC = () => { }; */ + /** 追加ボタンを押したときにダイアログを開く */ + const handleOpenAdd = () => { + setIsAddOpen(true); + }; + /** 削除ダイアログを閉じる */ + const handleCloseAdd = () => { + setIsAddOpen(false); + }; + /** * セルを選択する関数. 再度クリックで選択解除 */ @@ -315,12 +377,136 @@ const StockPage: React.FC = () => { 在庫一覧 - {/* タスク編集ボタン(全テーブル共通) */} + {/* 在庫の食材追加ボタン */} + + + {/* 新規タスク作成ダイアログ */} + setIsAddOpen(false)} disableScrollLock={true}> + + 在庫に食材を追加 + + } + label="食材を新規追加" + checked={newStock.newAddition} + onChange={(e) => setNewStock({ ...newStock, newAddition: (e.target as HTMLInputElement).checked })} + /> + + + + + {/*材料カテゴリ選択 */} + + + カテゴリ + + + + {!newStock.newAddition && + 材料名(選択) + + } + + {/* タスクタイトル入力フィールド */} + {newStock.newAddition && setNewStock({ ...newStock, stuffName: e.target.value })} + sx={{ marginBottom: 2 }} + />} + {/* 数量入力フィールド */} + { + const value = e.target.value; + const parsedValue = parseInt(value, 10); // 数値に変換 + if (!isNaN(parsedValue)) { + setNewStock({ ...newStock, amount: parsedValue }); // number型で保存 + } + }} + // sx={{ width: "50%" }} + type="number" + inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可 + /> + {/* 購入価格入力フィールド */} + { + const value = e.target.value; + const parsedValue = parseInt(value, 10); // 数値に変換 + if (!isNaN(parsedValue)) { + setNewStock({ ...newStock, price: parsedValue }); // number型で保存 + } + }} + // sx={{ width: "50%" }} + type="number" + inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可 + /> + + {/* 賞味・消費期限入力フィールド */} + setNewStock({ ...newStock, expDate: e.target.value })} + /> + + {/* 購入日入力フィールド */} + setNewStock({ ...newStock, buyDate: e.target.value })} + /> + + + + + + + + + {/* 在庫の食材編集ボタン(全テーブル共通) */} - {/* タスク削除ボタン */} + {/* 在庫の食材削除ボタン (全テーブル共通) */} {/* 在庫一覧リスト */} diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 59951bf..75c5c67 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -246,6 +246,40 @@ export const stockApi = { }, + /** + * 在庫リストへの新規食材追加 + * @param stock 作成する材料情報 + * @returns 作成された材料情報 + */ + addStock: async (stock: Omit & { stuffId: number | null }): Promise<{ result: boolean; message: string }> => { + + console.log("送信するデータ:", stock); // 送信前のデータ確認 + + stock.buyDate = makeDateObject(stock.buyDate)?.toISOString()?.substring(0, 10) || '' + stock.expDate = makeDateObject(stock.expDate)?.toISOString()?.substring(0, 10) || '' + + console.log("変換後のデータ:", stock); // 日付変換後のデータ確認 + + const response = await fetch(`${API_BASE_URL}/api/stocks/add`, { + method: 'POST', + headers: getHeaders(), + body: JSON.stringify(stock), + }); + + console.log("レスポンスステータス:", response.status); + console.log("レスポンスヘッダー:", response.headers); + console.log("レスポンス内容:", await response.text()); + + + if (!response.ok) { + throw new Error(STOCK_ERRORS.CREATE_FAILED); + } + + return response.json(); + // return {result: true} + + }, + /** * 在庫リストの編集 */ @@ -255,7 +289,7 @@ export const stockApi = { req.buyDate = makeDateObject(req.buyDate)?.toISOString()?.substring(0, 10) || '' req.expDate = makeDateObject(req.expDate)?.toISOString()?.substring(0, 10) || '' - console.log('req: ', req) + console.log('req: ', req) const response = await fetch(`${API_BASE_URL}/api/stocks/update`, { method: 'PUT',