フォーマット調整

feature-frontend-bug-fixes
Masaharu.Kato 4 months ago
parent 8b4afe5731
commit 525a52bbb8
  1. 26
      frontend/src/App.css
  2. 4
      frontend/src/components/AddByRecipeDialog.tsx
  3. 50
      frontend/src/components/AddStuffAmountDialog.tsx
  4. 167
      frontend/src/components/BuyDialog.tsx
  5. 10
      frontend/src/components/BuyExpDateSelect.tsx
  6. 28
      frontend/src/components/CategoryDropDown.tsx
  7. 2
      frontend/src/components/DeleteStuffDialog.tsx
  8. 2
      frontend/src/components/EditAmountDialog.tsx
  9. 154
      frontend/src/components/Layout.tsx
  10. 2
      frontend/src/components/MessageAlert.tsx
  11. 6
      frontend/src/components/StuffHistoryDialog.tsx
  12. 210
      frontend/src/pages/AddRecipe.tsx
  13. 457
      frontend/src/pages/DishList.tsx
  14. 2
      frontend/src/pages/LoginPage.tsx
  15. 8
      frontend/src/pages/RecipeList.tsx
  16. 310
      frontend/src/pages/StockPage.tsx

@ -7,18 +7,24 @@ body {
/* アプリケーションのルートコンテナスタイル */
.app {
display: flex;
flex-direction: column; /* 子要素を縦方向に配置 */
min-height: 100vh; /* ビューポートの高さいっぱいに広げる */
background-color: #f5f5f5; /* 薄いグレーの背景色 */
flex-direction: column;
/* 子要素を縦方向に配置 */
min-height: 100vh;
/* ビューポートの高さいっぱいに広げる */
background-color: #f5f5f5;
/* 薄いグレーの背景色 */
}
/* メインコンテンツエリアのスタイル */
.main-content {
flex: 1; /* 利用可能なスペースをすべて使用 */
flex: 1;
/* 利用可能なスペースをすべて使用 */
padding: 24px;
width: 100%;
max-width: 1200px; /* コンテンツの最大幅を制限 */
margin: 0 auto; /* 中央揃え */
max-width: 1200px;
/* コンテンツの最大幅を制限 */
margin: 0 auto;
/* 中央揃え */
}
/* Material UIのコンテナコンポーネントのカスタマイズ */
@ -29,14 +35,16 @@ body {
/* Material UIのペーパーコンポーネントのカスタマイズ */
.MuiPaper-root {
background-color: white; /* 白背景を確保 */
background-color: white;
/* 白背景を確保 */
}
.mainContainer {
padding-top: 0;
padding-left: 0;
padding-right: 0;
padding-bottom: 80px; /* ボトムナビゲーションバーで隠れる分 */
padding-bottom: 80px;
/* ボトムナビゲーションバーで隠れる分 */
}
.mainTitle {
@ -75,4 +83,4 @@ body {
.numberField {
width: 6rem;
/* text-align: right; */
}
}

@ -76,10 +76,10 @@ const AddByRecipeDialog = ({
/>
</DialogTitle>
<DialogContent dividers sx={{ padding: 2 }}>
<Typography sx={{fontSize: '1.6rem'}}>
<Typography sx={{ fontSize: '1.6rem' }}>
{recipe.recipeName}
</Typography>
<Typography sx={{mt: 2, mb: 2}}>
<Typography sx={{ mt: 2, mb: 2 }}>
({recipe.maxServings})
</Typography>
<div>

@ -50,7 +50,7 @@ const AddStuffAmountDialog = ({
const [stuffs, setStuffs] = useState<Stuff[]>();
const [newAddition, setNewAddition] = useState(false);
// エラーメッセージ表示
const { showErrorMessage } = useMessage();
@ -88,30 +88,30 @@ const AddStuffAmountDialog = ({
</FormControl>
{!newAddition && <FormControl sx={{ width: "100%", marginBottom: 2 }}>
{stuffs ?
<>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
labelId="demo-simple-select-label"
value={newItem.stuffId}
onChange={(e) => setNewItem({ ...newItem, stuffId: Number(e.target.value) })}
>
{stuffs.map((stuff) => (
<MenuItem key={stuff.stuffId} value={stuff.stuffId}>
{stuff.stuffName}
</MenuItem>
))}
</Select>
</>
:
<>
<InputLabel id="demo-simple-select-label">
{newItem.category ? '読み込み中...' : 'カテゴリを選択してください...'}
</InputLabel>
<Select labelId="demo-simple-select-label" value="" disabled>
</Select>
</>
}
{stuffs ?
<>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
labelId="demo-simple-select-label"
value={newItem.stuffId}
onChange={(e) => setNewItem({ ...newItem, stuffId: Number(e.target.value) })}
>
{stuffs.map((stuff) => (
<MenuItem key={stuff.stuffId} value={stuff.stuffId}>
{stuff.stuffName}
</MenuItem>
))}
</Select>
</>
:
<>
<InputLabel id="demo-simple-select-label">
{newItem.category ? '読み込み中...' : 'カテゴリを選択してください...'}
</InputLabel>
<Select labelId="demo-simple-select-label" value="" disabled>
</Select>
</>
}
</FormControl>}
{/* タスクタイトル入力フィールド */}

@ -1,16 +1,16 @@
import { useState } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
Button,
Box,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
Button,
Box,
} from '@mui/material';
import { NewStock } from '../types/types';
import BuyExpDateSelect from './BuyExpDateSelect';
/*import DatePicker, { registerLocale } from 'react-datepicker';
/*import DatePicker, { registerLocale } from 'react-datepicker';F
import { ja } from 'date-fns/locale/ja'; // date-fnsの日本語ロケールをインポート*/
/*// yyyy-MM-dd形式で返す関数
@ -25,91 +25,90 @@ const formatDateLocal = (date: Date) => {
//registerLocale('ja', ja);
const BuyDialog = ({
openDialog,
setOpenDialog,
stuffName,
newStock,
setNewStock,
onSubmit,
openDialog,
setOpenDialog,
stuffName,
newStock,
setNewStock,
onSubmit,
}: {
openDialog: boolean,
setOpenDialog: (open: boolean) => void,
stuffName: string,
newStock: NewStock,
setNewStock: (tobuy: NewStock) => void,
onSubmit: () => void,
openDialog: boolean,
setOpenDialog: (open: boolean) => void,
stuffName: string,
newStock: NewStock,
setNewStock: (tobuy: NewStock) => void,
onSubmit: () => void,
}) => {
return (
return (
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true} PaperProps={{ sx: { minHeight: '600px', maxHeight: '80vh' } }}
>
<DialogTitle></DialogTitle>
<DialogContent>
<Box sx={{ pt: 1 }}>
{/* 材料名表示 */}
<TextField
margin="dense"
label="材料名"
fullWidth
value={stuffName}
disabled
sx={{ marginBottom: 2, marginTop: 2 }}
/>
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true} PaperProps={{ sx: { minHeight: '600px', maxHeight: '80vh' } }}
>
<DialogTitle></DialogTitle>
<DialogContent>
<Box sx={{ pt: 1 }}>
{/* 材料名表示 */}
<TextField
margin="dense"
label="材料名"
fullWidth
value={stuffName}
disabled
sx={{ marginBottom: 2, marginTop: 2 }}
/>
{/* 価格入力フィールド */}
<TextField
autoFocus
margin="dense"
label="価格"
fullWidth
value={newStock.price}
onChange={(e) => {
const value = e.target.value;
if (/^\d*$/.test(value)) {
setNewStock({ ...newStock, price: value })
};
}}
sx={{ marginBottom: 2 }}
/>
{/* 価格入力フィールド */}
<TextField
autoFocus
margin="dense"
label="価格"
fullWidth
value={newStock.price}
onChange={(e) => {
const value = e.target.value;
if (/^\d*$/.test(value)) {
setNewStock({ ...newStock, price: value })
};
}}
sx={{ marginBottom: 2 }}
/>
{/* 価格入力フィールド */}
<TextField
autoFocus
margin="dense"
label="購入数量"
fullWidth
value={newStock.amount}
onChange={(e) => {
const value = e.target.value;
if (/^\d*$/.test(value)) {
setNewStock({ ...newStock, amount: value })
};
}}
sx={{ marginBottom: 2 }}
/>
{/* 価格入力フィールド */}
<TextField
autoFocus
margin="dense"
label="購入数量"
fullWidth
value={newStock.amount}
onChange={(e) => {
const value = e.target.value;
if (/^\d*$/.test(value)) {
setNewStock({ ...newStock, amount: value })
};
}}
sx={{ marginBottom: 2 }}
/>
{/* 購入日・賞味期限入力 */}
<BuyExpDateSelect newStock={newStock} setNewStock={({ buyDate, expDate }) => setNewStock({ ...newStock, buyDate, expDate })} />
{/* 購入日・賞味期限入力 */}
<BuyExpDateSelect newStock={newStock} setNewStock={({buyDate, expDate}) => setNewStock({...newStock, buyDate, expDate}) } />
{/* 購入店舗入力フィールド */}
<TextField
margin="dense"
label="店舗"
value={newStock.shop}
onChange={(e) => setNewStock({ ...newStock, shop: e.target.value })}
fullWidth
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenDialog(false)}></Button>
<Button onClick={() => { onSubmit() }} variant="contained"></Button>
</DialogActions>
</Dialog>
{/* 購入店舗入力フィールド */}
<TextField
margin="dense"
label="店舗"
value={newStock.shop}
onChange={(e) => setNewStock({ ...newStock, shop: e.target.value })}
fullWidth
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenDialog(false)}></Button>
<Button onClick={() => { onSubmit() }} variant="contained"></Button>
</DialogActions>
</Dialog>
)
)
}
export default BuyDialog;

@ -28,11 +28,11 @@ const validateExpDate = ((buyDate: string, expDate: string | null) => {
})
const BuyExpDateSelect = ({
newStock,
setNewStock,
newStock,
setNewStock,
}: {
newStock: {buyDate: string, expDate: string | null},
setNewStock: (tobuy: {buyDate: string, expDate: string | null}) => void,
newStock: { buyDate: string, expDate: string | null },
setNewStock: (tobuy: { buyDate: string, expDate: string | null }) => void,
}) => {
{/* 購入日・消費期限を横並びに */ }
@ -72,7 +72,7 @@ const BuyExpDateSelect = ({
}
}}
/>
</Box>
}

