From d89c6440f5146efbcd93b0bbcc9884e8fede5369 Mon Sep 17 00:00:00 2001 From: kikiyeom Date: Wed, 6 Mar 2024 11:43:25 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Feat:=20useScript=20=ED=9B=85=EC=9D=84=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=ED=95=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/index.ts | 1 + src/hooks/useScript.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/hooks/useScript.ts diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 4152c898..073e07da 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -13,3 +13,4 @@ export { default as useHistory } from './useHistory'; export { default as usePrompt } from './usePrompt'; export { default as useMyTeam } from './useMyTeam'; export { default as useRefreshSelectorFamilyByKey } from './useRefreshSelectorFamilyByKey'; +export { default as useScript } from './useScript'; diff --git a/src/hooks/useScript.ts b/src/hooks/useScript.ts new file mode 100644 index 00000000..1b3eb927 --- /dev/null +++ b/src/hooks/useScript.ts @@ -0,0 +1,15 @@ +import { useEffect } from 'react'; + +const useScript = (url: string) => { + useEffect(() => { + const script = document.createElement('script'); + script.src = url; + script.async = true; + document.body.appendChild(script); + return () => { + document.body.removeChild(script); + }; + }, [url]); +}; + +export default useScript; From ed9155813f85680332b274bb8ac7b2990d583653 Mon Sep 17 00:00:00 2001 From: kikiyeom Date: Wed, 6 Mar 2024 11:48:00 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Refactor:=20=EC=A3=BC=EC=86=8C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B4=80=EB=A0=A8=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20?= =?UTF-8?q?=EC=A0=95=EB=8F=88=ED=95=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 1 - .../ScheduleTemplate.component.tsx | 41 ++++++++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/public/index.html b/public/index.html index 5b9493d7..25433363 100644 --- a/public/index.html +++ b/public/index.html @@ -40,7 +40,6 @@ /> -
diff --git a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx index e61862c2..d021232f 100644 --- a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx +++ b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx @@ -10,6 +10,7 @@ import { SessionTemplate } from '../SessionTemplate'; import Plus from '@/assets/svg/plus-20.svg'; import { EventCreateRequest } from '@/types'; import { LocationType, ScheduleFormValues } from '@/utils'; +import { useScript } from '@/hooks'; const DEFAULT_SESSION: EventCreateRequest = { startedAt: '', @@ -18,6 +19,9 @@ const DEFAULT_SESSION: EventCreateRequest = { contentsCreateRequests: [], }; +const DAUM_POSTCODE_SCRIPT = '//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js'; +const DAUM_POSTCODE_API_URL = 'https://dapi.kakao.com/v2/local/search/address'; + const ScheduleTemplate = () => { const { register, control, formState, getValues, watch, setValue } = useFormContext(); @@ -30,6 +34,8 @@ const ScheduleTemplate = () => { control, }); + useScript(DAUM_POSTCODE_SCRIPT); + const generationOptions = useMemo(() => { return generations.map(({ generationNumber }) => ({ label: `${generationNumber}기`, @@ -43,25 +49,30 @@ const ScheduleTemplate = () => { const handleClickAddressSearch = () => { new window.daum.Postcode({ async oncomplete(data: { address: string }) { - const res = await fetch( - `https://dapi.kakao.com/v2/local/search/address?query=${data.address}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: 'KakaoAK cc4af66dc10aa1a20830f3cc62c40a87', - }, + const res = await fetch(`${DAUM_POSTCODE_API_URL}?query=${data.address}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: 'KakaoAK cc4af66dc10aa1a20830f3cc62c40a87', }, - ); + }); const json = await res.json(); - const roadAddress = json.documents[0].road_address; + + const { + address_name: address, + x: longitude, + y: latitude, + building_name: buildingName, + } = json.documents[0].road_address; + const placeName = buildingName || address; + setValue('locationInfo', { - address: roadAddress.address_name, - latitude: roadAddress.y, - longitude: roadAddress.x, - placeName: roadAddress.building_name ?? roadAddress.address_name, + address, + latitude, + longitude, + placeName, }); - setValue('placeName', roadAddress.building_name); + setValue('placeName', placeName); }, }).open(); }; From 7a00c91f8f6a2cff0c935ffda6e5a260dcb1b19d Mon Sep 17 00:00:00 2001 From: kikiyeom Date: Thu, 7 Mar 2024 17:58:21 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Feat:=20=EC=8A=A4=EC=BC=80=EC=A4=84=20?= =?UTF-8?q?=EC=9E=A5=EC=86=8C=EC=97=90=20=EC=83=81=EC=84=B8=EC=A3=BC?= =?UTF-8?q?=EC=86=8C=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScheduleTemplate.component.tsx | 21 ++++++---- .../ScheduleTemplate.styled.ts | 8 +++- src/utils/schedule.ts | 38 ++++++++++++++++--- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx index d021232f..aec49d44 100644 --- a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx +++ b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx @@ -125,16 +125,23 @@ const ScheduleTemplate = () => { /> {locationType === LocationType.OFFLINE && ( - + + + + + - - + )} diff --git a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.styled.ts b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.styled.ts index 4dd16bc6..93648f02 100644 --- a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.styled.ts +++ b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.styled.ts @@ -64,10 +64,16 @@ export const RequiredDot = styled.span` export const RadioButtonGroup = styled.div` display: flex; gap: 2rem; - margin-bottom: 1rem; + margin-bottom: 0.6rem; `; export const InputWithButton = styled.div` display: flex; gap: 1rem; `; + +export const LocationWrapper = styled.div` + display: flex; + flex-direction: column; + gap: 0.6rem; +`; diff --git a/src/utils/schedule.ts b/src/utils/schedule.ts index caaa7a89..d4a2282a 100644 --- a/src/utils/schedule.ts +++ b/src/utils/schedule.ts @@ -27,6 +27,7 @@ export interface ScheduleFormValues { longitude: string; placeName: string; }; + detailAddress?: string; } export const getScheduleStatusText = (status: ValueOf) => { @@ -43,7 +44,13 @@ export const getScheduleStatusText = (status: ValueOf) => export const parseScheduleResponseToFormValues = ( response: ScheduleResponse, ): ScheduleFormValues => { - const { name, generationNumber, startedAt, eventList, location } = response; + const { + name, + generationNumber, + startedAt, + eventList, + location: { address, placeName, latitude, longitude }, + } = response; const date: Dayjs = dayjs(startedAt, 'YYYY-MM-DD').startOf('day'); @@ -58,22 +65,41 @@ export const parseScheduleResponseToFormValues = ( })), })); - const isOffline = !!location.address; + if (address) { + // address의 형식: 주소 (상세주소) + const baseAddress = address.replace(/\s*\(.*?\)\s*/g, ''); + const [, detailAddress] = address.match(/\(([^)]+)\)/) ?? []; + return { + name, + generationNumber, + date, + sessions, + locationType: LocationType.OFFLINE, + placeName, + detailAddress, + locationInfo: { + address: baseAddress, + latitude: String(latitude), + longitude: String(longitude), + placeName, + }, + }; + } return { name, generationNumber, date, sessions, - locationType: isOffline ? LocationType.OFFLINE : LocationType.ONLINE, - placeName: isOffline ? location.placeName : undefined, + locationType: LocationType.ONLINE, }; }; export const parseFormValuesToScheduleRequest = ( formValues: ScheduleFormValues, ): ScheduleCreateRequest | ScheduleUpdateRequest => { - const { generationNumber, date, sessions, name, locationType, locationInfo } = formValues; + const { generationNumber, date, sessions, name, locationType, locationInfo, detailAddress } = + formValues; const formattedDate = date.format('YYYY-MM-DD'); @@ -99,7 +125,7 @@ export const parseFormValuesToScheduleRequest = ( }; if (locationType === LocationType.OFFLINE && locationInfo) { - scheduleRequest.address = locationInfo.address; + scheduleRequest.address = `${locationInfo.address}${detailAddress ? `(${detailAddress})` : ''}`; scheduleRequest.latitude = Number(locationInfo.latitude); scheduleRequest.longitude = Number(locationInfo.longitude); scheduleRequest.placeName = locationInfo.placeName; From e761ec6e2b66aa82b1e25900275dcd9758613f6c Mon Sep 17 00:00:00 2001 From: kikiyeom Date: Fri, 8 Mar 2024 21:17:31 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Refactor:=20API=20KEY=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=EB=B3=80=EC=88=98=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 1 + .../Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 717a4c76..ba3e1d11 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ BASE_URL= +KAKAO_KEY= diff --git a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx index aec49d44..854804ea 100644 --- a/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx +++ b/src/components/Schedule/ScheduleTemplate/ScheduleTemplate.component.tsx @@ -53,7 +53,7 @@ const ScheduleTemplate = () => { method: 'GET', headers: { 'Content-Type': 'application/json', - Authorization: 'KakaoAK cc4af66dc10aa1a20830f3cc62c40a87', + Authorization: `KakaoAK ${process.env.KAKAO_KEY}`, }, }); const json = await res.json();