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

[가게 등록] 가게 등록 페이지 PC 버전 로직 구현 및 API 구현 #30

Merged
merged 52 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
7ba6413
feat: 사진 업로드 및 미리보기 기능 추가
dooohun Oct 29, 2023
68da4e8
feat: 모달의 전역상태관리 변수 생성
dooohun Oct 31, 2023
e889a87
refactor: 상점 휴무일의 초기 상태 값 수정
dooohun Nov 9, 2023
034daf9
feat: 가게명을 전역변수로 할당
dooohun Nov 9, 2023
2fd2b35
feat: 카테고리명을 전역 변수에 할당
dooohun Nov 9, 2023
5833820
feat: 운영 시간값을 전역 상태에 할당
dooohun Nov 9, 2023
b424831
feat: 전역 변수인 가게 운영 시간을 출력
dooohun Nov 9, 2023
caba708
feat: 상점 api 추가
dooohun Nov 12, 2023
b68ab9c
feat: 공용모달에 hasOverflow 추가
dooohun Nov 12, 2023
4b7c603
feat: 모든 음식점 상점 스키마 추가
dooohun Nov 12, 2023
129a019
feat: 상점 등록 시 필요한 사장님 상점 스키마 추가
dooohun Nov 12, 2023
6eb455a
feat: useAllShops 커스텀 훅을 생성하여 모든 상점 목록을 가져오는 기능 추가
dooohun Nov 12, 2023
7f5022b
chore: "import/prefer-default-export" 규칙을 비활성화함
dooohun Nov 12, 2023
225910f
refactor: modalStore를 조건에 맞게 수정
dooohun Nov 12, 2023
9045926
feat: 운영시간 로직 구현
dooohun Nov 12, 2023
4465aac
feat: 카테고리 id 추가
dooohun Nov 12, 2023
4fb5c2d
feat: 가게 검색 기능 추가
dooohun Nov 12, 2023
9e3908b
feat: confirmPopup을 통해 값 전달
dooohun Nov 12, 2023
018a6a2
feat: 가게 검색에서 선택한 가게 값으로 변경
dooohun Nov 12, 2023
43c068d
feat: InputBox 컴포넌트에서 입력값을 register함수를 사용하여 전달
dooohun Nov 12, 2023
4d5a1ec
feat: 가게 등록 로직 구현
dooohun Nov 12, 2023
535893a
style: confirmStore의 width 수정
dooohun Nov 12, 2023
c30e6df
Refactor: input의 type을 수정
dooohun Nov 16, 2023
03fd754
refactor: e.currentTarget.value를 직접 값에 넣도록 수정
dooohun Nov 16, 2023
19cc465
refactor: hasOverflow를 isOverflowVisible로 수정
dooohun Nov 16, 2023
59a1094
refactor: 가게 뜻을 가진 store 변수를 shop 변수로 통일
dooohun Nov 16, 2023
fcaabb0
refactor: StoreRegistration을 ShopRegistration으로 변경
dooohun Nov 16, 2023
47ed48d
refactor: 가게 등록 path를 원래 상태로 수정
dooohun Nov 16, 2023
23a605b
refactor: useState로 filteredShopList 상태 관리
dooohun Nov 16, 2023
4437b76
feat: enter키 누르거나 검색 버튼을 누르면 상점 리스트 필터링 되는 기능 추가
dooohun Nov 17, 2023
80e49fc
feat: useAllShops 에러 핸들링 기능 추가
dooohun Nov 17, 2023
f3a5d3e
refactor: 통일성 있게 네이밍 수정
dooohun Nov 21, 2023
bb53be7
refactor: DAY_OF_WEEK 파일 이동, WEEK를 export로 수정
dooohun Nov 21, 2023
85f1b2e
refactor: 변수명 통일
dooohun Nov 21, 2023
8d9c6c0
refactor: CheckSameTime 훅 분리
dooohun Nov 22, 2023
9cbaf8d
refactor: useImageUpload 훅 분리
dooohun Nov 22, 2023
94fdf1f
refactor: useOperateTimeState 훅 분리
dooohun Nov 22, 2023
a1f352c
refactor: 훅 분리 및 변수명 수정
dooohun Nov 22, 2023
9b5ff4f
refactor: useImageUpload 훅 분리
dooohun Nov 23, 2023
1fe134b
refactor: OperateTimeProps를 Record Type으로 수정
dooohun Nov 23, 2023
bbce10e
refactor: useImageUpload를 utils/hooks로 이동
dooohun Nov 23, 2023
073da35
refactor: 기존의 복잡한 타입을OperatingTime으로 정의
dooohun Nov 23, 2023
7aebeee
refactor: InputBoxProps로 타입명 통일
dooohun Nov 23, 2023
dc8531f
feat: 카테고리 섹션을 조작하기 위한 handleCategoryClick 함수 생성
dooohun Nov 23, 2023
bdcfdc8
refactor: handleShopClosedChange를 이전 상태를 고려하도록 수정
dooohun Nov 24, 2023
bbdff93
feat: 전화번호 입력 시 하이픈 자동 입력 기능 추가
dooohun Nov 24, 2023
28eb56b
style: 가게 확인 모달 위치 고정하도록 수정
dooohun Nov 24, 2023
4018363
feat: 모달 오버레이 스크롤 제어 기능 추가
dooohun Nov 24, 2023
8e9ce22
refactor: height를 modalSize로 수정
dooohun Nov 24, 2023
c966bd6
Merge branch 'develop' of https://github.com/BCSDLab/KOIN_OWNER_WEB i…
dooohun Nov 25, 2023
ec44861
Merge branch 'develop' into feature/#27
dooohun Nov 28, 2023
ad2fc39
refactor: getShopList를 인증이 필요하지 않는 요청으로 수정
dooohun Nov 28, 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
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"react/jsx-props-no-spreading": "off",
"react/require-default-props": "off",
"@typescript-eslint/no-redeclare" : "off",
"import/prefer-default-export": "off",
dooohun marked this conversation as resolved.
Show resolved Hide resolved
"no-restricted-imports": [
"error",
{
Expand Down
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import CompleteChangePassword from 'page/Auth/FindPassword/CompleteChangePasswor
import AuthLayout from 'layout/AuthLayout';

import MyStorePage from 'page/MyShopPage';
import StoreRegistration from 'page/StoreRegistration';
import ShopRegistration from 'page/ShopRegistration';
import AddMenu from 'page/AddMenu';

function App() {
return (
<Routes>
<Route path="/" element={<DefaultLayout />}>
<Route path="/" element={<MyStorePage />} />
<Route path="/store-registration" element={<StoreRegistration />} />
<Route path="/store-registration" element={<ShopRegistration />} />
<Route path="/add-menu" element={<AddMenu />} />
</Route>
<Route element={<AuthLayout />}>
Expand Down
4 changes: 2 additions & 2 deletions src/api/category/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { accessClient } from 'api';
import { StoreCategory } from 'model/category/storeCategory';

const getStoreCategory = async () => {
const getShopCategory = async () => {
const { data } = await accessClient.get<StoreCategory>('/shops/categories');
return StoreCategory.parse(data);
};

export default getStoreCategory;
export default getShopCategory;
17 changes: 13 additions & 4 deletions src/api/shop/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { MyShopList, MyShopInfoRes, MyShopParam } from 'model/shopInfo/myShopInfo';
import { MyShopListRes, MyShopInfoRes, MyShopParam } from 'model/shopInfo/myShopInfo';
import { MenuInfoRes } from 'model/shopInfo/menuCategory';
import { accessClient } from 'api';
import { ShopListRes } from 'model/shopInfo/allShopInfo';
import { accessClient, client } from 'api';
import { OwnerShop } from 'model/shopInfo/ownerShop';

export const getMyShopList = async () => {
const { data } = await accessClient.get<MyShopList>('/owner/shops');
return MyShopList.parse(data);
const { data } = await accessClient.get<MyShopListRes>('/owner/shops');
return MyShopListRes.parse(data);
};

export const getShopInfo = async (param: MyShopParam) => {
Expand All @@ -16,3 +18,10 @@ export const getMenuInfoList = async (param: MyShopParam) => {
const { data } = await accessClient.get<MenuInfoRes>(`/owner/shops/${param.id}/menus`);
return MenuInfoRes.parse(data);
};

export const getShopList = async () => {
const { data } = await client.get<ShopListRes>('/shops');
return ShopListRes.parse(data);
};

export const postShop = (data: OwnerShop) => accessClient.post('/owner/shops', data);
61 changes: 56 additions & 5 deletions src/component/common/CustomModal/CustomModal.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,71 @@
}

.container {
display: flex;
flex-direction: column;
align-items: center;
width: 430px;
background-color: #ffffff;
&__small {
display: flex;
flex-direction: column;
align-items: center;
width: 430px;
height: 434px;
background-color: #ffffff;
overflow: auto;

&--visible {
overflow: visible;
}

&::-webkit-scrollbar {
display: none;
}
}

&__medium {
display: flex;
flex-direction: column;
align-items: center;
width: 430px;
height: 536px;
background-color: #ffffff;
overflow: auto;

&--visible {
overflow: visible;
}

&::-webkit-scrollbar {
display: none;
}
}

&__large {
display: flex;
flex-direction: column;
align-items: center;
width: 430px;
height: 75vh;
background-color: #ffffff;
overflow: auto;

&--visible {
overflow: visible;
}

&::-webkit-scrollbar {
display: none;
}
}

&__header {
position: sticky;
top: 0;
display: flex;
align-items: center;
justify-content: space-between;
width: 398px;
height: 30px;
background-color: #175c8e;
padding: 24px 16px;
z-index: 3;
}

&__title {
Expand Down
32 changes: 28 additions & 4 deletions src/component/common/CustomModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
import { ReactComponent as XClose } from 'assets/svg/StoreRegistration/close-x.svg';
import { ReactComponent as XClose } from 'assets/svg/shopRegistration/close-x.svg';
import CustomButton from 'page/Auth/Signup/component/CustomButton';
import { createPortal } from 'react-dom';
import cn from 'utils/ts/className';
import { useEffect } from 'react';
import styles from './CustomModal.module.scss';

interface CustomModalProps {
buttonText?: string;
title: string;
height: string;
modalSize: string;
hasFooter: boolean;
isOpen: boolean;
isOverflowVisible: boolean;
onCancel: () => void;
children: React.ReactNode
}

export default function CustomModal({
buttonText = '', title, height, hasFooter, isOpen, onCancel, children,
buttonText = '', title, modalSize, hasFooter, isOpen, isOverflowVisible, onCancel, children,
}: CustomModalProps) {
useEffect(() => {
if (isOpen) {
document.body.style.cssText = `
position: fixed;
top: -${window.scrollY}px;
overflow-y: scroll;
width: 100%;`;
return () => {
const scrollY = document.body.style.top;
document.body.style.cssText = '';
window.scrollTo(0, parseInt(scrollY || '0', 10) * -1);
};
}
return undefined;
}, [isOpen]);

if (!isOpen) return null;
return createPortal(
<div className={styles.modal}>
<div className={styles.container} style={{ height }}>
<div
className={cn({
[styles[`container__${modalSize}`]]: true,
[styles[`container__${modalSize}--visible`]]: isOverflowVisible,
})}
>
<div className={styles.container__header}>
<span className={styles.container__title}>{title}</span>
<XClose
Expand Down
28 changes: 28 additions & 0 deletions src/model/shopInfo/allShopInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import z from 'zod';

const Open = z.object({
day_of_week: z.string(),
closed: z.boolean(),
open_time: z.string().nullable(),
close_time: z.string().nullable(),
dooohun marked this conversation as resolved.
Show resolved Hide resolved
});

export const Shop = z.object({
id: z.number(),
name: z.string(),
phone: z.string(),
delivery: z.boolean(),
pay_bank: z.boolean(),
pay_card: z.boolean(),
open: z.array(Open),
category_ids: z.array(z.number()),
});

export type Shop = z.infer<typeof Shop>;

export const ShopListRes = z.object({
count: z.number(),
shops: z.array(Shop),
});

export type ShopListRes = z.infer<typeof ShopListRes>;
4 changes: 2 additions & 2 deletions src/model/shopInfo/myShopInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export const MyShop = z.object({

export type MyShop = z.infer<typeof MyShop>;

export const MyShopList = z.object({
export const MyShopListRes = z.object({
count: z.number(),
shops: z.array(MyShop),
});

export type MyShopList = z.infer<typeof MyShopList>;
export type MyShopListRes = z.infer<typeof MyShopListRes>;

export const OpenInfo = z.object({
day_of_week: z.string(),
Expand Down
11 changes: 11 additions & 0 deletions src/model/shopInfo/ownerShop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import z from 'zod';
import { Shop } from './allShopInfo';

export const OwnerShop = Shop.omit({ id: true }).extend({
address: z.string(),
description: z.string(),
delivery_price: z.string(),
image_urls: z.array(z.string()),
});

export type OwnerShop = z.infer<typeof OwnerShop>;
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { createPortal } from 'react-dom';
import useStepStore from 'store/useStepStore';
import styles from './ConfirmPopup.module.scss';

interface ConfirmPopupProps {
Expand All @@ -8,11 +6,9 @@ interface ConfirmPopupProps {
}

export default function ConfirmPopup({ isOpen, onCancel }: ConfirmPopupProps) {
const { setStep } = useStepStore();

if (!isOpen) return null;

return createPortal(
return (
<div className={styles.popup}>
<div className={styles.content}>
<span className={styles['content__top-text']}>가게 정보를 저장하시겠습니까?</span>
Expand All @@ -27,15 +23,13 @@ export default function ConfirmPopup({ isOpen, onCancel }: ConfirmPopupProps) {
취소
</button>
<button
type="button"
onClick={() => setStep(5)}
type="submit"
className={styles['content__next-button']}
>
확인
</button>
</div>
</div>
</div>,
document.body,
</div>
);
}
44 changes: 44 additions & 0 deletions src/page/ShopRegistration/component/InputBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { UseFormRegister } from 'react-hook-form';
import { OwnerShop } from 'model/shopInfo/ownerShop';
import { HTMLInputTypeAttribute, useState } from 'react';
import styles from './InputBox.module.scss';

interface InputBoxProps {
content: string;
id: keyof OwnerShop
register: UseFormRegister<OwnerShop>;
inputType: HTMLInputTypeAttribute;
}

function formatPhoneNumber(inputNumber: string) {
const phoneNumber = inputNumber.replace(/\D/g, '');

const formattedPhoneNumber = phoneNumber.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');

return formattedPhoneNumber;
}

export default function InputBox({
content, id, register, inputType,
}: InputBoxProps) {
const [formattedPhoneNumber, setFormattedPhoneNumber] = useState('');

const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const inputNumber = e.target.value;
const formattedNumber = formatPhoneNumber(inputNumber);
setFormattedPhoneNumber(formattedNumber);
};
return (
<label htmlFor={id} className={styles.form}>
<span className={styles.form__label}>{content}</span>
<input
type={inputType}
id={id}
className={styles.form__input}
{...register(id)}
onChange={inputType === 'tel' ? handlePhoneChange : undefined}
value={inputType === 'tel' ? formattedPhoneNumber : undefined}
/>
</label>
);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import useStoreCategory from 'query/storeCategory';
import useShopCategory from 'query/shopCategory';
import { useState } from 'react';
import cn from 'utils/ts/className';
import useModalStore from 'store/modalStore';
import { Category as CategoryProps } from 'model/category/storeCategory';
import styles from './Category.module.scss';

export default function Category() {
const [selectedCategory, setSelectedCategory] = useState('');
const { categoryList } = useStoreCategory();
const { categoryList } = useShopCategory();
const { setCategoryState } = useModalStore();

const handleCategoryClick = (category: CategoryProps) => {
setSelectedCategory(category.name);
setCategoryState([category.name, category.id]);
};

return (
<div className={styles.category}>
{categoryList?.shop_categories.filter((_, index) => index > 0).map((category) => (
Expand All @@ -15,7 +24,7 @@ export default function Category() {
[styles['category__menu--selected']]: category.name === selectedCategory,
})}
type="button"
onClick={() => setSelectedCategory(category.name)}
onClick={() => { handleCategoryClick(category); }}
key={category.id}
>
<img className={styles.category__image} src={category.image_url} alt="" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
.container {
position: absolute;
position: sticky;
bottom: 0;
left: 0;
display: flex;
justify-content: space-around;
justify-content: space-between;
align-items: center;
height: 25%;
height: 23%;
width: 100%;
border-radius: 20px 20px 0 0;
box-shadow: 0 -5px 10px #00000026;
background-color: #ffffff;

&__info {
margin-left: 32px;
}

&__title {
font-size: 20px;
Expand All @@ -34,6 +38,7 @@
width: 144px;
height: 48px;
background-color: #175c8e;
margin-right: 31px;
font-size: 20px;
font-weight: 600;
color: #ffffff;
Expand Down
Loading
Loading