tosanoob's picture
update a lot
0d37b12
import { useState, useEffect } from 'react';
import { Modal, Button, Container, Row, Col, Tab, Tabs, Form, InputGroup } from 'react-bootstrap';
import MenuItem from '../../molecules/MenuItem';
import BasicTemplate from '../../templates/BasicTemplate';
import DataStorage from '../../organisms/DataStorage';
import CacheStorage from '../../organisms/CacheStorage';
import axios from 'axios';
const categoryMapper = [
{ itemType: 1, category: 'Món chính' },
{ itemType: 2, category: 'Đồ uống' },
{ itemType: 3, category: 'Tráng miệng' },
];
function MenuPage() {
const [key, setKey] = useState(0);
const [selectedDish, setSelectedDish] = useState(null);
const [show, setShow] = useState(false);
const [cartAmount, setCartAmount] = useState(0);
const [branches, setBranches] = useState([]);
const defaultSelectedStore = CacheStorage.get('selectedStore') || "";
const [selectedStore, setSelectedStore] = useState(defaultSelectedStore);
const [loadingBranches, setLoadingBranches] = useState(true);
const [loading, setLoading] = useState(true);
const [menuItems, setMenuItems] = useState({});
function handleClose() {
const cart = JSON.parse(DataStorage.get('cart')) || {}; // Đảm bảo cart không null
cart[selectedDish.id] = {
'name': selectedDish.item_name,
'amount': cartAmount,
'imageSrc': selectedDish.image_url,
'price': selectedDish.price
};
for (let id in cart) {
if (cart[id].amount === 0) {
delete cart[id];
}
DataStorage.set('cart', JSON.stringify(cart));
// console.log(JSON.stringify(filteredCart));
setShow(false);
}
}
function notLoggedInClose() {
setShow(false);
}
function handleShow(dish) {
if (DataStorage.get('isLoggedIn') !== 'true' || !DataStorage.get('cart')) {
setShow(true);
return;
} else {
setSelectedDish(dish); // Đặt selectedDish ngay lập tức
// Sau khi cập nhật selectedDish, lấy dữ liệu từ cart theo tên món ăn mới
const cart = JSON.parse(DataStorage.get('cart')) || {};
// Kiểm tra số lượng món ăn trong cart
const amount = cart[dish.id] !== undefined ? cart[dish.id].amount : 0;
setCartAmount(amount); // Cập nhật số lượng
setShow(true); // Hiển thị modal
}
}
function setIncrease() {
setCartAmount(cartAmount + 1);
}
function setDecrease() {
if (cartAmount > 0) {
setCartAmount(cartAmount - 1);
}
}
useEffect(() => {
const fetchBranches = async () => {
try {
const response = await axios.get(process.env.REACT_APP_API_URL + '/branchs'); // Thay 'API_ENDPOINT' bằng URL của API
setBranches(response.data); // Lưu dữ liệu vào state
setLoadingBranches(false); // Đặt loading thành false khi hoàn tất
CacheStorage.set('stores', JSON.stringify(Object(response.data)));
} catch (error) {
console.error('Error fetching branches:', error);
setLoadingBranches(false); // Đặt loading thành false nếu lỗi
}
};
if (CacheStorage.get('stores')) {
setBranches(JSON.parse(CacheStorage.get('stores')));
setLoadingBranches(false);
} else {
fetchBranches();
}
}, [])
// useEffect(() => {
// const fetchMenuItems = async () => {
// try {
// const menuItemsByType = {};
// for (const item of categoryMapper) {
// // Gọi API để lấy món theo itemType
// const response = await axios.get(process.env.REACT_APP_API_URL + `/menu-items?filter.item_type=${item.itemType}`);
// // Lưu danh sách món theo itemType
// menuItemsByType[item.itemType] = response.data.data;
// }
// console.log(menuItemsByType);
// setMenuItems(menuItemsByType);
// setLoading(false);
// CacheStorage.set('menuItems',JSON.stringify(menuItemsByType));
// } catch (error) {
// console.error('Error fetching menu items:', error);
// setLoading(false);
// }
// };
// if (CacheStorage.get('menuItems')) {
// setMenuItems(JSON.parse(CacheStorage.get('menuItems')));
// setLoading(false);
// } else {
// fetchMenuItems();
// }
// }, []);
function organizeMenuItemsByType(menuData) {
// Lấy ra tất cả menu_item từ array ban đầu
const menuItems = menuData.map(item => item.menu_item);
// Tạo một object để nhóm menu_item theo item_type, khởi tạo các mảng rỗng cho mỗi item_type từ categoryMapper
const organizedItems = categoryMapper.reduce((acc, { itemType }) => {
acc[itemType] = [];
return acc;
}, {});
// Thêm menu_item vào organizedItems theo item_type
menuItems.forEach(menuItem => {
const type = menuItem.item_type;
// Đưa menu_item vào array của item_type tương ứng
if (organizedItems[type]) {
organizedItems[type].push(menuItem);
}
});
return organizedItems;
}
useEffect(() => {
const fetchStoreData = async (storeId) => {
if (storeId!=="") {
try {
let menuItemsByType = {};
// Gọi API để lấy món theo itemType
const response = await axios.get(process.env.REACT_APP_API_URL + `/branchs/${storeId}/menus?limit=100`);
// Lưu danh sách món theo itemType
console.log('Response', response.data.data);
menuItemsByType = organizeMenuItemsByType(response.data.data);
console.log(menuItemsByType);
setMenuItems(menuItemsByType);
setLoading(false);
CacheStorage.set(`store_menu_${storeId}`, JSON.stringify(menuItemsByType));
} catch (error) {
console.error('Error fetching menu items:', error);
setLoading(false);
}
}
}
// Kiểm tra cache thông tin chi nhánh trong sessionStorage
const cachedStoreData = CacheStorage.get(`store_menu_${selectedStore}`);
if (cachedStoreData) {
setMenuItems(JSON.parse(cachedStoreData));
setLoading(false);
} else {
fetchStoreData(selectedStore);
}
}, [selectedStore]);
const handleSelectStore = (e) => {
setSelectedStore(e.target.value);
CacheStorage.set('selectedStore',e.target.value);
setLoading(true);
};
let selectboxContent;
if (loadingBranches) {
selectboxContent = (<p>Đang tải dữ liệu...</p>)
} else {
selectboxContent = (<Form>
<Form.Group controlId="branchSelect">
<Form.Label>Chọn chi nhánh:</Form.Label>
<Form.Control as="select" onChange={handleSelectStore} value={selectedStore}>
<option value="">-- Chọn chi nhánh --</option>
{branches.map((store) => (
<option key={store.id} value={store.id}>
{store.name + ' - ' + store.location}
</option>
))}
</Form.Control>
</Form.Group>
</Form>);
}
let modalContent;
if (DataStorage.get('isLoggedIn') !== 'true' || !DataStorage.get('cart')) {
modalContent = (
<Modal show={show} onHide={notLoggedInClose} className='text-center align-items-center'>
<Modal.Header closeButton className='text-center'>
<Modal.Title>Bạn chưa đăng nhập</Modal.Title>
</Modal.Header>
<Modal.Body>
Vui lòng đăng nhập để xem chi tiết món và đặt hàng
</Modal.Body>
<Modal.Footer>
<Button variant="primary" as='a' href='/login'>
Đăng nhập
</Button>
<Button variant="secondary" onClick={notLoggedInClose}>
Đóng
</Button>
</Modal.Footer>
</Modal>
)
}
else {
modalContent = (<Modal show={show} onHide={handleClose} className='text-center'>
<Modal.Header closeButton className='text-center'>
<Modal.Title >{selectedDish?.item_name}</Modal.Title> {/* Dish name in the title */}
</Modal.Header>
<Modal.Body>
<img src={selectedDish?.image_url} alt={selectedDish?.item_name} style={{ width: '100%' }} /> {/* Dish image */}
<p>{selectedDish?.description}</p> {/* Dish description */}
<Row className='mb-5'>
<Col md={2}></Col>
<Col md={8}>
<Form.Label>Số lượng</Form.Label>
<Row>
<InputGroup mb={4} className='mb-3'>
<InputGroup.Text as='button' onClick={setDecrease}>-</InputGroup.Text>
<Form.Control
value={cartAmount}
aria-label="Amount"
onChange={(e) => setCartAmount(e.target.value)} />
<InputGroup.Text as='button' onClick={setIncrease}>+</InputGroup.Text>
</InputGroup>
</Row>
</Col>
<Col md={2}></Col>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Đóng
</Button>
</Modal.Footer>
</Modal>);
}
let menuContent;
if (loading) {
menuContent = (<p>Đang tải thực đơn...</p>);
} else {
menuContent = (<Tabs
id="controlled-tab-example"
activeKey={key}
onSelect={(k) => setKey(k)}
className="mb-3 custom-tab"
>
{categoryMapper.map((category, index) => (
<Tab eventKey={index} title={category.category}>
<Container fluid className='my-5'>
<Row md={3} className="g-4">
{menuItems[category.itemType]?.map((item, idx) => (
<Col key={item.id}>
<div onClick={() => handleShow(item)} className="text-center">
<MenuItem
dishName={item.item_name}
description={item.description}
imageSrc={item.image_url}
/>
</div>
</Col>
))}
</Row>
</Container>
</Tab>
))}
</Tabs>);
}
return <BasicTemplate content={(
<Container fluid className='d-flex my-5 justify-content-center' style={{ minHeight: '70vh' }}>
<div className='align-items-center'>
{modalContent}
</div>
{/* selectbox branches */}
<Row style={{ maxWidth: "80vw" }}>
<Col xs='12'>
{selectboxContent}
</Col>
<Col xs='12' className='my-5'>
<h1 className='text-center'>Thực đơn</h1>
</Col>
{/* <Col xs={1} md={2}></Col> */}
<Col className='text-center'>
{menuContent}
</Col>
{/* <Col xs={1} md={2}></Col> */}
</Row>
</Container>
)} />
}
export default MenuPage;