全体的なレイアウトを統一

feature-dishuiandcolor^2
Masaharu.Kato 4 months ago
parent 2f910ce675
commit 51886f3730
  1. 40
      frontend/src/App.css
  2. 2
      frontend/src/App.tsx
  3. 2
      frontend/src/components/Layout.tsx
  4. 17
      frontend/src/pages/AddRecipe.tsx
  5. 50
      frontend/src/pages/RecipeList.tsx
  6. 123
      frontend/src/pages/StockPage.tsx
  7. 37
      frontend/src/pages/TaskListPage.tsx

@ -31,3 +31,43 @@ body {
.MuiPaper-root { .MuiPaper-root {
background-color: white; /* 白背景を確保 */ background-color: white; /* 白背景を確保 */
} }
.mainContainer {
padding-top: 0;
padding-left: 0;
padding-right: 0;
padding-bottom: 80px; /* ボトムナビゲーションバーで隠れる分 */
}
.mainTitle {
padding-left: 1rem;
font-size: 2rem;
margin-bottom: 0.25rem;
}
.listWrapper {
background: #ebcba2;
margin: 0;
padding: 1rem;
}
.plusButtonWrapper {
position: fixed !important;
text-align: center;
bottom: 80px;
left: 80%;
transform: translateX(-50%);
}
.plusButtonLabel {
font-size: 0.9rem;
color: #000;
background: rgba(255, 255, 255, 0.8);
padding: 0.5rem;
border-radius: 4px;
white-space: nowrap;
}
.plusButton {
/* box-shadow: 0px 4px 15px 5px #ebcba2 !important; */
}

@ -29,7 +29,7 @@ const theme = createTheme({
palette: { palette: {
mode: 'light', mode: 'light',
primary: { primary: {
main: '#1976d2', main: '#d27619',
}, },
secondary: { secondary: {
main: '#dc004e', main: '#dc004e',

@ -167,7 +167,7 @@ const Layout: React.FC = () => {
{/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */} {/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */}
<Box component="main" sx={{ flexGrow: 1, bgcolor: 'background.default', py: 3 }}> <Box component="main" sx={{ flexGrow: 1, bgcolor: 'background.default', py: 3 }}>
<Container> <Container sx={{ padding: 0, margin: 0 }}>
<MessageContext.Provider value={{ showErrorMessage, showWarningMessage, showSuccessMessage, showInfoMessage }}> <MessageContext.Provider value={{ showErrorMessage, showWarningMessage, showSuccessMessage, showInfoMessage }}>
<MessageAlert <MessageAlert
open={msgOpen} open={msgOpen}

@ -21,6 +21,7 @@ import {
Checkbox, Checkbox,
FormControlLabel, FormControlLabel,
Box, Box,
Container,
} from '@mui/material'; } from '@mui/material';
import { import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon, Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
@ -203,16 +204,17 @@ const AddRecipe: React.FC = () => {
}, []); }, []);
return ( return (
<> <div className="mainContainer">
{(recipeId && !recipeLoaded) {(recipeId && !recipeLoaded)
? <p>...</p> ? <p>...</p>
: :
<Box> <>
<div> <div className="mainTitle">
<h1>
<SoupKitchenIcon sx={{ marginRight: "0.5em" }} /> <SoupKitchenIcon sx={{ marginRight: "0.5em" }} />
{!recipeId ? '料理の追加' : '料理の編集'} {!recipeId ? '料理の追加' : '料理の編集'}
</h1> </div>
<div style={{padding: '1rem'}}>
<div>
<TextField autoFocus margin="dense" label="料理名" fullWidth <TextField autoFocus margin="dense" label="料理名" fullWidth
value={recipeName} onChange={(e) => setRecipeName(e.target.value)} value={recipeName} onChange={(e) => setRecipeName(e.target.value)}
/> />
@ -381,9 +383,10 @@ const AddRecipe: React.FC = () => {
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</Box> </div>
}
</> </>
}
</div>
); );
}; };

@ -26,6 +26,7 @@ import {
FormControl, FormControl,
InputLabel InputLabel
} from '@mui/material'; } from '@mui/material';
import '../App.css';
import { import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon, Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
SoupKitchen as SoupKitchenIcon SoupKitchen as SoupKitchenIcon
@ -63,54 +64,45 @@ const RecipeList: React.FC = () => {
}, []); }, []);
return ( return (
<Container> <div className="mainContainer">
<Box> <div className="mainTitle">
<div> <SoupKitchenIcon sx={{ mr: "0.5em" }} />
<h1 style={{ fontSize: "40px", textAlign: "center" }}></h1>
</div> </div>
<div style={{ <div className="listWrapper">
border: '3px solid black', borderRadius: '8px', height: '500px', <List>
overflowY: 'auto', padding: '20px'
}}>
{/* <List> */}
{/* 料理一覧をマップして各タスクをリストアイテムとして表示 */} {/* 料理一覧をマップして各タスクをリストアイテムとして表示 */}
{!allRecipes {!allRecipes
? <p>...</p> ? <p>...</p>
: allRecipes.map((recipe, index) => ( : allRecipes.map((recipe, index) => (
<FormGroup> <ListItem
<Button
// <ListItem
key={recipe.recipeId} key={recipe.recipeId}
sx={{ sx={{
color: 'primary',
bgcolor: 'background.paper', bgcolor: 'background.paper',
mb: 1, mb: 1,
borderRadius: 1, borderRadius: 1,
boxShadow: 1, boxShadow: 1,
fontSize: '40px' fontSize: '1.5rem'
}} }}
onClick={() => openRecipeById(recipe.recipeId)} onClick={() => openRecipeById(recipe.recipeId)}
> >
{recipe.recipeName} {recipe.recipeName}
</Button> </ListItem>
</FormGroup>
// </ListItem>
))} ))}
{/* </List> */} </List>
</div>
<div style={{ width: "100%", position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "64px" }}>
<Button variant='contained' sx={{
width: "60%", height: "60px",
fontSize: "32px", left: "50%", transform: 'translateX(-50%)'
}}
color="primary"
onClick={() => navigate('/addRecipe')}
>
</Button>
</div> </div>
<Box className="plusButtonWrapper">
<Fab color="primary" onClick={() => navigate('/addRecipe')} className="plusButton">
<AddIcon />
</Fab>
{/* <Typography className="plusButtonLabel">
</Typography> */}
</Box> </Box>
</Container> </div>
); );
}; };

