Merge branch 'dev-frontend-top' into dev-frontend-add_dishes

dev-frontend-add_dishes
masato.fujita 5 months ago
commit 411327ec40
  1. 15
      frontend/package-lock.json
  2. 1
      frontend/package.json
  3. 25
      frontend/src/App.tsx
  4. 28
      frontend/src/components/CategoryDropDown.tsx
  5. 28
      frontend/src/components/DropDown.tsx
  6. 28
      frontend/src/components/Layout.tsx
  7. 16
      frontend/src/pages/StockPage.tsx
  8. 116
      frontend/src/pages/TaskListPage.tsx

@ -21,6 +21,7 @@
"@types/react-dom": "^18.2.18",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.5.0",
"react-router-dom": "^6.21.1",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
@ -13444,6 +13445,14 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz",
"integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ=="
},
"node_modules/react-icons": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -26113,6 +26122,12 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz",
"integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ=="
},
"react-icons": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
"requires": {}
},
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",

@ -18,6 +18,7 @@
"@types/react-dom": "^18.2.18",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "5.3.0",
"react-router-dom": "^6.21.1",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",

@ -9,6 +9,7 @@ import Layout from './components/Layout';
import LoginPage from './pages/LoginPage';
import RegisterPage from './pages/RegisterPage';
import TaskListPage from './pages/TaskListPage';
import StockPage from './pages/StockPage';
import './App.css';
// 必要なインポートを追加
import AddDishes1 from './pages/AddDishes1';
@ -113,6 +114,30 @@ const App: React.FC = () => {
}
/>
</Route>
<Route path="/" element={<Layout />}>
{/* ルートパスへのアクセスはタスク一覧にリダイレクト */}
<Route index element={<Navigate to="/stock" replace />} />
{/* タスク一覧は認証が必要なため、PrivateRouteでラップ */}
<Route
path="stock"
element={
<PrivateRoute>
<StockPage />
</PrivateRoute>
}
/>
{/* テストページへのルートを追加 */}
<Route
path="stock"
element={
<PrivateRoute>
<StockPage />
</PrivateRoute>
}
/>
</Route>
</Routes>
</BrowserRouter>
</Box>

@ -0,0 +1,28 @@
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;

