[41 | UIの更新] << [ホーム] >> [43 | UI設定フォーム]
「qrmenu_react/src/pages」フォルダに「MenuSettings.js」ファイルを新規作成します。
作成した「MenuSettings.js」ファイルを以下のように編集します。
新規作成 【QRMenu/qrmenu_react/src/pages/MenuSettings.js】
import { IoMdArrowBack } from 'react-icons/io'; import { Row, Col, Button } from 'react-bootstrap'; import { useParams, useHistory } from 'react-router-dom'; import React, { useState, useEffect } from 'react'; import { fetchPlace } from '../apis'; import MainLayout from '../layouts/MainLayout'; import MenuList from '../components/MenuList'; const MenuSettings = ()=> { const [place, setPlace] = useState({}); const params = useParams(); const history = useHistory(); const onBack = () => history.push(`/places/${params.id}`); const onFetchPlace = async () => { const json = await fetchPlace(params.id); if(json) { setPlace(json); } } useEffect(() => { onFetchPlace(); }, []); return ( <MainLayout> <div className="d-flex align-items-center mb-4"> <Button variant="link" onClick={onBack}> <IoMdArrowBack size={25} color="black" /> </Button> <h3 className="mb-0 mr-2 ml-2">メニュー設定</h3> </div> <Row> <Col md={8}> <MenuList place={place} font={place.font} color={place.color} onOrder={() => []}/> </Col> </Row> </MainLayout> ) } export default MenuSettings;
「src/router/App.js」ファイルを編集します。
記述編集 【Desktop/QRMenu/qrmenu_react/src/router/App.js】
import { BrowserRouter, Switch, Route } from 'react-router-dom'; import { ToastContainer } from 'react-toastify'; import React from 'react'; import { AuthProvider } from '../contexts/AuthContext'; import PrivateRoute from './PrivateRoute'; import Home from '../pages/Home'; import Login from '../pages/Login'; import Register from '../pages/Register'; import Places from '../pages/Places'; import Place from '../pages/Place'; import Menu from '../pages/Menu'; import Orders from '../pages/Orders'; import MenuSettings from '../pages/MenuSettings'; function App() { return ( <AuthProvider> <BrowserRouter> <Switch> <Route exact path='/'> <Home /> </Route> <Route exact path='/login'> <Login /> </Route> <Route exact path='/menu/:id/:table'> <Menu /> </Route> <Route exact path='/register'> <Register /> </Route> <PrivateRoute exact path='/places/:id'> <Place /> </PrivateRoute> <PrivateRoute exact path='/places'> <Places /> </PrivateRoute> <PrivateRoute exact path='/places/:id/orders'> <Orders /> </PrivateRoute> <PrivateRoute exact path='/places/:id/settings'> <MenuSettings /> </PrivateRoute> </Switch> </BrowserRouter> <ToastContainer /> </AuthProvider> ) } export default App;
「src/components/MenuList.js」ファイルの記述を変更します。
記述変更 【Desktop/QRMenu/qrmenu_react/src/components/MenuList.js】20行目
import React from 'react'; import styled from 'styled-components'; import MenuItem from './MenuItem'; const Place = styled.div` text-align: center; img { border-radius: 5px; margin-bottom: 20px; margin-top: 20px; } `; const Container = styled.div` b, p { ${({ font }) => font && `font-family: ${font};`} } `; const MenuList = ({ place, shoppingCart = {}, onOrder, font = "", color = "" }) => { return ( <Container font={font}> <Place> <img src={place.image} with={100} height={100} /> <h3><b>{place.name}</b></h3> </Place> {place?.categories ?.filter( (category) => category.menu_items.filter((i) => i.is_available).length ) .map((category) => ( <div key={category.id} className="mt-5"> <h4 className="mb-4"> <b>{category.name}</b> </h4> {category.menu_items .filter((item) => item.is_available) .map((item) => ( <MenuItem key={item.id} item={{ ...item, quantity: shoppingCart[item.id]?.quantity, }} onOrder={onOrder} color={color} /> )) } </div> )) } </Container> ) }; export default MenuList;
ブラウザを確認します。
http://localhost:3000/places/5/settings
設定ページが表示されるようになりました。
「src/pages/Place.js」ファイルを編集します。
記述編集 【Desktop/QRMenu/qrmenu_react/src/pages/Place.js】
import { IoMdArrowBack } from 'react-icons/io'; import { AiOutlineDelete, AiOutlineQrcode, AioutlineQrcode } from 'react-icons/ai'; import { RiFileList3Line } from 'react-icons/ri'; import { FiSettings } from 'react-icons/fi'; import { Row, Col, Button, Modal } from 'react-bootstrap'; import { useParams, useHistory } from 'react-router-dom'; import React, { useEffect, useState, useContext } from 'react'; import styled from 'styled-components'; import { fetchPlace, removePlace, removeCategory, removeMenuItem, updatePlace } from '../apis'; import AuthContext from '../contexts/AuthContext'; import MainLayout from '../layouts/MainLayout'; import MenuItemForm from '../containers/MenuItemForm'; import MenuItem from '../components/MenuItem'; import QRCodeModal from '../components/QRCodeModal'; const Panel = styled.div` background-color: white; padding: 20px; border-radius: 5px; box-shadow: 1px 1px 10px rgba(0,0,0,0.05); `; const Place = () => { const [place, setPlace] = useState({}); const [menuItemFormShow, setMenuItemFormShow] = useState(false); const [selectedItem, setSelectedItem] = useState(null); const [qrCode, setQrCode] = useState(false); const showModal = () => setMenuItemFormShow(true); const hideModal = () => setMenuItemFormShow(false); const showQRModal = () => setQrCode(true); const hideQRModal = () => setQrCode(false); const auth = useContext(AuthContext); const params = useParams(); const history = useHistory(); const onBack = () => history.push("/places"); const onFetchPlace = async () => { const json = await fetchPlace(params.id, auth.token); if(json) { setPlace(json); } }; const onRemovePlace = () => { const c = window.confirm("本当に削除してもよろしいですか?") if (c) { removePlace(params.id, auth.token).then(onBack); } }; const onRemoveCategory = (id) => { const c = window.confirm("本当に削除してもよろしいですか?") if (c) { removeCategory(id, auth.token).then(onFetchPlace); } }; const onRemoveMenuItem = (id) => { const c = window.confirm("本当に削除してもよろしいですか?") if (c) { removeMenuItem(id, auth.token).then(onFetchPlace); } }; const onUpdatePlace = (tables) => { updatePlace(place.id, {number_of_tables: tables }, auth.token).then( (json) => { if (json) { setPlace(json); } } ) } useEffect(() => { onFetchPlace(); }, []); return ( <MainLayout> <Row> <Col lg={12}> <div className="mb-4"> <div className="d-flex justify-content-between align-items-center mb-4"> <Button variant="link" onClick={onBack}> <IoMdArrowBack size={25} color="black" /> </Button> <h3 className="mb-0 ml-2 mr-2"><img src={place.image} with={50} height={50} /><br/>{place.name}</h3> <Button variant="link" onClick={onRemovePlace}> <AiOutlineDelete size={25} color="red" /> </Button> </div> <Button variant="link" onClick={showQRModal} Style=" text-decoration: none;"> <AiOutlineQrcode size={25} /><span>QR</span> </Button> <Button variant="link" href={`/places/${params.id}/orders`} Style=" text-decoration: none;"> <RiFileList3Line size={25} color="green" /><span Style="color: green; font-size: 0.8rem;">オーダー</span> </Button> <Button variant="link" href={`/places/${params.id}/settings`} Style=" text-decoration: none;"> <FiSettings size={25} color="#4b0082" /><span Style="color: #4b0082; font-size: 0.8rem;">設定</span> </Button> </div> </Col> <Col md={4}> <Panel> <MenuItemForm place={place} onDone={onFetchPlace} /> </Panel> </Col> <Col md={8}> {place?.categories?.map((category) => ( <div key={category.id} className="mb-5"> <div className="d-flex align-items-center mb4"> <h4 className="mb-0 mr-2"> <b>{category.name}</b> </h4> <Button variant="link" onClick={() => onRemoveCategory(category.id)}> <AiOutlineDelete size={25} color="red" /> </Button> </div> <br/> {category.menu_items.map((item) => ( <MenuItem key={item.id} item={item} onEdit={() => { setSelectedItem(item); showModal() }} onRemove={() => onRemoveMenuItem(item.id)} /> ))} </div> ))} </Col> </Row> <Modal show={menuItemFormShow} onHide={hideModal} centerd> <Modal.Body> <h4 className="text-center">メニューアイテム</h4> <MenuItemForm place={place} onDone={() =>{ onFetchPlace(); hideModal() }} item={selectedItem} /> </Modal.Body> </Modal> <QRCodeModal show={qrCode} onHide={hideQRModal} place={place} centered onUpdatePlace={onUpdatePlace} /> </MainLayout> ) }; export default Place;
設定ページのリンクができました。
↓↓クリックして頂けると励みになります。
[41 | UIの更新] << [ホーム] >> [43 | UI設定フォーム]