Stockpageに追加ボタンを入れました

feature-frontend-dishedit-kato
Yuna.Suzuki 4 months ago
parent 90db267963
commit 48ed1c67dc
  1. 196
      frontend/src/pages/StockPage.tsx
  2. 36
      frontend/src/services/api.ts

@ -3,8 +3,8 @@
*
*/
import React, { useState, useEffect } from 'react';
import { stockApi } from '../services/api';
import { Stock } from '../types/types';
import { stockApi, stuffApi } from '../services/api';
import { Stock, Stuff } from '../types/types';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from "@mui/material";
import {
Container,
@ -18,15 +18,40 @@ import {
TextField,
Button,
Box,
Checkbox,
FormControlLabel,
FormGroup,
FormControl,
InputLabel,
Select,
MenuItem,
} from '@mui/material';
import { STOCK_ERRORS } from '../constants/errorMessages';
// 新規在庫の初期状態
const EMPTY_STOCK: Omit<Stock, 'stockId' | 'stuffId'> & { stuffId: number | null } & { newAddition: boolean } = {
stuffId: null,
stuffName: '',
amount: 0,
price: 0,
lastUpdate: '',
buyDate: '',
expDate: '',
category: '',
newAddition: false, // 材料を新規作成するか否か
// shop '',
}
const StockPage: React.FC = () => {
const [stocks, setStocks] = useState<Stock[]>([]);
// セル選択の表示状態
const [selectedRow, setSelectedRow] = useState<Stock | null>(null);
// 追加ダイアログボックスの表示状態
const [isAddOpen, setIsAddOpen] = useState(false);
// 在庫追加に使う状態
const [newStock, setNewStock] = useState(EMPTY_STOCK);
const [stuffs, setStuffs] = useState<Stuff[]>([]);
// 編集ダイアロボックスの表示状態
const [isEditOpen, setIsEditOpen] = useState(false);
// 削除メッセージダイアログの表示状態
@ -53,6 +78,25 @@ const StockPage: React.FC = () => {
}
};
/**
*
*/
const handleCreateStock = async () => {
try {
if (newStock.newAddition) {
newStock.stuffId = null;
}
console.log(newStock)
const today = new Date().toISOString().substring(0, 10);
await stockApi.addStock(newStock);
setIsAddOpen(false); // ダイアログを閉じる
setNewStock(EMPTY_STOCK); // 入力内容をリセット
fetchStocks(); // 作成後のタスク一覧を再取得
} catch (error) {
console.error(`${STOCK_ERRORS.CREATE_FAILED}:`, error);
}
};
/**
*
*/
@ -79,6 +123,15 @@ const StockPage: React.FC = () => {
}
};
/**
*
*/
const onChangeCategory = async (category: string) => {
setNewStock({ ...newStock, category })
const result = await stuffApi.getStuffs(category)
setStuffs(result)
}
/**
* (ISO 8601)yyyy/MM/ddに変換する関数
*/
@ -98,6 +151,15 @@ const StockPage: React.FC = () => {
};
*/
/** 追加ボタンを押したときにダイアログを開く */
const handleOpenAdd = () => {
setIsAddOpen(true);
};
/** 削除ダイアログを閉じる */
const handleCloseAdd = () => {
setIsAddOpen(false);
};
/**
* .
*/
@ -315,12 +377,136 @@ const StockPage: React.FC = () => {
</Typography>
{/* タスク編集ボタン(全テーブル共通) */}
{/* 在庫の食材追加ボタン */}
<Button variant="contained" color="primary" onClick={handleOpenAdd} sx={{ mt: 3, mb: 2, left: '78%' }}>
</Button>
{/* 新規タスク作成ダイアログ */}
<Dialog open={isAddOpen} onClose={() => setIsAddOpen(false)} disableScrollLock={true}>
<Box display="flex" alignItems="center" >
<DialogTitle sx={{ flexGrow: 1 }}></DialogTitle>
<FormGroup row>
<FormControlLabel
control={<Checkbox />}
label="食材を新規追加"
checked={newStock.newAddition}
onChange={(e) => setNewStock({ ...newStock, newAddition: (e.target as HTMLInputElement).checked })}
/>
</FormGroup>
</Box>
<DialogContent>
<Box sx={{ pt: 1 }}>
{/*材料カテゴリ選択 */}
<FormControl sx={{ width: "50%", marginBottom: 2 }}>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
labelId="demo-simple-select-label"
value={newStock.category}
onChange={(e) => onChangeCategory(e.target.value)}
>
<MenuItem value="乳製品"></MenuItem>
<MenuItem value="魚・肉"></MenuItem>
<MenuItem value="野菜"></MenuItem>
<MenuItem value="調味料">調</MenuItem>
<MenuItem value="その他"></MenuItem>
</Select>
</FormControl>
{!newStock.newAddition && <FormControl sx={{ width: "100%", marginBottom: 2 }}>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
labelId="demo-simple-select-label"
value={newStock.stuffId}
onChange={(e) => setNewStock({ ...newStock, stuffId: Number(e.target.value) })}
>
{stuffs.map((stuff) => (
<MenuItem key={stuff.stuffId} value={stuff.stuffId}>
{stuff.stuffName}
</MenuItem>
))}
</Select>
</FormControl>}
{/* タスクタイトル入力フィールド */}
{newStock.newAddition && <TextField
autoFocus
margin="dense"
label="材料名"
fullWidth
value={newStock.stuffName}
onChange={(e) => setNewStock({ ...newStock, stuffName: e.target.value })}
sx={{ marginBottom: 2 }}
/>}
{/* 数量入力フィールド */}
<TextField
margin="dense"
label="数量"
fullWidth
value={newStock.amount}
onChange={(e) => {
const value = e.target.value;
const parsedValue = parseInt(value, 10); // 数値に変換
if (!isNaN(parsedValue)) {
setNewStock({ ...newStock, amount: parsedValue }); // number型で保存
}
}}
// sx={{ width: "50%" }}
type="number"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可
/>
{/* 購入価格入力フィールド */}
<TextField
margin="dense"
label="購入価格"
fullWidth
value={newStock.price}
onChange={(e) => {
const value = e.target.value;
const parsedValue = parseInt(value, 10); // 数値に変換
if (!isNaN(parsedValue)) {
setNewStock({ ...newStock, price: parsedValue }); // number型で保存
}
}}
// sx={{ width: "50%" }}
type="number"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可
/>
{/* 賞味・消費期限入力フィールド */}
<TextField
margin="dense"
label="消費・賞味期限(yyyy/MM/dd)"
fullWidth
value={newStock.expDate}
onChange={(e) => setNewStock({ ...newStock, expDate: e.target.value })}
/>
{/* 購入日入力フィールド */}
<TextField
margin="dense"
label="購入日(yyyy/MM/dd)"
fullWidth
value={newStock.buyDate}
onChange={(e) => setNewStock({ ...newStock, buyDate: e.target.value })}
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsAddOpen(false)}></Button>
<Button onClick={handleCreateStock} variant="contained">
</Button>
</DialogActions>
</Dialog>
{/* 在庫の食材編集ボタン(全テーブル共通) */}
<Button variant="contained" color="success" onClick={handleOpenEdit} sx={{ mt: 3, mb: 2, left: '80%' }}>
</Button>
{/* タスク削除ボタン */}
{/* 在庫の食材削除ボタン (全テーブル共通) */}
<Button variant="contained" color="error" onClick={handleOpenDelete} sx={{ mt: 3, mb: 2, left: '82%' }}></Button>
{/* 在庫一覧リスト */}