@ -0,0 +1,28 @@
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 DropDown = () => {
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 DropDown;

@ -3,13 +3,13 @@
* AppBar
*/
import React, { useState } from 'react';
import {
AppBar,
Toolbar,
Typography,
Container,
Box,
Button,
import {
AppBar,
Toolbar,
Typography,
Container,
Box,
Button,
Drawer,
List,
ListItemText,
@ -18,10 +18,11 @@ import {
Divider,
IconButton
} from '@mui/material';
import {
import {
Menu as MenuIcon,
ListAlt as ListAltIcon,
Science as ScienceIcon, // テストページ用のアイコン
Inventory as InventoryIcon, // テストページ用のアイコン
} from '@mui/icons-material';
import { useNavigate, Outlet, useLocation } from 'react-router-dom';
@ -92,8 +93,8 @@ const Layout: React.FC = () => {
role="presentation"
>
<List>
<ListItemButton
onClick={() => handleNavigate('/tasks')}
<ListItemButton
onClick={() => handleNavigate('/tasks')}
selected={isSelected('/tasks')}
>
<ListItemIcon><ListAltIcon /></ListItemIcon>
@ -107,6 +108,13 @@ const Layout: React.FC = () => {
<ListItemIcon><ScienceIcon /></ListItemIcon>
<ListItemText primary="料理の追加" />
</ListItemButton>
<ListItemButton
onClick={() => handleNavigate('/stock')}
selected={isSelected('/stock')}
>
<ListItemIcon><InventoryIcon /></ListItemIcon>
<ListItemText primary="在庫管理" />
</ListItemButton>
<Divider />
</List>
</Box>

@ -0,0 +1,16 @@
/**
*
*
*/
import React from 'react';
import { Box } from '@mui/material';
const StockPage: React.FC = () => {
return (
<Box>
{/* 白紙のページ - 何も表示しない */}
</Box>
);
};
export default StockPage;

@ -7,6 +7,7 @@ import { taskApi } from '../services/api';
import {
Container,
Typography,
Tooltip,
List,
ListItem,
ListItemText,
@ -21,13 +22,25 @@ import {
TextField,
Button,
Box,
MenuItem,
Select,
FormControl,
InputLabel
} from '@mui/material';
import { Add as AddIcon, Delete as DeleteIcon } from '@mui/icons-material';
import {
Add as AddIcon, Delete as DeleteIcon, ShoppingBasket as ShoppingBasketIcon,
SoupKitchen as SoupKitchenIcon
} from '@mui/icons-material';
import { Task } from '../types/types';
import { TASK_ERRORS } from '../constants/errorMessages';
//import { FaCarrot } from "react-icons/fa6"; //エラー起きる いったん保留
import CategoryDropDown from "../components/CategoryDropDown";
// 新規タスクの初期状態
const EMPTY_TASK = { title: '', description: '', completed: false };
const EMPTY_TASK = { id: 0, title: '', amount: 0, completed: false };
const TaskListPage: React.FC = () => {
// タスク一覧の状態管理
@ -106,7 +119,7 @@ const TaskListPage: React.FC = () => {
</Typography>
{/* タスク一覧表示エリア - 青い背景のコンテナ */}
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px'}}>
<div style={{ border: '3px solid black', borderRadius: '8px', backgroundColor: '#add8e6', height: 'auto', padding: '20px' }}>
<List>
{/* タスク一覧をマップして各タスクをリストアイテムとして表示 */}
{tasks.map((task) => (
@ -132,59 +145,108 @@ const TaskListPage: React.FC = () => {
textDecoration: task.completed ? 'line-through' : 'none',
}}
/>
{/* タスク削除ボタン */}
{/* 買い物リスト:食材情報記入ボタン */}
<ListItemSecondaryAction>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteTask(task.id)}
<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",
},
},
}}
>
<DeleteIcon />
</IconButton>
<IconButton
edge="end"
aria-label="delete"
onClick={() => handleDeleteTask(task.id)}
>
<DeleteIcon />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
))}
</List>
</div>
{/* 新規タスク作成ボタン - 画面下部に固定表示 */}
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 16, left: '50%', transform: 'translateX(-50%)'}}
onClick={() => setOpenDialog(true)}
>
<AddIcon />
</Fab>
{/* 新規材料作成ボタン - 画面下部に固定表示 */}
<Tooltip title="材料のみ追加">
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 16, left: '40%', transform: 'translateX(-50%)' }}
onClick={() => setOpenDialog(true)}
>
<AddIcon />
</Fab>
</Tooltip>
{/*新規料理追加ボタン - 画面下部に固定表示 */}
<Tooltip title="料理から追加">
<Fab
color="primary"
sx={{ position: 'fixed', bottom: 16, left: '60%', transform: 'translateX(-50%)' }}
onClick={() => setOpenDialog(true)}
>
<SoupKitchenIcon />
</Fab>
</Tooltip>
{/* 新規タスク作成ダイアログ */}
<Dialog open={openDialog} onClose={() => setOpenDialog(false)} disableScrollLock={true}>
<DialogTitle></DialogTitle>
<DialogTitle></DialogTitle>
<DialogContent>
<Box sx={{ pt: 1 }}>
{/*材料カテゴリ選択 */}
<CategoryDropDown></CategoryDropDown>
{/* タスクタイトル入力フィールド */}
<TextField
autoFocus
margin="dense"
label="タイトル"
label="材料名"
fullWidth
value={newTask.title}
onChange={(e) => setNewTask({ ...newTask, title: e.target.value })}
sx={{ marginBottom: 2 }}
/>
{/* タスク説明入力フィールド - 複数行入力可能 */}
{/* 数量入力フィールド */}
<TextField
margin="dense"
label="説明"
label="数量"
fullWidth
multiline
rows={4}
value={newTask.description}
onChange={(e) => setNewTask({ ...newTask, description: e.target.value })}
value={newTask.amount}
onChange={(e) => {
const value = e.target.value;
const parsedValue = parseInt(value, 10); // 数値に変換
if (!isNaN(parsedValue)) {
setNewTask({ ...newTask, amount: parsedValue }); // number型で保存
}
}}
sx={{ width: "20%" }}
type="number"
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} // ここで整数のみ許可
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpenDialog(false)}></Button>
<Button onClick={handleCreateTask} variant="contained">
</Button>
</DialogActions>
</Dialog>

Loading…
Cancel
Save