Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
45dfe12
🔧chore #1: CRA 프로젝트 초기 설정
youzysu Jun 19, 2023
58d8f43
📝 docs: 리드미 파일 작성 및 gitmessage 템플릿 추가
youzysu Jun 19, 2023
b0a0157
🔧 chore #1: 메뉴 mock data 생성
youzysu Jun 20, 2023
341afa3
🔧 chore #1: 메뉴 mock data 수정
qkdflrgs Jun 20, 2023
ab87b21
✨ feat #4: 메인 페이지 구성
youzysu Jun 20, 2023
fba23d3
✨ feat #4: 메인 페이지 컴포넌트 분리
youzysu Jun 20, 2023
f81eb67
✨ feat #4: 메뉴 아이템 컴포넌트 추가
qkdflrgs Jun 20, 2023
bd24044
✨ feat #12: 메인 메뉴 영역 UI 생성
youzysu Jun 21, 2023
ddfaedb
📝 docs: 프로젝트 소개 리드미 파일 수정
youzysu Jun 21, 2023
0996b3f
✨feat #10: 메뉴 담기 모달 컴포넌트 추가
qkdflrgs Jun 21, 2023
f3cac75
✨ feat #13: 주문 영역 주문 내역 UI
youzysu Jun 21, 2023
99f3df7
✨feat #10: 메뉴 담기 모달 컴포넌트 수정
qkdflrgs Jun 22, 2023
0af4161
✨ feat #33: 주문 영역 타이머, 버튼 UI 생성
youzysu Jun 22, 2023
3ce4748
♻️refactor #10: 메뉴 담기 모달 상태 관리 리팩토링
qkdflrgs Jun 22, 2023
c046155
Merge branch 'feat/fe/mainpage' of https://github.com/codesquad-gwana…
youzysu Jun 22, 2023
69dd223
♻️refactor #10: 메뉴 담기 모달 상태 관리 리팩토링
qkdflrgs Jun 22, 2023
4c49d90
Merge branch 'feat/fe/mainpage' of https://github.com/codesquad-gwana…
youzysu Jun 22, 2023
6595471
✨ feat #10 #19: 유저가 담은 메뉴 주문 내역 상태에 추가
youzysu Jun 22, 2023
d16aadc
♻️refactor #10: 메뉴 담기 모달 props 수정
qkdflrgs Jun 22, 2023
49ba13b
♻️refactor #10: 메뉴 담기 모달 로직 변경
qkdflrgs Jun 22, 2023
81d5d7f
♻️refactor #13: 메뉴 ID 타입 변경
qkdflrgs Jun 22, 2023
a95902c
💄design #10: 메뉴 담기 모달 CSS 적용
qkdflrgs Jun 22, 2023
21bf5d6
♻️refactor #10: 메뉴 담기 모달 클래스 이름 변경
qkdflrgs Jun 22, 2023
f8e94ae
✨ feat #13: 주문 내역 취소, 타이머 로직 리팩토링
youzysu Jun 22, 2023
8a5287d
💄 design #12: 메인 메뉴 영역 CSS 수정
youzysu Jun 22, 2023
3d5f786
🎨 style: 불필요한 주석 제거
youzysu Jun 22, 2023
14ac999
🐛 fix: 주문 영역 메뉴 총수량 버그 수정
youzysu Jun 23, 2023
cbbbd80
docs: 프로젝트 리드미 파일 수정
youzysu Jun 23, 2023
f9b6bc3
✨ feat #12: 베스트 메뉴인 경우 인기 로고 추가
youzysu Jun 24, 2023
35412b2
♻️ refactor #13: OrderArea Cart로 컴포넌트 이름 수정, 메뉴 id가 동일하면 합쳐서 카운트
youzysu Jun 24, 2023
850a9b8
♻️ refactor: sprint01 로직 전반 리팩토링
youzysu Jun 26, 2023
247ca7b
♻️refactor #10: 버튼 컴포넌트 리팩토링
qkdflrgs Jun 26, 2023
40d5743
✨feat #47: 로딩 인디케이터 컴포넌트 생성
qkdflrgs Jun 26, 2023
62bf1c7
✨ feat #46: 결제하기 버튼 클릭 시 결제 방식 선택 모달 보여주기
youzysu Jun 26, 2023
330d300
♻️ refactor: 타입 및 인터페이스 전반 수정
youzysu Jun 26, 2023
b25253e
Merge pull request #61 from codesquad-gwanaksan/dev-fe-feat/paymentIn…
youzysu Jun 26, 2023
14982b2
Merge pull request #63 from codesquad-gwanaksan/dev-fe-feat/paymentModal
qkdflrgs Jun 26, 2023
0b44310
✨ feat #47: 카드 결제 방식 선택 후 결제 요청
youzysu Jun 27, 2023
708c409
✨feat #58: 영수증 컴포넌트 생성
qkdflrgs Jun 27, 2023
d0eafd2
✨feat #58: 영수증 페이지 UI 생성
qkdflrgs Jun 27, 2023
26316b7
✨feat #58: 영수증 컴포넌트 생성
qkdflrgs Jun 27, 2023
f2a39ea
✨ feat #48: 클라이언트 라우팅 처리
youzysu Jun 27, 2023
6686014
♻️refactor #58: 영수증 페이지 라우팅 리팩토링
qkdflrgs Jun 27, 2023
fae555b
Merge pull request #67 from codesquad-gwanaksan/dev-fe-feat/receiptPage
qkdflrgs Jun 27, 2023
8f78481
✨ feat #48: ReceiptPage 렌더링
youzysu Jun 27, 2023
cff3971
♻️ refactor #12: ‘인기’ 로고 이미지 위치 수정
youzysu Jun 27, 2023
91f5a84
♻️ refactor: HomePage 전반 리팩토링
youzysu Jun 27, 2023
e732d14
temp: 스쿼드 세션을 위한 임시 커밋
youzysu Jun 28, 2023
5514ad1
♻️refactor #57: 모달 이외 영역 클릭 시 모달이 닫히는 커스텀 훅을 적용하여 리팩토링
qkdflrgs Jun 28, 2023
dd23c94
♻️refactor #58: 영수증 페이지 api data fetch 리팩토링
qkdflrgs Jun 28, 2023
7d4be23
🎨 style: HomePage Dim CSS 수정
youzysu Jun 28, 2023
29b7272
🐛 fix #70: 주문 메뉴 목록 수량 버그 수정
youzysu Jun 28, 2023
bf2cd78
♻️ refactor: 불필요한 코드 삭제
youzysu Jun 28, 2023
2c75024
♻️ refactor: API menu -> product 네이밍 전반 반영
youzysu Jun 28, 2023
84de10d
♻️ refactor: page component 전반 리팩토링
youzysu Jun 28, 2023
29ee92f
♻️ refactor: 카트 컴포넌트 렌더링 이후 로직 useEffect 내부로 이동
youzysu Jun 28, 2023
810e6a4
♻️ refactor: 메뉴 담기 버튼 disabled 속성 추가
youzysu Jun 28, 2023
4e1a296
♻️refactor #10: 메뉴 담기 모달 버튼 컴포넌트 적용 및 리팩토링
qkdflrgs Jun 28, 2023
7fd760d
♻️refactor: 버튼 컴포넌트 분리
qkdflrgs Jun 28, 2023
794c7d4
♻️refactor: 영수증 api 변경에 따른 타입 수정
qkdflrgs Jun 28, 2023
a2055e0
♻️refact #57: 모달 이외 영역 클릭 시 모달이 닫히는 로직 리팩토링
qkdflrgs Jun 28, 2023
997352d
✨feat #59: 현금 결제 페이지 생성
qkdflrgs Jun 28, 2023
ad36d3c
Merge pull request #73 from codesquad-gwanaksan/dev-fe-refactor/home
youzysu Jun 28, 2023
08286b8
🐛 fix: 영수증 API 변경 인터페이스에 맞춰 Receipt 컴포넌트 수정
youzysu Jun 28, 2023
543281c
🔧 chore: 의존성 추가
youzysu Jun 28, 2023
97f5c0f
Merge branch 'dev-fe-feat/cashPayment' of https://github.com/codesqua…
youzysu Jun 29, 2023
6ad068b
Merge pull request #76 from codesquad-gwanaksan/dev-fe-feat/cashPayment
youzysu Jun 29, 2023
59c8ab4
✨ feat #64, refactor: Large 사이즈인 경우 가격 500원 추가하기
youzysu Jun 29, 2023
cb827b5
✨ feat #64: 카트에서 메뉴 삭제 시 동일한 사이즈만 삭제
youzysu Jun 29, 2023
cfd4094
[FE] 재확인 모달 구현 및 적용 (#81)
qkdflrgs Jun 29, 2023
290741c
Merge branch 'dev-fe-sprint02' of https://github.com/codesquad-gwanak…
youzysu Jun 29, 2023
e9e7f53
Merge pull request #80 from codesquad-gwanaksan/dev-fe-feat/menuSizeP…
qkdflrgs Jun 29, 2023
f2eb4dd
♻️ refactor #58: Receipt Page 리팩토링
youzysu Jun 29, 2023
cacea66
Merge pull request #84 from codesquad-gwanaksan/dev-fe-refactor/recei…
qkdflrgs Jun 29, 2023
a7759c0
♻️refactor #10: 메뉴 담기 모달 옵션 선택 버튼 리팩토링
qkdflrgs Jun 29, 2023
4125e9d
♻️refactor: 버튼 컴포넌트 리팩토링
qkdflrgs Jun 29, 2023
3e60939
💄design: 음료 온도 선택 버튼 색상 추가
qkdflrgs Jun 29, 2023
7d9b5cb
💄design: 음료 사이즈 선택 버튼 아이콘 추가
qkdflrgs Jun 29, 2023
9e1a786
Merge pull request #87 from codesquad-gwanaksan/dev-fe-refactor/order…
youzysu Jun 29, 2023
8b0f535
✨feat #55: 메인 화면의 네비바의 카테고리 3개만 노출
qkdflrgs Jun 29, 2023
b9d1c23
✨ feat #77: 카테고리 변경 시 메뉴 슬라이딩 애니메이션 효과
youzysu Jun 29, 2023
06a5bcc
Merge pull request #94 from codesquad-gwanaksan/dev-fe-feat/mainMenuA…
youzysu Jun 29, 2023
eb00d31
🔧 chore: DOMAIN API 환경 변수 설정
youzysu Jun 30, 2023
3102dfa
Merge branch 'dev-fe-sprint02' into dev-fe-feat/navBarScroll
qkdflrgs Jun 30, 2023
a06cfa0
Merge pull request #91 from codesquad-gwanaksan/dev-fe-feat/navBarScroll
qkdflrgs Jun 30, 2023
0157f4e
🐛fix #56: 카테고리 영역 슬라이딩 버스 수정
qkdflrgs Jun 30, 2023
4354a5d
Merge pull request #95 from codesquad-gwanaksan/dev-fe-sprint02
youzysu Jun 30, 2023
2707582
Merge branch 'team-03' into dev-fe
youzysu Jun 30, 2023
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
3 changes: 2 additions & 1 deletion fe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
]
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.59.11",
"eslint": "^8.0.1",
Expand All @@ -50,4 +51,4 @@
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.32.2"
}
}
}
Binary file added fe/public/assets/icon/drink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 6 additions & 8 deletions fe/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
display: flex;
align-items: center;
justify-content: center;
align-items: center;
}

