From 3d85dce994a064b57586c65a06aa21fbfa9844f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EC=A4=80?= Date: Wed, 20 Mar 2024 02:24:02 +0900 Subject: [PATCH 01/38] =?UTF-8?q?feat:=20queryKey=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/query/KeyFactory/allShopKeys.ts | 3 +++ src/query/KeyFactory/menuKeys.ts | 4 ++++ src/query/KeyFactory/registerKeys.ts | 8 ++++++++ src/query/KeyFactory/shopCategoryKeys.ts | 3 +++ src/query/KeyFactory/shopKeys.ts | 6 ++++++ src/query/menu.ts | 4 +++- src/query/register.ts | 11 ++++++----- src/query/shop.ts | 9 +++++---- src/query/shopCategory.ts | 3 ++- src/query/shops.ts | 3 ++- 10 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/query/KeyFactory/allShopKeys.ts create mode 100644 src/query/KeyFactory/menuKeys.ts create mode 100644 src/query/KeyFactory/registerKeys.ts create mode 100644 src/query/KeyFactory/shopCategoryKeys.ts create mode 100644 src/query/KeyFactory/shopKeys.ts diff --git a/src/query/KeyFactory/allShopKeys.ts b/src/query/KeyFactory/allShopKeys.ts new file mode 100644 index 00000000..18f057e6 --- /dev/null +++ b/src/query/KeyFactory/allShopKeys.ts @@ -0,0 +1,3 @@ +export const allShopKeys = { + all: ['shop'] as const, +}; diff --git a/src/query/KeyFactory/menuKeys.ts b/src/query/KeyFactory/menuKeys.ts new file mode 100644 index 00000000..2886ace5 --- /dev/null +++ b/src/query/KeyFactory/menuKeys.ts @@ -0,0 +1,4 @@ +export const menuKeys = { + all: ['menu'] as const, + menuInfo: (menuId: number) => [...menuKeys.all, 'menuInfo', menuId] as const, +}; diff --git a/src/query/KeyFactory/registerKeys.ts b/src/query/KeyFactory/registerKeys.ts new file mode 100644 index 00000000..a70c73c0 --- /dev/null +++ b/src/query/KeyFactory/registerKeys.ts @@ -0,0 +1,8 @@ +export const registerKeys = { + all: ['register'] as const, + emailCheck: (email: string) => [...registerKeys.all, 'emailDuplicateCheck', email] as const, + authCode: (email: string) => [...registerKeys.all, 'generateEmailAuthCode', email] as const, + verificationCode: (code: string, email: string) => [...registerKeys.all, 'verificationCode', code, email] as const, + registerUser: ['registerUser'] as const, + fileUrlList: ['fileUrlList'] as const, +}; diff --git a/src/query/KeyFactory/shopCategoryKeys.ts b/src/query/KeyFactory/shopCategoryKeys.ts new file mode 100644 index 00000000..cba5bdbb --- /dev/null +++ b/src/query/KeyFactory/shopCategoryKeys.ts @@ -0,0 +1,3 @@ +export const shopCategoryKeys = { + shopCategory: ['shopCategory'] as const, +}; diff --git a/src/query/KeyFactory/shopKeys.ts b/src/query/KeyFactory/shopKeys.ts new file mode 100644 index 00000000..f085afbe --- /dev/null +++ b/src/query/KeyFactory/shopKeys.ts @@ -0,0 +1,6 @@ +export const shopKeys = { + all: ['shop'] as const, + myShopList: (myShopQueryKey: string | undefined) => [...shopKeys.all, 'myShop', myShopQueryKey] as const, + myShopInfo: (shopId: number) => [...shopKeys.all, 'myShopInfo', shopId] as const, + myMenuInfo: (shopId: number) => [...shopKeys.all, 'myMenuInfo', shopId] as const, +}; diff --git a/src/query/menu.ts b/src/query/menu.ts index 42cbf7cf..ef24e0df 100644 --- a/src/query/menu.ts +++ b/src/query/menu.ts @@ -2,13 +2,14 @@ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { getMenu, modifyMenu, deleteMenu } from 'api/shop'; import { NewMenu } from 'model/shopInfo/newMenu'; import useAddMenuStore from 'store/addMenu'; +import { shopKeys } from './KeyFactory/shopKeys'; const useMenuInfo = (menuId:number) => { const { resetAddMenuStore } = useAddMenuStore(); const queryClient = useQueryClient(); const { data: menuData } = useQuery( { - queryKey: ['menuInfo', menuId], + queryKey: shopKeys.myMenuInfo(menuId), queryFn: () => getMenu(menuId), }, ); @@ -32,6 +33,7 @@ export const useDeleteMenu = () => { queryClient.invalidateQueries(); }, }); + return { deleteMenuMutation, }; diff --git a/src/query/register.ts b/src/query/register.ts index 2f162618..9139a9cf 100644 --- a/src/query/register.ts +++ b/src/query/register.ts @@ -7,10 +7,11 @@ import useRegisterInfo from 'store/registerStore'; import useShopRegistrationStore from 'store/shopRegistration'; import useUploadToken from 'store/uploadToken'; import showToast from 'utils/ts/showToast'; +import { registerKeys } from './KeyFactory/registerKeys'; export const useCheckDuplicate = (email:string) => { const { status, refetch, error } = useQuery({ - queryKey: ['emailDuplicateCheck', email], + queryKey: registerKeys.emailCheck(email), queryFn: () => getEmailDuplicate(email), enabled: false, }); @@ -21,7 +22,7 @@ export const useGenerateAuthCode = (email:string) => { const { status, refetch, isError, error, } = useQuery({ - queryKey: ['generateEmailAuthCode', email], + queryKey: registerKeys.authCode(email), queryFn: () => getEmailAuthCode({ address: email }), enabled: false, }); @@ -35,7 +36,7 @@ export const useVerificationAuthCode = (code:string, email:string) => { const { status, refetch, isError, error, data, } = useQuery({ - queryKey: ['verificationCode', code], + queryKey: registerKeys.verificationCode(code, email), queryFn: () => verificationAuthCode({ certification_code: code, address: email }), enabled: false, }); @@ -49,7 +50,7 @@ export const useRegisterUser = (goNext:()=>void) => { const { userInfo, ownerInfo, resetRegisterInfo } = useRegisterInfo(); const { shopId, name } = useShopRegistrationStore(); const register = useMutation({ - mutationKey: ['registerUser'], + mutationKey: registerKeys.registerUser, mutationFn: async (fileUrls:string[]) => ( registerUser(await parseRegisterData( userInfo, @@ -76,7 +77,7 @@ export const useGetFileUrls = (goNext:()=>void) => { formData.append('files', file); }); const fileMutation = useMutation({ - mutationKey: ['getFileUrls'], + mutationKey: registerKeys.fileUrlList, mutationFn: async () => { try { const data = await getFileUrls(formData, uploadToken!); diff --git a/src/query/shop.ts b/src/query/shop.ts index 816a5019..396bdae7 100644 --- a/src/query/shop.ts +++ b/src/query/shop.ts @@ -7,26 +7,27 @@ import { import useUserStore from 'store/user'; import useAddMenuStore from 'store/addMenu'; import { NewMenu } from 'model/shopInfo/newMenu'; +import { shopKeys } from './KeyFactory/shopKeys'; const useMyShop = () => { const myShopQueryKey = useUserStore.getState().user?.company_number; const queryClient = useQueryClient(); const { resetAddMenuStore } = useAddMenuStore(); const { data: myShop } = useSuspenseQuery({ - queryKey: ['myShop', myShopQueryKey], + queryKey: shopKeys.myShopList(myShopQueryKey), queryFn: () => getMyShopList(), }); const shopId = myShop.shops[0]?.id; const { data: shopData, refetch: refetchShopData, isLoading } = useQuery({ - queryKey: ['myShopInfo', shopId], + queryKey: shopKeys.myShopInfo(shopId), queryFn: () => getShopInfo({ id: shopId }), enabled: !!shopId, }); const { data: menusData } = useQuery({ - queryKey: ['myMenuInfo', shopId], + queryKey: shopKeys.myMenuInfo(shopId), queryFn: () => getMenuInfoList({ id: shopId }), enabled: !!shopId, }); @@ -40,7 +41,7 @@ const useMyShop = () => { }, onSuccess: () => { resetAddMenuStore(); - queryClient.invalidateQueries({ queryKey: ['myMenuInfo', shopId] }); + queryClient.invalidateQueries({ queryKey: shopKeys.myMenuInfo(shopId) }); }, }); diff --git a/src/query/shopCategory.ts b/src/query/shopCategory.ts index be05037d..b18c6be8 100644 --- a/src/query/shopCategory.ts +++ b/src/query/shopCategory.ts @@ -1,9 +1,10 @@ import { useQuery } from '@tanstack/react-query'; import getShopCategory from 'api/category'; +import { shopCategoryKeys } from './KeyFactory/shopCategoryKeys'; const useShopCategory = () => { const { data: categoryList } = useQuery({ - queryKey: ['shopCategory'], + queryKey: shopCategoryKeys.shopCategory, queryFn: () => getShopCategory(), }); return { categoryList }; diff --git a/src/query/shops.ts b/src/query/shops.ts index ea48522e..538a13eb 100644 --- a/src/query/shops.ts +++ b/src/query/shops.ts @@ -1,9 +1,10 @@ import { useQuery } from '@tanstack/react-query'; import { getShopList } from 'api/shop'; +import { shopKeys } from './KeyFactory/shopKeys'; const useShopList = () => { const { data: shopList, isError } = useQuery({ - queryKey: ['allshops'], + queryKey: shopKeys.all, queryFn: () => getShopList(), }); return { shopList, isError }; From 1b932ce7271db4ea5b292417e02b9e08940c4a81 Mon Sep 17 00:00:00 2001 From: "(hoooooony)" <(cjh41820@gmail.com)> Date: Tue, 26 Mar 2024 16:12:59 +0900 Subject: [PATCH 02/38] =?UTF-8?q?feat:=20=EA=B0=80=EA=B2=A9=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=94=94=ED=8F=B4=ED=8A=B8=EA=B0=92=20=EB=8B=A8?= =?UTF-8?q?=EC=9D=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/addMenu.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/addMenu.ts b/src/store/addMenu.ts index 2560916c..eefc8e79 100644 --- a/src/store/addMenu.ts +++ b/src/store/addMenu.ts @@ -36,7 +36,7 @@ const useAddMenuStore = create((set) => ({ categoryIds: [], description: '', imageUrl: [], - isSingle: false, + isSingle: true, name: '', optionPrices: [{ id: 0, option: '', price: 0 }], singlePrice: 0, @@ -57,7 +57,7 @@ const useAddMenuStore = create((set) => ({ categoryIds: [], description: '', imageUrl: [], - isSingle: false, + isSingle: true, name: '', optionPrices: [{ id: 0, option: '', price: 0 }], singlePrice: 0, From 025b8ada1d5070673d7d2f91bf74c377b895dd0d Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 19:16:54 +0900 Subject: [PATCH 03/38] =?UTF-8?q?feat:=20error=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 31 +++++++++++++++++++++++++------ src/model/error/index.ts | 12 ++++++++++++ src/utils/ts/isKoinError.ts | 10 ++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/model/error/index.ts create mode 100644 src/utils/ts/isKoinError.ts diff --git a/src/api/index.ts b/src/api/index.ts index e11e0cc6..b0628427 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,8 +1,9 @@ /* eslint-disable no-param-reassign */ /* eslint-disable no-underscore-dangle */ -import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; +import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import API_PATH from 'config/constants'; import { RefreshParams, RefreshResponse } from 'model/auth'; +import { KoinError } from 'model/error'; const client = axios.create({ baseURL: `${API_PATH}`, @@ -51,20 +52,38 @@ accessClient.interceptors.request.use( }, ); +function isAxiosErrorWithResponseData(error: AxiosError) { + const { response } = error; + return response?.status !== undefined + && response.data.code !== undefined + && response.data.message !== undefined; +} + accessClient.interceptors.response.use( (response) => response, async (error) => { - if (error.message) return Promise.reject(error.message); - const originalRequest = error.config; - // accessToken만료시 새로운 accessToken으로 재요청 + // accessToken 만료시 새로운 accessToken으로 재요청 if (error.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true; - return refresh(originalRequest); } - return Promise.reject(error); + + // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. + if (isAxiosErrorWithResponseData(error)) { + const koinError = error.response!; + return { + type: 'koin-error', + status: koinError.status, + code: koinError.data.code, + message: koinError.data.message, + }; + } + return { + type: 'axios-error', + ...error, + }; }, ); diff --git a/src/model/error/index.ts b/src/model/error/index.ts new file mode 100644 index 00000000..60926a28 --- /dev/null +++ b/src/model/error/index.ts @@ -0,0 +1,12 @@ +import { AxiosError } from 'axios'; + +export interface KoinError { + type: 'koin-error'; + status: number; + code: number; + message: string; +} + +export interface CustomAxiosError extends AxiosError { + type: 'axios-error'; +} diff --git a/src/utils/ts/isKoinError.ts b/src/utils/ts/isKoinError.ts new file mode 100644 index 00000000..04642db7 --- /dev/null +++ b/src/utils/ts/isKoinError.ts @@ -0,0 +1,10 @@ +import { KoinError } from 'model/error'; + +export function isKoinError(error: unknown): error is KoinError { + try { + // 코인 서버 에러인지 아닌지를 확인 + return (error as KoinError).type === 'koin-error'; + } catch { + return false; + } +} From 76cc1d305ecca4a53a2ac4967130df6e60dd9e02 Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 19:28:35 +0900 Subject: [PATCH 04/38] =?UTF-8?q?fix:=20client=20=EB=B3=84=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/api/index.ts b/src/api/index.ts index b0628427..a80feb85 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -59,6 +59,26 @@ function isAxiosErrorWithResponseData(error: AxiosError) { && response.data.message !== undefined; } +client.interceptors.response.use( + (response) => response, + async (error) => { + // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. + if (isAxiosErrorWithResponseData(error)) { + const koinError = error.response!; + return { + type: 'koin-error', + status: koinError.status, + code: koinError.data.code, + message: koinError.data.message, + }; + } + return { + type: 'axios-error', + ...error, + }; + }, +); + accessClient.interceptors.response.use( (response) => response, async (error) => { @@ -93,4 +113,25 @@ multipartClient.interceptors.request.use( return config; }, ); + +multipartClient.interceptors.response.use( + (response) => response, + async (error) => { + // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. + if (isAxiosErrorWithResponseData(error)) { + const koinError = error.response!; + return { + type: 'koin-error', + status: koinError.status, + code: koinError.data.code, + message: koinError.data.message, + }; + } + return { + type: 'axios-error', + ...error, + }; + }, +); + export { client, accessClient, multipartClient }; From 1affba1c4fe9bde045677dff85d40256c58501ee Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 20:16:42 +0900 Subject: [PATCH 05/38] =?UTF-8?q?fix:=20step=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/common/Header/index.tsx | 3 --- src/query/auth.ts | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/component/common/Header/index.tsx b/src/component/common/Header/index.tsx index ba553a3a..88441938 100644 --- a/src/component/common/Header/index.tsx +++ b/src/component/common/Header/index.tsx @@ -9,7 +9,6 @@ import useMediaQuery from 'utils/hooks/useMediaQuery'; import { createPortal } from 'react-dom'; import { postLogout } from 'api/auth'; import useUserStore from 'store/user'; -import useStepStore from 'store/useStepStore'; import styles from './Header.module.scss'; import useMobileSidebar from './hooks/useMobileSidebar'; import useMegaMenu from './hooks/useMegaMenu'; @@ -37,7 +36,6 @@ function Header() { } = useMobileSidebar(pathname, isMobile); const isMain = true; const { user, removeUser } = useUserStore(); - const setStep = useStepStore((state) => state.setStep); const logout = () => { postLogout() @@ -45,7 +43,6 @@ function Header() { sessionStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); removeUser(); - setStep(0); }); }; diff --git a/src/query/auth.ts b/src/query/auth.ts index d7d2179c..3d5cb790 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -9,6 +9,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useErrorMessageStore } from 'store/errorMessageStore'; import usePrevPathStore from 'store/path'; +import useStepStore from 'store/useStepStore'; interface VerifyInput { email: string; @@ -34,6 +35,7 @@ export const useLogin = () => { const navigate = useNavigate(); const { setPrevPath } = usePrevPathStore((state) => state); const { setLoginError } = useErrorMessageStore(); + const setStep = useStepStore((state) => state.setStep); const { mutate, error, isError } = useMutation({ mutationFn: (variables: LoginForm) => postLogin({ @@ -51,6 +53,7 @@ export const useLogin = () => { setPrevPath('/'); navigate('/'); } else { + setStep(0); navigate('/store-registration'); } }, From 4539b0cd3a2f6f257453015856f04904e79f3aba Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 20:29:13 +0900 Subject: [PATCH 06/38] =?UTF-8?q?fix:=20deliveryPrice=20state=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/Mobile/Sub/index.tsx | 16 ++++-------- src/page/ShopRegistration/view/PC/index.tsx | 26 +++---------------- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/src/page/ShopRegistration/view/Mobile/Sub/index.tsx b/src/page/ShopRegistration/view/Mobile/Sub/index.tsx index d7c4edc4..59fae75a 100644 --- a/src/page/ShopRegistration/view/Mobile/Sub/index.tsx +++ b/src/page/ShopRegistration/view/Mobile/Sub/index.tsx @@ -7,7 +7,7 @@ import useOperateTimeState from 'page/ShopRegistration/hooks/useOperateTimeState import CheckSameTime from 'page/ShopRegistration/hooks/CheckSameTime'; import { WEEK } from 'utils/constant/week'; import useModalStore from 'store/modalStore'; -import { useRef, useState } from 'react'; +import { useState } from 'react'; import ErrorMessage from 'page/Auth/Signup/component/ErrorMessage'; import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage'; import cn from 'utils/ts/className'; @@ -26,6 +26,7 @@ export default function Sub() { const { phone, + deliveryPrice, description, delivery, payBank, @@ -41,7 +42,6 @@ export default function Sub() { } = CheckSameTime(); const { shopClosedState } = useModalStore(); const [isError, setIsError] = useState(false); - const deliveryPriceRef = useRef(null); const formatPhoneNumber = (inputNumber: string) => { const phoneNumber = inputNumber.replace(/\D/g, ''); @@ -52,7 +52,7 @@ export default function Sub() { const phoneNumberPattern = /^\d{3}-\d{4}-\d{4}$/; const isValidPhoneNumber = phoneNumberPattern.test(phone); const handleNextClick = () => { - if (phone === '' || deliveryPriceRef.current?.value === '' || !isValidPhoneNumber) { + if (phone === '' || Number.isNaN(deliveryPrice) || !isValidPhoneNumber) { setIsError(true); } else { setIsError(false); @@ -90,23 +90,17 @@ export default function Sub() { -
- {deliveryPriceRef.current?.value === '' && isError && } -
운영시간 diff --git a/src/page/ShopRegistration/view/PC/index.tsx b/src/page/ShopRegistration/view/PC/index.tsx index 7d9da79b..b48dcc03 100644 --- a/src/page/ShopRegistration/view/PC/index.tsx +++ b/src/page/ShopRegistration/view/PC/index.tsx @@ -2,7 +2,7 @@ import { ReactComponent as Memo } from 'assets/svg/shopRegistration/memo.svg'; import { ReactComponent as Logo } from 'assets/svg/auth/koin-logo.svg'; import { ReactComponent as Cutlery } from 'assets/svg/shopRegistration/cutlery.svg'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useState } from 'react'; import useStepStore from 'store/useStepStore'; import Copyright from 'component/common/Copyright'; import CustomButton from 'page/Auth/Signup/component/CustomButton'; @@ -57,7 +57,6 @@ export default function ShopRegistrationPC() { imageFile, imgRef, saveImgFile, uploadError, } = useImageUpload(); const [isError, setIsError] = useState(false); - const deliveryPriceRef = useRef(null); const { openTimeState, @@ -67,7 +66,6 @@ export default function ShopRegistrationPC() { const { setImageUrl, - setOwner, setName, setDelivery, setPayCard, @@ -82,7 +80,6 @@ export default function ShopRegistrationPC() { imageUrl, categoryId, category, - owner, name, delivery, payCard, @@ -121,7 +118,7 @@ export default function ShopRegistrationPC() { const phoneNumberPattern = /^\d{3}-\d{4}-\d{4}$/; const isValidPhoneNumber = phoneNumberPattern.test(phone); const handleNextClick = () => { - if (imageUrl === '' || name === '' || category === '' || Number.isNaN(deliveryPrice) + if (imageUrl === '' || name === '' || category === '' || address === '' || phone === '' || !isValidPhoneNumber) { setIsError(true); } else { @@ -234,20 +231,6 @@ export default function ShopRegistrationPC() { > -
- 대표자명 -
- { - setOwner(e.target.value); - }} - /> -
- {owner === '' && isError && } -
가게명
@@ -311,15 +294,12 @@ export default function ShopRegistrationPC() { { setDeliveryPrice(Number(e.target.value)); }} />
- {(Number.isNaN(deliveryPrice) && deliveryPriceRef.current?.value === '') - && isError && }
운영시간 From 7ad15babf0041d19888f184a9cbe711c21c4acf1 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 20:29:31 +0900 Subject: [PATCH 07/38] =?UTF-8?q?fix:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=97=90=EB=9F=AC=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/ShopRegistration/constant/errorMessage.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/page/ShopRegistration/constant/errorMessage.ts b/src/page/ShopRegistration/constant/errorMessage.ts index 8a7218ce..4f261776 100644 --- a/src/page/ShopRegistration/constant/errorMessage.ts +++ b/src/page/ShopRegistration/constant/errorMessage.ts @@ -1,11 +1,9 @@ export const ERRORMESSAGE: { [key: string]: string } = { image: '이미지를 등록해주세요.', category: '카테고리를 선택해주세요.', - owner: '대표자명을 입력해주세요', name: '가게명을 입력해주세요', address: '주소를 입력해주세요.', phone: '전화번호를 입력해주세요.', - deliveryPrice: '배달금액을 입력해주세요.', invalidPhone: '전화번호 형식이 올바르지 않습니다.', networkError: '네트워크 오류가 발생했습니다. 다시 시도해주세요.', 401: '이미지 등록에 실패했습니다. 다시 시도해주세요.', From a2205d1ee00bd4ca8941f9b0cad7f1566ddda9d7 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 20:39:17 +0900 Subject: [PATCH 08/38] =?UTF-8?q?fix:=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EB=AC=B8=EA=B5=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/AddMenu/components/MenuName/MenuName.module.scss | 2 +- src/page/AddMenu/components/MenuName/index.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/page/AddMenu/components/MenuName/MenuName.module.scss b/src/page/AddMenu/components/MenuName/MenuName.module.scss index 5fb1b4f7..3b76b940 100644 --- a/src/page/AddMenu/components/MenuName/MenuName.module.scss +++ b/src/page/AddMenu/components/MenuName/MenuName.module.scss @@ -2,6 +2,7 @@ &__container { margin-top: 5px; width: 100%; + margin-bottom: 24px; } &__caption { @@ -18,7 +19,6 @@ border: 0.5px solid #898a8d; padding: 8px; box-sizing: border-box; - margin-bottom: 24px; &::placeholder { color: #a1a1a1; diff --git a/src/page/AddMenu/components/MenuName/index.tsx b/src/page/AddMenu/components/MenuName/index.tsx index 43dc7633..a26499a7 100644 --- a/src/page/AddMenu/components/MenuName/index.tsx +++ b/src/page/AddMenu/components/MenuName/index.tsx @@ -33,6 +33,7 @@ export default function MenuName({ isComplete }: MenuNameProps) { value={name} /> )} + {menuError && {menuError}}
) : (
From d587f857d7b4eac1a37e9b81272c97edd60a4b5c Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 21:11:21 +0900 Subject: [PATCH 09/38] =?UTF-8?q?fix:=20createKoinErrorFromAxiosError=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 68 +++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index a80feb85..e324747c 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -3,7 +3,7 @@ import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import API_PATH from 'config/constants'; import { RefreshParams, RefreshResponse } from 'model/auth'; -import { KoinError } from 'model/error'; +import { CustomAxiosError, KoinError } from 'model/error'; const client = axios.create({ baseURL: `${API_PATH}`, @@ -59,24 +59,26 @@ function isAxiosErrorWithResponseData(error: AxiosError) { && response.data.message !== undefined; } -client.interceptors.response.use( - (response) => response, - async (error) => { - // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. - if (isAxiosErrorWithResponseData(error)) { - const koinError = error.response!; - return { - type: 'koin-error', - status: koinError.status, - code: koinError.data.code, - message: koinError.data.message, - }; - } +function createKoinErrorFromAxiosError(error: AxiosError): KoinError | CustomAxiosError { + if (isAxiosErrorWithResponseData(error)) { + const koinError = error.response!; return { - type: 'axios-error', - ...error, + type: 'koin-error', + status: koinError.status, + code: koinError.data.code, + message: koinError.data.message, }; - }, + } + return { + type: 'axios-error', + ...error, + }; +} + +client.interceptors.response.use( + (response) => response, + async (error) => createKoinErrorFromAxiosError(error) + , ); accessClient.interceptors.response.use( @@ -90,20 +92,7 @@ accessClient.interceptors.response.use( return refresh(originalRequest); } - // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. - if (isAxiosErrorWithResponseData(error)) { - const koinError = error.response!; - return { - type: 'koin-error', - status: koinError.status, - code: koinError.data.code, - message: koinError.data.message, - }; - } - return { - type: 'axios-error', - ...error, - }; + return createKoinErrorFromAxiosError(error); }, ); @@ -116,22 +105,7 @@ multipartClient.interceptors.request.use( multipartClient.interceptors.response.use( (response) => response, - async (error) => { - // error 를 경우에 따라 KoinError와 AxiosError 로 반환합니다. - if (isAxiosErrorWithResponseData(error)) { - const koinError = error.response!; - return { - type: 'koin-error', - status: koinError.status, - code: koinError.data.code, - message: koinError.data.message, - }; - } - return { - type: 'axios-error', - ...error, - }; - }, + async (error) => createKoinErrorFromAxiosError(error), ); export { client, accessClient, multipartClient }; From f25d4cb946a7ebc85402dcecbba788cfc8feb267 Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 21:23:39 +0900 Subject: [PATCH 10/38] =?UTF-8?q?chore:=20=EC=A4=84=EA=B0=84=EA=B2=A9=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index e324747c..f839eb7e 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -77,8 +77,7 @@ function createKoinErrorFromAxiosError(error: AxiosError): KoinError client.interceptors.response.use( (response) => response, - async (error) => createKoinErrorFromAxiosError(error) - , + async (error) => createKoinErrorFromAxiosError(error), ); accessClient.interceptors.response.use( From 32d964b5ce198fc2d70399bd07a7990e1adb4bae Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 22:35:27 +0900 Subject: [PATCH 11/38] =?UTF-8?q?fix:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/query/register.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/query/register.ts b/src/query/register.ts index 2f162618..8a977580 100644 --- a/src/query/register.ts +++ b/src/query/register.ts @@ -2,6 +2,7 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import { getEmailAuthCode, getEmailDuplicate, getFileUrls, registerUser, verificationAuthCode, } from 'api/register'; +import axios from 'axios'; import parseRegisterData from 'page/Auth/Signup/utils/parseRegisterData'; import useRegisterInfo from 'store/registerStore'; import useShopRegistrationStore from 'store/shopRegistration'; @@ -83,7 +84,9 @@ export const useGetFileUrls = (goNext:()=>void) => { try { await register.mutateAsync(data.file_urls); } catch (e) { - showToast('error', `회원가입 중 에러가 발생했어요${e}`); + if (axios.isAxiosError(e)) { + showToast('error', `${e.response?.data.message || e.message}`); + } } } catch (e) { showToast('error', `파일업로드 중 에러가 발생했어요${e}`); From 452467f688254e7af0035c4252000b273218ac3d Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Tue, 26 Mar 2024 22:35:50 +0900 Subject: [PATCH 12/38] =?UTF-8?q?fix:=20=EC=97=90=EB=9F=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=83=81=ED=83=9C=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/query/auth.ts | 7 +++++-- src/store/errorMessageStore.ts | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/query/auth.ts b/src/query/auth.ts index d7d2179c..1b5bb653 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -15,7 +15,7 @@ interface VerifyInput { verify: string; } -interface ErrorResponse { +export interface ErrorResponse { response: undefined | { message: string; data: { @@ -33,7 +33,7 @@ interface ErrorResponse { export const useLogin = () => { const navigate = useNavigate(); const { setPrevPath } = usePrevPathStore((state) => state); - const { setLoginError } = useErrorMessageStore(); + const { setLoginError, setLoginErrorCode } = useErrorMessageStore(); const { mutate, error, isError } = useMutation({ mutationFn: (variables: LoginForm) => postLogin({ @@ -58,6 +58,9 @@ export const useLogin = () => { sessionStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); setLoginError(err.response?.data.message || err.message); + if (err.response?.data && 'code' in err.response.data) { + setLoginErrorCode(err.response?.data?.code as number); + } }, }); diff --git a/src/store/errorMessageStore.ts b/src/store/errorMessageStore.ts index 8497ab41..648d0040 100644 --- a/src/store/errorMessageStore.ts +++ b/src/store/errorMessageStore.ts @@ -7,6 +7,8 @@ interface ErrorMessageStore { setCategoryError: (error: string) => void; loginError: string; setLoginError: (error: string) => void; + loginErrorCode: number; + setLoginErrorCode: (error: number) => void; } export const useErrorMessageStore = create((set) => ({ @@ -16,4 +18,6 @@ export const useErrorMessageStore = create((set) => ({ setCategoryError: (error) => set({ categoryError: error }), loginError: '', setLoginError: (error) => set({ loginError: error }), + loginErrorCode: 0, + setLoginErrorCode: (error) => set({ loginErrorCode: error }), })); From c134bd14696e0c0bf24425b1d1de46a0682b4157 Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 22:43:13 +0900 Subject: [PATCH 13/38] =?UTF-8?q?fix:=20error=20throw=20issue=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 7 ++++--- src/query/auth.ts | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index f839eb7e..77d3aa8e 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-throw-literal */ /* eslint-disable no-param-reassign */ /* eslint-disable no-underscore-dangle */ import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; @@ -77,7 +78,7 @@ function createKoinErrorFromAxiosError(error: AxiosError): KoinError client.interceptors.response.use( (response) => response, - async (error) => createKoinErrorFromAxiosError(error), + async (error) => { throw createKoinErrorFromAxiosError(error); }, ); accessClient.interceptors.response.use( @@ -91,7 +92,7 @@ accessClient.interceptors.response.use( return refresh(originalRequest); } - return createKoinErrorFromAxiosError(error); + throw createKoinErrorFromAxiosError(error); }, ); @@ -104,7 +105,7 @@ multipartClient.interceptors.request.use( multipartClient.interceptors.response.use( (response) => response, - async (error) => createKoinErrorFromAxiosError(error), + async (error) => { throw createKoinErrorFromAxiosError(error); }, ); export { client, accessClient, multipartClient }; diff --git a/src/query/auth.ts b/src/query/auth.ts index d7d2179c..be1fc20a 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -54,10 +54,11 @@ export const useLogin = () => { navigate('/store-registration'); } }, - onError: (err: AxiosError) => { + onError: (err) => { + console.log('loginerror', err); sessionStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); - setLoginError(err.response?.data.message || err.message); + setLoginError(err.message || '로그인에 실패했습니다.'); }, }); From a3b68497af747dc4dfc0bbff69d2aac81fdba73d Mon Sep 17 00:00:00 2001 From: hana Date: Tue, 26 Mar 2024 22:44:53 +0900 Subject: [PATCH 14/38] =?UTF-8?q?fix:=20console=20=EB=A1=9C=EA=B9=85=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/PICK_REVIEWER.yml | 6 ------ src/query/auth.ts | 1 - 2 files changed, 7 deletions(-) diff --git a/.github/workflows/PICK_REVIEWER.yml b/.github/workflows/PICK_REVIEWER.yml index d3937713..37e867e5 100644 --- a/.github/workflows/PICK_REVIEWER.yml +++ b/.github/workflows/PICK_REVIEWER.yml @@ -51,12 +51,6 @@ jobs: core.setOutput('reviewer2GithubName', reviewer2.githubName); } - - name: test valiable - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: console.log(${{ steps.pick_random_reviewer.outputs.reviewer1Name }}) - - name: Add Reviewers uses: madrapps/add-reviewers@v1 with: diff --git a/src/query/auth.ts b/src/query/auth.ts index be1fc20a..1c508548 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -55,7 +55,6 @@ export const useLogin = () => { } }, onError: (err) => { - console.log('loginerror', err); sessionStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); setLoginError(err.message || '로그인에 실패했습니다.'); From 1dd5cb01db3fd5a2d9bb61959cf551472a79121b Mon Sep 17 00:00:00 2001 From: hana Date: Wed, 27 Mar 2024 15:38:53 +0900 Subject: [PATCH 15/38] =?UTF-8?q?fix:=20auth=20login=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=BD=94=EC=9D=B8=20=EC=97=90=EB=9F=AC=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/query/auth.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/query/auth.ts b/src/query/auth.ts index 1c508548..c2b84a83 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -9,6 +9,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useErrorMessageStore } from 'store/errorMessageStore'; import usePrevPathStore from 'store/path'; +import { isKoinError } from 'utils/ts/isKoinError'; interface VerifyInput { email: string; @@ -54,10 +55,13 @@ export const useLogin = () => { navigate('/store-registration'); } }, - onError: (err) => { - sessionStorage.removeItem('access_token'); - localStorage.removeItem('refresh_token'); - setLoginError(err.message || '로그인에 실패했습니다.'); + onError: (err: unknown) => { + if (isKoinError(err)) { + // TODO: 분기별 에러 처리 + sessionStorage.removeItem('access_token'); + localStorage.removeItem('refresh_token'); + setLoginError(err.message || '로그인에 실패했습니다.'); + } }, }); From 0da544d1b7866cd48653eadddb26989922c330f3 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Thu, 28 Mar 2024 11:40:49 +0900 Subject: [PATCH 16/38] =?UTF-8?q?fix:=20=EB=B0=B0=EB=8B=AC=EB=B9=84?= =?UTF-8?q?=EC=97=90=20=EC=82=BC=ED=95=AD=EC=97=B0=EC=82=B0=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShopRegistration/view/Mobile/ShopConfirmation/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page/ShopRegistration/view/Mobile/ShopConfirmation/index.tsx b/src/page/ShopRegistration/view/Mobile/ShopConfirmation/index.tsx index f37e8dee..7a0fc54c 100644 --- a/src/page/ShopRegistration/view/Mobile/ShopConfirmation/index.tsx +++ b/src/page/ShopRegistration/view/Mobile/ShopConfirmation/index.tsx @@ -91,7 +91,7 @@ export default function ShopConfirmation() {
배달금액 - {deliveryPrice} + {deliveryPrice === 0 ? '무료' : `${deliveryPrice}원`}
운영시간 From ff2dcc83b279a0d4da5a70df65560c59c83ef568 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Thu, 28 Mar 2024 20:19:17 +0900 Subject: [PATCH 17/38] =?UTF-8?q?feat:=20=EC=8A=B9=EC=9D=B8=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApprovalModal/ApprovalModal.module.scss | 72 +++++++++++++++++++ src/page/Auth/Login/ApprovalModal/index.tsx | 37 ++++++++++ src/page/Auth/Login/index.tsx | 6 +- 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/page/Auth/Login/ApprovalModal/ApprovalModal.module.scss create mode 100644 src/page/Auth/Login/ApprovalModal/index.tsx diff --git a/src/page/Auth/Login/ApprovalModal/ApprovalModal.module.scss b/src/page/Auth/Login/ApprovalModal/ApprovalModal.module.scss new file mode 100644 index 00000000..4655fca4 --- /dev/null +++ b/src/page/Auth/Login/ApprovalModal/ApprovalModal.module.scss @@ -0,0 +1,72 @@ +.background { + background-color: rgb(0 0 0 / 70%); + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; +} + +.container { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: #000000; + opacity: 1; + background-color: #ffffff; + width: 300px; + height: 200px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 8px; + + &__title { + font-size: 18px; + font-weight: 500; + + span { + color: #175c8e; + } + } + + &__description { + display: flex; + flex-direction: column; + align-items: center; + font-size: 14px; + color: #8e8e8e; + } + + &__phone { + font-size: 16px; + color: #175c8e; + font-weight: 500; + } +} + +.button { + display: flex; + gap: 8px; + margin-top: 8px; + + &__confirm { + width: 115px; + height: 40px; + border-radius: 4px; + border: 1px solid #8e8e8e; + box-sizing: border-box; + cursor: pointer; + } + + &__clipboard { + width: 115px; + height: 40px; + border-radius: 4px; + background-color: #175c8e; + color: #ffffff; + cursor: pointer; + } +} diff --git a/src/page/Auth/Login/ApprovalModal/index.tsx b/src/page/Auth/Login/ApprovalModal/index.tsx new file mode 100644 index 00000000..02e68a65 --- /dev/null +++ b/src/page/Auth/Login/ApprovalModal/index.tsx @@ -0,0 +1,37 @@ +import { createPortal } from 'react-dom'; +import showToast from 'utils/ts/showToast'; +import styles from './ApprovalModal.module.scss'; + +const PHONE_NUMBER = '010-7724-5536'; + +export default function ApprovalModal({ toggle }:{ toggle: () => void }) { + const copyPhone = () => { + navigator.clipboard.writeText(PHONE_NUMBER).then(() => { + showToast('success', '전화번호를 클립보드에 복사하였습니다.'); + }).catch(() => { + showToast('error', '전화번호를 복사하는데 실패했습니다.'); + }); + }; + + return createPortal( +
+
+
+ 관리자의 승인 + 이 진행 중입니다. +
+
+ 해당 화면이 지속해서 보일 시 + 아래 연락처로 문의하시기 바랍니다. +
+
{PHONE_NUMBER}
+
+ + +
+
+ +
, + document.body, + ); +} diff --git a/src/page/Auth/Login/index.tsx b/src/page/Auth/Login/index.tsx index 29db67ae..668242a5 100644 --- a/src/page/Auth/Login/index.tsx +++ b/src/page/Auth/Login/index.tsx @@ -15,6 +15,7 @@ import sha256 from 'utils/ts/SHA-256'; import { useErrorMessageStore } from 'store/errorMessageStore'; import styles from './Login.module.scss'; import OPTION from './static/option'; +import ApprovalModal from './ApprovalModal'; export default function Login() { const { value: isBlind, changeValue: changeIsBlind } = useBooleanState(); @@ -23,8 +24,9 @@ export default function Login() { const { login, isError: isServerError } = useLogin(); const [isFormError, setIsFormError] = useState(false); const navigate = useNavigate(); - const { loginError } = useErrorMessageStore(); + const { loginError, loginErrorCode } = useErrorMessageStore(); const [emailError, setEmailError] = useState(''); + const { value: isModalOpen, changeValue: toggle } = useBooleanState(false); const isError = isServerError || isFormError; @@ -107,6 +109,7 @@ export default function Login() { [styles['form__button--login']]: true, })} type="submit" + onClick={toggle} > 로그인 @@ -132,6 +135,7 @@ export default function Login() {
+ {loginErrorCode === 100005 && isModalOpen && } ); } From ad75aa69c8c17739bd45f84b21789a97652fe63c Mon Sep 17 00:00:00 2001 From: "(hoooooony)" <(cjh41820@gmail.com)> Date: Thu, 28 Mar 2024 20:48:31 +0900 Subject: [PATCH 18/38] =?UTF-8?q?refactor:=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EA=B0=80=EA=B2=A9=20=EB=8B=A8=EC=9D=BC=EB=A1=9C=EB=A7=8C=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MenuPrice/MenuPrice.module.scss | 5 +- .../AddMenu/components/MenuPrice/index.tsx | 246 +++--------------- src/page/ModifyMenu/ModifyMenu.module.scss | 2 +- 3 files changed, 38 insertions(+), 215 deletions(-) diff --git a/src/page/AddMenu/components/MenuPrice/MenuPrice.module.scss b/src/page/AddMenu/components/MenuPrice/MenuPrice.module.scss index 7de73a86..faf91011 100644 --- a/src/page/AddMenu/components/MenuPrice/MenuPrice.module.scss +++ b/src/page/AddMenu/components/MenuPrice/MenuPrice.module.scss @@ -220,6 +220,7 @@ display: flex; gap: 16px; align-items: center; + width: 100%; &__size-input { box-sizing: border-box; @@ -252,7 +253,7 @@ &__price-input-box { position: relative; box-sizing: border-box; - width: 335px; + width: 100%; height: 62px; border: 0.5px solid #858585; } @@ -260,7 +261,7 @@ &__price-input { text-align: right; box-sizing: border-box; - width: 303px; + width: 98%; height: 60px; padding: 16px; color: #252525; diff --git a/src/page/AddMenu/components/MenuPrice/index.tsx b/src/page/AddMenu/components/MenuPrice/index.tsx index b83c1588..cdb789c8 100644 --- a/src/page/AddMenu/components/MenuPrice/index.tsx +++ b/src/page/AddMenu/components/MenuPrice/index.tsx @@ -1,13 +1,5 @@ import useMediaQuery from 'utils/hooks/useMediaQuery'; import useAddMenuStore from 'store/addMenu'; -import { ReactComponent as PlusIcon } from 'assets/svg/main/plus.svg'; -import { ReactComponent as DeleteIcon } from 'assets/svg/addmenu/delete-icon.svg'; -import { ReactComponent as MobileDeleteIcon } from 'assets/svg/addmenu/mobile-delete-icon.svg'; -import { ReactComponent as MobileCheckCircleIcon } from 'assets/svg/addmenu/mobile-single-menu-check.svg'; -import { ReactComponent as CheckCircleIcon } from 'assets/svg/addmenu/single-menu-check.svg'; -import { ReactComponent as MobilePlusIcon } from 'assets/svg/addmenu/mobile-plus-icon.svg'; -import { ReactComponent as SelectedCheck } from 'assets/svg/addmenu/selected-check.svg'; -import { ReactComponent as MobileselectedCheck } from 'assets/svg/addmenu/mobile-single-menu-check-selected.svg'; import styles from './MenuPrice.module.scss'; interface MenuPriceProps { @@ -18,37 +10,11 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) { const { isMobile } = useMediaQuery(); const { optionPrices, - setOptionPrices, isSingle, - setIsSingle, singlePrice, setSinglePrice, - resetOptionPrice, } = useAddMenuStore(); - const updatePriceInput = (index: number, field: string, newValue: string | number) => { - const updatedOptionPrices = (optionPrices || []).map( - (price, idx) => (index === idx ? { ...price, [field]: newValue } : price), - ); - setOptionPrices(updatedOptionPrices); - }; - - const addPriceInput = () => { - const newId = (optionPrices || []).length; - if (!isSingle) { - setOptionPrices([...(optionPrices || []), { id: newId, option: '', price: 0 }]); - } else { - setIsSingle(false); - } - }; - - const deletePriceInput = (index: number) => { - setOptionPrices((optionPrices || []).filter((_, idx) => idx !== index)); - }; - const handleIsSingleMenu = () => { - setIsSingle(!isSingle); - resetOptionPrice(); - }; return (
{isMobile ? ( @@ -58,116 +24,34 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) {
가격
- {isSingle ? ( -
-
-
- {singlePrice} - 원 -
+
+
+
+ {singlePrice} + 원
- ) - : (optionPrices || []).map((input) => ( -
-
-
- {input.option} -
-
- / -
-
- {input.price} - 원 -
-
-
- ))} +
) : ( <>
가격
-
-
단일메뉴
- -
- {isSingle - ? ( -
-
- -
- setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))} - /> -

-
-
- -
- ) - : (optionPrices || []).map((input) => ( -
-
- updatePriceInput(input.id, 'option', e.target.value)} - disabled={isSingle} - /> -
- updatePriceInput(input.id, 'price', e.target.value)} - /> -

-
-
- +
+
+ +
+ setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))} + /> +

- ))} - +
+
)}
@@ -209,85 +93,23 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) { <>
가격
-
-
단일메뉴
- -
+
- {isSingle - ? ( -
-
- -
- setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))} - /> -

-
-
- -
- ) - : (optionPrices || []).map((input) => ( -
-
- updatePriceInput(input.id, 'option', e.target.value)} - disabled={isSingle} - /> -
- updatePriceInput(input.id, 'price', e.target.value)} - /> -

-
-
- + +
+
+
+ setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))} + /> +

- ))} - +
+ +
)}
diff --git a/src/page/ModifyMenu/ModifyMenu.module.scss b/src/page/ModifyMenu/ModifyMenu.module.scss index 2ac079a7..3f64e51c 100644 --- a/src/page/ModifyMenu/ModifyMenu.module.scss +++ b/src/page/ModifyMenu/ModifyMenu.module.scss @@ -53,7 +53,7 @@ } &__button-check { - width: 226px; + width: 180px; height: 43px; flex-shrink: 0; background: #175c8e; From 34402e2540fd26436b0f87ac5c99945c357e54e7 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Thu, 28 Mar 2024 22:21:13 +0900 Subject: [PATCH 19/38] =?UTF-8?q?refactor:=20=EA=B5=AC=EA=B8=80=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EB=B2=88=EC=97=AD=20=EB=B0=A9=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/index.html b/public/index.html index 35a5fcbc..70a9baed 100644 --- a/public/index.html +++ b/public/index.html @@ -8,6 +8,7 @@ name="description" content="backoffice for koin's store owner" /> + From b25474ba779ff1f12c1f7b15bc7c0c3238f9e0f8 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 29 Mar 2024 00:35:01 +0900 Subject: [PATCH 20/38] =?UTF-8?q?feat:=20=EB=8B=A4=EC=A4=91=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=9B=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useImagesUpload.ts | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/utils/hooks/useImagesUpload.ts diff --git a/src/utils/hooks/useImagesUpload.ts b/src/utils/hooks/useImagesUpload.ts new file mode 100644 index 00000000..2bce11f4 --- /dev/null +++ b/src/utils/hooks/useImagesUpload.ts @@ -0,0 +1,75 @@ +import { uploadFile } from 'api/uploadFile/Uploadfile'; +import { useRef, useState } from 'react'; +import showToast from 'utils/ts/showToast'; + +// 정의할 수 있는 에러 타입 +type UploadError = '413' | '415' | '404' | '422' | 'networkError' | '401' | ''; + +/* eslint-disable */ +export default function useImagesUpload() { + const [imageFile, setImageFile] = useState([]); + const [uploadError, setUploadError] = useState(''); + const imgRef = useRef(null); + + const saveImgFile = async () => { + const files = imgRef.current?.files; + + if (files && files.length > 3) { + showToast('error', '파일은 3개까지 등록할 수 있습니다.') + return; + } + if (files && files.length) { + const uploadedFiles: string[] = []; + const maxSize = 1024 * 1024 * 10; // 10 MB limit for each file + const correctForm = new RegExp('(.*?)\\.(jpg|jpeg|gif|bmp|png)$'); + + for (let i = 0; i < files.length; i++) { + const file = files[i]; + + if (file.size > maxSize) { + setUploadError('413'); // File size too large + setImageFile([]); + return; + } + + if (!correctForm.test(file.name)) { + setUploadError('415'); // Unsupported file type + setImageFile([]); + return; + } + + const formData = new FormData(); + formData.append('multipartFile', file); + + try { + const data = await uploadFile(formData); + if (data?.data?.file_url) { + uploadedFiles.push(data.data.file_url); + } + } catch (error: any) { + setImageFile([]); + const errorMessage = error.toString(); + if (errorMessage.includes('415')) { + setUploadError('415'); + } else if (errorMessage.includes('404')) { + setUploadError('404'); + } else if (errorMessage.includes('422')) { + setUploadError('422'); + } else if (errorMessage.includes('Network Error')) { + setUploadError('networkError'); + } else { + setUploadError('401'); + } + return; + } + } + + setImageFile(uploadedFiles); + setUploadError(''); + } + }; + + return { + imageFile, imgRef, saveImgFile, uploadError, + }; +} From 175e15f4b29a1d98a356cf4cb07a695026005142 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 29 Mar 2024 00:35:24 +0900 Subject: [PATCH 21/38] =?UTF-8?q?refactor:=20pc=20=EB=B0=8F=20=EB=AA=A8?= =?UTF-8?q?=EB=B0=94=EC=9D=BC=20=EB=B2=84=EC=A0=84=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=EC=97=90=20=EB=8B=A4=EC=A4=91=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/AddMenuImgModal/index.tsx | 15 ++++--- .../AddMenu/components/MenuImage/index.tsx | 44 ++++++++++--------- src/store/addMenu.ts | 4 ++ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/page/AddMenu/components/AddMenuImgModal/index.tsx b/src/page/AddMenu/components/AddMenuImgModal/index.tsx index 31b5bb1c..0de66a5d 100644 --- a/src/page/AddMenu/components/AddMenuImgModal/index.tsx +++ b/src/page/AddMenu/components/AddMenuImgModal/index.tsx @@ -2,9 +2,9 @@ import React, { useEffect } from 'react'; import { createPortal } from 'react-dom'; import { ReactComponent as CancelIcon } from 'assets/svg/addmenu/mobile-cancle-icon.svg'; import useAddMenuStore from 'store/addMenu'; -import useImageUpload from 'utils/hooks/useImageUpload'; import ErrorMessage from 'page/Auth/Signup/component/ErrorMessage'; -import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage'; import styles from './AddMenuImgModal.module.scss'; +import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage'; import useImagesUpload from 'utils/hooks/useImagesUpload'; +import styles from './AddMenuImgModal.module.scss'; interface AddMenuImgModalProps { isOpen: boolean; @@ -12,10 +12,11 @@ interface AddMenuImgModalProps { } export default function AddMenuImgModal({ isOpen, closeModal }: AddMenuImgModalProps) { - const { setImageUrl } = useAddMenuStore(); + const { setImageUrls } = useAddMenuStore(); + const { imageFile, imgRef, saveImgFile, uploadError, - } = useImageUpload(); + } = useImagesUpload(); const triggerFileInput = () => { imgRef.current?.click(); @@ -28,10 +29,10 @@ export default function AddMenuImgModal({ isOpen, closeModal }: AddMenuImgModalP }; useEffect(() => { if (imageFile && !uploadError) { - setImageUrl(imageFile); + setImageUrls(imageFile); closeModal(); } - }, [imageFile, uploadError, setImageUrl, closeModal]); + }, [imageFile, uploadError, setImageUrls, closeModal]); if (!isOpen) return null; @@ -44,7 +45,7 @@ export default function AddMenuImgModal({ isOpen, closeModal }: AddMenuImgModalP 이미지 추가 메뉴 사진을 추가할 수 있습니다.
- +
diff --git a/src/page/AddMenu/components/MenuImage/index.tsx b/src/page/AddMenu/components/MenuImage/index.tsx index 91a83cf3..b4129da7 100644 --- a/src/page/AddMenu/components/MenuImage/index.tsx +++ b/src/page/AddMenu/components/MenuImage/index.tsx @@ -5,9 +5,9 @@ import useMediaQuery from 'utils/hooks/useMediaQuery'; import useBooleanState from 'utils/hooks/useBooleanState'; import AddMenuImgModal from 'page/AddMenu/components/AddMenuImgModal'; import useAddMenuStore from 'store/addMenu'; -import useImageUpload from 'utils/hooks/useImageUpload'; import ErrorMessage from 'page/Auth/Signup/component/ErrorMessage'; import { ERRORMESSAGE } from 'page/ShopRegistration/constant/errorMessage'; +import useImagesUpload from 'utils/hooks/useImagesUpload'; import styles from './MenuImage.module.scss'; interface MenuImageProps { @@ -16,15 +16,16 @@ interface MenuImageProps { export default function MenuImage({ isComplete }: MenuImageProps) { const { isMobile } = useMediaQuery(); - const { imageUrl, setImageUrl, removeImageUrl } = useAddMenuStore(); + const { imageUrl, setImageUrls, removeImageUrl } = useAddMenuStore(); const { value: isAddMenuImgModal, setTrue: openAddMenuImgModal, setFalse: closeAddMenuImgModal, } = useBooleanState(false); + const { imageFile, imgRef, saveImgFile, uploadError, - } = useImageUpload(); + } = useImagesUpload(); const handleAddImage = () => { imgRef.current?.click(); }; @@ -36,9 +37,9 @@ export default function MenuImage({ isComplete }: MenuImageProps) { }; useEffect(() => { if (imageFile) { - setImageUrl(imageFile); + setImageUrls(imageFile); } - }, [imageFile, setImageUrl]); + }, [imageFile, setImageUrls]); return (
{isMobile ? ( @@ -52,14 +53,14 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
{`Selected {!isComplete && ( - + )}
))} @@ -88,14 +89,14 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
{`Selected {!isComplete && ( - + )}
))} @@ -114,6 +115,7 @@ export default function MenuImage({ isComplete }: MenuImageProps) { style={{ display: 'none' }} onChange={handleImageChange} ref={imgRef} + multiple />
diff --git a/src/store/addMenu.ts b/src/store/addMenu.ts index eefc8e79..f064a97e 100644 --- a/src/store/addMenu.ts +++ b/src/store/addMenu.ts @@ -19,6 +19,7 @@ interface AddMenuStore { setCategoryIds: (categoryIds: number[]) => void; setDescription: (description: string) => void; setImageUrl: (newImageUrl: string) => void; + setImageUrls: (newImageUrls: string[]) => void, removeImageUrl: (imageUrlToRemove: string) => void; setIsSingle: (isSingle: boolean) => void; setName: (name: string) => void; @@ -45,6 +46,9 @@ const useAddMenuStore = create((set) => ({ setImageUrl: (newImageUrl) => set((state) => ({ imageUrl: [...state.imageUrl, newImageUrl], })), + setImageUrls: (newImageUrl) => set((state) => ({ + imageUrl: [...state.imageUrl, ...newImageUrl], + })), removeImageUrl: (imageUrlToRemove) => set((state) => ({ imageUrl: state.imageUrl.filter((img) => img !== imageUrlToRemove), })), From 10f055dd6c4826e9c42d90c9c1b003fb5d6590ce Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 29 Mar 2024 00:39:14 +0900 Subject: [PATCH 22/38] =?UTF-8?q?refactor:=203=EA=B0=9C=EC=9D=98=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=ED=9B=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=8B=9C=20=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useImagesUpload.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/hooks/useImagesUpload.ts b/src/utils/hooks/useImagesUpload.ts index 2bce11f4..2088060c 100644 --- a/src/utils/hooks/useImagesUpload.ts +++ b/src/utils/hooks/useImagesUpload.ts @@ -14,10 +14,11 @@ export default function useImagesUpload() { const saveImgFile = async () => { const files = imgRef.current?.files; - if (files && files.length > 3) { + if (files && (files.length > 3 || imageFile.length >= 3)) { showToast('error', '파일은 3개까지 등록할 수 있습니다.') return; } + if (files && files.length) { const uploadedFiles: string[] = []; const maxSize = 1024 * 1024 * 10; // 10 MB limit for each file From c36d07475e301952304cb180e8af8b02ce460f45 Mon Sep 17 00:00:00 2001 From: hana Date: Fri, 29 Mar 2024 00:55:34 +0900 Subject: [PATCH 23/38] =?UTF-8?q?fix:=20error=20type=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EC=BB=A8=EB=B2=A4=EC=85=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/index.ts | 4 ++-- src/model/error/index.ts | 4 ++-- src/utils/ts/isKoinError.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/index.ts b/src/api/index.ts index 77d3aa8e..4bc1c746 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -64,14 +64,14 @@ function createKoinErrorFromAxiosError(error: AxiosError): KoinError if (isAxiosErrorWithResponseData(error)) { const koinError = error.response!; return { - type: 'koin-error', + type: 'KOIN_ERROR', status: koinError.status, code: koinError.data.code, message: koinError.data.message, }; } return { - type: 'axios-error', + type: 'AXIOS_ERROR', ...error, }; } diff --git a/src/model/error/index.ts b/src/model/error/index.ts index 60926a28..ecf34591 100644 --- a/src/model/error/index.ts +++ b/src/model/error/index.ts @@ -1,12 +1,12 @@ import { AxiosError } from 'axios'; export interface KoinError { - type: 'koin-error'; + type: 'KOIN_ERROR'; status: number; code: number; message: string; } export interface CustomAxiosError extends AxiosError { - type: 'axios-error'; + type: 'AXIOS_ERROR'; } diff --git a/src/utils/ts/isKoinError.ts b/src/utils/ts/isKoinError.ts index 04642db7..f3efde8a 100644 --- a/src/utils/ts/isKoinError.ts +++ b/src/utils/ts/isKoinError.ts @@ -3,7 +3,7 @@ import { KoinError } from 'model/error'; export function isKoinError(error: unknown): error is KoinError { try { // 코인 서버 에러인지 아닌지를 확인 - return (error as KoinError).type === 'koin-error'; + return (error as KoinError).type === 'KOIN_ERROR'; } catch { return false; } From a5632839dcc9c5a86e77b1dfa4fd4f3eda470aec Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Fri, 29 Mar 2024 14:36:26 +0900 Subject: [PATCH 24/38] =?UTF-8?q?fix:=20useLogin=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/query/auth.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/query/auth.ts b/src/query/auth.ts index a4967bb4..8d2275d7 100644 --- a/src/query/auth.ts +++ b/src/query/auth.ts @@ -64,9 +64,7 @@ export const useLogin = () => { sessionStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); setLoginError(err.message || '로그인에 실패했습니다.'); - if (err.response?.data && 'code' in err.response.data) { - setLoginErrorCode(err.response?.data?.code as number); - } + setLoginErrorCode(err.code); } }, }); From 52f4512abdc9c559fc483d8fe2fc96de86b711b9 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Fri, 29 Mar 2024 15:33:06 +0900 Subject: [PATCH 25/38] =?UTF-8?q?fix:=20singlePrice=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/addMenu.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/addMenu.ts b/src/store/addMenu.ts index eefc8e79..da643247 100644 --- a/src/store/addMenu.ts +++ b/src/store/addMenu.ts @@ -15,7 +15,7 @@ interface AddMenuStore { isSingle: boolean; name: string; optionPrices: OptionPrices[] | null; - singlePrice: number | null; + singlePrice: number; setCategoryIds: (categoryIds: number[]) => void; setDescription: (description: string) => void; setImageUrl: (newImageUrl: string) => void; @@ -79,7 +79,7 @@ const useAddMenuStore = create((set) => ({ isSingle: menuData.is_single, name: menuData.name, optionPrices: newOptionPrices, - singlePrice: 'single_price' in menuData ? menuData.single_price : null, + singlePrice: menuData.single_price !== null ? menuData.single_price : undefined, }); } }, From bcdc817b7824bf620fe28594f3eb5ade28164247 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Fri, 29 Mar 2024 15:33:32 +0900 Subject: [PATCH 26/38] =?UTF-8?q?feat:=20showToast=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/AddMenu/hook/useFormValidation.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/page/AddMenu/hook/useFormValidation.ts b/src/page/AddMenu/hook/useFormValidation.ts index 6afc46b4..f1331a19 100644 --- a/src/page/AddMenu/hook/useFormValidation.ts +++ b/src/page/AddMenu/hook/useFormValidation.ts @@ -1,5 +1,6 @@ import useAddMenuStore from 'store/addMenu'; import { useErrorMessageStore } from 'store/errorMessageStore'; +import showToast from 'utils/ts/showToast'; const useFormValidation = () => { const { setMenuError, setCategoryError } = useErrorMessageStore(); @@ -10,6 +11,7 @@ const useFormValidation = () => { if (name.length === 0) { setMenuError('메뉴명을 입력해주세요.'); + showToast('error', '메뉴명을 입력해주세요.'); isValid = false; } else { setMenuError(''); @@ -17,6 +19,7 @@ const useFormValidation = () => { if (categoryIds.length === 0) { setCategoryError('카테고리를 1개 이상 선택해주세요.'); + showToast('error', '카테고리를 1개 이상 선택해주세요.'); isValid = false; } else { setCategoryError(''); From a9f84b3caddb4b331a8dcb40955c76dbf65f3240 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Fri, 29 Mar 2024 15:34:02 +0900 Subject: [PATCH 27/38] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20css=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AddMenu/components/MenuName/MenuName.module.scss | 8 ++++++++ src/page/AddMenu/components/MenuName/index.tsx | 11 +++++++++-- src/page/AddMenu/components/MenuPrice/index.tsx | 6 ++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/page/AddMenu/components/MenuName/MenuName.module.scss b/src/page/AddMenu/components/MenuName/MenuName.module.scss index 3b76b940..8916328d 100644 --- a/src/page/AddMenu/components/MenuName/MenuName.module.scss +++ b/src/page/AddMenu/components/MenuName/MenuName.module.scss @@ -25,6 +25,10 @@ font-size: 13px; font-weight: 400; } + + &--error { + border: 0.5px #f7941e solid; + } } &__name-text { @@ -67,6 +71,10 @@ font-size: 20px; font-weight: 400; } + + &--error { + border: 0.5px #f7941e solid; + } } .name-text { diff --git a/src/page/AddMenu/components/MenuName/index.tsx b/src/page/AddMenu/components/MenuName/index.tsx index a26499a7..56fa9fd5 100644 --- a/src/page/AddMenu/components/MenuName/index.tsx +++ b/src/page/AddMenu/components/MenuName/index.tsx @@ -1,6 +1,7 @@ import useMediaQuery from 'utils/hooks/useMediaQuery'; import useAddMenuStore from 'store/addMenu'; import { useErrorMessageStore } from 'store/errorMessageStore'; +import cn from 'utils/ts/className'; import styles from './MenuName.module.scss'; interface MenuNameProps { @@ -27,7 +28,10 @@ export default function MenuName({ isComplete }: MenuNameProps) { {name} ) : ( {name} ) : ( setSinglePrice(e.target.value === '' ? 0 : Number(e.target.value))} + value={singlePrice} + onChange={(e) => setSinglePrice(Number(e.target.value))} />

@@ -93,9 +93,7 @@ export default function MenuPrice({ isComplete }:MenuPriceProps) { <>
가격
-
-
From c3e4cd73c6443599a7d49d914145646539c940f6 Mon Sep 17 00:00:00 2001 From: Daeeui Kim Date: Fri, 29 Mar 2024 15:37:47 +0900 Subject: [PATCH 28/38] =?UTF-8?q?fix:=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/AddMenu/components/MenuImage/index.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/page/AddMenu/components/MenuImage/index.tsx b/src/page/AddMenu/components/MenuImage/index.tsx index 91a83cf3..56d72131 100644 --- a/src/page/AddMenu/components/MenuImage/index.tsx +++ b/src/page/AddMenu/components/MenuImage/index.tsx @@ -48,6 +48,14 @@ export default function MenuImage({ isComplete }: MenuImageProps) {
(최대 이미지 3장)
+ {imageUrl.map((image, index) => (
{`Selected @@ -63,14 +71,6 @@ export default function MenuImage({ isComplete }: MenuImageProps) { )}
))} -
Date: Fri, 29 Mar 2024 15:43:17 +0900 Subject: [PATCH 29/38] =?UTF-8?q?fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=96=88=EC=9D=84=EB=95=8C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=20=EC=97=85=EB=A1=9C=EB=93=9C=ED=95=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EC=9D=B4=20=EC=82=AC=EB=9D=BC=EC=A7=80?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useImagesUpload.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/utils/hooks/useImagesUpload.ts b/src/utils/hooks/useImagesUpload.ts index 2088060c..8b48c105 100644 --- a/src/utils/hooks/useImagesUpload.ts +++ b/src/utils/hooks/useImagesUpload.ts @@ -24,18 +24,16 @@ export default function useImagesUpload() { const maxSize = 1024 * 1024 * 10; // 10 MB limit for each file const correctForm = new RegExp('(.*?)\\.(jpg|jpeg|gif|bmp|png)$'); - for (let i = 0; i < files.length; i++) { + for (let i = 0; i < files.length; i += 1) { const file = files[i]; if (file.size > maxSize) { - setUploadError('413'); // File size too large - setImageFile([]); + setUploadError('413'); // 파일 사이즈가 너무 큰 경우 return; } if (!correctForm.test(file.name)) { - setUploadError('415'); // Unsupported file type - setImageFile([]); + setUploadError('415'); // 지원하지 않는 타입 에러 return; } From ebabfe901648c73c6d8dd66377a983ff525fd314 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 29 Mar 2024 15:53:38 +0900 Subject: [PATCH 30/38] =?UTF-8?q?refactor:=20=ED=8C=8C=EC=9D=BC=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useImagesUpload.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/hooks/useImagesUpload.ts b/src/utils/hooks/useImagesUpload.ts index 8b48c105..bb332c3b 100644 --- a/src/utils/hooks/useImagesUpload.ts +++ b/src/utils/hooks/useImagesUpload.ts @@ -5,6 +5,8 @@ import showToast from 'utils/ts/showToast'; // 정의할 수 있는 에러 타입 type UploadError = '413' | '415' | '404' | '422' | 'networkError' | '401' | ''; +const MAXSIZE = 1024 * 1024 * 10; + /* eslint-disable */ export default function useImagesUpload() { const [imageFile, setImageFile] = useState([]); @@ -21,13 +23,12 @@ export default function useImagesUpload() { if (files && files.length) { const uploadedFiles: string[] = []; - const maxSize = 1024 * 1024 * 10; // 10 MB limit for each file const correctForm = new RegExp('(.*?)\\.(jpg|jpeg|gif|bmp|png)$'); for (let i = 0; i < files.length; i += 1) { const file = files[i]; - if (file.size > maxSize) { + if (file.size > MAXSIZE) { setUploadError('413'); // 파일 사이즈가 너무 큰 경우 return; } From 3c975b8b2669d83062ff80792073a4068b3cb212 Mon Sep 17 00:00:00 2001 From: dooohun Date: Fri, 5 Apr 2024 22:19:10 +0900 Subject: [PATCH 31/38] =?UTF-8?q?fix:=20=EA=B0=80=EA=B2=8C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20=EB=AA=A8=EB=8B=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditShopInfoModal.module.scss | 13 ++++++ .../components/EditShopInfoModal/index.tsx | 43 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/page/MyShopPage/components/EditShopInfoModal/EditShopInfoModal.module.scss b/src/page/MyShopPage/components/EditShopInfoModal/EditShopInfoModal.module.scss index 73681394..b45a9ecd 100644 --- a/src/page/MyShopPage/components/EditShopInfoModal/EditShopInfoModal.module.scss +++ b/src/page/MyShopPage/components/EditShopInfoModal/EditShopInfoModal.module.scss @@ -151,6 +151,12 @@ padding: 8px 0 8px 12px; } + &__select { + width: 345px; + height: 40px; + padding-left: 12px; + } + &__operate-time { display: flex; @@ -171,6 +177,7 @@ &__checkboxes { display: grid; grid-template-columns: 1fr 1fr; + gap: 16px; } &__checkbox { @@ -295,6 +302,12 @@ border: 1px solid #898a8d; } + &--select { + width: 262px; + height: 37px; + padding: 0 8px; + } + &__checkboxes { display: flex; justify-content: space-between; diff --git a/src/page/MyShopPage/components/EditShopInfoModal/index.tsx b/src/page/MyShopPage/components/EditShopInfoModal/index.tsx index 041bfa06..4972b157 100644 --- a/src/page/MyShopPage/components/EditShopInfoModal/index.tsx +++ b/src/page/MyShopPage/components/EditShopInfoModal/index.tsx @@ -13,6 +13,7 @@ import { OwnerShop } from 'model/shopInfo/ownerShop'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; import { putShop } from 'api/shop'; +import useShopCategory from 'query/shopCategory'; import useBooleanState from 'utils/hooks/useBooleanState'; import CustomModal from 'component/common/CustomModal'; import OperateTimePC from 'page/ShopRegistration/component/Modal/OperateTimePC'; @@ -41,12 +42,14 @@ EditShopInfoModalProps) { const { imageFile, saveImgFile, imgRef } = useImageUpload(); const { setName, setAddress, setPhone, setDeliveryPrice, setDescription, setDelivery, setPayBank, - setPayCard, + setPayCard, setCategoryId, } = useShopRegistrationStore(); const { - name, address, phone, deliveryPrice, description, delivery, payBank, payCard, + name, address, phone, deliveryPrice, description, delivery, payBank, payCard, categoryId, } = useShopRegistrationStore(); + const { categoryList } = useShopCategory(); + const { openTimeState, closeTimeState, @@ -64,6 +67,10 @@ EditShopInfoModalProps) { isAllClosed, } = CheckSameTime(); + const handleCategoryIdChange = (e: React.ChangeEvent) => { + setCategoryId(Number(e.target.value)); + }; + const { handleSubmit, setValue, } = useForm({ @@ -91,6 +98,7 @@ EditShopInfoModalProps) { setDelivery(shopInfo.delivery); setPayBank(shopInfo.pay_bank); setPayCard(shopInfo.pay_card); + setCategoryId(shopInfo.shop_categories[1].id); shopInfo.open.forEach((day, index) => { useModalStore.setState((prev) => ({ ...prev, @@ -133,12 +141,9 @@ EditShopInfoModalProps) { open_time: openTimeArray[index], })); // shop_categories[0]은 전체보기이므로 따로 처리 - if (shopInfo.shop_categories.length === 1) { - setValue('category_ids', [shopInfo.shop_categories[0].id]); - } else { - const categoryIds = shopInfo.shop_categories.map((category) => category.id); - setValue('category_ids', categoryIds); - } + const totalCategory = 1; + const categoryIds = categoryId === 0 ? [totalCategory] : [totalCategory, categoryId]; + setValue('category_ids', categoryIds); setValue('open', openValue); setValue('delivery_price', Number(deliveryPrice)); setValue('description', description); @@ -149,7 +154,7 @@ EditShopInfoModalProps) { setValue('phone', phone); setValue('address', address); }, [imageUrlList, openTimeState, closeTimeState, shopClosedState, deliveryPrice, - description, delivery, payBank, payCard, name, phone, address]); + description, delivery, payBank, payCard, name, phone, address, categoryId]); const onSubmit: SubmitHandler = (data) => { mutation.mutate(data); @@ -197,6 +202,16 @@ EditShopInfoModalProps) { className={styles['mobile-main-info--input']} /> + +
-
-