Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] feat #23: 메뉴 담기 화면 모달 구현 #29

Merged
merged 4 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions fe/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions fe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@types/react-dom": "^18.2.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.13.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Expand Down
150 changes: 19 additions & 131 deletions fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@

import { Outlet } from 'react-router-dom';
import { useState, useEffect } from 'react';


import classes from './App.module.css';
import { AddMenu } from './components/AddMenu';
import { TabMenu } from './components/TabMenu';
import { MainArea } from './components/MainArea';
import { TestBtnForModal } from './components/TestBtnForModal';

function App() {
const [activeTab, setActiveTab] = useState(0);
const [menuList, setMenuList] = useState([]);
const [productList, setProductList] = useState([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
setLoading(true);
fetch('/api/menus')
Expand All @@ -28,140 +33,23 @@ function App() {
setProductList(data);
setLoading(false);
});
}, [activeTab]);

// const menuList: Menu[] = [
// {
// category: '커피',
// products: [
// {
// imgURL: '/assets/americano.jpeg',
// name: '아메리카노',
// price: 4000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '콜드브루',
// price: 4500,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '에스프레스',
// price: 3000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '카페모카',
// price: 5000,
// },
// ],
// },
// {
// category: '라떼',
// products: [
// {
// imgURL: '/assets/americano.jpeg',
// name: '라떼1',
// price: 4000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '라떼2',
// price: 4500,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '라떼3',
// price: 3000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '라떼4',
// price: 5000,
// },
// ],
// },
// {
// category: '쥬스',
// products: [
// {
// imgURL: '/assets/americano.jpeg',
// name: '쥬스1',
// price: 4000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '쥬스2',
// price: 4500,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '쥬스3',
// price: 3000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '쥬스4',
// price: 5000,
// },
// ],
// },
// {
// category: '티',
// products: [
// {
// imgURL: '/assets/americano.jpeg',
// name: '티1',
// price: 4000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '티2',
// price: 4500,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '티3',
// price: 3000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '티4',
// price: 5000,
// },
// ],
// },
// {
// category: '디카페인',
// products: [
// {
// imgURL: '/assets/americano.jpeg',
// name: '디카페인1',
// price: 4000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '디카페인2',
// price: 4500,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '디카페인3',
// price: 3000,
// },
// {
// imgURL: '/assets/americano.jpeg',
// name: '디카페인4',
// price: 5000,
// },
// ],
// },
// ];

}, [activeTab]);

const menu = [
{ name: '아메리카노', price: '4000', id: '1', img: '{url}' },
{ name: '콜드브루', price: '4500', id: '2', img: '{url}' },
{ name: '라떼', price: '4500', id: '3', img: '{url}' },
{ name: '바닐라라떼', price: '4500', id: '4', img: '{url}' },
{ name: '헤이즐넛', price: '4500', id: '5', img: '{url}' },
];
return (
<div className={classes.kiosk}>
<TabMenu menuList={menuList} activeTab={activeTab} setActiveTab={setActiveTab} />
<MainArea productList={productList} activeTab={activeTab} setActiveTab={setActiveTab} />
{menu.map((menuItem) => (
<TestBtnForModal key={menuItem.id} id={menuItem.id} name={menuItem.name} />
))}
<Outlet />
</div>
);
}
Expand Down
63 changes: 63 additions & 0 deletions fe/src/components/AddMenu.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.menuLayout {
width: 100%;
display: flex;
gap: 30px;
align-items: center;
justify-content: space-between;
}

.menuCard {
border: 1px solid var(--color-black);
width: 260px;
height: 260px;
border-radius: 5px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font: var(--font-body-large);
}

.optionsLayout {
height: 260px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}

.buttonsLayout {
width: 290px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 24px;
}

.counterLayout {
display: flex;
gap: 20px;
font: var(--font-body-large);
align-items: center;
}

.counterButton {
font: var(--font-body-large);
border-radius: 5px;
width: 45px;
height: 45px;
border: 2px solid var(--color-secondary);
background-color: var(--color-secondary);
}

.addBtn {
width: 100%;
padding: 2rem;
border-radius: 5px;
font: var(--font-body-large);
color: var(--color-white);
background: #f0c8c8;
}

.active {
background: var(--color-red);
}
69 changes: 69 additions & 0 deletions fe/src/components/AddMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useState } from 'react';
import { Modal } from './Modal';
import classes from './AddMenu.module.css';
import { OptionButton } from './OptionButton';

/* 여기에서 바뀐 수량, 가격 정보 같은걸 가지고 있어야 함 => 장바구니에 내려주기 위해 */
export function AddMenu() {
const [count, setCount] = useState(1);
const [temperature, setTemperature] = useState<string | null>(null);
const [size, setSize] = useState<string | null>(null);

function temperatureHandler(selectedTemperature: string | null) {
if (temperature === selectedTemperature) {
return;
}
setTemperature(selectedTemperature);
}

function sizeHandler(selectedSize: string | null) {
if (size === selectedSize) {
return;
}
setSize(selectedSize);
}

function incrementHandler() {
setCount(count + 1);
}

function decrementHandler() {
if (count === 1) {
return;
}
setCount(count - 1);
}

const isActive = temperature && size;

return (
<Modal>
<div className={classes.menuLayout}>
<div className={classes.menuCard}>
<img src="" alt="" />
이미지
<p>아메리카노</p>
<p>4000</p>
</div>
<div className={classes.optionsLayout}>
<div className={classes.buttonsLayout}>
<OptionButton label="HOT" selected={temperature === 'hot'} onClick={() => temperatureHandler('hot')} />
<OptionButton label="ICE" selected={temperature === 'ice'} onClick={() => temperatureHandler('ice')} />
<OptionButton label="LARGE" selected={size === 'large'} onClick={() => sizeHandler('large')} />
<OptionButton label="SMALL" selected={size === 'small'} onClick={() => sizeHandler('small')} />
</div>
<div className={classes.counterLayout}>
<button className={classes.counterButton} onClick={decrementHandler}>
-
</button>
<p>{count}</p>
<button className={classes.counterButton} onClick={incrementHandler}>
+
</button>
</div>
</div>
</div>
<button className={`${classes.addBtn} ${isActive ? classes.active : ''}`}>담기</button>
</Modal>
);
}
Loading