.mainPage {
.App {
display: flex;
width: 50rem;
height: 100%;
height: 70rem;
justify-content: center;
align-items: center;
border: 2px solid var(--color-primary);
font-family: var(--font-family);
font-weight: var(--font-weight-bold);
font-size: var(--font-size-title-md);
line-height: auto;
}
}
44 changes: 25 additions & 19 deletions fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { fetchMenus } from 'api';
import MainPage from 'pages/MainPage';
import { CategoryInfo } from 'pages/types';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import Home from 'pages/Home';
import ReceiptPage from 'pages/ReceiptPage';
import { useState } from 'react';
import './App.css';

function App() {
const [loading, setLoading]: [boolean, Dispatch<SetStateAction<boolean>>] = useState(true);
const [menuData, setMenuData]: [CategoryInfo[], Dispatch<SetStateAction<[]>>] = useState([]);
export default function App() {
return <Router />;
}

const getMenus = async () => {
const menuData = await fetchMenus();
setMenuData(menuData);
setLoading(false);
function Router() {
const [page, setPage] = useState('/');
const navigate = (path: string) => {
setPage(path);
window.history.pushState({}, '', path);
};

useEffect(() => {
getMenus();
}, []);
const goHome = () => navigate('/');

return (
<div className="App">{loading ? <div>메뉴를 불러오고 있습니다...</div> : <MainPage allMenus={menuData} />}</div>
);
}
let content;
const orderId = Number(page.split('/')[3]);

export default App;
switch (page) {
case '/': {
content = <Home navigate={navigate} />;
break;
}
case `/receipt/orderId/${orderId}`: {
content = <ReceiptPage orderId={orderId} goHome={goHome} />;
}
}
return <div className="App">{content}</div>;
}
99 changes: 94 additions & 5 deletions fe/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const BASE_API_DOMAIN = new URL(`https://050ac41b-0add-475f-9551-31bf41119bcc.mock.pstmn.io`);
import { CategoryInfo, OrderResult, OrderSuccessInfo, ProductOrder } from 'pages/types';
import { formatMenuOptionOrderList } from 'utils';

const fetchJSON = async (url: URL) => {
const response = await fetch(url);
const BASE_API_DOMAIN = process.env.REACT_APP_BASE_API_DOMAIN;

const fetchJSON = async (url: URL, option?: {}) => {
const response = await fetch(url, option);

if (!response.ok) {
throw new Error(response.statusText);
Expand All @@ -10,11 +13,97 @@ const fetchJSON = async (url: URL) => {
return response.json();
};

export const fetchMenus = async () => {
export const fetchMenus = async (): Promise<CategoryInfo[] | undefined> => {
try {
const url = new URL('products', BASE_API_DOMAIN);
return await fetchJSON(url);
} catch (error) {
console.error(error);
}
};

export const requestCardOrder = async (
orderList: ProductOrder[],
totalPrice: number
): Promise<OrderResult | undefined> => {
const formattedOrderList = formatMenuOptionOrderList(orderList);
const json = JSON.stringify({
orderProducts: formattedOrderList,
totalPrice: totalPrice,
});
const option = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: json,
};

try {
const url = new URL('api/payment/card', BASE_API_DOMAIN);
return await fetchJSON(url, option);
} catch (error) {
console.error(error);
}
};

export const fetchReceipt = async (orderId: number): Promise<OrderSuccessInfo | undefined> => {
try {
const url = new URL('menus', BASE_API_DOMAIN);
const url = new URL(`api/receipt?orderId=${orderId}`, BASE_API_DOMAIN);
return await fetchJSON(url);
} catch (error) {
console.error(error);
}
};

export const requestCashOrder = async (
orderList: ProductOrder[],
totalPrice: number,
receivedPrice: number
): Promise<OrderResult | undefined> => {
const formattedOrderList = formatMenuOptionOrderList(orderList);
const json = JSON.stringify({
orderProducts: formattedOrderList,
totalPrice: totalPrice,
receivedPrice: receivedPrice,
});
const option = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: json,
};

try {
const url = new URL('api/payment/cash', BASE_API_DOMAIN);
return await fetchJSON(url, option);
} catch (error) {
console.error(error);
}
};

export const failCardOrder = async (
orderList: ProductOrder[],
totalPrice: number
): Promise<OrderResult | undefined> => {
const formattedOrderList = formatMenuOptionOrderList(orderList);
const json = JSON.stringify({
orderItems: formattedOrderList,
totalPrice: totalPrice,
});
const option = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: json,
};

try {
const url = new URL('api/payment/card?fail=500', BASE_API_DOMAIN);
return await fetchJSON(url, option);
} catch (error) {
console.error(error);
}
};
95 changes: 95 additions & 0 deletions fe/src/components/LoadingIndicator/LoadingIndicator.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
.loadingIndicator {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 40px;
}

.loadingIndicator span {
color: #e9d78d;
font-family: var(--font-family);
font-weight: var(--font-weight-bold);
font-size: var(--font-size-display);
}

.indicatorWrap {
color: official;
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}

.indicatorWrap div {
transform-origin: 40px 40px;
animation: indicator 1.2s linear infinite;
}

.indicatorWrap div:after {
content: ' ';
display: block;
position: absolute;
top: 3px;
left: 37px;
width: 6px;
height: 18px;
border-radius: 20%;
background: #e9d78d;
}
.indicatorWrap div:nth-child(1) {
transform: rotate(0deg);
animation-delay: -1.1s;
}
.indicatorWrap div:nth-child(2) {
transform: rotate(30deg);
animation-delay: -1s;
}
.indicatorWrap div:nth-child(3) {
transform: rotate(60deg);
animation-delay: -0.9s;
}
.indicatorWrap div:nth-child(4) {
transform: rotate(90deg);
animation-delay: -0.8s;
}
.indicatorWrap div:nth-child(5) {
transform: rotate(120deg);
animation-delay: -0.7s;
}
.indicatorWrap div:nth-child(6) {
transform: rotate(150deg);
animation-delay: -0.6s;
}
.indicatorWrap div:nth-child(7) {
transform: rotate(180deg);
animation-delay: -0.5s;
}
.indicatorWrap div:nth-child(8) {
transform: rotate(210deg);
animation-delay: -0.4s;
}
.indicatorWrap div:nth-child(9) {
transform: rotate(240deg);
animation-delay: -0.3s;
}
.indicatorWrap div:nth-child(10) {
transform: rotate(270deg);
animation-delay: -0.2s;
}
.indicatorWrap div:nth-child(11) {
transform: rotate(300deg);
animation-delay: -0.1s;
}
.indicatorWrap div:nth-child(12) {
transform: rotate(330deg);
animation-delay: 0s;
}
@keyframes indicator {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
29 changes: 29 additions & 0 deletions fe/src/components/LoadingIndicator/LoadingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import styles from './LoadingIndicator.module.css';

export function LoadingIndicator({ text }: { text: string }) {
return (
<div className={styles.loadingIndicator}>
<Indicator />
<span>{text}</span>
</div>
);
}

function Indicator() {
return (
<div className={styles.indicatorWrap}>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
);
}
Loading