Merge remote-tracking branch 'origin/feature-frontend-tobuy-error' into feature-frontend-dateselect-fix

feature-frontend-dateselect-fix
Masaharu.Kato 4 months ago
commit 4285d1ea24
  1. 10
      frontend/src/constants/errorMessages.ts
  2. 16
      frontend/src/constants/normalMessages.ts
  3. 38
      frontend/src/pages/AddRecipe.tsx
  4. 3
      frontend/src/pages/RecipeList.tsx
  5. 28
      frontend/src/pages/TaskListPage.tsx

@ -6,6 +6,7 @@
// 一般的なエラーメッセージ // 一般的なエラーメッセージ
export const GENERAL_ERRORS = { export const GENERAL_ERRORS = {
UNEXPECTED_ERROR: '予期せぬエラーが発生しました', UNEXPECTED_ERROR: '予期せぬエラーが発生しました',
INVALID_STUFF_NAME: '材料名が正しく入力されていません。',
INVALID_AMOUNT: '数量が正しく入力されていません。', INVALID_AMOUNT: '数量が正しく入力されていません。',
INVALID_PRICE: '価格が正しく入力されていません。', INVALID_PRICE: '価格が正しく入力されていません。',
}; };
@ -23,6 +24,7 @@ export const TOBUY_ERRORS = {
UPDATE_FAILED: '買うものリストの更新に失敗しました', UPDATE_FAILED: '買うものリストの更新に失敗しました',
DELETE_FAILED: '買うものリストの削除に失敗しました', DELETE_FAILED: '買うものリストの削除に失敗しました',
BUY_FAILED: '買うものリストの購入処理に失敗しました', BUY_FAILED: '買うものリストの購入処理に失敗しました',
INVALID_BUYAMOUNT: '購入数量が正しく入力されていません。',
}; };
// 材料リスト関連のエラーメッセージ(料理の追加編集で用いる) // 材料リスト関連のエラーメッセージ(料理の追加編集で用いる)
@ -40,7 +42,6 @@ export const STOCK_ERRORS = {
CREATE_FAILED: '在庫リストの作成に失敗しました', CREATE_FAILED: '在庫リストの作成に失敗しました',
UPDATE_FAILED: '在庫リストの更新に失敗しました', UPDATE_FAILED: '在庫リストの更新に失敗しました',
DELETE_FAILED: '在庫リストの削除に失敗しました', DELETE_FAILED: '在庫リストの削除に失敗しました',
BUY_FAILED: '在庫リストの購入処理に失敗しました',
}; };
// 料理リスト関連のエラーメッセージ // 料理リスト関連のエラーメッセージ
@ -50,8 +51,15 @@ export const RECIPE_ERRORS = {
CREATE_FAILED: '料理リストの作成に失敗しました', CREATE_FAILED: '料理リストの作成に失敗しました',
UPDATE_FAILED: '料理リストの更新に失敗しました', UPDATE_FAILED: '料理リストの更新に失敗しました',
DELETE_FAILED: '料理リストの削除に失敗しました', DELETE_FAILED: '料理リストの削除に失敗しました',
INVALID_RECIPE_NAME: 'レシピ名が入力されていません!',
NO_STUFFS: '材料が追加されていません!',
INVALID_SERVINGS: '人数が入力されていません。',
}; };
// 購入履歴関連のエラーメッセージ
export const STUFF_HISTORY_ERRORS = {
FETCH_FAILED: '履歴の取得に失敗しました。',
};
// // タスク関連のエラーメッセージ // // タスク関連のエラーメッセージ
// export const TASK_ERRORS = { // export const TASK_ERRORS = {

@ -0,0 +1,16 @@
/**
*
* 使
*/
// 買うものリスト
export const TOBUY_MESSAGES = {
CREATE_OK: '買うものリストに追加されました!',
};
// 料理リスト
export const RECIPE_MESSAGES = {
SAVED: 'レシピが保存されました!',
SAVED_AND_ADDED: 'レシピが保存されて買うものリストに追加されました!',
NO_ADDITIONALS: '必要な食材が在庫にあったのでリストには追加されませんでした。',
}

