・テーブルの行選択するときにチェックボックスを押すようにしました

・追加ボタンなどをスクロールしても上固定になるようにしました
・編集で数量と購入金額に負の値が入らないようにしました
・編集で数量に0を入れたら削除ダイアログに飛ぶようにしました
feature-frontend-stock-suzuki
Yuna.Suzuki 4 months ago
parent 0fb3e0c21a
commit 1b7665585f
  1. 129
      frontend/src/pages/StockPage.tsx

@ -177,18 +177,23 @@ const StockPage: React.FC = () => {
const handleOpenAdd = () => {
setIsAddOpen(true);
};
/** 削除ダイアログを閉じる */
/** 追加ダイアログを閉じる */
const handleCloseAdd = () => {
setIsAddOpen(false);
};
/**
* .
* .
*/
const handleRowClick = (stock: Stock) => {
// const handleRowClick = (stock: Stock) => {
// setSelectedRow(prev => (prev?.stockId === stock.stockId ? null : stock));
// };
// チェックボックス切り替え
const handleCheckboxChange = (stock: Stock) => {
setSelectedRow(prev => (prev?.stockId === stock.stockId ? null : stock));
};
/** 編集ボタンを押したときにダイアログを開く */
// ダイアログを開く際に `selectedRow` の値を `editStock` にセット
const handleOpenEdit = () => {
@ -199,26 +204,35 @@ const StockPage: React.FC = () => {
alert("編集する食材を選択してください。");
}
};
// 変更を適用
// 変更を適用. 数量に0を入力したとき、削除ダイアログに飛ぶ機能を追加
const handleApplyChanges = async () => {
if (editStock) {
try {
await handleUpdateStock(
editStock.stockId,
Number(editStock.amount),
Number(editStock.price),
editStock.buyDate,
editStock.expDate
);
setSelectedRow(editStock); // `selectedRow` を更新して変更を即時反映
fetchStocks(); // 最新データを取得してテーブルに反映
setSelectedRow(null); // セルの選択を解除
} catch (error) {
console.error(`${STOCK_ERRORS.UPDATE_FAILED}:`, error);
if (!editStock) return;
try {
if (Number(editStock.amount) === 0) {
// 数量が 0 の場合は削除処理へ誘導
setIsEditOpen(false); // 編集ダイアログを閉じる
setSelectedRow(editStock); // 削除対象をセット
setIsDeleteOpen(true); // 削除ダイアログを開く
return;
}
await handleUpdateStock(
editStock.stockId,
Number(editStock.amount),
Number(editStock.price),
editStock.buyDate,
editStock.expDate
);
setSelectedRow(editStock); // 更新後に選択行を反映
fetchStocks(); // 最新データを取得
setSelectedRow(null); // 選択解除
} catch (error) {
console.error(`${STOCK_ERRORS.UPDATE_FAILED}:`, error);
}
setIsEditOpen(false); // ダイアログを閉じる
setIsEditOpen(false); // 編集ダイアログを閉じる
};
// ダイアログを開く際に `selectedRow` の値を `editStock` にコピー
@ -229,15 +243,25 @@ const StockPage: React.FC = () => {
}, [selectedRow]); // `selectedRow` が変更されたら `editStock` に反映
// テキストフィールドの変更を検知
// 負の値を入力できないように書き換え
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
// 数値項目に対して負の値をブロック
const numericFields = ['amount', 'price'];
if (numericFields.includes(name) && Number(value) < 0) {
return; // 無視して更新しない
}
if (editStock) {
setEditStock({
...editStock,
[event.target.name]: event.target.value,
[name]: value,
});
}
};
/** 編集ダイアログを閉じる */
const handleCloseEdit = () => {
setIsEditOpen(false);
@ -268,6 +292,7 @@ const StockPage: React.FC = () => {
<Table>
<TableHead sx={{ backgroundColor: "#dcdcdc", color: "#333" }}>
<TableRow>
<TableCell padding="checkbox" />
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
@ -275,6 +300,7 @@ const StockPage: React.FC = () => {
</TableHead>
<TableBody>
{filteredStocks.map(stock => {
const isSelected = selectedRow?.stockId === stock.stockId;
const today = new Date();
const expDate = new Date(stock.expDate);
const timeDiff = expDate.getTime() - today.getTime();
@ -283,9 +309,17 @@ const StockPage: React.FC = () => {
return (
<TableRow
key={stock.stockId}
onClick={() => handleRowClick(stock)}
style={{ backgroundColor: selectedRow?.stockId === stock.stockId ? "yellow" : "white", cursor: "pointer" }}
sx={{
backgroundColor: isSelected ? 'yellow' : 'white',
}}
>
<TableCell padding="checkbox">
<Checkbox
checked={isSelected}
onChange={() => handleCheckboxChange(stock)}
/>
</TableCell>
<TableCell>{stock.stuffName}</TableCell>
<TableCell>{stock.amount}</TableCell>
<TableCell
@ -373,23 +407,6 @@ const StockPage: React.FC = () => {
isClearable
/>
</Box>
{/*
<TextField
label="購入日 (yyyy-MM-dd)"
fullWidth
margin="normal"
name="buyDate"
value={editStock.buyDate}
onChange={handleChange}
/>
<TextField
label="消費・賞味期限 (yyyy-MM-dd)"
fullWidth
margin="normal"
name="expDate"
value={editStock.expDate}
onChange={handleChange}
/> */}
<Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 2, mt: 3, mb: 2 }}>
<Button onClick={() => { setIsEditOpen(false); setSelectedRow(null); }}>
@ -451,15 +468,29 @@ const StockPage: React.FC = () => {
</Typography>
<Box sx={{ textAlign: 'right' }}>
{/* <Box sx={{ position: 'fixed', top: 16, right: 16, zIndex: 1000, display: 'flex', gap: 2 }}> */}
{/* <Box sx={{ textAlign: 'right' }}> */}
<Box
sx={{
position: 'sticky',
top: 0,
zIndex: 1000,
backgroundColor: '#f5f5f5',
padding: 2,
display: 'flex',
gap: 0.5,
justifyContent: 'flex-end', // ← 右寄せ
borderBottom: 'none', // ← これで線を消す
boxShadow: 'none', // ← 影も消す
}}
>
{/* 在庫の食材追加ボタン */}
<Button variant="contained" color="primary" onClick={handleOpenAdd} sx={{ mt: 3, mb: 2, mr: 1 }}>
</Button>
{/* 新規タスク作成ダイアログ */}
<Dialog open={isAddOpen} onClose={() => setIsAddOpen(false)} disableScrollLock={true}>
<Dialog open={isAddOpen} onClose={handleCloseAdd} disableScrollLock={true}>
<Box display="flex" alignItems="center" >
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
<FormGroup row>
@ -570,15 +601,6 @@ const StockPage: React.FC = () => {
isClearable
//withPortal // ← 他の文字との重なり対策
/>
{/*
<TextField
margin="dense"
label="購入日(yyyy/MM/dd)"
fullWidth
value={newStock.buyDate}
onChange={(e) => setNewStock({ ...newStock, buyDate: e.target.value })}
/>
*/}
{/* 消費・賞味期限入力フィールド */}
<DatePicker
popperClassName="custom-datepicker-popper"
@ -610,7 +632,8 @@ const StockPage: React.FC = () => {
{/* 在庫の食材編集ボタン(全テーブル共通) */}
<Button variant="contained" color="success" onClick={handleOpenEdit} sx={{
mt: 3, mb: 2, mr: 1 }}>
mt: 3, mb: 2, mr: 1
}}>
</Button>

Loading…
Cancel
Save