From d9622a4a0aa49be5312f5cb8370ef8718de52467 Mon Sep 17 00:00:00 2001 From: HBSPS Date: Tue, 1 Oct 2024 17:12:10 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EB=8B=B4=EC=9D=80=20SPOT=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20API=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useDeleteSelectedSpotMutation.ts | 25 ++++++++++++ .../apis/queries/spot/useSpotDetailQuery.ts | 1 + .../src/components/detail/AroundCard.tsx | 13 +++++++ .../pages/TripPlanner/TripPlannerDetail.tsx | 39 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 packages/react-native/src/apis/mutations/useDeleteSelectedSpotMutation.ts diff --git a/packages/react-native/src/apis/mutations/useDeleteSelectedSpotMutation.ts b/packages/react-native/src/apis/mutations/useDeleteSelectedSpotMutation.ts new file mode 100644 index 00000000..c01dd397 --- /dev/null +++ b/packages/react-native/src/apis/mutations/useDeleteSelectedSpotMutation.ts @@ -0,0 +1,25 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import useAuthAxios from '../useAuthAxios'; +import QUERY_KEYS from '@/constants/QUERY_KEYS'; + +export default function useDeleteSelectedSpotMutation( + tripId: number, + options?: { onSuccess?: () => void }, +) { + const authAxios = useAuthAxios(); + const queryClient = useQueryClient(); + + const deleteSelectedSpots = async (id: number) => { + await authAxios.delete(`/api/schedule/selected-spot/${id}`); + }; + + return useMutation({ + mutationFn: deleteSelectedSpots, + onSuccess: async () => { + await queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.TRIP_PLAN_DETAIL, tripId], + }); + if (options?.onSuccess) options.onSuccess(); + }, + }); +} diff --git a/packages/react-native/src/apis/queries/spot/useSpotDetailQuery.ts b/packages/react-native/src/apis/queries/spot/useSpotDetailQuery.ts index d3f61da6..df47d534 100644 --- a/packages/react-native/src/apis/queries/spot/useSpotDetailQuery.ts +++ b/packages/react-native/src/apis/queries/spot/useSpotDetailQuery.ts @@ -9,6 +9,7 @@ interface UseSpotDetailQueryParams { } export interface SpotResponse { + id: number; contentId: number; title: string; image: string; diff --git a/packages/react-native/src/components/detail/AroundCard.tsx b/packages/react-native/src/components/detail/AroundCard.tsx index d06410fc..bcc0bf9d 100644 --- a/packages/react-native/src/components/detail/AroundCard.tsx +++ b/packages/react-native/src/components/detail/AroundCard.tsx @@ -1,19 +1,24 @@ import { ImageBackground, TouchableOpacity, View } from 'react-native'; import { Font, CheckBox } from 'design-system'; import { SpotResponse } from '@/apis/queries/spot/useSpotDetailQuery'; +import DotMenuIcon from '@/assets/DotMenuIcon'; interface AroundCardProps { data: SpotResponse; + withMenuIcon?: boolean; onCardClick: (spot: SpotResponse) => void; + onMenuClick?: () => void; selectedSpots?: SpotResponse[]; selectionMode?: boolean; } export default function AroundCard({ data, + withMenuIcon, selectedSpots, selectionMode, onCardClick, + onMenuClick, }: AroundCardProps) { const { image, title } = data; @@ -43,6 +48,14 @@ export default function AroundCard({ {title} + {withMenuIcon && ( + + + + )} ); diff --git a/packages/react-native/src/pages/TripPlanner/TripPlannerDetail.tsx b/packages/react-native/src/pages/TripPlanner/TripPlannerDetail.tsx index fd63fcac..bcef057c 100644 --- a/packages/react-native/src/pages/TripPlanner/TripPlannerDetail.tsx +++ b/packages/react-native/src/pages/TripPlanner/TripPlannerDetail.tsx @@ -12,13 +12,26 @@ import AroundCard from '@/components/detail/AroundCard'; import SpotDetailBottomSheet from '@/components/common/SpotDetailBottomSheet'; import useTripPlanMySpotQuery from '@/apis/queries/tripPlan/useTripPlanMySpotQuery'; import Spacing from '@/components/common/Spacing'; +import useDeleteSelectedSpotMutation from '@/apis/mutations/useDeleteSelectedSpotMutation'; +import BottomSheet from '@/components/common/BottomSheet'; +import { SpotResponse } from '@/apis/queries/spot/useSpotDetailQuery'; export default withSuspense(function TripPlannerDetail() { const route = useRoute>(); const { tripId, region, city, startDate, endDate } = route.params; const { data } = useTripPlanMySpotQuery({ id: tripId }); const [selectedSpot, setSelectedSpot] = useState(); + const [targetSpot, setTargetSpot] = useState(); const navigation = useNavigation>(); + const { mutate: deleteSelectedSpots } = useDeleteSelectedSpotMutation( + tripId, + { onSuccess: () => setTargetSpot(undefined) }, + ); + + const deleteSpot = () => { + if (!targetSpot) return; + deleteSelectedSpots(targetSpot.id); + }; return ( @@ -66,6 +79,8 @@ export default withSuspense(function TripPlannerDetail() { renderItem={({ item }) => ( setTargetSpot(item)} onCardClick={() => setSelectedSpot(item.contentId)} /> )} @@ -80,6 +95,8 @@ export default withSuspense(function TripPlannerDetail() { renderItem={({ item }) => ( setTargetSpot(item)} onCardClick={() => setSelectedSpot(item.contentId)} /> )} @@ -94,6 +111,8 @@ export default withSuspense(function TripPlannerDetail() { renderItem={({ item }) => ( setTargetSpot(item)} onCardClick={() => setSelectedSpot(item.contentId)} /> )} @@ -106,6 +125,26 @@ export default withSuspense(function TripPlannerDetail() { selectedDetailSpotId={selectedSpot} onClose={() => setSelectedSpot(undefined)} /> + setTargetSpot(undefined)} + > + + + {targetSpot?.title} + + + + + 삭제 + + + + ); }); From 0c29223e27b355cc5079930a76824589cf87b5bb Mon Sep 17 00:00:00 2001 From: HBSPS Date: Tue, 1 Oct 2024 17:16:00 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=EB=B1=83=EC=A7=80=20=EC=BF=BC?= =?UTF-8?q?=EB=A6=AC=20=EB=AC=B4=ED=9A=A8=ED=99=94=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/react-native/src/apis/mutations/useRecordMutation.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-native/src/apis/mutations/useRecordMutation.ts b/packages/react-native/src/apis/mutations/useRecordMutation.ts index 5ff46274..3b576b26 100644 --- a/packages/react-native/src/apis/mutations/useRecordMutation.ts +++ b/packages/react-native/src/apis/mutations/useRecordMutation.ts @@ -59,6 +59,9 @@ export default function useRecordMutation({ queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.RECORDS, location], }); + queryClient.invalidateQueries({ + queryKey: [QUERY_KEYS.MY_BADGES], + }); }; const { mutateAsync: postMutate, isPending: isPostPending } = useMutation({