@ -33,6 +33,8 @@ import { recipeApi, toBuyApi, stockApi } from '../services/api';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import MessageAlert from '../components/MessageAlert'; import MessageAlert from '../components/MessageAlert';
import { useMessage } from '../components/MessageContext'; import { useMessage } from '../components/MessageContext';
import { RECIPE_MESSAGES } from '../constants/normalMessages';
import { RECIPE_ERRORS } from '../constants/errorMessages';
const AddRecipe: React.FC = () => { const AddRecipe: React.FC = () => {
const { recipeId: recipeIdStr } = useParams(); const { recipeId: recipeIdStr } = useParams();
@ -66,7 +68,7 @@ const AddRecipe: React.FC = () => {
const [checked, setChecked] = useState(false); const [checked, setChecked] = useState(false);
// エラーメッセージ表示 // エラーメッセージ表示
const { showErrorMessage, showSuccessMessage } = useMessage(); const { showErrorMessage, showInfoMessage, showSuccessMessage } = useMessage();
const loadRecipe = async () => { const loadRecipe = async () => {
if (recipeId && !recipeLoaded) { if (recipeId && !recipeLoaded) {
@ -83,19 +85,19 @@ const AddRecipe: React.FC = () => {
if (!recipeName) { if (!recipeName) {
showErrorMessage('レシピ名が入力されていません!') showErrorMessage('レシピ名が入力されていません!')
console.log("yes1"); // console.log("yes1");
return false; return false;
} }
if (!items.length) { if (!items.length) {
showErrorMessage('材料が追加されていません!') showErrorMessage('材料が追加されていません!')
console.log("yes2"); // console.log("yes2");
return false; return false;
} }
try { try {
if (!recipeId) { if (!recipeId) {
console.log("yes3"); // console.log("yes3");
// 新規追加 // 新規追加
const response = await recipeApi.addRecipe({ const response = await recipeApi.addRecipe({
recipeName, recipeName,
@ -115,21 +117,21 @@ const AddRecipe: React.FC = () => {
showErrorMessage('レシピの送信に失敗しました。同じ料理名が存在する可能性があります。'); showErrorMessage('レシピの送信に失敗しました。同じ料理名が存在する可能性があります。');
return false; return false;
} }
console.log("yes4"); // console.log("yes4");
return recipeId; return recipeId;
} }
const checkRecipeAndItems = async () => { const checkRecipeAndItems = async () => {
if (!recipeName) { if (!recipeName) {
showErrorMessage('レシピ名が入力されていません!') showErrorMessage(RECIPE_ERRORS.INVALID_RECIPE_NAME);
console.log("yes1"); // console.log("yes1");
return false; return false;
} }
if (!items.length) { if (!items.length) {
showErrorMessage('材料が追加されていません!') showErrorMessage(RECIPE_ERRORS.NO_STUFFS);
console.log("yes2"); // console.log("yes2");
return false; return false;
} }
return true; return true;
@ -138,20 +140,20 @@ const AddRecipe: React.FC = () => {
const handleSubmit = async () => { const handleSubmit = async () => {
const recipeId = await handleSaveRecipe(); const recipeId = await handleSaveRecipe();
if (!recipeId) return; if (!recipeId) return;
showSuccessMessage('レシピが保存されました!'); showSuccessMessage(RECIPE_MESSAGES.SAVED);
navigate('/recipeList'); navigate('/recipeList');
} }
const handleSubmitAndAddToBuy = async () => { const handleSubmitAndAddToBuy = async () => {
console.log("too"); // console.log("too");
console.log(recipeName); console.log('recipeName:', recipeName);
const recipeId = await handleSaveRecipe(); const recipeId = await handleSaveRecipe();
console.log("before"); // console.log("before");
if (!recipeId) return false; if (!recipeId) return false;
console.log("ds"); // console.log("ds");
if (!numOfPeaple) { if (!numOfPeaple) {
showErrorMessage('人数が入力されていません!') showErrorMessage(RECIPE_ERRORS.INVALID_SERVINGS);
console.log("yes2"); // console.log("yes2");
return false; return false;
} }
const finalAddResult = await toBuyApi.addByRecipe(recipeId, numOfPeaple, checked); const finalAddResult = await toBuyApi.addByRecipe(recipeId, numOfPeaple, checked);
@ -175,10 +177,10 @@ const AddRecipe: React.FC = () => {
// })) // }))
// }); // });
if (finalAddResult.data.length === 0) { if (finalAddResult.data.length === 0) {
showSuccessMessage('必要な食材が在庫にあったのでリストには追加されませんでした!'); showInfoMessage(RECIPE_MESSAGES.NO_ADDITIONALS);
} }
else { else {
showSuccessMessage('レシピが保存されて買うものリストに追加されました!'); showSuccessMessage(RECIPE_MESSAGES.SAVED_AND_ADDED);
} }
navigate('/tasks'); navigate('/tasks');
} }

@ -32,6 +32,7 @@ import {
} from '@mui/icons-material'; } from '@mui/icons-material';
import { ToBuy, Stuff, RecipeWithId, RecipeDetail } from '../types/types'; import { ToBuy, Stuff, RecipeWithId, RecipeDetail } from '../types/types';
import { useMessage } from '../components/MessageContext'; import { useMessage } from '../components/MessageContext';
import { RECIPE_ERRORS } from '../constants/errorMessages';
const RecipeList: React.FC = () => { const RecipeList: React.FC = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -51,7 +52,7 @@ const RecipeList: React.FC = () => {
const recipes = await recipeApi.getAllRecipes(); const recipes = await recipeApi.getAllRecipes();
setAllRecipes(recipes); setAllRecipes(recipes);
} catch (error) { } catch (error) {
showErrorMessage("レシピの取得に失敗しました。"); showErrorMessage(RECIPE_ERRORS.FETCH_FAILED);
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error); // console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
} }
}; };

@ -25,7 +25,8 @@ import {
SoupKitchen as SoupKitchenIcon, Edit as EditIcon SoupKitchen as SoupKitchenIcon, Edit as EditIcon
} from '@mui/icons-material'; } from '@mui/icons-material';
import { ToBuy, Stuff, NewToBuy, NewStock, StuffAndCategoryAndAmount, StuffNameAndAmount, StockHistory, /*Stock*/ } from '../types/types'; import { ToBuy, Stuff, NewToBuy, NewStock, StuffAndCategoryAndAmount, StuffNameAndAmount, StockHistory, /*Stock*/ } from '../types/types';
import { GENERAL_ERRORS, TOBUY_ERRORS } from '../constants/errorMessages'; import { GENERAL_ERRORS, TOBUY_ERRORS, STUFF_HISTORY_ERRORS } from '../constants/errorMessages';
import { TOBUY_MESSAGES } from '../constants/normalMessages';
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';
@ -96,7 +97,7 @@ const TaskListPage: React.FC = () => {
shop: undefined, shop: undefined,
}); });
const { showErrorMessage } = useMessage(); const { showErrorMessage, showSuccessMessage } = useMessage();
// コンポーネントマウント時にタスク一覧を取得 // コンポーネントマウント時にタスク一覧を取得
useEffect(() => { useEffect(() => {
@ -158,11 +159,20 @@ const TaskListPage: React.FC = () => {
return; return;
} }
newToBuy.stuffName = newToBuy.stuffName.trim(); // 材料名の前後の空白を削除
if (!newToBuy.stuffName) {
showErrorMessage(GENERAL_ERRORS.INVALID_STUFF_NAME);
return;
}
console.log(newToBuy) console.log(newToBuy)
await toBuyApi.addToBuy(newToBuy); await toBuyApi.addToBuy(newToBuy);
setOpenAddToBuyDialog(false); // ダイアログを閉じる setOpenAddToBuyDialog(false); // ダイアログを閉じる
showSuccessMessage(TOBUY_MESSAGES.CREATE_OK);
setNewToBuy(EMPTY_TOBUY); // 入力内容をリセット setNewToBuy(EMPTY_TOBUY); // 入力内容をリセット
fetchTasks(); // 作成後のタスク一覧を再取得 fetchTasks(); // 作成後のタスク一覧を再取得
} catch (error) { } catch (error) {
console.error(`${TOBUY_ERRORS.CREATE_FAILED}:`, error); console.error(`${TOBUY_ERRORS.CREATE_FAILED}:`, error);
} }
@ -197,17 +207,17 @@ const TaskListPage: React.FC = () => {
try { try {
const today = new Date().toISOString().substring(0, 10); const today = new Date().toISOString().substring(0, 10);
const parsedPrice = parseInt(newStock.price, 10); const parsedPrice = parseInt(newStock.price, 10);
console.log("newPrice:", newStock.price) console.log("newPrice:", newStock.price);
console.log("parsedPrice: ", parsedPrice) console.log("parsedPrice: ", parsedPrice);
if (isNaN(parsedPrice)) { if (isNaN(parsedPrice)) {
showErrorMessage(GENERAL_ERRORS.INVALID_PRICE) showErrorMessage(GENERAL_ERRORS.INVALID_PRICE);
return return;
//setNewStock({ ...newStock, price: parsedPrice }); //setNewStock({ ...newStock, price: parsedPrice });
} }
const amount = parseInt(newStock.amount, 10); const amount = parseInt(newStock.amount, 10);
if (isNaN(amount)) { if (isNaN(amount)) {
showErrorMessage('購入数量が正しく入力されていません。') showErrorMessage(TOBUY_ERRORS.INVALID_BUYAMOUNT);
return return;
} }
await toBuyApi.buy({ await toBuyApi.buy({
tobuyId: selectedToBuyId, tobuyId: selectedToBuyId,
@ -236,7 +246,7 @@ const TaskListPage: React.FC = () => {
setStockHistories(await stockApi.getHistories(tobuy.stuffId)); setStockHistories(await stockApi.getHistories(tobuy.stuffId));
setOpenHistoryDialog(true); setOpenHistoryDialog(true);
} catch { } catch {
showErrorMessage("履歴の読み込みに失敗しました。"); showErrorMessage(STUFF_HISTORY_ERRORS.FETCH_FAILED);
} }
} }

Loading…
Cancel
Save