From ede2e1dca81b8660b984e709911720595dc9d79f Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Thu, 20 Jul 2023 17:21:28 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=EC=97=AC=ED=96=89=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EB=AA=A8=EB=8B=AC=20=EB=A7=88=ED=81=AC?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripInformation/TripInformation.tsx | 70 ++++++++++--------- .../TripInfoEditModal.style.ts | 13 ++++ .../TripInfoEditModal/TripInfoEditModal.tsx | 38 ++++++++++ frontend/src/types/trip.ts | 4 ++ 4 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts create mode 100644 frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index 324491bb5..69d6aee66 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -1,6 +1,6 @@ import DefaultThumbnail from '@assets/png/trip-information_default-thumbnail.png'; import type { TripData } from '@type/trip'; -import { Badge, Box, Button, Flex, Heading, Text, Theme } from 'hang-log-design-system'; +import { Badge, Box, Button, Flex, Heading, Text, Theme, useOverlay } from 'hang-log-design-system'; import { formatDate } from '@utils/formatter'; @@ -12,42 +12,48 @@ import { sectionStyling, titleStyling, } from '@components/common/TripInformation/TripInformation.style'; +import TripInfoEditModal from '@components/trip/TripInfoEditModal/TripInfoEditModal'; type TripInformationProps = Omit; const TripInformation = ({ ...information }: TripInformationProps) => { + const { isOpen: isEditModalOpen, close: closeEditModal, open: openEditModal } = useOverlay(); + return ( -
- -
- 여행 대표 이미지 - - - - {information.cities.map(({ id, name }) => ( - {name} - ))} - - - {information.title} - - - {formatDate(information.startDate)} - {formatDate(information.endDate)} - - - {information.description} - - - - {/* 수정 모드일 때만 보인다 */} - - - -
+ <> +
+ +
+ 여행 대표 이미지 + + + + {information.cities.map(({ id, name }) => ( + {name} + ))} + + + {information.title} + + + {formatDate(information.startDate)} - {formatDate(information.endDate)} + + + {information.description} + + + + {/* 수정 모드일 때만 보인다 */} + + + +
+ + ); }; diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts new file mode 100644 index 000000000..e669f2f97 --- /dev/null +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts @@ -0,0 +1,13 @@ +import { css } from '@emotion/react'; +import { Theme } from 'hang-log-design-system'; + +export const formStyling = css({ + display: 'flex', + flexDirection: 'column', + gap: Theme.spacer.spacing3, + padding: Theme.spacer.spacing4, + + '> button': { + width: '400px', + }, +}); diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx new file mode 100644 index 000000000..22d2fcbe0 --- /dev/null +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -0,0 +1,38 @@ +import { TripData } from '@type/trip'; +import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; + +import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; +import DateInput from '@components/common/DateInput/DateInput'; +import { formStyling } from '@components/trip/TripInfoEditModal/TripInfoEditModal.style'; + +interface TripInfoEditModalProps extends Omit { + isOpen: boolean; + onClose: () => void; +} + +const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModalProps) => { + const { id, title, cities, startDate, endDate, description, imageUrl } = information; + + return ( + {}} hasCloseButton> +
+ {}} /> + {}} /> + + + {}} + /> + + +
+ ); +}; + +export default TripInfoEditModal; diff --git a/frontend/src/types/trip.ts b/frontend/src/types/trip.ts index 87be44a12..be2836b3d 100644 --- a/frontend/src/types/trip.ts +++ b/frontend/src/types/trip.ts @@ -11,3 +11,7 @@ export interface TripData { cities: CityData[]; dayLogs: DayLogData[]; } + +export interface TripPutData extends Omit { + cityIds: number[]; +} From 3a2a277f0810aa5b0ba3fa62528fca2692d4511f Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Thu, 20 Jul 2023 17:51:18 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=EC=97=AC=ED=96=89=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EC=84=9C=EB=B2=84=EB=A1=9C=20put?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/trip/putTrip.ts | 16 ++++++++++++++++ .../api/trips/{newTrip.ts => postNewTrip.ts} | 0 frontend/src/hooks/api/useNewTripMutation.ts | 3 +-- frontend/src/hooks/api/useTripMutation.ts | 19 +++++++++++++++++++ frontend/src/types/trip.ts | 2 +- 5 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 frontend/src/api/trip/putTrip.ts rename frontend/src/api/trips/{newTrip.ts => postNewTrip.ts} (100%) create mode 100644 frontend/src/hooks/api/useTripMutation.ts diff --git a/frontend/src/api/trip/putTrip.ts b/frontend/src/api/trip/putTrip.ts new file mode 100644 index 000000000..1d867a456 --- /dev/null +++ b/frontend/src/api/trip/putTrip.ts @@ -0,0 +1,16 @@ +import { END_POINTS } from '@constants/api'; +import { TripPutData } from '@type/trip'; + +import { axiosInstance } from '@api/axiosInstance'; + +export interface PutTripParams extends TripPutData { + tripId: number; +} + +export const putTrip = + () => + ({ tripId, ...tripInformation }: PutTripParams) => { + return axiosInstance.put(END_POINTS.TRIP(tripId), { + ...tripInformation, + }); + }; diff --git a/frontend/src/api/trips/newTrip.ts b/frontend/src/api/trips/postNewTrip.ts similarity index 100% rename from frontend/src/api/trips/newTrip.ts rename to frontend/src/api/trips/postNewTrip.ts diff --git a/frontend/src/hooks/api/useNewTripMutation.ts b/frontend/src/hooks/api/useNewTripMutation.ts index ef9c74154..5a4e758d8 100644 --- a/frontend/src/hooks/api/useNewTripMutation.ts +++ b/frontend/src/hooks/api/useNewTripMutation.ts @@ -1,8 +1,7 @@ +import { postNewTrip } from '@/api/trips/postNewTrip'; import { NETWORK } from '@constants/api'; import { useMutation } from '@tanstack/react-query'; -import { postNewTrip } from '@api/trips/newTrip'; - export const useNewTripMutation = () => { const newTripMutation = useMutation(postNewTrip(), { onError: (err, _, context) => { diff --git a/frontend/src/hooks/api/useTripMutation.ts b/frontend/src/hooks/api/useTripMutation.ts new file mode 100644 index 000000000..b880552e8 --- /dev/null +++ b/frontend/src/hooks/api/useTripMutation.ts @@ -0,0 +1,19 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import { putTrip } from '@api/trip/putTrip'; + +export const useTripMutation = () => { + const queryClient = useQueryClient(); + + const tripMutation = useMutation(putTrip(), { + onSuccess: () => { + // 순서 변경 성공 시 Trip 정보 재요청 + queryClient.invalidateQueries({ queryKey: ['trip'] }); + }, + onError: (err, _, context) => { + alert('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); + }, + }); + + return tripMutation; +}; diff --git a/frontend/src/types/trip.ts b/frontend/src/types/trip.ts index be2836b3d..ae83015d5 100644 --- a/frontend/src/types/trip.ts +++ b/frontend/src/types/trip.ts @@ -12,6 +12,6 @@ export interface TripData { dayLogs: DayLogData[]; } -export interface TripPutData extends Omit { +export interface TripPutData extends Omit { cityIds: number[]; } From ee623e2bffe8bfc89224151e1b2d434e32359792 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Fri, 21 Jul 2023 12:00:20 +0900 Subject: [PATCH 03/17] =?UTF-8?q?refactor:=20=ED=95=84=EC=88=98=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EB=A7=88=ED=81=AC=EB=93=A4=EC=96=B4=EA=B0=80?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95,=20=EB=AA=A8=EB=8B=AC?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20padding=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/CitySearchBar/CitySearchBar.tsx | 5 +++-- .../src/components/common/DateInput/DateInput.tsx | 4 +++- .../TripInfoEditModal/TripInfoEditModal.style.ts | 1 - .../trip/TripInfoEditModal/TripInfoEditModal.tsx | 14 ++++++++++---- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx index 7293620df..932ab71bc 100644 --- a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx +++ b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx @@ -21,9 +21,10 @@ import CitySuggestion from '@components/common/CitySuggestion/CitySuggestion'; interface CitySearchBarProps { initialCityTags?: CityData[]; setCityData: (cities: CityData[]) => void; + required?: boolean; } -const CitySearchBar = ({ initialCityTags, setCityData }: CitySearchBarProps) => { +const CitySearchBar = ({ initialCityTags, setCityData, required = false }: CitySearchBarProps) => { const [queryWord, setQueryWord] = useState(''); const { cityTags, addCityTag, deleteCityTag } = useCityTags(initialCityTags ?? []); const { isOpen: isSuggestionOpen, open: openSuggestion, close: closeSuggestion } = useOverlay(); @@ -88,7 +89,7 @@ const CitySearchBar = ({ initialCityTags, setCityData }: CitySearchBarProps) => return (
- +
diff --git a/frontend/src/components/common/DateInput/DateInput.tsx b/frontend/src/components/common/DateInput/DateInput.tsx index 59ed744dc..d6e0ab9ee 100644 --- a/frontend/src/components/common/DateInput/DateInput.tsx +++ b/frontend/src/components/common/DateInput/DateInput.tsx @@ -14,11 +14,13 @@ import { interface DateInputProps { initialDateRange?: DateRangeData; setDateData: (dateRange: DateRangeData) => void; + required?:boolean } const DateInput = ({ initialDateRange = { start: null, end: null }, setDateData, + required=false, }: DateInputProps) => { const [inputValue, setInputValue] = useState(dateRangeToString(initialDateRange)); const [selectedDateRange, setSelectedDateRange] = useState(initialDateRange); @@ -37,7 +39,7 @@ const DateInput = ({ return ( - + button': { width: '400px', diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 22d2fcbe0..40d5ffd25 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,5 +1,7 @@ -import { TripData } from '@type/trip'; +import type { TripData } from '@type/trip'; import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; +import { useCallback, useState } from 'react'; +import type { FormEvent } from 'react'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; @@ -16,13 +18,17 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa return ( {}} hasCloseButton>
- {}} /> - {}} /> + {}} /> + {}} + /> {}} From 7385eb525aa8e6afb221ef8bdaf4ccd2f90fea2c Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Mon, 24 Jul 2023 21:29:22 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat:=EC=97=AC=ED=96=89=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EA=B0=80=EB=8A=A5=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripInfoEditModal/TripInfoEditModal.tsx | 38 ++++++++++----- frontend/src/hooks/newTrip/useEditTripInfo.ts | 48 +++++++++++++++++++ frontend/src/hooks/newTrip/useNewTripForm.ts | 4 +- 3 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 frontend/src/hooks/newTrip/useEditTripInfo.ts diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 40d5ffd25..5a6a2be0c 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,7 +1,7 @@ -import type { TripData } from '@type/trip'; +import { useEditTripInfo } from '@/hooks/newTrip/useEditTripInfo'; +import type { TripData, TripPutData } from '@type/trip'; import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; -import { useCallback, useState } from 'react'; -import type { FormEvent } from 'react'; +import type { ChangeEvent } from 'react'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; @@ -13,22 +13,36 @@ interface TripInfoEditModalProps extends Omit { } const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModalProps) => { - const { id, title, cities, startDate, endDate, description, imageUrl } = information; + const { tripInfo, updateInputValue, setCityData, setDateData, handleSubmit } = + useEditTripInfo(information); + + const handleChangeValue = (key: keyof TripPutData) => (e: ChangeEvent) => { + updateInputValue(key, e.currentTarget.value); + }; return ( - {}} hasCloseButton> - - {}} /> + + + {}} + initialDateRange={{ start: tripInfo.startDate, end: tripInfo.endDate }} + setDateData={setDateData} + /> + + - - {}} diff --git a/frontend/src/hooks/newTrip/useEditTripInfo.ts b/frontend/src/hooks/newTrip/useEditTripInfo.ts new file mode 100644 index 000000000..306ffad2c --- /dev/null +++ b/frontend/src/hooks/newTrip/useEditTripInfo.ts @@ -0,0 +1,48 @@ +import type { TripData, TripPutData } from '@type/trip'; +import { useEffect, useState } from 'react'; +import type { FormEvent } from 'react'; + +import { useNewTripForm } from './useNewTripForm'; + +export const useEditTripInfo = (information: Omit) => { + const { id, title, cities, startDate, endDate, description, imageUrl } = information; + const { + newTripData: cityDateInfo, + setCityData, + setDateData, + isAllInputFilled: isCityDateValid, + } = useNewTripForm({ + cityIds: cities.map((city) => city.id), + startDate, + endDate, + }); + const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); + const [isInputError, setIsInputError] = useState(false); + + useEffect(() => { + setTripInfo((prevTripInfo) => { + return { ...prevTripInfo, ...cityDateInfo }; + }); + }, [cityDateInfo]); + + const updateInputValue = (key: K, value: TripPutData[K]) => { + setTripInfo((prevTripInfo) => { + return { ...prevTripInfo, [key]: value }; + }); + }; + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + + if (!isCityDateValid || !tripInfo.title) { + setIsInputError(true); + console.log('error'); + return; + } + + //서버로 보내기 + console.log(tripInfo); + }; + + return { tripInfo, updateInputValue, setCityData, setDateData, handleSubmit }; +}; diff --git a/frontend/src/hooks/newTrip/useNewTripForm.ts b/frontend/src/hooks/newTrip/useNewTripForm.ts index d405ecaab..38f1c7b19 100644 --- a/frontend/src/hooks/newTrip/useNewTripForm.ts +++ b/frontend/src/hooks/newTrip/useNewTripForm.ts @@ -8,8 +8,8 @@ const initialNewTripData = { cityIds: [], }; -export const useNewTripForm = () => { - const [newTripData, setNewTripData] = useState(initialNewTripData); +export const useNewTripForm = (newTrip?: NewTripData) => { + const [newTripData, setNewTripData] = useState(newTrip ?? initialNewTripData); const [isAllInputFilled, setIsAllInputFilled] = useState(false); useEffect(() => { From d7cfd541702827f0d07d1f029c93990bc944a3c3 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Mon, 24 Jul 2023 22:03:20 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat:=EC=84=9C=EB=B2=84=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=95=9C=20=EC=A0=95=EB=B3=B4=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EB=8A=94=20=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripInfoEditModal/TripInfoEditModal.tsx | 11 +++++++-- ...TripMutation.ts => useEditTripMutation.ts} | 4 ++-- frontend/src/hooks/newTrip/useEditTripInfo.ts | 24 +++++++++---------- 3 files changed, 23 insertions(+), 16 deletions(-) rename frontend/src/hooks/api/{useTripMutation.ts => useEditTripMutation.ts} (81%) diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 5a6a2be0c..d1d3ed888 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,7 +1,7 @@ import { useEditTripInfo } from '@/hooks/newTrip/useEditTripInfo'; import type { TripData, TripPutData } from '@type/trip'; import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; -import type { ChangeEvent } from 'react'; +import type { ChangeEvent, FormEvent } from 'react'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; @@ -13,13 +13,20 @@ interface TripInfoEditModalProps extends Omit { } const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModalProps) => { - const { tripInfo, updateInputValue, setCityData, setDateData, handleSubmit } = + const { tripInfo, updateInputValue, setCityData, setDateData, putEditedInfo } = useEditTripInfo(information); const handleChangeValue = (key: keyof TripPutData) => (e: ChangeEvent) => { updateInputValue(key, e.currentTarget.value); }; + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + putEditedInfo(); + + onClose(); + }; + return ( diff --git a/frontend/src/hooks/api/useTripMutation.ts b/frontend/src/hooks/api/useEditTripMutation.ts similarity index 81% rename from frontend/src/hooks/api/useTripMutation.ts rename to frontend/src/hooks/api/useEditTripMutation.ts index b880552e8..9ea118b1c 100644 --- a/frontend/src/hooks/api/useTripMutation.ts +++ b/frontend/src/hooks/api/useEditTripMutation.ts @@ -2,12 +2,12 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { putTrip } from '@api/trip/putTrip'; -export const useTripMutation = () => { +export const useEditTripMutation = () => { const queryClient = useQueryClient(); const tripMutation = useMutation(putTrip(), { onSuccess: () => { - // 순서 변경 성공 시 Trip 정보 재요청 + // 여행 정보 수정 성공시 Trip 정보 재요청 queryClient.invalidateQueries({ queryKey: ['trip'] }); }, onError: (err, _, context) => { diff --git a/frontend/src/hooks/newTrip/useEditTripInfo.ts b/frontend/src/hooks/newTrip/useEditTripInfo.ts index 306ffad2c..f8d936e0b 100644 --- a/frontend/src/hooks/newTrip/useEditTripInfo.ts +++ b/frontend/src/hooks/newTrip/useEditTripInfo.ts @@ -1,8 +1,8 @@ import type { TripData, TripPutData } from '@type/trip'; import { useEffect, useState } from 'react'; -import type { FormEvent } from 'react'; -import { useNewTripForm } from './useNewTripForm'; +import { useEditTripMutation } from '@hooks/api/useEditTripMutation'; +import { useNewTripForm } from '@hooks/newTrip/useNewTripForm'; export const useEditTripInfo = (information: Omit) => { const { id, title, cities, startDate, endDate, description, imageUrl } = information; @@ -17,7 +17,7 @@ export const useEditTripInfo = (information: Omit) => { endDate, }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); - const [isInputError, setIsInputError] = useState(false); + const tripMutation = useEditTripMutation(); useEffect(() => { setTripInfo((prevTripInfo) => { @@ -31,18 +31,18 @@ export const useEditTripInfo = (information: Omit) => { }); }; - const handleSubmit = (e: FormEvent) => { - e.preventDefault(); - - if (!isCityDateValid || !tripInfo.title) { - setIsInputError(true); - console.log('error'); + const putEditedInfo = () => { + if (isCityDateValid && !!tripInfo.title) { return; } - //서버로 보내기 - console.log(tripInfo); + tripMutation.mutate({ + tripId: id, + ...tripInfo, + startDate: tripInfo.startDate!, + endDate: tripInfo.endDate!, + }); }; - return { tripInfo, updateInputValue, setCityData, setDateData, handleSubmit }; + return { tripInfo, updateInputValue, setCityData, setDateData, putEditedInfo }; }; From 238ecd21356be0385e974c6949c9e2a261e82905 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Mon, 24 Jul 2023 22:35:05 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=EA=B8=B0=EA=B0=84=EC=9D=B4=20?= =?UTF-8?q?=EA=B8=B0=EC=A1=B4=EA=B0=92=EB=B3=B4=EB=8B=A4=20=EC=9E=91?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EA=B2=BD=EA=B3=A0=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/newTrip/useEditTripInfo.ts | 15 ++++++++++++++- frontend/src/utils/calculator.ts | 10 ++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 frontend/src/utils/calculator.ts diff --git a/frontend/src/hooks/newTrip/useEditTripInfo.ts b/frontend/src/hooks/newTrip/useEditTripInfo.ts index f8d936e0b..45a60b297 100644 --- a/frontend/src/hooks/newTrip/useEditTripInfo.ts +++ b/frontend/src/hooks/newTrip/useEditTripInfo.ts @@ -1,3 +1,5 @@ +import { getDayLengthFromDateRange } from '@/utils/calculator'; +import { isEmptyString } from '@/utils/validator'; import type { TripData, TripPutData } from '@type/trip'; import { useEffect, useState } from 'react'; @@ -18,6 +20,7 @@ export const useEditTripInfo = (information: Omit) => { }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); const tripMutation = useEditTripMutation(); + const originalDayLength = getDayLengthFromDateRange(startDate, endDate); useEffect(() => { setTripInfo((prevTripInfo) => { @@ -32,10 +35,20 @@ export const useEditTripInfo = (information: Omit) => { }; const putEditedInfo = () => { - if (isCityDateValid && !!tripInfo.title) { + if (isCityDateValid && isEmptyString(tripInfo.title)) { return; } + const changedDayLength = getDayLengthFromDateRange(tripInfo.startDate, tripInfo.endDate); + + if (changedDayLength < originalDayLength) { + confirm( + '기존 입력한 날짜보다 기간이 짧습니다. \n 줄어든만큼 입력한 여행정보가 삭제됩니다. 그래도 변경하시겠습니까?' + ); + } + + console.log(tripInfo); + tripMutation.mutate({ tripId: id, ...tripInfo, diff --git a/frontend/src/utils/calculator.ts b/frontend/src/utils/calculator.ts new file mode 100644 index 000000000..978601d12 --- /dev/null +++ b/frontend/src/utils/calculator.ts @@ -0,0 +1,10 @@ +export const getDayLengthFromDateRange = (startDate: string | null, endDate: string | null) => { + if (!startDate || !endDate) return Infinity; + + const start = new Date(startDate); + const end = new Date(endDate); + + const timeDiff = Math.abs(end.getTime() - start.getTime()); + + return Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1; +}; From 0ffc2f6e9d26791ee84c544813f958139a1a86a6 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Mon, 24 Jul 2023 22:48:00 +0900 Subject: [PATCH 07/17] =?UTF-8?q?refactor:=20rename=20=ED=95=A8=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/CitySearchBar/CitySearchBar.tsx | 10 ++--- .../components/common/DateInput/DateInput.tsx | 10 ++--- .../newTrip/NewTripForm/NewTripForm.tsx | 16 ++++---- .../TripInfoEditModal/TripInfoEditModal.tsx | 16 +++++--- frontend/src/hooks/common/useCityDateForm.ts | 38 +++++++++++++++++++ frontend/src/hooks/newTrip/useNewTripForm.ts | 38 ------------------- .../useTripInfoForm.ts} | 16 +++----- .../pages/TripCreatePage/TripCreatePage.tsx | 4 +- .../stories/common/CitySearchBar.stories.tsx | 2 +- 9 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 frontend/src/hooks/common/useCityDateForm.ts delete mode 100644 frontend/src/hooks/newTrip/useNewTripForm.ts rename frontend/src/hooks/{newTrip/useEditTripInfo.ts => trip/useTripInfoForm.ts} (80%) diff --git a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx index 932ab71bc..463975694 100644 --- a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx +++ b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx @@ -19,19 +19,19 @@ import { import CitySuggestion from '@components/common/CitySuggestion/CitySuggestion'; interface CitySearchBarProps { - initialCityTags?: CityData[]; - setCityData: (cities: CityData[]) => void; + initialCities?: CityData[]; + updateCityInfo: (cities: CityData[]) => void; required?: boolean; } -const CitySearchBar = ({ initialCityTags, setCityData, required = false }: CitySearchBarProps) => { +const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: CitySearchBarProps) => { const [queryWord, setQueryWord] = useState(''); - const { cityTags, addCityTag, deleteCityTag } = useCityTags(initialCityTags ?? []); + const { cityTags, addCityTag, deleteCityTag } = useCityTags(initialCities ?? []); const { isOpen: isSuggestionOpen, open: openSuggestion, close: closeSuggestion } = useOverlay(); const inputRef = useRef(null); useEffect(() => { - setCityData(cityTags); + updateCityInfo(cityTags); }, [cityTags]); const handleInputChange = (event: FormEvent) => { diff --git a/frontend/src/components/common/DateInput/DateInput.tsx b/frontend/src/components/common/DateInput/DateInput.tsx index d6e0ab9ee..f341ff3e6 100644 --- a/frontend/src/components/common/DateInput/DateInput.tsx +++ b/frontend/src/components/common/DateInput/DateInput.tsx @@ -13,21 +13,21 @@ import { interface DateInputProps { initialDateRange?: DateRangeData; - setDateData: (dateRange: DateRangeData) => void; - required?:boolean + updateDateInfo: (dateRange: DateRangeData) => void; + required?: boolean; } const DateInput = ({ initialDateRange = { start: null, end: null }, - setDateData, - required=false, + updateDateInfo, + required = false, }: DateInputProps) => { const [inputValue, setInputValue] = useState(dateRangeToString(initialDateRange)); const [selectedDateRange, setSelectedDateRange] = useState(initialDateRange); const { isOpen: isCalendarOpen, close: closeCalendar, toggle: toggleCalendar } = useOverlay(); useEffect(() => { - setDateData(selectedDateRange); + updateDateInfo(selectedDateRange); }, [selectedDateRange]); const handleDateClick = (dateRange: DateRangeData) => { diff --git a/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx b/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx index 225567523..31fa2afd1 100644 --- a/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx +++ b/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx @@ -1,24 +1,24 @@ +import { useCityDateForm } from '@/hooks/common/useCityDateForm'; import { PATH } from '@constants/path'; import { Button } from 'hang-log-design-system'; import type { FormEvent } from 'react'; import { useNavigate } from 'react-router-dom'; import { useNewTripMutation } from '@hooks/api/useNewTripMutation'; -import { useNewTripForm } from '@hooks/newTrip/useNewTripForm'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; import { formStyling } from '@components/newTrip/NewTripForm/NewTripForm.style'; -const NewTripForm = () => { - const { newTripData, setCityData, setDateData, isAllInputFilled } = useNewTripForm(); +const TripAddForm = () => { + const { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid } = useCityDateForm(); const newTripMutation = useNewTripMutation(); const navigate = useNavigate(); const handleSubmit = (e: FormEvent) => { e.preventDefault(); - newTripMutation.mutate(newTripData, { + newTripMutation.mutate(cityDateInfo, { onSuccess: goToTripEditPageWithId, }); }; @@ -30,13 +30,13 @@ const NewTripForm = () => { return ( - - - ); }; -export default NewTripForm; +export default TripAddForm; diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index d1d3ed888..7b1d98056 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,4 +1,4 @@ -import { useEditTripInfo } from '@/hooks/newTrip/useEditTripInfo'; +import { useTripInfoForm } from '@/hooks/trip/useTripInfoForm'; import type { TripData, TripPutData } from '@type/trip'; import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; import type { ChangeEvent, FormEvent } from 'react'; @@ -13,8 +13,8 @@ interface TripInfoEditModalProps extends Omit { } const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModalProps) => { - const { tripInfo, updateInputValue, setCityData, setDateData, putEditedInfo } = - useEditTripInfo(information); + const { tripInfo, updateInputValue, updateCityInfo, updateDateInfo, submitEditedInfo } = + useTripInfoForm(information); const handleChangeValue = (key: keyof TripPutData) => (e: ChangeEvent) => { updateInputValue(key, e.currentTarget.value); @@ -22,7 +22,7 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa const handleSubmit = (e: FormEvent) => { e.preventDefault(); - putEditedInfo(); + submitEditedInfo(); onClose(); }; @@ -30,11 +30,15 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa return (
- + { + const [cityDateInfo, setCityDateInfo] = useState(initialTripData ?? defaultTripData); + const [isCityDateValid, setIsCityDateValid] = useState(false); + + useEffect(() => { + validateInputs(); + }, [cityDateInfo]); + + const updateCityInfo = (cities: CityData[]) => { + const cityIds = cities.map((city) => city.id); + + setCityDateInfo((prev) => ({ ...prev, cityIds })); + }; + + const updateDateInfo = (dateRange: DateRangeData) => { + const { start: startDate, end: endDate } = dateRange; + + setCityDateInfo((prev) => ({ ...prev, startDate, endDate })); + }; + + const validateInputs = () => { + const { startDate, endDate, cityIds } = cityDateInfo; + + setIsCityDateValid(!!startDate && !!endDate && !!cityIds.length); + }; + + return { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid }; +}; diff --git a/frontend/src/hooks/newTrip/useNewTripForm.ts b/frontend/src/hooks/newTrip/useNewTripForm.ts deleted file mode 100644 index 38f1c7b19..000000000 --- a/frontend/src/hooks/newTrip/useNewTripForm.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { CityData } from '@type/city'; -import type { DateRangeData, NewTripData } from '@type/trips'; -import { useEffect, useState } from 'react'; - -const initialNewTripData = { - startDate: null, - endDate: null, - cityIds: [], -}; - -export const useNewTripForm = (newTrip?: NewTripData) => { - const [newTripData, setNewTripData] = useState(newTrip ?? initialNewTripData); - const [isAllInputFilled, setIsAllInputFilled] = useState(false); - - useEffect(() => { - validateInputs(); - }, [newTripData]); - - const setCityData = (cities: CityData[]) => { - const cityIds = cities.map((city) => city.id); - - setNewTripData((prev) => ({ ...prev, cityIds })); - }; - - const setDateData = (dateRange: DateRangeData) => { - const { start: startDate, end: endDate } = dateRange; - - setNewTripData((prev) => ({ ...prev, startDate, endDate })); - }; - - const validateInputs = () => { - const { startDate, endDate, cityIds } = newTripData; - - setIsAllInputFilled(!!startDate && !!endDate && !!cityIds.length); - }; - - return { newTripData, setCityData, setDateData, isAllInputFilled }; -}; diff --git a/frontend/src/hooks/newTrip/useEditTripInfo.ts b/frontend/src/hooks/trip/useTripInfoForm.ts similarity index 80% rename from frontend/src/hooks/newTrip/useEditTripInfo.ts rename to frontend/src/hooks/trip/useTripInfoForm.ts index 45a60b297..8d454f2f5 100644 --- a/frontend/src/hooks/newTrip/useEditTripInfo.ts +++ b/frontend/src/hooks/trip/useTripInfoForm.ts @@ -1,24 +1,20 @@ +import { useCityDateForm } from '@/hooks/common/useCityDateForm'; import { getDayLengthFromDateRange } from '@/utils/calculator'; import { isEmptyString } from '@/utils/validator'; import type { TripData, TripPutData } from '@type/trip'; import { useEffect, useState } from 'react'; import { useEditTripMutation } from '@hooks/api/useEditTripMutation'; -import { useNewTripForm } from '@hooks/newTrip/useNewTripForm'; -export const useEditTripInfo = (information: Omit) => { +export const useTripInfoForm = (information: Omit) => { const { id, title, cities, startDate, endDate, description, imageUrl } = information; - const { - newTripData: cityDateInfo, - setCityData, - setDateData, - isAllInputFilled: isCityDateValid, - } = useNewTripForm({ + const { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid } = useCityDateForm({ cityIds: cities.map((city) => city.id), startDate, endDate, }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); + const tripMutation = useEditTripMutation(); const originalDayLength = getDayLengthFromDateRange(startDate, endDate); @@ -34,7 +30,7 @@ export const useEditTripInfo = (information: Omit) => { }); }; - const putEditedInfo = () => { + const submitEditedInfo = () => { if (isCityDateValid && isEmptyString(tripInfo.title)) { return; } @@ -57,5 +53,5 @@ export const useEditTripInfo = (information: Omit) => { }); }; - return { tripInfo, updateInputValue, setCityData, setDateData, putEditedInfo }; + return { tripInfo, updateInputValue, updateCityInfo, updateDateInfo, submitEditedInfo }; }; diff --git a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx index e58ef2db4..d05eb1536 100644 --- a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx +++ b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx @@ -9,7 +9,7 @@ import { containerStyling, } from '@pages/TripCreatePage/TripCreatePage.style'; -import NewTripForm from '@components/newTrip/NewTripForm/NewTripForm'; +import TripAddForm from '@components/newTrip/NewTripForm/NewTripForm'; const TripCreatePage = () => { useCityQuery(); @@ -18,7 +18,7 @@ const TripCreatePage = () => { 여행을 기록해 보세요 - + diff --git a/frontend/src/stories/common/CitySearchBar.stories.tsx b/frontend/src/stories/common/CitySearchBar.stories.tsx index 55b3f5f9d..2a162103e 100644 --- a/frontend/src/stories/common/CitySearchBar.stories.tsx +++ b/frontend/src/stories/common/CitySearchBar.stories.tsx @@ -6,7 +6,7 @@ const meta = { title: 'common/CitySearchBar', component: CitySearchBar, args: { - initialCityTags: [ + initialCities: [ { id: 16, name: '오사카, 일본' }, { id: 13, name: '부산, 한국' }, { id: 20, name: '제주도, 한국' }, From c401fce5124841d5c93b8faf3d01d99db5ab9eef Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Tue, 25 Jul 2023 11:01:16 +0900 Subject: [PATCH 08/17] =?UTF-8?q?refactor:=EA=B8=B0=EA=B0=84=20=EC=A4=84?= =?UTF-8?q?=EC=96=B4=EB=93=9C=EB=8A=94=20=EA=B2=BD=EA=B3=A0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/trip/useTripInfoForm.ts | 27 ++++++++++------------ frontend/src/mocks/handlers/trips.ts | 3 +++ frontend/src/utils/calculator.ts | 10 -------- 3 files changed, 15 insertions(+), 25 deletions(-) delete mode 100644 frontend/src/utils/calculator.ts diff --git a/frontend/src/hooks/trip/useTripInfoForm.ts b/frontend/src/hooks/trip/useTripInfoForm.ts index 8d454f2f5..00a5d5bc9 100644 --- a/frontend/src/hooks/trip/useTripInfoForm.ts +++ b/frontend/src/hooks/trip/useTripInfoForm.ts @@ -1,13 +1,13 @@ -import { useCityDateForm } from '@/hooks/common/useCityDateForm'; -import { getDayLengthFromDateRange } from '@/utils/calculator'; -import { isEmptyString } from '@/utils/validator'; import type { TripData, TripPutData } from '@type/trip'; import { useEffect, useState } from 'react'; +import { isEmptyString } from '@utils/validator'; + import { useEditTripMutation } from '@hooks/api/useEditTripMutation'; +import { useCityDateForm } from '@hooks/common/useCityDateForm'; export const useTripInfoForm = (information: Omit) => { - const { id, title, cities, startDate, endDate, description, imageUrl } = information; + const { id: tripId, title, cities, startDate, endDate, description, imageUrl } = information; const { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid } = useCityDateForm({ cityIds: cities.map((city) => city.id), startDate, @@ -16,7 +16,6 @@ export const useTripInfoForm = (information: Omit) => { const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); const tripMutation = useEditTripMutation(); - const originalDayLength = getDayLengthFromDateRange(startDate, endDate); useEffect(() => { setTripInfo((prevTripInfo) => { @@ -30,23 +29,21 @@ export const useTripInfoForm = (information: Omit) => { }); }; - const submitEditedInfo = () => { + const validateInfo = () => { if (isCityDateValid && isEmptyString(tripInfo.title)) { - return; + return false; } - const changedDayLength = getDayLengthFromDateRange(tripInfo.startDate, tripInfo.endDate); + return true; + }; - if (changedDayLength < originalDayLength) { - confirm( - '기존 입력한 날짜보다 기간이 짧습니다. \n 줄어든만큼 입력한 여행정보가 삭제됩니다. 그래도 변경하시겠습니까?' - ); + const submitEditedInfo = () => { + if (!validateInfo()) { + return; } - console.log(tripInfo); - tripMutation.mutate({ - tripId: id, + tripId, ...tripInfo, startDate: tripInfo.startDate!, endDate: tripInfo.endDate!, diff --git a/frontend/src/mocks/handlers/trips.ts b/frontend/src/mocks/handlers/trips.ts index e30700b56..274a78ce4 100644 --- a/frontend/src/mocks/handlers/trips.ts +++ b/frontend/src/mocks/handlers/trips.ts @@ -27,4 +27,7 @@ export const tripsHandlers = [ rest.get(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { return res(ctx.status(200), ctx.json(trip)); }), + rest.post(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { + return res(ctx.status(202)); + }), ]; diff --git a/frontend/src/utils/calculator.ts b/frontend/src/utils/calculator.ts deleted file mode 100644 index 978601d12..000000000 --- a/frontend/src/utils/calculator.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const getDayLengthFromDateRange = (startDate: string | null, endDate: string | null) => { - if (!startDate || !endDate) return Infinity; - - const start = new Date(startDate); - const end = new Date(endDate); - - const timeDiff = Math.abs(end.getTime() - start.getTime()); - - return Math.ceil(timeDiff / (1000 * 3600 * 24)) + 1; -}; From 93f2955b9a3b7e364978994aa916d36af8818832 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Tue, 25 Jul 2023 11:27:53 +0900 Subject: [PATCH 09/17] =?UTF-8?q?refactor:=20=EC=88=98=EC=A0=95=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EA=B8=B0=EA=B0=84=20=EC=A1=B0=EC=A0=95=EC=97=90=20?= =?UTF-8?q?=EA=B4=80=ED=95=9C=20=EA=B2=BD=EA=B3=A0=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripInfoEditModal.style.ts | 4 ++++ .../TripInfoEditModal/TripInfoEditModal.tsx | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts index ac00a7e1d..8f3ed59f6 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts @@ -10,3 +10,7 @@ export const formStyling = css({ width: '400px', }, }); + +export const supportingTextStyling = css({ + maxWidth: '400px', +}); diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 7b1d98056..9c6224cd2 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,11 +1,21 @@ import { useTripInfoForm } from '@/hooks/trip/useTripInfoForm'; import type { TripData, TripPutData } from '@type/trip'; -import { Button, ImageUploadInput, Input, Modal } from 'hang-log-design-system'; +import { + Button, + Flex, + ImageUploadInput, + Input, + Modal, + SupportingText, +} from 'hang-log-design-system'; import type { ChangeEvent, FormEvent } from 'react'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; -import { formStyling } from '@components/trip/TripInfoEditModal/TripInfoEditModal.style'; +import { + formStyling, + supportingTextStyling, +} from '@components/trip/TripInfoEditModal/TripInfoEditModal.style'; interface TripInfoEditModalProps extends Omit { isOpen: boolean; @@ -40,6 +50,10 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa initialDateRange={{ start: tripInfo.startDate, end: tripInfo.endDate }} updateDateInfo={updateDateInfo} /> + + ⚠︎ 여행 기간을 단축하면 마지막 날짜부터 작성한 기록들이
+ 삭제됩니다. +
Date: Tue, 25 Jul 2023 13:08:22 +0900 Subject: [PATCH 10/17] =?UTF-8?q?refactor:=EB=8F=84=EC=8B=9C=20=EB=AF=B8?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EC=8B=9C=20=EA=B2=BD=EA=B3=A0=EB=AC=B8?= =?UTF-8?q?=EA=B5=AC=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripInfoEditModal.style.ts | 7 +++- .../TripInfoEditModal/TripInfoEditModal.tsx | 29 ++++++++------ frontend/src/hooks/trip/useTripInfoForm.ts | 39 +++++++++++++------ frontend/src/mocks/handlers/trips.ts | 3 +- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts index 8f3ed59f6..b5e67dd9a 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.style.ts @@ -11,6 +11,11 @@ export const formStyling = css({ }, }); -export const supportingTextStyling = css({ +export const cityInputErrorTextStyling = css({ + lineHeight: 0, + color: Theme.color.red200, +}); + +export const dateInputTextStyling = css({ maxWidth: '400px', }); diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 9c6224cd2..1f855e583 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -13,8 +13,9 @@ import type { ChangeEvent, FormEvent } from 'react'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; import { + cityInputErrorTextStyling, + dateInputTextStyling, formStyling, - supportingTextStyling, } from '@components/trip/TripInfoEditModal/TripInfoEditModal.style'; interface TripInfoEditModalProps extends Omit { @@ -23,20 +24,19 @@ interface TripInfoEditModalProps extends Omit { } const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModalProps) => { - const { tripInfo, updateInputValue, updateCityInfo, updateDateInfo, submitEditedInfo } = - useTripInfoForm(information); + const { + tripInfo, + isCityInputError, + updateInputValue, + updateCityInfo, + updateDateInfo, + handleSubmit, + } = useTripInfoForm(information, onClose); const handleChangeValue = (key: keyof TripPutData) => (e: ChangeEvent) => { updateInputValue(key, e.currentTarget.value); }; - const handleSubmit = (e: FormEvent) => { - e.preventDefault(); - submitEditedInfo(); - - onClose(); - }; - return ( @@ -45,13 +45,18 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa initialCities={information.cities} updateCityInfo={updateCityInfo} /> + {isCityInputError && ( + + 방문 도시는 최소 한개 이상 선택해야 합니다 + + )} - - ⚠︎ 여행 기간을 단축하면 마지막 날짜부터 작성한 기록들이
+ + ⚠︎ 방문 기간을 단축하면 마지막 날짜부터 작성한 기록들이
삭제됩니다.
) => { +export const useTripInfoForm = (information: Omit, onClose: () => void) => { const { id: tripId, title, cities, startDate, endDate, description, imageUrl } = information; - const { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid } = useCityDateForm({ + const { cityDateInfo, updateCityInfo, updateDateInfo } = useCityDateForm({ cityIds: cities.map((city) => city.id), startDate, endDate, }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); - + const [isCityInputError, setCityInputError] = useState(false); const tripMutation = useEditTripMutation(); useEffect(() => { + validateCityInput(); + setTripInfo((prevTripInfo) => { return { ...prevTripInfo, ...cityDateInfo }; }); @@ -29,16 +30,21 @@ export const useTripInfoForm = (information: Omit) => { }); }; - const validateInfo = () => { - if (isCityDateValid && isEmptyString(tripInfo.title)) { - return false; + const validateCityInput = () => { + const cityLength = cityDateInfo.cityIds.length; + + if (cityLength > 0) { + setCityInputError(false); + return; } - return true; + setCityInputError(true); }; - const submitEditedInfo = () => { - if (!validateInfo()) { + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + + if (isCityInputError) { return; } @@ -48,7 +54,16 @@ export const useTripInfoForm = (information: Omit) => { startDate: tripInfo.startDate!, endDate: tripInfo.endDate!, }); + + onClose(); }; - return { tripInfo, updateInputValue, updateCityInfo, updateDateInfo, submitEditedInfo }; + return { + tripInfo, + isCityInputError, + updateInputValue, + updateCityInfo, + updateDateInfo, + handleSubmit, + }; }; diff --git a/frontend/src/mocks/handlers/trips.ts b/frontend/src/mocks/handlers/trips.ts index 274a78ce4..15f091b62 100644 --- a/frontend/src/mocks/handlers/trips.ts +++ b/frontend/src/mocks/handlers/trips.ts @@ -27,7 +27,8 @@ export const tripsHandlers = [ rest.get(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { return res(ctx.status(200), ctx.json(trip)); }), - rest.post(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { + + rest.put(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { return res(ctx.status(202)); }), ]; From a2822962ccd1c5354c91994ebfaa68c0e5e103d8 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Tue, 25 Jul 2023 16:42:41 +0900 Subject: [PATCH 11/17] =?UTF-8?q?refactor:=EC=BD=94=EB=93=9C=20=EC=BB=A8?= =?UTF-8?q?=EB=B0=B4=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=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 --- frontend/src/api/trip/putTrip.ts | 6 ++--- ...pForm.style.ts => TripCreateForm.style.ts} | 0 .../{NewTripForm.tsx => TripCreateForm.tsx} | 14 +++++------ .../TripInfoEditModal/TripInfoEditModal.tsx | 24 +++++++------------ .../src/hooks/api/useAddTripItemMutation.ts | 2 +- ...ipMutation.ts => useCreateTripMutation.ts} | 8 +++---- ...TripMutation.ts => useTripEditMutation.ts} | 5 ++-- frontend/src/hooks/trip/useTripInfoForm.ts | 19 +++++++-------- frontend/src/mocks/handlers/trips.ts | 2 +- .../pages/TripCreatePage/TripCreatePage.tsx | 5 ++-- frontend/src/types/trip.ts | 2 +- 11 files changed, 38 insertions(+), 49 deletions(-) rename frontend/src/components/newTrip/NewTripForm/{NewTripForm.style.ts => TripCreateForm.style.ts} (100%) rename frontend/src/components/newTrip/NewTripForm/{NewTripForm.tsx => TripCreateForm.tsx} (72%) rename frontend/src/hooks/api/{useNewTripMutation.ts => useCreateTripMutation.ts} (66%) rename frontend/src/hooks/api/{useEditTripMutation.ts => useTripEditMutation.ts} (83%) diff --git a/frontend/src/api/trip/putTrip.ts b/frontend/src/api/trip/putTrip.ts index 1d867a456..5381f81f6 100644 --- a/frontend/src/api/trip/putTrip.ts +++ b/frontend/src/api/trip/putTrip.ts @@ -1,16 +1,16 @@ import { END_POINTS } from '@constants/api'; -import { TripPutData } from '@type/trip'; +import type { TripFormData } from '@type/trip'; import { axiosInstance } from '@api/axiosInstance'; -export interface PutTripParams extends TripPutData { +export interface PutTripParams extends TripFormData { tripId: number; } export const putTrip = () => ({ tripId, ...tripInformation }: PutTripParams) => { - return axiosInstance.put(END_POINTS.TRIP(tripId), { + return axiosInstance.put(END_POINTS.TRIP(tripId), { ...tripInformation, }); }; diff --git a/frontend/src/components/newTrip/NewTripForm/NewTripForm.style.ts b/frontend/src/components/newTrip/NewTripForm/TripCreateForm.style.ts similarity index 100% rename from frontend/src/components/newTrip/NewTripForm/NewTripForm.style.ts rename to frontend/src/components/newTrip/NewTripForm/TripCreateForm.style.ts diff --git a/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx b/frontend/src/components/newTrip/NewTripForm/TripCreateForm.tsx similarity index 72% rename from frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx rename to frontend/src/components/newTrip/NewTripForm/TripCreateForm.tsx index 31fa2afd1..332f7c854 100644 --- a/frontend/src/components/newTrip/NewTripForm/NewTripForm.tsx +++ b/frontend/src/components/newTrip/NewTripForm/TripCreateForm.tsx @@ -1,24 +1,24 @@ -import { useCityDateForm } from '@/hooks/common/useCityDateForm'; +import { formStyling } from '@/components/newTrip/NewTripForm/TripCreateForm.style'; import { PATH } from '@constants/path'; import { Button } from 'hang-log-design-system'; import type { FormEvent } from 'react'; import { useNavigate } from 'react-router-dom'; -import { useNewTripMutation } from '@hooks/api/useNewTripMutation'; +import { useCreateTripMutation } from '@hooks/api/useCreateTripMutation'; +import { useCityDateForm } from '@hooks/common/useCityDateForm'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; -import { formStyling } from '@components/newTrip/NewTripForm/NewTripForm.style'; -const TripAddForm = () => { +const TripCreateForm = () => { const { cityDateInfo, updateCityInfo, updateDateInfo, isCityDateValid } = useCityDateForm(); - const newTripMutation = useNewTripMutation(); + const createTripMutation = useCreateTripMutation(); const navigate = useNavigate(); const handleSubmit = (e: FormEvent) => { e.preventDefault(); - newTripMutation.mutate(cityDateInfo, { + createTripMutation.mutate(cityDateInfo, { onSuccess: goToTripEditPageWithId, }); }; @@ -39,4 +39,4 @@ const TripAddForm = () => { ); }; -export default TripAddForm; +export default TripCreateForm; diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index 1f855e583..2859eb709 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -1,14 +1,8 @@ -import { useTripInfoForm } from '@/hooks/trip/useTripInfoForm'; -import type { TripData, TripPutData } from '@type/trip'; -import { - Button, - Flex, - ImageUploadInput, - Input, - Modal, - SupportingText, -} from 'hang-log-design-system'; -import type { ChangeEvent, FormEvent } from 'react'; +import type { TripData, TripFormData } from '@type/trip'; +import { Button, ImageUploadInput, Input, Modal, SupportingText } from 'hang-log-design-system'; +import type { ChangeEvent } from 'react'; + +import { useTripInfoForm } from '@hooks/trip/useTripInfoForm'; import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar'; import DateInput from '@components/common/DateInput/DateInput'; @@ -33,7 +27,7 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa handleSubmit, } = useTripInfoForm(information, onClose); - const handleChangeValue = (key: keyof TripPutData) => (e: ChangeEvent) => { + const handleChangeValue = (key: keyof TripFormData) => (e: ChangeEvent) => { updateInputValue(key, e.currentTarget.value); }; @@ -73,13 +67,11 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa {}} /> - +
); diff --git a/frontend/src/hooks/api/useAddTripItemMutation.ts b/frontend/src/hooks/api/useAddTripItemMutation.ts index d6f7987fc..6f88aa4c9 100644 --- a/frontend/src/hooks/api/useAddTripItemMutation.ts +++ b/frontend/src/hooks/api/useAddTripItemMutation.ts @@ -10,7 +10,7 @@ export const useAddTripItemMutation = () => { // 순서 변경 성공 시 Trip 정보 재요청 queryClient.invalidateQueries({ queryKey: ['trip'] }); }, - onError: (err, _, context) => { + onError: () => { alert('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); }, }); diff --git a/frontend/src/hooks/api/useNewTripMutation.ts b/frontend/src/hooks/api/useCreateTripMutation.ts similarity index 66% rename from frontend/src/hooks/api/useNewTripMutation.ts rename to frontend/src/hooks/api/useCreateTripMutation.ts index 5a4e758d8..077d908e0 100644 --- a/frontend/src/hooks/api/useNewTripMutation.ts +++ b/frontend/src/hooks/api/useCreateTripMutation.ts @@ -1,11 +1,11 @@ -import { postNewTrip } from '@/api/trips/postNewTrip'; import { NETWORK } from '@constants/api'; import { useMutation } from '@tanstack/react-query'; -export const useNewTripMutation = () => { +import { postNewTrip } from '@api/trips/postNewTrip'; + +export const useCreateTripMutation = () => { const newTripMutation = useMutation(postNewTrip(), { - onError: (err, _, context) => { - //toast 띄우기 + onError: () => { alert('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); }, retry: NETWORK.RETRY_COUNT, diff --git a/frontend/src/hooks/api/useEditTripMutation.ts b/frontend/src/hooks/api/useTripEditMutation.ts similarity index 83% rename from frontend/src/hooks/api/useEditTripMutation.ts rename to frontend/src/hooks/api/useTripEditMutation.ts index 9ea118b1c..5bd275029 100644 --- a/frontend/src/hooks/api/useEditTripMutation.ts +++ b/frontend/src/hooks/api/useTripEditMutation.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { putTrip } from '@api/trip/putTrip'; -export const useEditTripMutation = () => { +export const useTripEditMutation = () => { const queryClient = useQueryClient(); const tripMutation = useMutation(putTrip(), { @@ -10,7 +10,8 @@ export const useEditTripMutation = () => { // 여행 정보 수정 성공시 Trip 정보 재요청 queryClient.invalidateQueries({ queryKey: ['trip'] }); }, - onError: (err, _, context) => { + onError: () => { + //TODO: toast 띄우기 alert('오류가 발생했습니다. 잠시 후 다시 시도해주세요.'); }, }); diff --git a/frontend/src/hooks/trip/useTripInfoForm.ts b/frontend/src/hooks/trip/useTripInfoForm.ts index a3c6d474f..3957e3747 100644 --- a/frontend/src/hooks/trip/useTripInfoForm.ts +++ b/frontend/src/hooks/trip/useTripInfoForm.ts @@ -1,8 +1,8 @@ -import type { TripData, TripPutData } from '@type/trip'; +import { createTripMutation } from '@/hooks/api/useTripEditMutation'; +import type { TripData, TripFormData } from '@type/trip'; import { useEffect, useState } from 'react'; import type { FormEvent } from 'react'; -import { useEditTripMutation } from '@hooks/api/useEditTripMutation'; import { useCityDateForm } from '@hooks/common/useCityDateForm'; export const useTripInfoForm = (information: Omit, onClose: () => void) => { @@ -14,7 +14,7 @@ export const useTripInfoForm = (information: Omit, onClose: }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); const [isCityInputError, setCityInputError] = useState(false); - const tripMutation = useEditTripMutation(); + const tripEditMutation = createTripMutation(); useEffect(() => { validateCityInput(); @@ -24,17 +24,16 @@ export const useTripInfoForm = (information: Omit, onClose: }); }, [cityDateInfo]); - const updateInputValue = (key: K, value: TripPutData[K]) => { + const updateInputValue = (key: K, value: TripFormData[K]) => { setTripInfo((prevTripInfo) => { return { ...prevTripInfo, [key]: value }; }); }; const validateCityInput = () => { - const cityLength = cityDateInfo.cityIds.length; - - if (cityLength > 0) { + if (cityDateInfo.cityIds.length > 0) { setCityInputError(false); + return; } @@ -44,11 +43,9 @@ export const useTripInfoForm = (information: Omit, onClose: const handleSubmit = (e: FormEvent) => { e.preventDefault(); - if (isCityInputError) { - return; - } + if (isCityInputError) return; - tripMutation.mutate({ + tripEditMutation.mutate({ tripId, ...tripInfo, startDate: tripInfo.startDate!, diff --git a/frontend/src/mocks/handlers/trips.ts b/frontend/src/mocks/handlers/trips.ts index 15f091b62..0a0edf532 100644 --- a/frontend/src/mocks/handlers/trips.ts +++ b/frontend/src/mocks/handlers/trips.ts @@ -29,6 +29,6 @@ export const tripsHandlers = [ }), rest.put(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { - return res(ctx.status(202)); + return res(ctx.status(204)); }), ]; diff --git a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx index d05eb1536..8f5d1c53a 100644 --- a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx +++ b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx @@ -1,3 +1,4 @@ +import TripCreateForm from '@/components/newTrip/NewTripForm/TripCreateForm'; import CreatePageImage from '@assets/svg/create-page-image.svg'; import { Box, Flex, Heading } from 'hang-log-design-system'; @@ -9,8 +10,6 @@ import { containerStyling, } from '@pages/TripCreatePage/TripCreatePage.style'; -import TripAddForm from '@components/newTrip/NewTripForm/NewTripForm'; - const TripCreatePage = () => { useCityQuery(); @@ -18,7 +17,7 @@ const TripCreatePage = () => { 여행을 기록해 보세요 - + diff --git a/frontend/src/types/trip.ts b/frontend/src/types/trip.ts index ae83015d5..b53563aa3 100644 --- a/frontend/src/types/trip.ts +++ b/frontend/src/types/trip.ts @@ -12,6 +12,6 @@ export interface TripData { dayLogs: DayLogData[]; } -export interface TripPutData extends Omit { +export interface TripFormData extends Omit { cityIds: number[]; } From 15803f4b13f7314872df1e78fd93433a907549f1 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Tue, 25 Jul 2023 17:36:49 +0900 Subject: [PATCH 12/17] =?UTF-8?q?refactor:=EC=97=AC=ED=96=89=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=88=98=EC=A0=95=EB=AA=A8=EB=8B=AC=20css=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/svg/warning-icon.svg | 3 + .../common/CitySearchBar/CitySearchBar.tsx | 24 +++--- .../TripInfoEditModal.style.ts | 9 --- .../TripInfoEditModal/TripInfoEditModal.tsx | 77 +++++++++++-------- frontend/src/hooks/common/useCityDateForm.ts | 10 +-- frontend/src/hooks/trip/useTripInfoForm.ts | 7 +- 6 files changed, 67 insertions(+), 63 deletions(-) create mode 100644 frontend/src/assets/svg/warning-icon.svg diff --git a/frontend/src/assets/svg/warning-icon.svg b/frontend/src/assets/svg/warning-icon.svg new file mode 100644 index 000000000..8ec1be71a --- /dev/null +++ b/frontend/src/assets/svg/warning-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx index 463975694..716f4c2fd 100644 --- a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx +++ b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx @@ -73,19 +73,6 @@ const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: City } }; - const CityTags = () => { - return cityTags.map((cityTag) => ( - - {cityTag.name} - - - )); - }; - return (
@@ -93,7 +80,16 @@ const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: City
- + {cityTags.map((cityTag) => ( + + {cityTag.name} + + + ))} { isOpen: boolean; @@ -25,41 +30,49 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa updateCityInfo, updateDateInfo, handleSubmit, - } = useTripInfoForm(information, onClose); + } = useTripEditForm(information, onClose); - const handleChangeValue = (key: keyof TripFormData) => (e: ChangeEvent) => { - updateInputValue(key, e.currentTarget.value); - }; + const handleChangeValue = + (key: keyof TripFormData) => (e: ChangeEvent) => { + updateInputValue(key, e.currentTarget.value); + }; return ( -
- - {isCityInputError && ( - - 방문 도시는 최소 한개 이상 선택해야 합니다 - - )} - - - ⚠︎ 방문 기간을 단축하면 마지막 날짜부터 작성한 기록들이
- 삭제됩니다. -
+ + + + {isCityInputError && ( + + 방문 도시는 최소 한개 이상 선택해야 합니다 + + )} + + + + + + + 방문 기간을 단축하면 마지막 날짜부터 작성한 기록들이
+ 삭제됩니다. +
+
+
- { validateInputs(); }, [cityDateInfo]); - const updateCityInfo = (cities: CityData[]) => { + const updateCityInfo = useCallback((cities: CityData[]) => { const cityIds = cities.map((city) => city.id); setCityDateInfo((prev) => ({ ...prev, cityIds })); - }; + }, []); - const updateDateInfo = (dateRange: DateRangeData) => { + const updateDateInfo = useCallback((dateRange: DateRangeData): void => { const { start: startDate, end: endDate } = dateRange; setCityDateInfo((prev) => ({ ...prev, startDate, endDate })); - }; + }, []); const validateInputs = () => { const { startDate, endDate, cityIds } = cityDateInfo; diff --git a/frontend/src/hooks/trip/useTripInfoForm.ts b/frontend/src/hooks/trip/useTripInfoForm.ts index 3957e3747..b378d2ce7 100644 --- a/frontend/src/hooks/trip/useTripInfoForm.ts +++ b/frontend/src/hooks/trip/useTripInfoForm.ts @@ -1,11 +1,12 @@ -import { createTripMutation } from '@/hooks/api/useTripEditMutation'; +import { isEmptyString } from '@/utils/validator'; import type { TripData, TripFormData } from '@type/trip'; import { useEffect, useState } from 'react'; import type { FormEvent } from 'react'; +import { useTripEditMutation } from '@hooks/api/useTripEditMutation'; import { useCityDateForm } from '@hooks/common/useCityDateForm'; -export const useTripInfoForm = (information: Omit, onClose: () => void) => { +export const useTripEditForm = (information: Omit, onClose: () => void) => { const { id: tripId, title, cities, startDate, endDate, description, imageUrl } = information; const { cityDateInfo, updateCityInfo, updateDateInfo } = useCityDateForm({ cityIds: cities.map((city) => city.id), @@ -14,7 +15,7 @@ export const useTripInfoForm = (information: Omit, onClose: }); const [tripInfo, setTripInfo] = useState({ title, description, imageUrl, ...cityDateInfo }); const [isCityInputError, setCityInputError] = useState(false); - const tripEditMutation = createTripMutation(); + const tripEditMutation = useTripEditMutation(); useEffect(() => { validateCityInput(); From 54fa0bb7468ca079a9faf06bcceb098191f25566 Mon Sep 17 00:00:00 2001 From: Dahye <06robin11@gmail.com> Date: Wed, 26 Jul 2023 13:43:53 +0900 Subject: [PATCH 13/17] =?UTF-8?q?refactor:=EC=97=AC=ED=96=89=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=8F=BC=20=EC=A0=9C=EC=B6=9C=ED=95=A0=20=EB=95=8C?= =?UTF-8?q?=20validate=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/CitySearchBar/CitySearchBar.tsx | 2 +- .../TripInformation/TripInformation.tsx | 4 +- .../TripInfoEditModal/TripInfoEditModal.tsx | 21 +++++--- frontend/src/hooks/trip/useTripInfoForm.ts | 54 +++++++++++++------ 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx index 783af588b..ab7b91b29 100644 --- a/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx +++ b/frontend/src/components/common/CitySearchBar/CitySearchBar.tsx @@ -1,4 +1,3 @@ -import useDebounce from '@/hooks/common/useDebounce'; import CloseIcon from '@assets/svg/close-icon.svg'; import SearchPinIcon from '@assets/svg/search-pin-icon.svg'; import type { CityData } from '@type/city'; @@ -7,6 +6,7 @@ import type { FormEvent, KeyboardEvent } from 'react'; import { useEffect, useRef, useState } from 'react'; import { useCityTags } from '@hooks/common/useCityTags'; +import { useDebounce } from '@hooks/common/useDebounce'; import { badgeStyling, diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index 69d6aee66..fd573b1b2 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -52,7 +52,9 @@ const TripInformation = ({ ...information }: TripInformationProps) => { - + {isEditModalOpen && ( + + )} ); }; diff --git a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx index e56a62215..3d5cdcc83 100644 --- a/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx +++ b/frontend/src/components/trip/TripInfoEditModal/TripInfoEditModal.tsx @@ -26,6 +26,7 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa const { tripInfo, isCityInputError, + isTitleError, updateInputValue, updateCityInfo, updateDateInfo, @@ -66,12 +67,18 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa - + + + {isTitleError && ( + 여행 제목을 입력하세요 + )} +