@ -26,8 +26,9 @@ import {
Select, Select,
MenuItem, MenuItem,
} from '@mui/material'; } from '@mui/material';
import '../App.css';
import { GENERAL_ERRORS, STOCK_ERRORS } from '../constants/errorMessages'; import { GENERAL_ERRORS, STOCK_ERRORS } from '../constants/errorMessages';
import { Add as AddIcon } from '@mui/icons-material'; import { Add as AddIcon, KeyboardArrowDown as ArrowDownIcon, KeyboardArrowUp as ArrowUpIcon, Inventory as InventoryIcon } from '@mui/icons-material';
import DatePicker, { registerLocale } from 'react-datepicker'; import DatePicker, { registerLocale } from 'react-datepicker';
import { ja } from 'date-fns/locale/ja'; // date-fnsの日本語ロケールをインポート import { ja } from 'date-fns/locale/ja'; // date-fnsの日本語ロケールをインポート
import { useMessage } from '../components/MessageContext'; import { useMessage } from '../components/MessageContext';
@ -79,6 +80,19 @@ const StockPage: React.FC = () => {
const { showErrorMessage, showWarningMessage } = useMessage(); const { showErrorMessage, showWarningMessage } = useMessage();
// カテゴリ名一覧
const CATEGORY_NAMES = [
"乳製品",
"魚・肉",
"野菜",
"調味料",
"その他",
];
const [openCategory, setOpenCategory] = useState(Object.fromEntries(
CATEGORY_NAMES.map(category => [category, true])
));
// コンポーネントマウント時にタスク一覧を取得 // コンポーネントマウント時にタスク一覧を取得
useEffect(() => { useEffect(() => {
fetchStocks(); fetchStocks();
@ -209,15 +223,6 @@ const StockPage: React.FC = () => {
}; };
*/ */
/** 追加ボタンを押したときにダイアログを開く */
const handleOpenAdd = () => {
setIsAddOpen(true);
};
/** 追加ダイアログを閉じる */
const handleCloseAdd = () => {
setIsAddOpen(false);
};
/** /**
* *
*/ */
@ -358,8 +363,8 @@ const StockPage: React.FC = () => {
return ( return (
<> <>
<TableContainer component={Paper}> <TableContainer component={Paper}>
<Table> <Table size="small">
<TableHead sx={{ backgroundColor: "#dcdcdc", color: "#333" }}> <TableHead sx={{ backgroundColor: "#ebcba2", color: "#333" }}>
<TableRow> <TableRow>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell> <TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell>
<TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}></TableCell> <TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}></TableCell>
@ -588,44 +593,14 @@ const StockPage: React.FC = () => {
}; };
return ( return (
<Container> <div className="mainContainer">
<Typography variant="h3" component="h1" sx={{ mb: 4 }} > <div className="mainTitle">
<InventoryIcon sx={{ mr: "0.5em" }} />
</Typography> </div>
<Box
sx={{
position: 'fixed', // ← sticky から fixed に変更
bottom: 55, // ← 下に固定
left: 0,
right: 0,
zIndex: 1300, // ダイアログよりは低く
backgroundColor: '#f5f5f5',
// backgroundColor: 'white',
// padding: 2,
px: 2,
py: 1,
display: 'flex',
justifyContent: 'flex-end', // ← 左寄せ
boxShadow: 'none', // 軽めの上向きシャドウ
}}
>
{/* 在庫の食材追加ボタン */}
<Box sx={{
display: 'flex', flexDirection: 'column', alignItems: 'flex-end',
mr: 2
}}>
<Typography variant="caption" color="textSecondary">
</Typography>
<Fab color="primary" onClick={handleOpenAdd} >
<AddIcon />
</Fab>
</Box>
{/* 新規タスク作成ダイアログ */} {/* 新規タスク作成ダイアログ */}
<Dialog open={isAddOpen} onClose={handleCloseAdd} disableScrollLock={true}> <Dialog open={isAddOpen} onClose={() => setIsAddOpen(false)} disableScrollLock={true}>
<Box display="flex" alignItems="center" > <Box display="flex" alignItems="center" >
<DialogTitle sx={{ flexGrow: 1 }}> <DialogTitle sx={{ flexGrow: 1 }}>
<Typography variant="h5" > <Typography variant="h5" >
@ -641,6 +616,7 @@ const StockPage: React.FC = () => {
/> />
</FormGroup> </FormGroup>
</Box> </Box>
<DialogContent> <DialogContent>
<Box sx={{ pt: 1 }}> <Box sx={{ pt: 1 }}>
{/*材料カテゴリ選択 */} {/*材料カテゴリ選択 */}
@ -792,40 +768,33 @@ const StockPage: React.FC = () => {
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</Box>
{/* 在庫一覧リスト */}
{/* 乳製品 */}
<Typography variant="h4" component="h1" gutterBottom></Typography>
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px', marginBottom: "20px" }}>
{StockTable(stocks, ["乳製品"])}
</div>
{/* 肉・魚 */} {/* 各カテゴリを表示 */}
<Typography variant="h4" component="h1" gutterBottom></Typography> {CATEGORY_NAMES.map(category => {
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px', marginBottom: "20px" }}> return (
{StockTable(stocks, ["魚・肉"])} <Box sx={{ padding: "1rem" }}>
</div> <Typography variant="h5" component="h1" gutterBottom
onClick={() => setOpenCategory({...openCategory, [category]: !openCategory[category]})}
{/* 野菜 */} >
<Typography variant="h4" component="h1" gutterBottom></Typography> {!openCategory[category] ? <ArrowDownIcon color="primary" /> : <ArrowUpIcon color="primary" />}
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px', marginBottom: "20px" }}> {category}
{StockTable(stocks, ["野菜"])} </Typography>
</div> {openCategory[category] && StockTable(stocks, [category])}
</Box>
)
})}
{/* 調味料 */} {/* 材料ボタン - 画面下部に固定表示 */}
<Typography variant="h4" component="h1" gutterBottom>調</Typography> <Box className="plusButtonWrapper">
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px', marginBottom: "20px" }}> <Fab color="primary" onClick={() => setIsAddOpen(true)} className="plusButton">
{StockTable(stocks, ["調味料"])} <AddIcon />
</div> </Fab>
{/* <Typography className="plusButtonLabel">
</Typography> */}
</Box>
{/* その他 */}
<Typography variant="h4" component="h1" gutterBottom></Typography>
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px', marginBottom: "20px" }}>
{StockTable(stocks, ["その他"])}
</div> </div>
<Box sx={{ height: '80px' }} /> {/* フッターの高さと同じくらいに調整 */}
</Container>
); );
}; };

@ -22,8 +22,9 @@ import {
} from '@mui/material'; } from '@mui/material';
import { import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon, Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
SoupKitchen as SoupKitchenIcon, Edit as EditIcon SoupKitchen as SoupKitchenIcon, Edit as EditIcon, ShoppingCart as ShoppingCartIcon
} from '@mui/icons-material'; } from '@mui/icons-material';
import '../App.css';
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, STUFF_HISTORY_ERRORS } from '../constants/errorMessages'; import { GENERAL_ERRORS, TOBUY_ERRORS, STUFF_HISTORY_ERRORS } from '../constants/errorMessages';
import { TOBUY_MESSAGES } from '../constants/normalMessages'; import { TOBUY_MESSAGES } from '../constants/normalMessages';
@ -251,19 +252,20 @@ const TaskListPage: React.FC = () => {
} }
return ( return (
<Container> <div className="mainContainer">
<Typography variant="h4" component="h1" gutterBottom> <div className="mainTitle">
<ShoppingCartIcon sx={{ mr: "0.5em" }} />
</Typography> </div>
{/* タスク一覧表示エリア - 青い背景のコンテナ */} {/* 買うものリスト表示エリア - 背景色のコンテナ */}
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px' }}> <div className="listWrapper">
<List> <List>
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */} {/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{tobuys && tobuys.map((tobuy) => ( {tobuys && tobuys.map((tobuy) => (
<ListItem <ListItem
key={tobuy.tobuyId} key={tobuy.tobuyId}
sx={{ sx={{
bgcolor: 'background.paper', bgcolor: "background.paper",
mb: 1, mb: 1,
borderRadius: 1, borderRadius: 1,
boxShadow: 1, boxShadow: 1,
@ -339,19 +341,16 @@ const TaskListPage: React.FC = () => {
))} ))}
</List> </List>
</div> </div>
{/* 新規材料作成ボタン - 画面下部に固定表示 */}
<Box sx={{ textAlign: 'center', position: 'fixed', bottom: 66, left: '80%', transform: 'translateX(-50%)' }}> {/* 材料追加ボタン - 画面下部に固定表示 */}
<Typography variant="caption" color="textSecondary"> <Box className="plusButtonWrapper">
<Fab color="primary" onClick={() => setOpenAddToBuyDialog(true)} className="plusButton">
</Typography>
</Box>
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 90, left: '80%', transform: 'translateX(-50%)' }}
onClick={() => setOpenAddToBuyDialog(true)}
>
<AddIcon /> <AddIcon />
</Fab> </Fab>
{/* <Typography className="plusButtonLabel">
</Typography> */}
</Box>
{/*新規料理追加ボタン - 画面下部に固定表示 */} {/*新規料理追加ボタン - 画面下部に固定表示 */}
{/* <Box sx={{ textAlign: 'center', position: 'fixed', bottom: 66, left: '80%', transform: 'translateX(-50%)' }}> {/* <Box sx={{ textAlign: 'center', position: 'fixed', bottom: 66, left: '80%', transform: 'translateX(-50%)' }}>
@ -413,7 +412,7 @@ const TaskListPage: React.FC = () => {
<StuffHistoryDialog openDialog={openHistoryDialog} setOpenDialog={setOpenHistoryDialog} stuffName={historyTobuy.stuffName} stockHistories={stockHistories} /> <StuffHistoryDialog openDialog={openHistoryDialog} setOpenDialog={setOpenHistoryDialog} stuffName={historyTobuy.stuffName} stockHistories={stockHistories} />
} }
</Container> </div>
); );
}; };

Loading…
Cancel
Save