/** * アプリケーションの共通レイアウトを提供するコンポーネント * ヘッダー(AppBar)とメインコンテンツ領域を含む基本的なページ構造を定義 */ import React, { useState } from 'react'; import { AppBar, Toolbar, Typography, Container, Box, Button, Drawer, List, ListItemText, ListItemIcon, ListItemButton, Divider, IconButton } from '@mui/material'; import { Menu as MenuIcon, ListAlt as ListAltIcon, Inventory as InventoryIcon, // テストページ用のアイコン Science as ScienceIcon, // 鈴木 SoupKitchen as SoupKitchenIcon, } from '@mui/icons-material'; import { useNavigate, Outlet, useLocation } from 'react-router-dom'; const Layout: React.FC = () => { const navigate = useNavigate(); const location = useLocation(); const [drawerOpen, setDrawerOpen] = useState(false); /** * ログアウト処理を行うハンドラー関数 * ローカルストレージからトークンを削除し、ログインページにリダイレクト */ const handleLogout = () => { localStorage.removeItem('token'); navigate('/login'); }; /** * 画面遷移処理を行うハンドラー関数 * 指定されたパスに遷移し、サイドメニューを閉じる */ const handleNavigate = (path: string) => { navigate(path); setDrawerOpen(false); }; // 現在のパスに基づいてメニュー項目が選択状態かどうかを判定 const isSelected = (path: string): boolean => { return location.pathname === path; }; // メニューを開閉するハンドラー const toggleDrawer = () => { setDrawerOpen(!drawerOpen); }; return ( {/* ヘッダー部分 - アプリ名とログアウトボタンを表示 */} shopchop {/* サイドメニュー */} setDrawerOpen(false)} > handleNavigate('/tasks')} selected={isSelected('/tasks')} > {/* テストページへのリンクを追加 */} {/* 在庫リストへのリンクを追加 */} handleNavigate('/addRecipe')} selected={isSelected('/addRecipe')} > handleNavigate('/recipeList')} selected={isSelected('/recipeList')} > handleNavigate('/stock')} selected={isSelected('/stock')} > {/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */} {/* React Router の Outlet - 子ルートのコンポーネントがここにレンダリングされる */} ); }; export default Layout;