@ -246,6 +246,40 @@ export const stockApi = {
},
/**
*
* @param stock
* @returns
*/
addStock: async (stock: Omit<Stock, 'stockId' | 'stuffId'> & { stuffId: number | null }): Promise<{ result: boolean; message: string }> => {
console.log("送信するデータ:", stock); // 送信前のデータ確認
stock.buyDate = makeDateObject(stock.buyDate)?.toISOString()?.substring(0, 10) || ''
stock.expDate = makeDateObject(stock.expDate)?.toISOString()?.substring(0, 10) || ''
console.log("変換後のデータ:", stock); // 日付変換後のデータ確認
const response = await fetch(`${API_BASE_URL}/api/stocks/add`, {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify(stock),
});
console.log("レスポンスステータス:", response.status);
console.log("レスポンスヘッダー:", response.headers);
console.log("レスポンス内容:", await response.text());
if (!response.ok) {
throw new Error(STOCK_ERRORS.CREATE_FAILED);
}
return response.json();
// return {result: true}
},
/**
*
*/
@ -255,7 +289,7 @@ export const stockApi = {
req.buyDate = makeDateObject(req.buyDate)?.toISOString()?.substring(0, 10) || ''
req.expDate = makeDateObject(req.expDate)?.toISOString()?.substring(0, 10) || ''
console.log('req: ', req)
console.log('req: ', req)
const response = await fetch(`${API_BASE_URL}/api/stocks/update`, {
method: 'PUT',

Loading…
Cancel
Save