From 5a85ea5dbc973e4ff52649c90a4bb43edb7d41ef Mon Sep 17 00:00:00 2001 From: "masato.fujita" Date: Thu, 12 Jun 2025 09:51:17 +0900 Subject: [PATCH 1/4] =?UTF-8?q?API=E3=81=A8=E3=81=AE=E7=B5=B1=E5=90=88(?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=81=82=E3=82=8A)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/todoapp/config/InitTables.java | 10 ++-- frontend/src/pages/DishList.tsx | 47 +++++++++++-------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/backend/src/main/java/com/example/todoapp/config/InitTables.java b/backend/src/main/java/com/example/todoapp/config/InitTables.java index 413f9f2..12eb13b 100644 --- a/backend/src/main/java/com/example/todoapp/config/InitTables.java +++ b/backend/src/main/java/com/example/todoapp/config/InitTables.java @@ -43,11 +43,11 @@ public class InitTables { @PostConstruct public void initTables() { - // tobuysRepository.deleteAll(); //データを残す場合はコメントアウト - // stocksRepository.deleteAll(); //データを残す場合はコメントアウト - // recipeStuffsRepository.deleteAll(); //データを残す場合はコメントアウト - // recipesRepository.deleteAll(); //データを残す場合はコメントアウト - // stuffsRepository.deleteAll(); //データを残す場合はコメントアウト + tobuysRepository.deleteAll(); //データを残す場合はコメントアウト + stocksRepository.deleteAll(); //データを残す場合はコメントアウト + recipeStuffsRepository.deleteAll(); //データを残す場合はコメントアウト + recipesRepository.deleteAll(); //データを残す場合はコメントアウト + stuffsRepository.deleteAll(); //データを残す場合はコメントアウト if (stuffsRepository.count() > 0) { return; // すでにデータが存在する場合は何もしない diff --git a/frontend/src/pages/DishList.tsx b/frontend/src/pages/DishList.tsx index 2202f23..f30216f 100644 --- a/frontend/src/pages/DishList.tsx +++ b/frontend/src/pages/DishList.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import { toBuyApi } from '../services/api'; +import { toBuyApi, recipeApi } from '../services/api'; import { Container, Typography, @@ -44,21 +44,29 @@ const DishList: React.FC = () => { const test = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1]; // APIができるまでのテスト用の型 interface Dish { - id:number, - name:string, - amount:number + recipeId: number, + recipeName: string, + summary: number } + // APIができるまでの食材配列 const testdish : Dish[] = [ - { id: 1, name: 'ジャガイモ', amount:1 }, - { id: 2, name: '人参', amount:2 }, - { id: 3, name: '人参', amount:2 }, - { id: 4, name: '人参', amount:2 } + { recipeId: 1, recipeName: 'ジャガイモ', summary:1 }, + { recipeId: 2, recipeName: '人参', summary:2 }, + { recipeId: 3, recipeName: '人参', summary:2 }, + { recipeId: 4, recipeName: '人参', summary:2 } ]; + // interface testdish { + // recipeId: number, + // recipeName: string, + // summary: number + // } + + // すべての料理リスト + const [allDish, setAllDish] = useState(); // 画面表示用の食材情報配列 const [testDishArray, setTestDishArray] = useState(testdish); - // エラーメッセージの状態管理 const [error, setError] = useState(false); // 選択した料理の情報を表示するダイアログの表示状態 @@ -112,9 +120,10 @@ const DishList: React.FC = () => { const fetchTasks = async () => { try { - const tobuys = await toBuyApi.getToBuys(); - setToBuys(tobuys); + const dishlistfirst = await recipeApi.getAllRecipes(); + setAllDish(dishlistfirst); } catch (error) { + alert("取得失敗"); // console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); } }; @@ -128,13 +137,13 @@ const DishList: React.FC = () => { overflowY: 'auto', padding: '20px'}}> {/* */} {/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} - {test.map((test, index) => ( + {allDish && allDish.map((allDish, recipeId) => ( {/*新規料理追加ボタン - 画面下部に固定表示 */} - + {/* { > - + */} - {/* 新規タスク作成ダイアログ */} + {/* 料理リストの詳細表示ダイアログ */} setOpenDialog(false)} disableScrollLock={true} maxWidth="lg" fullWidth @@ -234,13 +247,13 @@ const DishList: React.FC = () => { - {/* 食材の個数の編集ダイアログ */} + {/* 食材編集ダイアログ */} setOpenChangeDialog(false)} disableScrollLock={true} maxWidth="lg" fullWidth > - 食材名 + 料理名 {/* */} @@ -277,11 +290,11 @@ const DishList: React.FC = () => { /> {/* 買い物リスト:食材情報記入ボタン */} - + handleDeleteTask(task.id)} + aria-label="個数を編集" + onClick={() => changeSelectedItemAmount(test, test.recipeName, test.summary)} > @@ -346,115 +359,52 @@ const DishList: React.FC = () => { - {/* 食材編集ダイアログ */} - setOpenChangeDialog(false)} disableScrollLock={true} + {/* 食材の個数の編集ダイアログ */} + setOpenChangeAmountDialog(false)} disableScrollLock={true} maxWidth="lg" fullWidth > - 料理名 + 数量の変更 - - {/* */} - {/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} - {testDishArray.map((test, id) => ( - - {/* タスク完了状態を切り替えるチェックボックス - handleToggleComplete(task.id)} - /> */} - {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} - - {/* 食材の個数を表示 */} - 個数
- {test.summary} - - } - // secondary={task.description} - sx={{ align: "right", fontSize: "20px" }} - /> - {/* 買い物リスト:食材情報記入ボタン */} - - - handleDeleteTask(task.id)} - > - - - - {/* 買い物リスト:食材削除ボタン */} - - - handleDeleteStuffTemp(id)} - > - - - - - -
- // - // - // {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} - // - // - ))} - {/*
*/} -
+ + + + {/* 材料名表示 */} + + {/* 数量入力フィールド */} + { + const value = e.target.value; + const parsedValue = parseInt(value, 10); // 数値に変換 + // if (/*!isNaN(parsedValue) && */ isNaN(parsedValue) || parsedValue >= 1) { //負数除外 + // setSelectedEditingTask({ ...selectedEditingTask, amount: parsedValue }); // number型で保存 + // } + + }} + sx={{ width: "20%" }} + type="number" + inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可 + + /> + + - - +
From dc6ab8662fd5973d5f88c5c36d56c2c61d9a5d33 Mon Sep 17 00:00:00 2001 From: "masato.fujita" Date: Thu, 12 Jun 2025 15:19:51 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=99=E7=90=86=E3=83=AA=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=81=ABAPI=E3=81=AE=E5=86=85=E5=AE=B9=E3=82=92?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/DishList.tsx | 144 +++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 48 deletions(-) diff --git a/frontend/src/pages/DishList.tsx b/frontend/src/pages/DishList.tsx index 387b634..5eef344 100644 --- a/frontend/src/pages/DishList.tsx +++ b/frontend/src/pages/DishList.tsx @@ -56,15 +56,40 @@ const DishList: React.FC = () => { { recipeId: 3, recipeName: '人参', summary:2 }, { recipeId: 4, recipeName: '人参', summary:2 } ]; + + interface RecipeInfo { + recipeId: number; + recipeName: string; + summary: string; + stuffs: Array<{ + stuffId: number; stuffName: string; amount: number + }>; + } - // interface testdish { - // recipeId: number, - // recipeName: string, - // summary: number - // } + const EMPTY_RECIPE: RecipeInfo = { + recipeId: 0, + recipeName: '', + summary: '', + stuffs: [] + } + + interface Stuff { + stuffId: number; + stuffName: string; + amount: number; + } // すべての料理リスト - const [allDish, setAllDish] = useState(testdish); + const [allDish, setAllDish] = useState(); + // 食材リスト + const [stuff, setStuff] = useState([]); + // 料理名 + const [selectedDishName, setSelectedDishName] = useState(''); + // 料理情報 + const [selectedrecipeInfo, setSelectedRecipeInfo] = useState({recipeId: 0, + recipeName: '', + summary: '', + stuffs: []}); // 画面表示用の食材情報配列 const [testDishArray, setTestDishArray] = useState(testdish); // エラーメッセージの状態管理 @@ -76,7 +101,16 @@ const DishList: React.FC = () => { // 料理リストの食材の個数編集ダイアログの表示状態 const [openChangeAmountDialog, setOpenChangeAmountDialog] = useState(false); // 編集する食材の状態 - const [selectedEditingStuff, setSelectedEditingStuff] = useState(); + const [selectedEditingStuff, setSelectedEditingStuff] = useState(); + + + // 食材表示ダイアログを表示 + const openStuffDialog = (recipeId : number) => { + setOpenDialog(true) + selectedDishId = recipeId; + fetchstuff(selectedDishId); + console.log(selectedDishId); + } const changeDialog = () => { setOpenDialog(false); @@ -88,26 +122,43 @@ const DishList: React.FC = () => { setOpenDialog(true); setOpenChangeDialog(false); }; + // 選択された料理のID + let selectedDishId : number = 0; // 選択された食材 let selectedItem : string = ''; // 選択された食材の個数 let selectedItemAmount : number = 0; // 選択された食材の個数を変更するダイアログを開く処理 - const changeSelectedItemAmount = (dish : Dish, stuff_name : string, stuff_amount : number) => { + const changeSelectedItemAmount = (stuff : Stuff, stuff_name : string, stuff_amount : number) => { setOpenChangeAmountDialog(true) - setSelectedEditingStuff(dish); + setSelectedEditingStuff(stuff); selectedItem = stuff_name; selectedItemAmount = stuff_amount; }; + const fetchstuff = async (recipeId : number) => { + try { + const dish = await recipeApi.getById(recipeId); + console.log(dish); + // 情報の取得にラグがあるバグあり。変数に格納するのは諦めるべきか + // setSelectedRecipeInfo(dish); + console.log(selectedrecipeInfo); + setSelectedDishName(dish.recipeName); + setStuff(dish.stuffs); + console.log(selectedDishName); + } catch (error) { + alert("取得失敗"); + // console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); + } + }; /** * タスクを削除するハンドラー * 指定されたIDのタスクをAPIを通じて削除 */ - const handleDeleteStuffTemp = async (dish_id: number) => { + const handleDeleteStuffTemp = async (stuff_id: number) => { try { - let testDishArrayCopy = [...testDishArray]; // 配列をコピー - testDishArrayCopy.splice(dish_id, 1); - setTestDishArray(testDishArrayCopy); + let stuffCopy = [...stuff]; // 配列をコピー + stuffCopy.splice(stuff_id, 1); + setStuff(stuff); // fetchTasks(); // 削除後のタスク一覧を再取得 } catch (error) { // console.error(`${TASK_ERRORS.DELETE_FAILED}:`, error); @@ -133,8 +184,8 @@ const DishList: React.FC = () => { const fetchTasks = async () => { try { - // const dishlistfirst = await recipeApi.getAllRecipes(); - // setAllDish(dishlistfirst); + const dishlistfirst = await recipeApi.getAllRecipes(); + setAllDish(dishlistfirst); } catch (error) { alert("取得失敗"); // console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); @@ -164,7 +215,7 @@ const DishList: React.FC = () => { boxShadow: 1, fontSize: '40px' }} - onClick={() => setOpenDialog(true)} + onClick={() => openStuffDialog(allDish.recipeId)} > {allDish.recipeName} {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} @@ -207,34 +258,31 @@ const DishList: React.FC = () => { fullWidth > - 料理名 + {selectedDishName} {/* */} - {/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} - {test.map((test, index) => ( - - // - // {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} - // - // + {/* 食材をマップして各食材をリストアイテムとして表示 */} + {stuff.map((stuff, stuffId) => ( + + {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} + + ))} {/* */} @@ -253,14 +301,14 @@ const DishList: React.FC = () => { fullWidth > - 料理名 + {selectedDishName} {/* */} {/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} - {testDishArray.map((test, id) => ( + {stuff.map((stuff, stuffId) => ( { /> */} {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */} {/* 食材の個数を表示 */} 個数
- {test.summary} + {stuff.amount} } // secondary={task.description} @@ -294,7 +342,7 @@ const DishList: React.FC = () => { changeSelectedItemAmount(test, test.recipeName, test.summary)} + onClick={() => changeSelectedItemAmount(stuff, stuff.stuffName, stuff.amount)} > @@ -317,7 +365,7 @@ const DishList: React.FC = () => { handleDeleteStuffTemp(id)} + onClick={() => handleDeleteStuffTemp(stuffId)} >