料理レシピが動くように修正

feature-frontend-dishedit-kato
Masaharu.Kato 4 months ago
parent b8e7a4ed1d
commit 4279750e3b
  1. 10
      backend/src/main/java/com/example/todoapp/config/InitTables.java
  2. 6
      frontend/src/App.tsx
  3. 4
      frontend/src/components/Layout.tsx
  4. 23
      frontend/src/pages/AddRecipe.tsx
  5. 113
      frontend/src/pages/RecipeList.tsx
  6. 8
      frontend/src/pages/TaskListPage.tsx
  7. 12
      frontend/src/services/api.ts
  8. 13
      frontend/src/types/types.ts

@ -43,11 +43,11 @@ public class InitTables {
@PostConstruct @PostConstruct
public void initTables() { public void initTables() {
tobuysRepository.deleteAll(); //データを残す場合はコメントアウト // tobuysRepository.deleteAll(); //データを残す場合はコメントアウト
stocksRepository.deleteAll(); //データを残す場合はコメントアウト // stocksRepository.deleteAll(); //データを残す場合はコメントアウト
recipeStuffsRepository.deleteAll(); //データを残す場合はコメントアウト // recipeStuffsRepository.deleteAll(); //データを残す場合はコメントアウト
recipesRepository.deleteAll(); //データを残す場合はコメントアウト // recipesRepository.deleteAll(); //データを残す場合はコメントアウト
stuffsRepository.deleteAll(); //データを残す場合はコメントアウト // stuffsRepository.deleteAll(); //データを残す場合はコメントアウト
if (stuffsRepository.count() > 0) { if (stuffsRepository.count() > 0) {
// すでにデータが存在する場合は何もしない // すでにデータが存在する場合は何もしない

@ -13,7 +13,7 @@ import StockPage from './pages/StockPage';
import './App.css'; import './App.css';
// 必要なインポートを追加 // 必要なインポートを追加
import AddRecipe from './pages/AddRecipe'; import AddRecipe from './pages/AddRecipe';
import DishList from './pages/DishList'; import RecipeList from './pages/RecipeList';
//カレンダーライブラリ //カレンダーライブラリ
import FullCalendar from '@fullcalendar/react'; import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from "@fullcalendar/daygrid"; import dayGridPlugin from "@fullcalendar/daygrid";
@ -110,10 +110,10 @@ const App: React.FC = () => {
/> />
{/* 料理リストへのルートを追加 */} {/* 料理リストへのルートを追加 */}
<Route <Route
path="dishList" path="recipeList"
element={ element={
<PrivateRoute> <PrivateRoute>
<DishList /> <RecipeList />
</PrivateRoute> </PrivateRoute>
} }
/> />

@ -112,8 +112,8 @@ const Layout: React.FC = () => {
<ListItemText primary="料理の追加" /> <ListItemText primary="料理の追加" />
</ListItemButton> </ListItemButton>
<ListItemButton <ListItemButton
onClick={() => handleNavigate('/dishList')} onClick={() => handleNavigate('/recipeList')}
selected={isSelected('/dishList')} selected={isSelected('/recipeList')}
> >
<ListItemIcon><ScienceIcon /></ListItemIcon> <ListItemIcon><ScienceIcon /></ListItemIcon>
<ListItemText primary="料理リスト" /> <ListItemText primary="料理リスト" />

@ -68,7 +68,6 @@ const AddRecipe: React.FC = () => {
setItems(recipe.stuffAndAmountArray) setItems(recipe.stuffAndAmountArray)
} }
} }
loadRecipe();
const handleSaveRecipe = async () => { const handleSaveRecipe = async () => {
@ -93,17 +92,23 @@ const AddRecipe: React.FC = () => {
} }
const handleSubmit = async () => { const handleSubmit = async () => {
const recipeId = await handleSaveRecipe() const recipeId = await handleSaveRecipe();
alert('レシピが保存されました!') // 仮メッセージ // alert('レシピが保存されました!');
// navigate('/tasks'); navigate('/recipeList');
} }
const handleSubmitAndAddToBuy = async () => { const handleSubmitAndAddToBuy = async () => {
const recipeId = await handleSaveRecipe(); const recipeId = await handleSaveRecipe();
await toBuyApi.addByRecipe(recipeId) await toBuyApi.addByRecipe(recipeId);
navigate('/tasks') // alert('レシピが保存されて買うものリストに追加されました!');
navigate('/tasks');
} }
// コンポーネントマウント時にタスク一覧を取得
useEffect(() => {
loadRecipe();
}, []);
return ( return (
(recipeId && !recipeName) (recipeId && !recipeName)
? <p>...</p> ? <p>...</p>
@ -117,11 +122,13 @@ const AddRecipe: React.FC = () => {
<TextField autoFocus margin="dense" label="料理名" fullWidth <TextField autoFocus margin="dense" label="料理名" fullWidth
value={recipeName} onChange={(e) => setRecipeName(e.target.value)} value={recipeName} onChange={(e) => setRecipeName(e.target.value)}
/> />
<TextField autoFocus margin="dense" label="説明" fullWidth <TextField margin="dense" label="説明" fullWidth
value={recipeSummary} onChange={(e) => setRecipeSummary(e.target.value)} value={recipeSummary} onChange={(e) => setRecipeSummary(e.target.value)}
/> />
</div> </div>
<h2></h2> <h2 style={{marginTop: "0.5em" }}>
</h2>
{/* すべての材料情報を表示 */} {/* すべての材料情報を表示 */}
{(!items || !items.length) {(!items || !items.length)
? (<p>+</p>) ? (<p>+</p>)

@ -0,0 +1,113 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { recipeApi } from '../services/api';
import {
Container,
Typography,
Tooltip,
List,
ListItem,
ListItemText,
ListItemSecondaryAction,
IconButton,
Checkbox,
Fab,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
Button,
Box,
FormControlLabel,
FormGroup,
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 { ToBuy, Stuff, RecipeWithId, RecipeDetail } from '../types/types';
const RecipeList: React.FC = () => {
const navigate = useNavigate();
// 料理リストの料理名を格納する配列
// すべての料理リスト
const [allRecipes, setAllRecipes] = useState<RecipeWithId[]>();
const openRecipeById = (recipeId: number) => {
navigate('/addRecipe/' + recipeId);
}
const fetchAllRecipes = async () => {
try {
const recipes = await recipeApi.getAllRecipes();
setAllRecipes(recipes);
} catch (error) {
alert("レシピの取得に失敗しました.");
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
}
};
// コンポーネントマウント時にタスク一覧を取得
useEffect(() => {
fetchAllRecipes();
}, []);
return (
<Container>
<Box>
<div>
<h1 style={{ fontSize: "40px", textAlign: "center" }}></h1>
</div>
<div style={{
border: '3px solid black', borderRadius: '8px', height: '500px',
overflowY: 'auto', padding: '20px'
}}>
{/* <List> */}
{/* 料理一覧をマップして各タスクをリストアイテムとして表示 */}
{!allRecipes
? <p>...</p>
: allRecipes.map((recipe, index) => (
<FormGroup>
<Button
// <ListItem
key={recipe.recipeId}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
fontSize: '40px'
}}
onClick={() => openRecipeById(recipe.recipeId)}
>
{recipe.recipeName}
</Button>
</FormGroup>
// </ListItem>
))}
{/* </List> */}
</div>
<div style={{ width: "100%", position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "20px" }}>
<Button variant='contained' sx={{
width: "60%", height: "60px",
fontSize: "40px", left: "50%", transform: 'translateX(-50%)'
}}
color="primary"
onClick={() => navigate('/AddRecipe')}
>
</Button>
</div>
</Box>
</Container>
);
};
export default RecipeList;

@ -25,6 +25,7 @@ import { TOBUY_ERRORS } from '../constants/errorMessages';
import EditAmountDialog from '../components/EditAmountDialog'; import EditAmountDialog from '../components/EditAmountDialog';
import AddStuffAmountDialog from '../components/AddStuffAmountDialog'; import AddStuffAmountDialog from '../components/AddStuffAmountDialog';
import BuyDialog from '../components/BuyDialog'; import BuyDialog from '../components/BuyDialog';
import { useNavigate } from 'react-router-dom';
//import { FaCarrot } from "react-icons/fa6"; //エラー起きる いったん保留 //import { FaCarrot } from "react-icons/fa6"; //エラー起きる いったん保留
@ -39,6 +40,9 @@ const EMPTY_TOBUY: NewToBuy = {
} }
const TaskListPage: React.FC = () => { const TaskListPage: React.FC = () => {
const navigate = useNavigate();
// タスク一覧の状態管理 // タスク一覧の状態管理
const [tobuys, setToBuys] = useState<ToBuy[]>([]); const [tobuys, setToBuys] = useState<ToBuy[]>([]);
@ -289,8 +293,8 @@ const TaskListPage: React.FC = () => {
color="primary" color="primary"
sx={{ position: 'fixed', bottom: 16, left: '60%', transform: 'translateX(-50%)' }} sx={{ position: 'fixed', bottom: 16, left: '60%', transform: 'translateX(-50%)' }}
onClick={() => { onClick={() => {
setOpenAddToBuyDialog(true); // setOpenAddToBuyDialog(true);
//handleNavigate('/AddDishies1'); navigate('/RecipeList');
}} }}
//selected={isSelected('/test')} //selected={isSelected('/test')}
> >

@ -3,7 +3,7 @@
* APIとの通信を担当するモジュール * APIとの通信を担当するモジュール
* *
*/ */
import { LoginCredentials, RegisterCredentials, AuthResponse, /* Task, */ ToBuy, Stuff, Stock, RecipeData, StuffAndCategoryAndAmount } from '../types/types'; import { LoginCredentials, RegisterCredentials, AuthResponse, /* Task, */ ToBuy, Stuff, Stock, RecipeDetail, StuffAndCategoryAndAmount, RecipeWithId } from '../types/types';
import { AUTH_ERRORS, TOBUY_ERRORS, STOCK_ERRORS, RECIPE_ERRORS } from '../constants/errorMessages'; import { AUTH_ERRORS, TOBUY_ERRORS, STOCK_ERRORS, RECIPE_ERRORS } from '../constants/errorMessages';
// APIのベースURL - 環境変数から取得するか、デフォルト値を使用 // APIのベースURL - 環境変数から取得するか、デフォルト値を使用
@ -343,7 +343,7 @@ export const recipeApi = {
* @param recipeData * @param recipeData
* @returns * @returns
*/ */
addRecipe: async (recipeData: RecipeData): Promise<{ addRecipe: async (recipeData: RecipeDetail): Promise<{
result: string; result: string;
recipeId: number; recipeId: number;
message: string; message: string;
@ -370,7 +370,7 @@ export const recipeApi = {
* @param recipeData * @param recipeData
* @returns / * @returns /
*/ */
updateRecipe: async (recipeData: { recipeId: number } & RecipeData): Promise<{ result: boolean; message: string }> => { updateRecipe: async (recipeData: { recipeId: number } & RecipeDetail): Promise<{ result: boolean; message: string }> => {
// console.log('recipeData:', recipeData) // console.log('recipeData:', recipeData)
const response = await fetch(`${API_BASE_URL}/api/recipes/update`, { const response = await fetch(`${API_BASE_URL}/api/recipes/update`, {
@ -392,11 +392,7 @@ export const recipeApi = {
* *
* @returns * @returns
*/ */
getAllRecipes: async (): Promise<Array<{ getAllRecipes: async (): Promise<RecipeWithId[]> => {
recipeId: number;
recipeName: string;
summary: number;
}>> => {
const response = await fetch(`${API_BASE_URL}/api/recipes/getAll`, { const response = await fetch(`${API_BASE_URL}/api/recipes/getAll`, {
method: 'GET', method: 'GET',
headers: getHeaders(), // 認証トークンを含むヘッダー headers: getHeaders(), // 認証トークンを含むヘッダー

@ -119,13 +119,20 @@ export interface RegisterCredentials {
password: string; // パスワード password: string; // パスワード
} }
export interface Recipe {
recipeName: string;// レシピ名
summary: string;// レシピ概要
}
export interface RecipeWithId extends Recipe {
recipeId: number;
}
/** /**
* *
* *
*/ */
export interface RecipeData { export interface RecipeDetail extends Recipe {
recipeName: string;// レシピ名
summary: string;// レシピ概要
// 材料リスト(直接配列として内包) // 材料リスト(直接配列として内包)
stuffAndAmountArray: { stuffAndAmountArray: {

Loading…
Cancel
Save