@ -1,28 +0,0 @@
import React, { useState } from "react";
import MenuItem from "@mui/material/MenuItem";
import Select from "@mui/material/Select";
import FormControl from "@mui/material/FormControl";
import InputLabel from "@mui/material/InputLabel";
const CategoryDropDown = () => {
const [selectedValue, setSelectedValue] = useState(""); // 選択された値の状態管理
return (
<FormControl sx={{ width: "50%", marginBottom:2 }}>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
labelId="demo-simple-select-label"
value={selectedValue}
onChange={(event) => setSelectedValue(event.target.value)}
>
<MenuItem value="乳製品"></MenuItem>
<MenuItem value="魚・肉"></MenuItem>
<MenuItem value="野菜"></MenuItem>
<MenuItem value="調味料">調</MenuItem>
<MenuItem value="その他"></MenuItem>
</Select>
</FormControl>
);
};
export default CategoryDropDown;

@ -27,7 +27,7 @@ const DeleteStuffDialog = ({
>
<DialogTitle></DialogTitle>
<DialogContent>
<Typography sx={{fontSize: '1.6rem'}}>{stuffName} </Typography>
<Typography sx={{ fontSize: '1.6rem' }}>{stuffName} </Typography>
<Typography variant="body1" color="error"> 注意: 削除すると復元できません</Typography>
</DialogContent>
<DialogActions>

@ -25,7 +25,7 @@ const EditAmountDialog = ({
setEditingItem: (tobuy: StuffNameAndAmount) => void,
onSubmit: () => void,
}) => {
// エラーメッセージ表示
const { showErrorMessage } = useMessage();

@ -40,48 +40,48 @@ const Layout: React.FC = () => {
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);
};
// メッセージ表示
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(() => {
@ -131,36 +131,36 @@ const Layout: React.FC = () => {
// ここでルーティング処理などを行う
}
return (
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
{/* ヘッダー部分 - アプリ名とログアウトボタンを表示 */}
<AppBar position="static" elevation={0}>
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
shopchop
</Typography>
<Button color="inherit" onClick={handleLogout}>
</Button>
</Toolbar>
</AppBar>
<Paper sx={{ position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: (theme) => theme.zIndex.drawer + 1 }} elevation={3}>
<BottomNavigation
showLabels
value={bottomNavi}
onChange={onBottomNaviChange}
>
<BottomNavigationAction label="在庫" icon={<InventoryIcon />} />
<BottomNavigationAction label="買うもの" icon={<ShoppingCartIcon />} />
<BottomNavigationAction label="レシピ" icon={<SoupKitchenIcon />} />
</BottomNavigation>
</Paper>
{/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */}
<Box component="main" sx={{ flexGrow: 1, bgcolor: 'background.default', py: 3 }}>
<Container sx={{ padding: 0, mt: 0, mb: 0, mr: 'auto', ml: 'auto' }}>
<MessageContext.Provider value={{ showErrorMessage, showWarningMessage, showSuccessMessage, showInfoMessage }}>
return (
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
{/* ヘッダー部分 - アプリ名とログアウトボタンを表示 */}
<AppBar position="static" elevation={0}>
<Toolbar>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
shopchop
</Typography>
<Button color="inherit" onClick={handleLogout}>
</Button>
</Toolbar>
</AppBar>
<Paper sx={{ position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: (theme) => theme.zIndex.drawer + 1 }} elevation={3}>
<BottomNavigation
showLabels
value={bottomNavi}
onChange={onBottomNaviChange}
>
<BottomNavigationAction label="在庫" icon={<InventoryIcon />} />
<BottomNavigationAction label="買うもの" icon={<ShoppingCartIcon />} />
<BottomNavigationAction label="レシピ" icon={<SoupKitchenIcon />} />
</BottomNavigation>
</Paper>
{/* メインコンテンツ領域 - 子ルートのコンポーネントがここに表示される */}
<Box component="main" sx={{ flexGrow: 1, bgcolor: 'background.default', py: 3 }}>
<Container sx={{ padding: 0, mt: 0, mb: 0, mr: 'auto', ml: 'auto' }}>
<MessageContext.Provider value={{ showErrorMessage, showWarningMessage, showSuccessMessage, showInfoMessage }}>
<MessageAlert
open={msgOpen}
message={msgText}
@ -169,11 +169,11 @@ const Layout: React.FC = () => {
/>
<Outlet /> {/* React Router の Outlet - 子ルートのコンポーネントがここにレンダリングされる */}
</MessageContext.Provider>
</Container>
</Box>
</Container>
</Box>
);
};
</Box>
);
};
export default Layout;
export default Layout;

@ -18,7 +18,7 @@ const MessageAlert: React.FC<MessageAlertProps> = ({
}) => {
return (
<Snackbar open={open} autoHideDuration={duration} onClose={onClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} sx={{bottom: '120px'}}>
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} sx={{ bottom: '120px' }}>
<Alert onClose={onClose} severity={severity} sx={{ width: '100%' }}>
{message}
</Alert>

@ -93,9 +93,9 @@ const StuffHistoryDialog = ({
{history.buyDate}
</StyledTableCell>
{/* 「購入店舗」セルに nowrap と minWidth を適用 */}
<StyledTableCell sx={{whiteSpace: 'wrap'}}>{history.shop || ''}</StyledTableCell>
<StyledTableCell align="right" sx={{pr: '16px'}}>{history.buyAmount}</StyledTableCell>
<StyledTableCell align="right" sx={{pr: '16px'}}>{history.price}</StyledTableCell>
<StyledTableCell sx={{ whiteSpace: 'wrap' }}>{history.shop || ''}</StyledTableCell>
<StyledTableCell align="right" sx={{ pr: '16px' }}>{history.buyAmount}</StyledTableCell>
<StyledTableCell align="right" sx={{ pr: '16px' }}>{history.price}</StyledTableCell>
</TableRow>
))}
</TableBody>

@ -99,7 +99,7 @@ const AddRecipe: React.FC = () => {
try {
if (!recipeId) {
// console.log("yes3");
// 新規追加
// 新規追加
const response = await recipeApi.addRecipe({
recipeName,
summary: recipeSummary,
@ -167,7 +167,7 @@ const AddRecipe: React.FC = () => {
// // const stockedStuffAmountRecipe = recipeStuff.filter(recipe => (stockStuff.some(stuff => recipe.stuffId === stuff.stuffId)));
// // console.log(stockedStuffAmountRecipe)
// // const stockedStuffAmountStock = stockStuff.filter(stock => (stockedStuffAmountRecipe.some(stocked => stock.stuffId === stocked.stuffId)));
// // recipeStuff.map(item => {
// // await Promise.all(stockStuff.map(async stock => {
// // if (item.stuffId == stock.stuffId)
@ -209,121 +209,121 @@ const AddRecipe: React.FC = () => {
return (
<div className="mainContainer">
{(recipeId && !recipeLoaded)
? <p>...</p>
:
<>
<div className="mainTitle">
<SoupKitchenIcon sx={{ marginRight: "0.5em" }} />
{!recipeId ? '料理の追加' : '料理の編集'}
</div>
<div style={{padding: '1rem'}}>
<div>
<TextField autoFocus margin="dense" label="料理名" fullWidth
value={recipeName} onChange={(e) => setRecipeName(e.target.value)}
/>
<TextField margin="dense" label="説明" fullWidth
value={recipeSummary} onChange={(e) => setRecipeSummary(e.target.value)}
/>
</div>
<h2 style={{ marginTop: "0.5em" }}>
</h2>
{/* すべての材料情報を表示 */}
{(!items || !items.length)
? (<p>+</p>)
: (<List>{items.map((item, index) => (
{(recipeId && !recipeLoaded)
? <p>...</p>
:
<>
<div className="mainTitle">
<SoupKitchenIcon sx={{ marginRight: "0.5em" }} />
{!recipeId ? '料理の追加' : '料理の編集'}
</div>
<div style={{ padding: '1rem' }}>
<div>
<TextField autoFocus margin="dense" label="料理名" fullWidth
value={recipeName} onChange={(e) => setRecipeName(e.target.value)}
/>
<TextField margin="dense" label="説明" fullWidth
value={recipeSummary} onChange={(e) => setRecipeSummary(e.target.value)}
/>
</div>
<h2 style={{ marginTop: "0.5em" }}>
</h2>
{/* すべての材料情報を表示 */}
{(!items || !items.length)
? (<p>+</p>)
: (<List>{items.map((item, index) => (
<ListItem
key={index}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
<ListItemText primary={item.stuffName} />
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Typography variant="body1" component="span" sx={{ marginRight: '1em' }}>
{`× ${item.amount}`}
</Typography>
{/* 買い物リスト:数量変更ボタン */}
<Tooltip title="数量変更">
<IconButton sx={{ marginRight: 0, marginLeft: 0 }} edge="end" aria-label="数量変更"
onClick={() => {
setEditingItem(item)
setEditingItemIdx(index)
setOpenAmountDialog(true)
}}
>
<EditIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: { sx: { backgroundColor: "white", color: "red", fontSize: "0.8rem", padding: "6px", borderRadius: "6px" } },
}}>
<IconButton edge="end" sx={{ marginRight: 0, marginLeft: 0 }} aria-label="delete"
onClick={() => {
setEditingItem(item)
setEditingItemIdx(index)
setOpenDeleteDialog(true)
}}>
<DeleteIcon />
</IconButton>
</Tooltip>
<ListItem
key={index}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
<ListItemText primary={item.stuffName} />
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Typography variant="body1" component="span" sx={{ marginRight: '1em' }}>
{`× ${item.amount}`}
</Typography>
{/* 買い物リスト:数量変更ボタン */}
<Tooltip title="数量変更">
<IconButton sx={{ marginRight: 0, marginLeft: 0 }} edge="end" aria-label="数量変更"
onClick={() => {
setEditingItem(item)
setEditingItemIdx(index)
setOpenAmountDialog(true)
}}
>
<EditIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: { sx: { backgroundColor: "white", color: "red", fontSize: "0.8rem", padding: "6px", borderRadius: "6px" } },
}}>
<IconButton edge="end" sx={{ marginRight: 0, marginLeft: 0 }} aria-label="delete"
onClick={() => {
setEditingItem(item)
setEditingItemIdx(index)
setOpenDeleteDialog(true)
}}>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItemSecondaryAction>
</ListItem>
</ListItem>
))}</List>)}
))}</List>)}
<div style={{ position: "fixed", left: "80%", transform: 'translateX(-50%)', bottom: "10%" }}>
{/* <Box sx={{ textAlign: 'center' }}>
<div style={{ position: "fixed", left: "80%", transform: 'translateX(-50%)', bottom: "10%" }}>
{/* <Box sx={{ textAlign: 'center' }}>
<Typography variant="caption"></Typography>
</Box> */}
<Fab color="primary" onClick={() => setOpenAddDialog(true)}>
<AddIcon sx={{ fontSize: "1.5rem" }} />
</Fab>
</div>
<Fab color="primary" onClick={() => setOpenAddDialog(true)}>
<AddIcon sx={{ fontSize: "1.5rem" }} />
</Fab>
</div>
<div style={{ position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "64px", whiteSpace: 'nowrap' }}>
<Button variant='contained' color="primary" onClick={handleSubmit} sx={{ marginRight: "1rem" }}>
<SaveIcon sx={{ fontSize: "1.5rem", marginRight: "0.5rem" }} />
</Button>
</div>
<div style={{ position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "64px", whiteSpace: 'nowrap' }}>
<Button variant='contained' color="primary" onClick={handleSubmit} sx={{ marginRight: "1rem" }}>
<SaveIcon sx={{ fontSize: "1.5rem", marginRight: "0.5rem" }} />
</Button>
</div>
{/* 新規材料追加ダイアログ */}
<AddStuffAmountDialog openDialog={openAddDialog} setOpenDialog={setOpenAddDialog} newItem={newItem} setNewItem={setNewItem}
onSubmit={() => {
// console.log('newItem:', newItem);
setItems([...items, newItem]);
setOpenAddDialog(false);
}} />
{/* 新規材料追加ダイアログ */}
<AddStuffAmountDialog openDialog={openAddDialog} setOpenDialog={setOpenAddDialog} newItem={newItem} setNewItem={setNewItem}
onSubmit={() => {
// console.log('newItem:', newItem);
setItems([...items, newItem]);
setOpenAddDialog(false);
}} />
{/* 削除ダイアログ */}
<DeleteStuffDialog openDialog={openDeleteDialog} setOpenDialog={setOpenDeleteDialog}
stuffName={newItem.stuffName}
onSubmit={() => setItems([...items.slice(0, editingItemIdx), ...items.slice(editingItemIdx + 1)])}
/>
{/* 削除ダイアログ */}
<DeleteStuffDialog openDialog={openDeleteDialog} setOpenDialog={setOpenDeleteDialog}
stuffName={newItem.stuffName}
onSubmit={() => setItems([...items.slice(0, editingItemIdx), ...items.slice(editingItemIdx + 1)])}
/>
{/* 数量変更ダイアログ */}
<EditAmountDialog openDialog={openAmountDialog} setOpenDialog={setOpenAmountDialog}
editingItem={editingItem}
setEditingItem={(v) => setEditingItem({ ...editingItem, ...v })}
onSubmit={() => {
setItems([...items.slice(0, editingItemIdx), editingItem, ...items.slice(editingItemIdx + 1)])
setOpenAmountDialog(false);
}} />
{/* 数量変更ダイアログ */}
<EditAmountDialog openDialog={openAmountDialog} setOpenDialog={setOpenAmountDialog}
editingItem={editingItem}
setEditingItem={(v) => setEditingItem({ ...editingItem, ...v })}
onSubmit={() => {
setItems([...items.slice(0, editingItemIdx), editingItem, ...items.slice(editingItemIdx + 1)])
setOpenAmountDialog(false);
}} />
</div>
</>
}
</div>
</>
}
</div>
);
};

@ -1,457 +0,0 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { toBuyApi } from '../services/api';
import {
Container,
Typography,
Tooltip,
List,
ListItem,
ListItemText,
ListItemSecondaryAction,
IconButton,
Checkbox,
Fab,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
TextField,
Button,
Box,
FormControlLabel,
FormGroup,
MenuItem,
Select,
FormControl,
InputLabel
} from '@mui/material';
import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
SoupKitchen as SoupKitchenIcon
} from '@mui/icons-material';
import { ToBuy, Stuff } from '../types/types';
import { GENERAL_ERRORS } from '../constants/errorMessages';
import CategoryDropDown from "../components/CategoryDropDown";
const DishList: React.FC = () => {
const navigate = useNavigate();
// 料理リストの料理名を格納する配列
// const dishes = ;
// タスク一覧の状態管理
const [tobuys, setToBuys] = useState<ToBuy[]>([]);
const test = [1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1];
// APIができるまでのテスト用の型
interface Dish {
id:number,
name:string,
amount:number
}
// APIができるまでの食材配列
const testdish : Dish[] = [
{ id: 1, name: 'ジャガイモ', amount:1 },
{ id: 2, name: '人参', amount:2 },
{ id: 3, name: '人参', amount:2 },
{ id: 4, name: '人参', amount:2 }
];
// 画面表示用の食材情報配列
const [testDishArray, setTestDishArray] = useState<Dish[]>(testdish);
// エラーメッセージの状態管理
const [error, setError] = useState(false);
// 選択した料理の情報を表示するダイアログの表示状態
const [openDialog, setOpenDialog] = useState(false);
// 料理リスト編集ダイアログの表示状態
const [openChangeDialog, setOpenChangeDialog] = useState(false);
// 料理リストの食材の個数編集ダイアログの表示状態
const [openChangeItemDialog, setOpenChangeItemDialog] = useState(false);
const changeDialog = () => {
setOpenDialog(false);
setOpenChangeDialog(true);
setTestDishArray(testdish);
};
const cancelChange = () => {
setOpenDialog(true);
setOpenChangeDialog(false);
};
/**
*
* IDのタスクをAPIを通じて削除
*/
const handleDeleteStuffTemp = async (dish_id: number) => {
try {
let testDishArrayCopy = [...testDishArray]; // 配列をコピー
testDishArrayCopy.splice(dish_id, 1);
setTestDishArray(testDishArrayCopy);
// fetchTasks(); // 削除後のタスク一覧を再取得
} catch (error) {
// console.error(`${TASK_ERRORS.DELETE_FAILED}:`, error);
}
};
// コンポーネントマウント時にタスク一覧を取得
useEffect(() => {
fetchTasks();
}, []);
/**
* APIからタスク一覧を取得する関数
* state(tasks)
*/
// const fetchTasks = async () => {
// try {
// const tasks = await taskApi.getTasks();
// setTasks(tasks);
// } catch (error) {
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
// }
// };
const fetchTasks = async () => {
try {
const tobuys = await toBuyApi.getToBuys();
setToBuys(tobuys);
} catch (error) {
// console.error(`${TASK_ERRORS.FETCH_FAILED}:`, error);
}
};
return (
<Container>
<Box>
<div>
<h1 style={{fontSize: "40px", textAlign: "center"}}></h1>
</div>
<div style = {{border: '3px solid black', borderRadius: '8px', height: '500px',
overflowY: 'auto', padding: '20px'}}>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{test.map((test, index) => (
<FormGroup>
<Button
// <ListItem
key={index}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
fontSize: '40px'
}}
onClick={() => setOpenDialog(true)}
>
{test}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
{/* <ListItemText
primary={test}
//secondary={tobuy.amount}
sx={{
textDecoration: false ? 'line-through' : 'none',
}}
/> */}
</Button>
</FormGroup>
// </ListItem>
))}
{/* </List> */}
</div>
<div style={{width: "100%", position: "fixed", left: "50%", transform: 'translateX(-50%)', bottom: "64px"}}>
<Button variant='contained' sx={{
width: "60%",
fontSize: "24px", left: "50%", transform: 'translateX(-50%)' }}
color="primary"
onClick={() => navigate('/add1')}
>
</Button>
</div>
{/*新規料理追加ボタン - 画面下部に固定表示 */}
<Tooltip title="料理から追加">
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 106, left: '60%', transform: 'translateX(-50%)' }}
onClick={() => setOpenDialog(true)}
>
<SoupKitchenIcon />
</Fab>
</Tooltip>
</Box>
{/* 新規タスク作成ダイアログ */}
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{test.map((test, index) => (
<Button onClick={() => setOpenDialog(true)} key = {index}>
{test}
</Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => setOpenDialog(false)}></Button>
<Button onClick={() => changeDialog()} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
{/* 食材の個数の編集ダイアログ */}
<Dialog open={openChangeDialog} onClose={() => setOpenChangeDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{testDishArray.map((test, id) => (
<ListItem
key={id}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
{/*
<Checkbox
checked={task.completed}
onChange={() => handleToggleComplete(task.id)}
/> */}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
<ListItemText
primary={test.name}
// secondary={task.description}
sx={{width: '80%'}}
/>
{/* 食材の個数を表示 */}
<ListItemText
primary={<Typography style={{textAlign:"center"}}><br />
{test.amount}
</Typography>
}
// secondary={task.description}
sx={{ align: "right", fontSize: "20px" }}
/>
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Tooltip title="食材情報追加">
<IconButton
edge="end"
aria-label="食材情報追加"
//onClick={() => handleDeleteTask(task.id)}
>
<ShoppingBasketIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: {
sx: {
backgroundColor: "white",
color: "red",
fontSize: "0.8rem",
padding: "6px",
borderRadius: "6px",
},
},
}}
>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteStuffTemp(id)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
// <Button onClick={() => setOpenDialog(true)} key = {index}>
// {test}
// </Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => cancelChange()}></Button>
<Button onClick={() => setOpenDialog(false)} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
{/* 食材編集ダイアログ */}
<Dialog open={openChangeDialog} onClose={() => setOpenChangeDialog(false)} disableScrollLock={true}
maxWidth="lg"
fullWidth
>
<Box display="flex" alignItems="center">
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
</Box>
<FormGroup>
{/* <List> */}
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{testDishArray.map((test, id) => (
<ListItem
key={id}
sx={{
bgcolor: 'background.paper',
mb: 1,
borderRadius: 1,
boxShadow: 1,
}}
>
{/*
<Checkbox
checked={task.completed}
onChange={() => handleToggleComplete(task.id)}
/> */}
{/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
<ListItemText
primary={test.name}
// secondary={task.description}
sx={{width: '80%'}}
/>
{/* 食材の個数を表示 */}
<ListItemText
primary={<Typography style={{textAlign:"center"}}><br />
{test.amount}
</Typography>
}
// secondary={task.description}
sx={{ align: "right", fontSize: "20px" }}
/>
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<Tooltip title="食材情報追加">
<IconButton
edge="end"
aria-label="食材情報追加"
//onClick={() => handleDeleteTask(task.id)}
>
<ShoppingBasketIcon />
</IconButton>
</Tooltip>
{/* 買い物リスト:食材削除ボタン */}
<Tooltip title="項目を削除"
componentsProps={{
tooltip: {
sx: {
backgroundColor: "white",
color: "red",
fontSize: "0.8rem",
padding: "6px",
borderRadius: "6px",
},
},
}}
>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteStuffTemp(id)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
// <Button onClick={() => setOpenDialog(true)} key = {index}>
// {test}
// </Button>
// <ListItem
// key={index}
// sx={{
// bgcolor: 'background.paper',
// mb: 1,
// borderRadius: 1,
// boxShadow: 2,
// }}
// >
// {/* タスクのタイトルと説明 - 完了状態に応じて取り消し線を表示 */}
// <ListItemText
// primary={test}
// //secondary={tobuy.amount}
// primaryTypographyProps={{ fontSize: '40px', margin: '10px' }}
// sx={{
// textDecoration: false ? 'line-through' : 'none',
// }}
// />
// </ListItem>
))}
{/* </List> */}
</FormGroup>
<DialogActions>
<Button onClick={() => cancelChange()}></Button>
<Button onClick={() => setOpenDialog(false)} variant="contained"
style={{width: '40%', fontSize: '40px'}}
>
</Button>
</DialogActions>
</Dialog>
</Container>
);
};
export default DishList;

@ -58,7 +58,7 @@ const LoginPage: React.FC = () => {
};
return (
<Container maxWidth="md" sx={{ mt: 8, height: '100vh'}}>
<Container maxWidth="md" sx={{ mt: 8, height: '100vh' }}>
<Grid container justifyContent="center" alignItems="center" sx={{ height: '100%' }}>
<Grid item xs={12} md={5}>
<Paper elevation={3} sx={{ p: 4 }}>

@ -112,12 +112,12 @@ const RecipeList: React.FC = () => {
/>
<ListItemSecondaryAction>
{recipe.maxServings ?
<Typography variant="body1" component="span" sx={{ mr: 0, color: "mediumaquamarine" }}>
{recipe.maxServings}
</Typography>
: <></>}
: <></>}
{recipe.maxServings === 0 ?
<Tooltip title="">
@ -151,8 +151,8 @@ const RecipeList: React.FC = () => {
{/* 買うものリストへ追加ダイアログ */}
{
<AddByRecipeDialog openDialog={openAddByRecipeDialog} setOpenDialog={setOpenAddByRecipeDialog}
recipeId = {addByRecipeId} numOfPeople={numOfPeople} setNumOfPeaple={setNumOfPeople}
checked = {checked} setChecked={setChecked}
recipeId={addByRecipeId} numOfPeople={numOfPeople} setNumOfPeaple={setNumOfPeople}
checked={checked} setChecked={setChecked}
/>
}

@ -380,163 +380,163 @@ const StockPage: React.FC = () => {
return (
!filteredStocks.length
? <Typography></Typography>
: <>
<TableContainer component={Paper}>
<Table size="small">
<TableHead sx={{ backgroundColor: "#ebcba2", color: "#333" }}>
<TableRow>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell>
<TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}></TableCell>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredStocks.map(stock => {
let daysLeft = null;
if (stock.expDate !== null) {
const today = new Date();
const expDate = new Date(stock.expDate);
// 時間をリセットして純粋な“日付のみ”のタイムスタンプを取得
const todayDateOnly = new Date(today);
todayDateOnly.setHours(0, 0, 0, 0);
const expDateOnly = new Date(expDate);
expDateOnly.setHours(0, 0, 0, 0);
const timeDiff = expDateOnly.getTime() - todayDateOnly.getTime();
daysLeft = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
// console.log("テーブルtoday:", today);
// console.log("テーブルexp:", expDate);
// console.log("テーブルtodayDateOnly:", todayDateOnly);
// console.log("テーブルexpDateOnly:", expDateOnly);
// console.log("日数差:", daysLeft);
}
return (
<TableRow
key={stock.stockId}
onClick={() => handleRowClick(stock)}
style={{ backgroundColor: selectedRow?.stockId === stock.stockId ? "yellow" : "white", cursor: "pointer" }}
>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}>{stock.stuffName}</TableCell>
<TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}>{stock.amount}</TableCell>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}
style={daysLeft !== null && daysLeft <= 3 ? { color: "red", fontWeight: "bold" } : {}}
? <Typography></Typography>
: <>
<TableContainer component={Paper}>
<Table size="small">
<TableHead sx={{ backgroundColor: "#ebcba2", color: "#333" }}>
<TableRow>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell>
<TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}></TableCell>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}></TableCell>
</TableRow>
</TableHead>
<TableBody>
{filteredStocks.map(stock => {
let daysLeft = null;
if (stock.expDate !== null) {
const today = new Date();
const expDate = new Date(stock.expDate);
// 時間をリセットして純粋な“日付のみ”のタイムスタンプを取得
const todayDateOnly = new Date(today);
todayDateOnly.setHours(0, 0, 0, 0);
const expDateOnly = new Date(expDate);
expDateOnly.setHours(0, 0, 0, 0);
const timeDiff = expDateOnly.getTime() - todayDateOnly.getTime();
daysLeft = Math.ceil(timeDiff / (1000 * 60 * 60 * 24));
// console.log("テーブルtoday:", today);
// console.log("テーブルexp:", expDate);
// console.log("テーブルtodayDateOnly:", todayDateOnly);
// console.log("テーブルexpDateOnly:", expDateOnly);
// console.log("日数差:", daysLeft);
}
return (
<TableRow
key={stock.stockId}
onClick={() => handleRowClick(stock)}
style={{ backgroundColor: selectedRow?.stockId === stock.stockId ? "yellow" : "white", cursor: "pointer" }}
>
{stock.expDate && formatDate(stock.expDate)}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
{/* 編集ダイアログ */}
<Dialog open={openEditDialog} onClose={handleCloseEdit} fullWidth maxWidth="sm">
<DialogTitle>
<Typography variant="h5" >
</Typography>
</DialogTitle>
<DialogContent>
{editStock && (
<>
{/* 材料の詳細 */}
<Typography variant="h4">{editStock.stuffName}</Typography>
{/* 現在の数量フィールド */}
<TextField
label="現在の数量"
margin="normal"
name="amount"
type="number"
fullWidth
className="numberField"
value={editStock.amount}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入時数量フィールド */}
<TextField
label="購入時数量"
margin="normal"
name="buyAmount"
type="number"
fullWidth
value={editStock.buyAmount}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入価格フィールド */}
<TextField
label="購入価格"
margin="normal"
name="price"
type="number"
fullWidth
value={editStock.price}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入店舗フィールド */}
<TextField
label="購入店舗"
fullWidth
margin="normal"
name="shop"
type="text"
value={editStock.shop}
onChange={handleChange}
/>
{/* 購入日・賞味期限入力 */}
<BuyExpDateSelect newStock={editStock} setNewStock={({ buyDate, expDate }) => setEditStock({ ...editStock, buyDate, expDate })} />
</>
)}
</DialogContent>
<DialogActions>
<Button onClick={() => { setOpenEditDialog(false); setSelectedRow(null); }}>
</Button>
<Button variant="contained" color="success" onClick={handleApplyChanges}>
</Button>
<Button variant="contained" color="error" onClick={() => setOpenDeleteDialog(true)}></Button>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}>{stock.stuffName}</TableCell>
<TableCell align="center" sx={{ width: '20%', fontSize: '16px' }}>{stock.amount}</TableCell>
<TableCell align="center" sx={{ width: '40%', fontSize: '16px' }}
style={daysLeft !== null && daysLeft <= 3 ? { color: "red", fontWeight: "bold" } : {}}
>
{stock.expDate && formatDate(stock.expDate)}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
{/* 編集ダイアログ */}
<Dialog open={openEditDialog} onClose={handleCloseEdit} fullWidth maxWidth="sm">
<DialogTitle>
<Typography variant="h5" >
</Typography>
</DialogTitle>
<DialogContent>
{editStock && (
<>
{/* 材料の詳細 */}
<Typography variant="h4">{editStock.stuffName}</Typography>
{/* 現在の数量フィールド */}
<TextField
label="現在の数量"
margin="normal"
name="amount"
type="number"
fullWidth
className="numberField"
value={editStock.amount}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入時数量フィールド */}
<TextField
label="購入時数量"
margin="normal"
name="buyAmount"
type="number"
fullWidth
value={editStock.buyAmount}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入価格フィールド */}
<TextField
label="購入価格"
margin="normal"
name="price"
type="number"
fullWidth
value={editStock.price}
onChange={handleChange}
inputProps={{ min: 0 }}
onKeyDown={(e) => {
if (e.key === '-' || e.key === 'e' || e.key === 'E') {
e.preventDefault();
}
}}
/>
{/* 購入店舗フィールド */}
<TextField
label="購入店舗"
fullWidth
margin="normal"
name="shop"
type="text"
value={editStock.shop}
onChange={handleChange}
/>
{/* 購入日・賞味期限入力 */}
<BuyExpDateSelect newStock={editStock} setNewStock={({ buyDate, expDate }) => setEditStock({ ...editStock, buyDate, expDate })} />
</>
)}
</DialogContent>
<DialogActions>
<Button onClick={() => { setOpenEditDialog(false); setSelectedRow(null); }}>
</Button>
<Button variant="contained" color="success" onClick={handleApplyChanges}>
</Button>
<Button variant="contained" color="error" onClick={() => setOpenDeleteDialog(true)}></Button>
</DialogActions>
</Dialog>
{/* 削除ダイアログ */}
{selectedRow &&
<DeleteStuffDialog openDialog={openDeleteDialog} setOpenDialog={setOpenDeleteDialog}
stuffName={selectedRow.stuffName}
onSubmit={() => {
handleDeleteStock(selectedRow.stockId);
setSelectedRow(null);
setOpenEditDialog(false); // 編集画面から飛んだ場合に備え、編集画面も閉じる
}}
/>}
</>
</Dialog>
{/* 削除ダイアログ */}
{selectedRow &&
<DeleteStuffDialog openDialog={openDeleteDialog} setOpenDialog={setOpenDeleteDialog}
stuffName={selectedRow.stuffName}
onSubmit={() => {
handleDeleteStock(selectedRow.stockId);
setSelectedRow(null);
setOpenEditDialog(false); // 編集画面から飛んだ場合に備え、編集画面も閉じる
}}
/>}
</>
);
};

Loading…
Cancel
Save