From 00b6f7f1c74adc4a28d5bc718ada8e226eb3a9dc Mon Sep 17 00:00:00 2001 From: "Masaharu.Kato" Date: Mon, 16 Jun 2025 13:04:58 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=83=9D=E3=83=BC=E3=83=8D=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/MessageAlert.tsx | 29 ++++++++++++++++++++++ frontend/src/pages/AddRecipe.tsx | 31 ++++++++++++++++++++---- 2 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 frontend/src/components/MessageAlert.tsx diff --git a/frontend/src/components/MessageAlert.tsx b/frontend/src/components/MessageAlert.tsx new file mode 100644 index 0000000..7368571 --- /dev/null +++ b/frontend/src/components/MessageAlert.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Snackbar, Alert, AlertColor } from '@mui/material'; + +interface MessageAlertProps { + open: boolean; + message: string; + severity: AlertColor; // 'error' | 'warning' | 'info' | 'success' + onClose: (event?: React.SyntheticEvent | Event, reason?: string) => void; + duration?: number; +} + +const MessageAlert: React.FC = ({ + open, + message, + severity, + onClose, + duration = 6000, +}) => { + return ( + + + {message} + + + ); +}; + +export default MessageAlert; diff --git a/frontend/src/pages/AddRecipe.tsx b/frontend/src/pages/AddRecipe.tsx index 72ca041..2486d70 100644 --- a/frontend/src/pages/AddRecipe.tsx +++ b/frontend/src/pages/AddRecipe.tsx @@ -25,7 +25,8 @@ import { Select, FormControl, InputLabel, - ListItemIcon + ListItemIcon, + AlertColor } from '@mui/material'; import { Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon, @@ -36,6 +37,7 @@ import { StuffAndCategoryAndAmount } from '../types/types'; import EditAmountDialog from '../components/EditAmountDialog'; import { recipeApi, toBuyApi } from '../services/api'; import { useNavigate, useParams } from 'react-router-dom'; +import MessageAlert from '../components/MessageAlert'; const AddRecipe: React.FC = () => { const { recipeId: recipeIdStr } = useParams(); @@ -43,6 +45,20 @@ const AddRecipe: React.FC = () => { const navigate = useNavigate(); + // メッセージ + const [_openMessage, _setOpenMessage] = useState(false); + const [_messageText, _setMessageText] = useState(''); + const [_messageType, _setMessageType] = useState('info'); + const _showMessage = (message: string, severity: AlertColor) => { + _setOpenMessage(true); + _setMessageText(message); + _setMessageType(severity); + } + const showErrorMessage = (message: string) => _showMessage(message, 'error'); + const showWarningMessage = (message: string) => _showMessage(message, 'warning'); + const showInfoMessage = (message: string) => _showMessage(message, 'info'); + const showSuccessMessage = (message: string) => _showMessage(message, 'success'); + // 編集時,既存情報を読み込んだかどうか const [recipeLoaded, setRecipeLoaded] = useState(false); // 料理名,説明 @@ -75,12 +91,12 @@ const AddRecipe: React.FC = () => { const handleSaveRecipe = async () => { if (!recipeName) { - alert('レシピ名が入力されていません!') + showErrorMessage('レシピ名が入力されていません!') return false; } if (!items.length) { - alert('材料が追加されていません!') + showErrorMessage('材料が追加されていません!') return false; } @@ -102,7 +118,7 @@ const AddRecipe: React.FC = () => { stuffAndAmountArray: items, }) } catch { - alert('レシピの送信に失敗しました。既に同じ名前の料理が存在する可能性があります。'); + showErrorMessage('レシピの送信に失敗しました。同じ料理名が存在する可能性があります。'); return false; } @@ -130,7 +146,10 @@ const AddRecipe: React.FC = () => { }, []); return ( - (recipeId && !recipeLoaded) + <> + _setOpenMessage(false)}> + + {(recipeId && !recipeLoaded) ?

読み込み中...

: @@ -237,6 +256,8 @@ const AddRecipe: React.FC = () => { }} /> + } + ); };