/** * アプリケーションの共通レイアウトを提供するコンポーネント * ヘッダー(AppBar)とメインコンテンツ領域を含む基本的なページ構造を定義 */ import React, { useEffect, useState } from 'react'; import { AppBar, Toolbar, Typography, Container, Box, Button, Drawer, List, ListItemText, ListItemIcon, ListItemButton, Divider, IconButton, AlertColor, BottomNavigation, BottomNavigationAction, Paper } from '@mui/material'; import { Menu as MenuIcon, ListAlt as ListAltIcon, Inventory as InventoryIcon, // テストページ用のアイコン Science as ScienceIcon, // 鈴木 SoupKitchen as SoupKitchenIcon, ShoppingCart as ShoppingCartIcon } 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(); const location = useLocation(); const [drawerOpen, setDrawerOpen] = useState(false); const getTabIndex = (pathname: string) => { pathname = pathname.split("/")[1]; console.log(pathname); switch (pathname) { case 'stock': return 0; case 'tasks': return 1; case 'recipeList': return 2; case 'addRecipe': return 2; default: return -1; } }; const [bottomNavi, setBottomNavi] = useState(getTabIndex(location.pathname)); useEffect(() => { setBottomNavi(getTabIndex(location.pathname)); }, [location.pathname]); /** * ログアウト処理を行うハンドラー関数 * ローカルストレージからトークンを削除し、ログインページにリダイレクト */ const handleLogout = () => { localStorage.removeItem('token'); navigate('/login'); }; // メニューを開閉するハンドラー const toggleDrawer = () => { 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('info'); const showMessage = (msg: string, sev: AlertColor) => { console.log('ShowMessage:', msg, sev); 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'); }; const onBottomNaviChange = (event: React.SyntheticEvent, value: any) => { setBottomNavi(value); switch (value) { case 0: navigate('stock'); break; case 1: navigate('tasks'); break; case 2: navigate('recipeList'); break; } // ここでルーティング処理などを行う } return ( {/* ヘッダー部分 - アプリ名とログアウトボタンを表示 */} shopchop theme.zIndex.drawer + 1 }} elevation={3}> } /> } /> } /> {/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */} {/* React Router の Outlet - 子ルートのコンポーネントがここにレンダリングされる */} ); }; export default Layout;