|
|
|
@ -2,7 +2,7 @@ |
|
|
|
|
* アプリケーションの共通レイアウトを提供するコンポーネント |
|
|
|
|
* ヘッダー(AppBar)とメインコンテンツ領域を含む基本的なページ構造を定義 |
|
|
|
|
*/ |
|
|
|
|
import React, { useState } from 'react'; |
|
|
|
|
import React, { useEffect, useState } from 'react'; |
|
|
|
|
import { |
|
|
|
|
AppBar, |
|
|
|
|
Toolbar, |
|
|
|
@ -16,7 +16,8 @@ import { |
|
|
|
|
ListItemIcon, |
|
|
|
|
ListItemButton, |
|
|
|
|
Divider, |
|
|
|
|
IconButton |
|
|
|
|
IconButton, |
|
|
|
|
AlertColor |
|
|
|
|
} from '@mui/material'; |
|
|
|
|
import { |
|
|
|
|
Menu as MenuIcon, |
|
|
|
@ -26,6 +27,8 @@ import { |
|
|
|
|
SoupKitchen as SoupKitchenIcon, |
|
|
|
|
} from '@mui/icons-material'; |
|
|
|
|
import { useNavigate, Outlet, useLocation } from 'react-router-dom'; |
|
|
|
|
import { MessageContext } from './MessageContext'; |
|
|
|
|
import MessageAlert from './MessageAlert'; |
|
|
|
|
|
|
|
|
|
const Layout: React.FC = () => { |
|
|
|
|
const navigate = useNavigate(); |
|
|
|
@ -60,6 +63,40 @@ const Layout: React.FC = () => { |
|
|
|
|
setDrawerOpen(!drawerOpen); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// メッセージ表示
|
|
|
|
|
|
|
|
|
|
// ページ遷移後もメッセージを維持
|
|
|
|
|
useEffect(() => { |
|
|
|
|
const saved = sessionStorage.getItem('globalMessage'); |
|
|
|
|
if (saved) { |
|
|
|
|
const { message, severity } = JSON.parse(saved); |
|
|
|
|
showMessage(message, severity); |
|
|
|
|
} |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
const [msgOpen, setMsgOpen] = useState(false); |
|
|
|
|
const [msgText, setMsgText] = useState(''); |
|
|
|
|
const [msgType, setMsgType] = useState<AlertColor>('info'); |
|
|
|
|
|
|
|
|
|
const showMessage = (msg: string, sev: AlertColor) => { |
|
|
|
|
setMsgText(msg); |
|
|
|
|
setMsgType(sev); |
|
|
|
|
setMsgOpen(true); |
|
|
|
|
sessionStorage.setItem('globalMessage', JSON.stringify({ message: msg, severity: sev })); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
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 handleMsgClose = () => { |
|
|
|
|
setMsgOpen(false); |
|
|
|
|
setMsgText(''); |
|
|
|
|
sessionStorage.removeItem('globalMessage'); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}> |
|
|
|
|
{/* ヘッダー部分 - アプリ名とログアウトボタンを表示 */} |
|
|
|
@ -103,16 +140,16 @@ const Layout: React.FC = () => { |
|
|
|
|
</ListItemButton> |
|
|
|
|
{/* テストページへのリンクを追加 */} |
|
|
|
|
|
|
|
|
|
{/* 在庫リストへのリンクを追加 */}
|
|
|
|
|
<ListItemButton
|
|
|
|
|
onClick={() => handleNavigate('/addRecipe')}
|
|
|
|
|
{/* 在庫リストへのリンクを追加 */} |
|
|
|
|
<ListItemButton |
|
|
|
|
onClick={() => handleNavigate('/addRecipe')} |
|
|
|
|
selected={isSelected('/addRecipe')} |
|
|
|
|
> |
|
|
|
|
<ListItemIcon><SoupKitchenIcon /></ListItemIcon> |
|
|
|
|
<ListItemText primary="料理の追加" /> |
|
|
|
|
</ListItemButton> |
|
|
|
|
<ListItemButton
|
|
|
|
|
onClick={() => handleNavigate('/recipeList')}
|
|
|
|
|
<ListItemButton |
|
|
|
|
onClick={() => handleNavigate('/recipeList')} |
|
|
|
|
selected={isSelected('/recipeList')} |
|
|
|
|
> |
|
|
|
|
<ListItemIcon><ScienceIcon /></ListItemIcon> |
|
|
|
@ -133,7 +170,17 @@ const Layout: React.FC = () => { |
|
|
|
|
{/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */} |
|
|
|
|
<Box component="main" sx={{ flexGrow: 1, bgcolor: 'background.default', py: 3 }}> |
|
|
|
|
<Container> |
|
|
|
|
<Outlet /> {/* React Router の Outlet - 子ルートのコンポーネントがここにレンダリングされる */} |
|
|
|
|
|
|
|
|
|
<MessageContext.Provider value={{ showErrorMessage, showWarningMessage, showSuccessMessage, showInfoMessage }}> |
|
|
|
|
<MessageAlert |
|
|
|
|
open={msgOpen} |
|
|
|
|
message={msgText} |
|
|
|
|
severity={msgType} |
|
|
|
|
onClose={handleMsgClose} |
|
|
|
|
/> |
|
|
|
|
<Outlet /> {/* React Router の Outlet - 子ルートのコンポーネントがここにレンダリングされる */} |
|
|
|
|
</MessageContext.Provider> |
|
|
|
|
|
|
|
|
|
</Container> |
|
|
|
|
</Box> |
|
|
|
|
</Box> |
|
|
|
|