From 17dcb9ae7c983fdfe6bdd8d69355b308c5bd45a0 Mon Sep 17 00:00:00 2001 From: mayrang Date: Thu, 17 Apr 2025 15:49:28 +0900 Subject: [PATCH 01/69] =?UTF-8?q?Feat:=20top=20filter=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/userProfile/[userNumber]/log/page.tsx | 5 ++ src/components/travellog/AriaFilter.tsx | 63 +++++++++++++++++++ src/page/TravelLog/TravelLog.tsx | 34 ++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/app/userProfile/[userNumber]/log/page.tsx create mode 100644 src/components/travellog/AriaFilter.tsx create mode 100644 src/page/TravelLog/TravelLog.tsx diff --git a/src/app/userProfile/[userNumber]/log/page.tsx b/src/app/userProfile/[userNumber]/log/page.tsx new file mode 100644 index 00000000..53ad35b8 --- /dev/null +++ b/src/app/userProfile/[userNumber]/log/page.tsx @@ -0,0 +1,5 @@ +import TravelLog from "@/page/TravelLog/TravelLog"; + +export default function TravelLogPage() { + return ; +} diff --git a/src/components/travellog/AriaFilter.tsx b/src/components/travellog/AriaFilter.tsx new file mode 100644 index 00000000..650d0fc2 --- /dev/null +++ b/src/components/travellog/AriaFilter.tsx @@ -0,0 +1,63 @@ +"use client"; + +import styled from "@emotion/styled"; +import { useSearchParams } from "next/navigation"; +import SearchFilterTag from "../designSystem/tag/SearchFilterTag"; +import { palette } from "@/styles/palette"; + +const FILTER_LIST = [ + { value: "world", title: "세계" }, + { value: "local", title: "국내" }, +] as const; + +export default function AriaFilter() { + const searchParams = useSearchParams(); + const filter = searchParams.get("filter") ?? "world"; + + const clickTag = (value: "world" | "local") => () => { + const newSearchParams = new URLSearchParams(searchParams?.toString()); + + newSearchParams.set("filter", value); + }; + + const isActive = (value: "world" | "local") => { + return value === filter ? true : false; + }; + + return ( + + {FILTER_LIST.map(({ title, value }, idx) => ( + + ))} + + ); +} + +const Container = styled.div` + display: flex; + align-items: center; + padding: 0 24px; + margin-top: 8px; + margin-bottom: 27px; + gap: 12px; +`; diff --git a/src/page/TravelLog/TravelLog.tsx b/src/page/TravelLog/TravelLog.tsx new file mode 100644 index 00000000..b2845b17 --- /dev/null +++ b/src/page/TravelLog/TravelLog.tsx @@ -0,0 +1,34 @@ +"use client"; +import AriaFilter from "@/components/travellog/AriaFilter"; +import React from "react"; + +const DUMMY_DATA = [ + { country: "대한민국", recent: "2025-04-13" }, + { country: "인도", recent: "2024-06-20" }, + { country: "아르헨티나", recent: "2024-12-31" }, + { country: "노르웨이", recent: "2024-07-21" }, + { country: "러시아", recent: "2024-09-17" }, + { country: "독일", recent: "2025-03-12" }, + { country: "브라질", recent: "2024-11-22" }, + { country: "멕시코", recent: "2024-06-14" }, + { country: "스웨덴", recent: "2025-04-14" }, + { country: "스페인", recent: "2025-01-31" }, + { country: "캐나다", recent: "2024-11-04" }, + { country: "프랑스", recent: "2024-12-10" }, + { country: "호주", recent: "2024-11-17" }, + { country: "일본", recent: "2024-11-26" }, + { country: "중국", recent: "2024-07-24" }, + { country: "네덜란드", recent: "2024-08-29" }, + { country: "터키", recent: "2025-01-23" }, + { country: "남아프리카공화국", recent: "2024-11-15" }, + { country: "이탈리아", recent: "2024-07-16" }, + { country: "미국", recent: "2024-12-28" }, +]; + +export default function TravelLog() { + return ( + <> + + + ); +} From 1c4099cc459959c6855eddd8bb7d5bd90362a71f Mon Sep 17 00:00:00 2001 From: mayrang Date: Fri, 18 Apr 2025 16:11:03 +0900 Subject: [PATCH 02/69] =?UTF-8?q?Fix:=20=EB=82=98=EB=9D=BC=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 --- .../[userNumber]/visited-countries/route.ts | 67 +++++++++++++++ src/components/RegionModal.tsx | 32 +++++++- src/components/TripRegion.tsx | 33 ++++++-- src/components/map/TravelLogMap.tsx | 24 +++++- .../CreateTripDetail/CreateTripDetail.tsx | 38 +++++---- .../CreateTripDetail/RegionWrapper.tsx | 82 +++++++++++++++++-- src/page/TripDetail/TripDetail.tsx | 12 ++- src/page/TripDetail/TripEdit.tsx | 13 ++- src/store/client/createTripStore.ts | 27 +++++- src/store/client/editTripStore.ts | 11 ++- src/store/client/tripDetailStore.ts | 12 ++- 11 files changed, 302 insertions(+), 49 deletions(-) create mode 100644 src/app/api/api/users/[userNumber]/visited-countries/route.ts diff --git a/src/app/api/api/users/[userNumber]/visited-countries/route.ts b/src/app/api/api/users/[userNumber]/visited-countries/route.ts new file mode 100644 index 00000000..fca2b57c --- /dev/null +++ b/src/app/api/api/users/[userNumber]/visited-countries/route.ts @@ -0,0 +1,67 @@ +export async function GET( + request: Request, + { params }: { params: Promise<{ userNumber: string }> } +) { + const { userNumber } = await params; + + return Response.json({ + userNumber: 3, + visitedCountriesCount: 8, + internationalLogs: { + ASIA: [ + { + countryName: "일본", + visitDates: ["2025-02-22", "2025-03-22", "2025-04-09"], + }, + { + countryName: "태국", + visitDates: ["2025-03-22"], + }, + { + countryName: "베트남", + visitDates: ["2024-12-15"], + }, + ], + NORTH_AMERICA: [ + { + countryName: "캐나다", + visitDates: ["2025-03-22"], + }, + { + countryName: "미국", + visitDates: ["2025-03-22"], + }, + ], + EUROPE: [ + { + countryName: "프랑스", + visitDates: ["2025-03-22"], + }, + { + countryName: "영국", + visitDates: ["2025-03-22"], + }, + ], + OCEANIA: [ + { + countryName: "호주", + visitDates: ["2024-10-10"], + }, + ], + }, + domesticLogs: [ + { + locationName: "부산", + visitDates: ["2025-04-09"], + }, + { + locationName: "경주", + visitDates: ["2025-04-09"], + }, + { + locationName: "서울", + visitDates: ["2025-03-15", "2025-04-01"], + }, + ], + }); +} diff --git a/src/components/RegionModal.tsx b/src/components/RegionModal.tsx index 83afa88f..9c42e1fa 100644 --- a/src/components/RegionModal.tsx +++ b/src/components/RegionModal.tsx @@ -9,14 +9,28 @@ import { palette } from "@/styles/palette"; interface RegionModalProps { isModalOpen: boolean; setIsModalOpen: React.Dispatch>; - addLocationName: ({ locationName, mapType }: { locationName: string; mapType: "google" | "kakao" }) => void; + addLocationName: ({ + locationName, + mapType, + countryName, + }: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }) => void; locationName: { locationName: string; mapType: "google" | "kakao"; + countryName: string; }; } -const RegionModal = ({ isModalOpen, setIsModalOpen, addLocationName, locationName }: RegionModalProps) => { +const RegionModal = ({ + isModalOpen, + setIsModalOpen, + addLocationName, + locationName, +}: RegionModalProps) => { const handleClose = () => { console.log("testing"); setIsModalOpen(false); @@ -27,7 +41,13 @@ const RegionModal = ({ isModalOpen, setIsModalOpen, addLocationName, locationNam
- + - + , document.getElementById("region-modal") as HTMLElement ); diff --git a/src/components/TripRegion.tsx b/src/components/TripRegion.tsx index beb1989f..ad7a60fe 100644 --- a/src/components/TripRegion.tsx +++ b/src/components/TripRegion.tsx @@ -16,8 +16,20 @@ const TripRegion = ({ initLocationName, isDetail = false, }: { - initLocationName: { locationName: string; mapType: "google" | "kakao" }; - addLocationName: ({ locationName, mapType }: { locationName: string; mapType: "google" | "kakao" }) => void; + initLocationName: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }; + addLocationName: ({ + locationName, + mapType, + countryName, + }: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }) => void; nextFunc: () => void; isDetail?: boolean; }) => { @@ -56,9 +68,17 @@ const TripRegion = ({ geocoder.addressSearch(keyword, (result, status) => { console.log("result", result, status); if (status === window.kakao.maps.services.Status.OK) { - addLocationName({ locationName: keyword, mapType: "kakao" }); + addLocationName({ + locationName: keyword, + mapType: "kakao", + countryName: "한국", + }); } else { - addLocationName({ locationName: keyword, mapType: "google" }); + addLocationName({ + locationName: keyword, + mapType: "google", + countryName: "", + }); } }); setSubmit(false); @@ -104,7 +124,10 @@ const TripRegion = ({ {showRelationList && ( <> - + )} diff --git a/src/components/map/TravelLogMap.tsx b/src/components/map/TravelLogMap.tsx index b3fbe8f5..ab22e441 100644 --- a/src/components/map/TravelLogMap.tsx +++ b/src/components/map/TravelLogMap.tsx @@ -1,5 +1,10 @@ "use client"; -import { APIProvider, Map, MapCameraChangedEvent, useMap } from "@vis.gl/react-google-maps"; +import { + APIProvider, + Map, + MapCameraChangedEvent, + useMap, +} from "@vis.gl/react-google-maps"; import React, { useEffect, useRef } from "react"; import sigoonGeoJsonData from "../../../public/geojson/korea.json"; import countryGeoJsonData from "../../../public/geojson/country.json"; @@ -15,6 +20,7 @@ const TravelLogMap = ({ highlightedRegions?: string[]; }) => { const { center, zoom } = getMapLocation(target, type); + return ( { +const TravelLog = ({ + type, + highlightedRegions = [], +}: { + type: "세계" | "국내"; + highlightedRegions?: string[]; +}) => { const map = useMap(); useEffect(() => { @@ -50,7 +62,9 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 const geoJsonLayer = new google.maps.Data({ map }); - geoJsonLayer.addGeoJson(type === "국내" ? sigoonGeoJsonData : countryGeoJsonData); + geoJsonLayer.addGeoJson( + type === "국내" ? sigoonGeoJsonData : countryGeoJsonData + ); geoJsonLayer.setStyle({ strokeColor: "#fff", @@ -59,7 +73,9 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 fillOpacity: 0, // 투명한 채우기 }); - geoJsonLayer.addGeoJson(type === "국내" ? sigoonGeoJsonData : countryGeoJsonData); + geoJsonLayer.addGeoJson( + type === "국내" ? sigoonGeoJsonData : countryGeoJsonData + ); geoJsonLayer.setStyle((feature) => { const regionName: any = diff --git a/src/page/CreateTrip/CreateTripDetail/CreateTripDetail.tsx b/src/page/CreateTrip/CreateTripDetail/CreateTripDetail.tsx index 71734535..ef2b686c 100644 --- a/src/page/CreateTrip/CreateTripDetail/CreateTripDetail.tsx +++ b/src/page/CreateTrip/CreateTripDetail/CreateTripDetail.tsx @@ -112,8 +112,12 @@ const CreateTripDetail = () => { genderType: genderType!, startDate: date?.startDate ?? "", endDate: date?.endDate ?? "", - periodType: getDateRangeCategory(date?.startDate ?? "", date?.endDate ?? ""), + periodType: getDateRangeCategory( + date?.startDate ?? "", + date?.endDate ?? "" + ), locationName: locationName.locationName, + countryName: locationName.countryName, tags, plans: newPlan, }; @@ -206,7 +210,10 @@ const CreateTripDetail = () => { /> - + { 여행 일정 {date && - getDatesArray(date?.startDate ?? "", date?.endDate ?? "").map((item, idx) => ( - handleItemToggle(idx)} - /> - ))} + getDatesArray(date?.startDate ?? "", date?.endDate ?? "").map( + (item, idx) => ( + handleItemToggle(idx)} + /> + ) + )} @@ -305,7 +314,8 @@ const BottomContainer = styled.div<{ topModalHeight: number; isMapFull: boolean; }>` - margin-top: ${(props) => `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; + margin-top: ${(props) => + `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; min-height: 100svh; transition: padding-top 0.3s ease-out; overscroll-behavior: none; diff --git a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx index e03d9386..d519a2fa 100644 --- a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx @@ -5,7 +5,12 @@ import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; import React, { useCallback, useEffect, useState } from "react"; -import { APIProvider, Map, useMap, useMapsLibrary } from "@vis.gl/react-google-maps"; +import { + APIProvider, + Map, + useMap, + useMapsLibrary, +} from "@vis.gl/react-google-maps"; import RegionModal from "@/components/RegionModal"; interface RegionInfo { @@ -13,7 +18,14 @@ interface RegionInfo { adminArea: string | null; } -const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometry, isLoad }) => { +const InnerMap = ({ + locationNameStr, + locationName, + setRegionInfo, + addInitGeometry, + addLocationName, + isLoad, +}) => { const map = useMap(); const placesLib = useMapsLibrary("places"); @@ -32,7 +44,10 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr service.findPlaceFromQuery(request, (results, status) => { if (status === google.maps.places.PlacesServiceStatus.OK && results) { console.log(results, "result"); - if (results[0].geometry?.location?.lat() && results[0].geometry?.location?.lng()) { + if ( + results[0].geometry?.location?.lat() && + results[0].geometry?.location?.lng() + ) { addInitGeometry({ lat: results[0].geometry?.location?.lat(), lng: results[0].geometry?.location?.lng(), @@ -40,17 +55,29 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr } if (results[0]) { - const parts = results[0].formatted_address?.split(",").map((part) => part.trim()); + const parts = results[0].formatted_address + ?.split(",") + .map((part) => part.trim()); setRegionInfo({ country: parts ? parts[parts.length - 1] : null, adminArea: parts ? parts[parts.length - 2] : null, }); + addLocationName({ + locationName: locationName.locationName, + mapType: "google", + countryName: parts ? parts[parts.length - 1] : "", + }); } } else { setRegionInfo({ country: locationNameStr, adminArea: locationNameStr, }); + addLocationName({ + locationName: locationName.locationName, + mapType: "google", + countryName: locationNameStr, + }); } }); }, [map, placesLib, locationNameStr, addInitGeometry, setRegionInfo]); @@ -62,7 +89,10 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr geocoder.addressSearch(locationNameStr, (result, status) => { console.log(result, "result"); - if (status === window.kakao.maps.services.Status.OK && result.length > 0) { + if ( + status === window.kakao.maps.services.Status.OK && + result.length > 0 + ) { if (result[0].x && result[0].y) { addInitGeometry({ lat: Number(result[0].y), @@ -73,6 +103,11 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr country: "한국", adminArea: result[0]?.address_name ?? locationNameStr, }); + addLocationName({ + locationName: locationName.locationName, + mapType: "kakao", + countryName: "한국", + }); } else { addInitGeometry(null); } @@ -88,11 +123,26 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr if (!isLoad) return; handleKakaoInfo(); } - }, [locationName.mapType, map, placesLib, isLoad, fetchPlaceInfo, handleKakaoInfo]); + }, [ + locationName.mapType, + map, + placesLib, + isLoad, + fetchPlaceInfo, + handleKakaoInfo, + ]); return ( void; + locationName: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }; + addLocationName: ({ + locationName, + mapType, + countryName, + }: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }) => void; addInitGeometry: (obj: { lat: number; lng: number } | null) => void; location?: string; isDetail?: boolean; @@ -147,6 +209,7 @@ const RegionWrapper = ({ locationName={locationName} setRegionInfo={setRegionInfo} addInitGeometry={addInitGeometry} + addLocationName={addLocationName} isLoad={isLoad} /> @@ -171,6 +234,7 @@ const RegionWrapper = ({ locationName={locationName} setRegionInfo={setRegionInfo} addInitGeometry={addInitGeometry} + addLocationName={addLocationName} isLoad={isLoad} /> diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index a66c1145..c1954244 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -197,9 +197,17 @@ export default function TripDetail() { const geocoder = new window.kakao.maps.services.Geocoder(); geocoder.addressSearch(location, (result, status) => { if (status === window.kakao.maps.services.Status.OK && result?.[0]) { - addLocationName({ locationName: location, mapType: "kakao" }); + addLocationName({ + locationName: location, + mapType: "kakao", + countryName: "", + }); } else { - addLocationName({ locationName: location, mapType: "google" }); + addLocationName({ + locationName: location, + mapType: "google", + countryName: "", + }); } }); }); diff --git a/src/page/TripDetail/TripEdit.tsx b/src/page/TripDetail/TripEdit.tsx index a0d1bcbe..9cc4874f 100644 --- a/src/page/TripDetail/TripEdit.tsx +++ b/src/page/TripDetail/TripEdit.tsx @@ -139,9 +139,17 @@ const TripEdit = () => { const geocoder = new window.kakao.maps.services.Geocoder(); geocoder.addressSearch(location, (result, status) => { if (status === window.kakao.maps.services.Status.OK && result?.[0]) { - addLocationName({ locationName: location, mapType: "kakao" }); + addLocationName({ + locationName: location, + mapType: "kakao", + countryName: "한국", + }); } else { - addLocationName({ locationName: location, mapType: "google" }); + addLocationName({ + locationName: location, + mapType: "google", + countryName: "", + }); } }); }); @@ -369,6 +377,7 @@ const TripEdit = () => { date?.endDate ?? "" ), locationName: locationName.locationName, + countryName: locationName.countryName, tags, planChanges: trackPlanChanges(originalPlans, plans), }; diff --git a/src/store/client/createTripStore.ts b/src/store/client/createTripStore.ts index ec7521a8..7e9abd42 100644 --- a/src/store/client/createTripStore.ts +++ b/src/store/client/createTripStore.ts @@ -6,8 +6,20 @@ import { create } from "zustand"; type Gender = "F" | "M" | ""; interface CreateTripState { - locationName: { locationName: string; mapType: "google" | "kakao" }; - addLocationName: ({ locationName, mapType }: { locationName: string; mapType: "google" | "kakao" }) => void; + locationName: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }; + addLocationName: ({ + locationName, + mapType, + countryName, + }: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }) => void; title: string; addTitle: (title: string) => void; details: string; @@ -19,7 +31,13 @@ interface CreateTripState { dueDate: string; addDueDate: (dueDate: string) => void; date: { startDate: string; endDate: string } | null; - addDate: ({ startDate, endDate }: { startDate: string; endDate: string }) => void; + addDate: ({ + startDate, + endDate, + }: { + startDate: string; + endDate: string; + }) => void; periodType: string; addPeriodType: (periodType: string) => void; tags: string[]; @@ -41,7 +59,7 @@ export const createTripStore = create((set) => ({ addTitle: (title) => { set({ title }); }, - locationName: { locationName: "", mapType: "google" }, + locationName: { locationName: "", mapType: "google", countryName: "" }, addLocationName: (locationName) => { set({ locationName }); }, @@ -94,6 +112,7 @@ export const createTripStore = create((set) => ({ set({ title: "", locationName: { + countryName: "", locationName: "", mapType: "google", }, diff --git a/src/store/client/editTripStore.ts b/src/store/client/editTripStore.ts index 5fb7491a..cb29339e 100644 --- a/src/store/client/editTripStore.ts +++ b/src/store/client/editTripStore.ts @@ -4,13 +4,19 @@ import { getCurrentFormattedDate } from "@/utils/time"; import { create } from "zustand"; interface EditTripStore { - locationName: { locationName: string; mapType: "google" | "kakao" }; + locationName: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }; addLocationName: ({ locationName, mapType, + countryName, }: { locationName: string; mapType: "google" | "kakao"; + countryName: string; }) => void; title: string; addTitle: (title: string) => void; @@ -74,7 +80,7 @@ export const editTripStore = create((set) => ({ setDataInitialized: (dataInitialized) => { set({ dataInitialized }); }, - locationName: { locationName: "", mapType: "google" }, + locationName: { locationName: "", mapType: "google", countryName: "" }, addLocationName: (locationName) => { set({ locationName }); }, @@ -131,6 +137,7 @@ export const editTripStore = create((set) => ({ set({ title: "", locationName: { + countryName: "", locationName: "", mapType: "google", }, diff --git a/src/store/client/tripDetailStore.ts b/src/store/client/tripDetailStore.ts index d74dbbf1..d5e75438 100644 --- a/src/store/client/tripDetailStore.ts +++ b/src/store/client/tripDetailStore.ts @@ -68,13 +68,19 @@ interface tripDetailState { initGeometry: { lng: number; lat: number } | null; addInitGeometry: (obj: { lat: number; lng: number } | null) => void; addCommentLength: (status: number) => void; - locationName: { locationName: string; mapType: "google" | "kakao" }; + locationName: { + locationName: string; + mapType: "google" | "kakao"; + countryName: string; + }; addLocationName: ({ locationName, mapType, + countryName, }: { locationName: string; mapType: "google" | "kakao"; + countryName: string; }) => void; resetTripDetail: () => void; @@ -85,7 +91,7 @@ export const tripDetailStore = create((set) => ({ addBookmarked: (status) => { set({ bookmarked: status }); }, - locationName: { locationName: "", mapType: "google" }, + locationName: { locationName: "", mapType: "google", countryName: "" }, addLocationName: (locationName) => { set({ locationName }); }, @@ -172,7 +178,7 @@ export const tripDetailStore = create((set) => ({ resetTripDetail: () => { set({ bookmarked: false, - locationName: { locationName: "", mapType: "google" }, + locationName: { locationName: "", mapType: "google", countryName: "" }, initGeometry: null, applySuccess: false, travelNumber: 0, From b48db7f24e4ea26b293982ef1979f1e90e74294b Mon Sep 17 00:00:00 2001 From: mayrang Date: Fri, 18 Apr 2025 16:24:47 +0900 Subject: [PATCH 03/69] =?UTF-8?q?Fix:=20route=20=EB=B2=84=EA=B7=B8=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/app/api/api/users/[userNumber]/visited-countries/route.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/api/api/users/[userNumber]/visited-countries/route.ts b/src/app/api/api/users/[userNumber]/visited-countries/route.ts index fca2b57c..6548129d 100644 --- a/src/app/api/api/users/[userNumber]/visited-countries/route.ts +++ b/src/app/api/api/users/[userNumber]/visited-countries/route.ts @@ -1,10 +1,12 @@ +import { NextResponse } from "next/server"; + export async function GET( request: Request, { params }: { params: Promise<{ userNumber: string }> } ) { const { userNumber } = await params; - return Response.json({ + return NextResponse.json({ userNumber: 3, visitedCountriesCount: 8, internationalLogs: { From 46bf2b722ca84eb2f6ef3addde1fcc7e861ced1e Mon Sep 17 00:00:00 2001 From: mayrang Date: Sat, 19 Apr 2025 15:38:58 +0900 Subject: [PATCH 04/69] =?UTF-8?q?Fix:=20=EC=97=90=EB=9F=AC=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/page/TripDetail/TripEdit.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/page/TripDetail/TripEdit.tsx b/src/page/TripDetail/TripEdit.tsx index 41c78dae..5f9a9056 100644 --- a/src/page/TripDetail/TripEdit.tsx +++ b/src/page/TripDetail/TripEdit.tsx @@ -84,7 +84,8 @@ const TripEdit = () => { if (!genderType) addGenderType(tripInfos.genderType); if (!date) addDate({ startDate: tripInfos.startDate, endDate: tripInfos.endDate }); - if (locationName.locationName === "") addLocationName({ locationName: location, mapType: "google" }); + if (locationName.locationName === "") + addLocationName({ locationName: location, mapType: "google", countryName: "" }); if (!tags) addTags(tripInfos.tags); if (!initGeometry) addInitGeometry(initInitGeometry || { lat: 37.57037778, lng: 126.9816417 }); } From c985934fe9e386c23c1a6d0c28e5be7aca8b58a6 Mon Sep 17 00:00:00 2001 From: mayrang Date: Sun, 20 Apr 2025 01:37:30 +0900 Subject: [PATCH 05/69] =?UTF-8?q?Fix:=20api=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/user.ts | 17 +++ .../[userNumber]/visited-countries/route.ts | 69 ----------- .../[userNumber]/visited-countries/route.ts | 69 +++++++++++ src/components/map/TravelLogMap.tsx | 3 +- src/components/travellog/AriaDropdown.tsx | 29 +++-- src/model/profile.ts | 20 +++ src/page/TravelLog/TravelLog.tsx | 115 ++++++------------ 7 files changed, 166 insertions(+), 156 deletions(-) delete mode 100644 src/app/api/api/users/[userNumber]/visited-countries/route.ts create mode 100644 src/app/api/users/[userNumber]/visited-countries/route.ts create mode 100644 src/model/profile.ts diff --git a/src/api/user.ts b/src/api/user.ts index f8c3a957..8355d3fb 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -3,6 +3,8 @@ import { getJWTHeader } from "@/utils/user"; import axios from "axios"; import { axiosInstance, handleApiResponse } from "."; +import RequestError from "@/context/ReqeustError"; +import { TravelLog } from "@/model/profile"; // export async function getUser(userId: number, accessToken: string) { @@ -95,3 +97,18 @@ export const getToken = async (domain: "naver" | "kakao" | "google", code: strin console.error("토큰 요청 실패:", error); } }; + +export async function getUserTravelLog(userNumber: number, accessToken: string | null) { + try { + const response = await axios.get( + `http://localhost:9999/api/users//${userNumber}/visited-countries`, + + { + ...(accessToken && { headers: getJWTHeader(accessToken) }), + } + ); + return handleApiResponse(response) as TravelLog; + } catch (err: any) { + throw new RequestError(err); + } +} diff --git a/src/app/api/api/users/[userNumber]/visited-countries/route.ts b/src/app/api/api/users/[userNumber]/visited-countries/route.ts deleted file mode 100644 index 6548129d..00000000 --- a/src/app/api/api/users/[userNumber]/visited-countries/route.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { NextResponse } from "next/server"; - -export async function GET( - request: Request, - { params }: { params: Promise<{ userNumber: string }> } -) { - const { userNumber } = await params; - - return NextResponse.json({ - userNumber: 3, - visitedCountriesCount: 8, - internationalLogs: { - ASIA: [ - { - countryName: "일본", - visitDates: ["2025-02-22", "2025-03-22", "2025-04-09"], - }, - { - countryName: "태국", - visitDates: ["2025-03-22"], - }, - { - countryName: "베트남", - visitDates: ["2024-12-15"], - }, - ], - NORTH_AMERICA: [ - { - countryName: "캐나다", - visitDates: ["2025-03-22"], - }, - { - countryName: "미국", - visitDates: ["2025-03-22"], - }, - ], - EUROPE: [ - { - countryName: "프랑스", - visitDates: ["2025-03-22"], - }, - { - countryName: "영국", - visitDates: ["2025-03-22"], - }, - ], - OCEANIA: [ - { - countryName: "호주", - visitDates: ["2024-10-10"], - }, - ], - }, - domesticLogs: [ - { - locationName: "부산", - visitDates: ["2025-04-09"], - }, - { - locationName: "경주", - visitDates: ["2025-04-09"], - }, - { - locationName: "서울", - visitDates: ["2025-03-15", "2025-04-01"], - }, - ], - }); -} diff --git a/src/app/api/users/[userNumber]/visited-countries/route.ts b/src/app/api/users/[userNumber]/visited-countries/route.ts new file mode 100644 index 00000000..af6adbef --- /dev/null +++ b/src/app/api/users/[userNumber]/visited-countries/route.ts @@ -0,0 +1,69 @@ +import { NextResponse } from "next/server"; + +export async function GET(request: Request, { params }: { params: Promise<{ userNumber: string }> }) { + const { userNumber } = await params; + + return NextResponse.json({ + resultType: "SUCCESS", + success: { + userNumber: 3, + visitedCountriesCount: 8, + internationalLogs: { + ASIA: [ + { + countryName: "일본", + visitDates: ["2025-02-22", "2025-03-22", "2025-04-09"], + }, + { + countryName: "태국", + visitDates: ["2025-03-22"], + }, + { + countryName: "베트남", + visitDates: ["2024-12-15"], + }, + ], + NORTH_AMERICA: [ + { + countryName: "캐나다", + visitDates: ["2025-03-22"], + }, + { + countryName: "미국", + visitDates: ["2025-03-22"], + }, + ], + EUROPE: [ + { + countryName: "프랑스", + visitDates: ["2025-03-22"], + }, + { + countryName: "영국", + visitDates: ["2025-03-22"], + }, + ], + OCEANIA: [ + { + countryName: "호주", + visitDates: ["2024-10-10"], + }, + ], + }, + domesticLogs: [ + { + locationName: "부산", + visitDates: ["2025-04-09"], + }, + { + locationName: "경주", + visitDates: ["2025-04-09"], + }, + { + locationName: "서울", + visitDates: ["2025-03-15", "2025-04-01"], + }, + ], + }, + }); +} diff --git a/src/components/map/TravelLogMap.tsx b/src/components/map/TravelLogMap.tsx index c812f562..08c57b8c 100644 --- a/src/components/map/TravelLogMap.tsx +++ b/src/components/map/TravelLogMap.tsx @@ -90,7 +90,7 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 strokeWeight: 1, strokeOpacity: 1, fillColor: isHighlighted ? "#3366FF" : "#FFFFFF", // 하이라이트된 지역은 파란색 - fillOpacity: isHighlighted ? 0.6 : 0, // 하이라이트된 지역만 채우기 표시 + fillOpacity: isHighlighted ? 1 : 0, // 하이라이트된 지역만 채우기 표시 }; }); }, [map]); @@ -98,6 +98,7 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 return null; }; +// 더미 함수 클릭이나 출처 표시 함수 // function createAttribution() { // const attributionLabel = document.createElement("div"); // // Define CSS styles. diff --git a/src/components/travellog/AriaDropdown.tsx b/src/components/travellog/AriaDropdown.tsx index bf92b5b8..cb42457c 100644 --- a/src/components/travellog/AriaDropdown.tsx +++ b/src/components/travellog/AriaDropdown.tsx @@ -20,14 +20,12 @@ interface AriaDropdownProps { } const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { - console.log("data", typeof data); const [showModal, setShowModal] = useState(false); const [targetData, setTargetData] = useState<{ locationName?: string; countryName?: string; visitDates: string[]; } | null>(null); - console.log("Data1", data[0]); const openModal = (data) => { setShowModal(true); @@ -51,18 +49,18 @@ const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { -
{dayjs(date).format("YY.MM.DD")}
+
{dayjs(date).format("YY.MM.DD")}
))} @@ -95,7 +93,10 @@ const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { openModal(region)}> {index + 1} {region.locationName ?? region.countryName} - {dayjs(region.visitDates[0]).format("YY.MM.DD")} + + {dayjs(region.visitDates[0]).format("YY.MM.DD")}{" "} + {region.visitDates.length > 1 && +{region.visitDates.length}} + ))} @@ -155,6 +156,18 @@ const ModalTitle = styled.div` border-bottom: 1px solid #e7e7e7; `; +const More = styled.span` + padding: 1px 4px; + border-radius: 20px; + background-color: ${palette.비강조2}; + color: white; + font-size: 12px; + line-height: 14px; + font-weight: 600; + height: 16px; + margin-left: 4px; +`; + const VisitContainer = styled.div` padding: 4px; display: flex; diff --git a/src/model/profile.ts b/src/model/profile.ts new file mode 100644 index 00000000..fc1ff379 --- /dev/null +++ b/src/model/profile.ts @@ -0,0 +1,20 @@ +type VisitLog = { + countryName: string; + visitDates: string[]; +}; + +type InternationalLogs = { + [region: string]: VisitLog[] | undefined; +}; + +type DomesticLog = { + locationName: string; + visitDates: string[]; +}; + +export type TravelLog = { + userNumber: number; + visitedCountriesCount: number; + internationalLogs: InternationalLogs; + domesticLogs: DomesticLog[]; +}; diff --git a/src/page/TravelLog/TravelLog.tsx b/src/page/TravelLog/TravelLog.tsx index eb85f304..a3fd826e 100644 --- a/src/page/TravelLog/TravelLog.tsx +++ b/src/page/TravelLog/TravelLog.tsx @@ -1,96 +1,55 @@ "use client"; +import { getUserTravelLog } from "@/api/user"; import TravelLogMap from "@/components/map/TravelLogMap"; import AllTravelCount from "@/components/travellog/AllTravelCount"; import AriaDropdown from "@/components/travellog/AriaDropdown"; import AriaFilter from "@/components/travellog/AriaFilter"; +import { authStore } from "@/store/client/authStore"; import { groupRegionData } from "@/utils/travellog/travelLog"; -import { useSearchParams } from "next/navigation"; +import { useQuery } from "@tanstack/react-query"; +import { useParams, useSearchParams } from "next/navigation"; import React, { useEffect, useState } from "react"; -const DUMMY_DATA = { - userNumber: 3, - visitedCountriesCount: 8, - internationalLogs: { - ASIA: [ - { - countryName: "일본", - visitDates: ["2025-02-22", "2025-03-22", "2025-04-09"], - }, - { - countryName: "태국", - visitDates: ["2025-03-22"], - }, - { - countryName: "베트남", - visitDates: ["2024-12-15"], - }, - ], - NORTH_AMERICA: [ - { - countryName: "캐나다", - visitDates: ["2025-03-22"], - }, - { - countryName: "미국", - visitDates: ["2025-03-22"], - }, - ], - EUROPE: [ - { - countryName: "프랑스", - visitDates: ["2025-03-22"], - }, - { - countryName: "영국", - visitDates: ["2025-03-22"], - }, - ], - OCEANIA: [ - { - countryName: "호주", - visitDates: ["2024-10-10"], - }, - ], - }, - domesticLogs: [ - { - locationName: "부산", - visitDates: ["2025-04-09"], - }, - { - locationName: "경주", - visitDates: ["2025-04-09"], - }, - { - locationName: "서울", - visitDates: ["2025-03-15", "2025-04-01"], - }, - ], -}; export default function TravelLog() { const searchParams = useSearchParams(); const filter = (searchParams.get("filter") ?? "세계") as "국내" | "세계"; + const { userNumber } = useParams(); + const { accessToken, isGuestUser } = authStore(); console.log(filter); - const data = DUMMY_DATA; - const logs: any = filter === "세계" ? data.internationalLogs : groupRegionData(data.domesticLogs, "국내"); + const { data, isLoading, isError } = useQuery({ + queryKey: ["userTravelLog", userNumber], + queryFn: () => getUserTravelLog(Number(userNumber)!, accessToken), + enabled: !!userNumber && (isGuestUser || !!accessToken), + }); + console.log("data", data); + const logs: any = filter === "세계" ? data?.internationalLogs : groupRegionData(data?.domesticLogs, "국내"); const [target, setTarget] = useState(null); - console.log("target", target); + useEffect(() => { - setTarget([Object.keys(logs)[0]]); + if (logs) { + setTarget([Object.keys(logs)[0]]); + } }, [JSON.stringify(logs)]); - console.log(logs, Object.values(logs)); + + if (isError) { + return null; + } return ( -
- - { - return item.map((item) => item.countryName ?? item.locationName); - })} - type={filter} - /> - {data.visitedCountriesCount > 0 && } - {logs && } -
+ !isLoading && ( +
+ + {logs && ( + { + return item.map((item) => item.countryName ?? item.locationName); + })} + type={filter} + /> + )} + {data && Boolean(data?.visitedCountriesCount > 0) && } + {logs && } +
+ ) ); } From f9361d8851294cd42ca2bbf9644e1d4d49183016 Mon Sep 17 00:00:00 2001 From: mayrang Date: Sun, 20 Apr 2025 01:53:41 +0900 Subject: [PATCH 06/69] =?UTF-8?q?Fix:=20build=EC=97=90=EB=9F=AC=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/page/TravelLog/TravelLog.tsx | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/page/TravelLog/TravelLog.tsx b/src/page/TravelLog/TravelLog.tsx index a3fd826e..07824f3e 100644 --- a/src/page/TravelLog/TravelLog.tsx +++ b/src/page/TravelLog/TravelLog.tsx @@ -34,22 +34,22 @@ export default function TravelLog() { if (isError) { return null; } - return ( - !isLoading && ( -
- - {logs && ( - { - return item.map((item) => item.countryName ?? item.locationName); - })} - type={filter} - /> - )} - {data && Boolean(data?.visitedCountriesCount > 0) && } - {logs && } -
- ) + return !isLoading ? ( +
+ + {logs && ( + { + return item.map((item) => item.countryName ?? item.locationName); + })} + type={filter} + /> + )} + {data && Boolean(data?.visitedCountriesCount > 0) && } + {logs && } +
+ ) : ( + <> ); } From 6c434b5d1c470d6a21bedd76a58c9d431bc5f7c2 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 12:22:24 +0900 Subject: [PATCH 07/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=20-=20=ED=97=A4=EB=8D=94,=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=EC=A0=95=EB=B3=B4,=20=ED=83=AD=EB=A9=94?= =?UTF-8?q?=EB=89=B4(=EB=A7=8C=EB=93=A0=20=EC=97=AC=ED=96=89,=20=EC=B0=B8?= =?UTF-8?q?=EA=B0=80=20=EC=97=AC=ED=96=89)=20=EA=B0=81=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20-=20profileS?= =?UTF-8?q?how,=20userProfileUserId=EB=A5=BC=20=EC=A0=84=EC=97=AD=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20=EA=B0=92=EC=9C=BC=EB=A1=9C=20=EB=91=90?= =?UTF-8?q?=EC=96=B4=20z-index=EB=A1=9C=20=ED=99=94=EB=A9=B4=20=EC=9C=84?= =?UTF-8?q?=EB=A1=9C=20=EB=9C=A8=EB=8A=94=20=ED=98=95=EC=8B=9D=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=AC=ED=98=84=20-=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EB=90=98=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20isMyPage=20props=20=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=9E=AC=EC=82=AC=EC=9A=A9(UserProfileDet?= =?UTF-8?q?ail)=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84.=20-=20=ED=83=AD=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EC=A2=8C=EC=9A=B0=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84.=20>=20overflo?= =?UTF-8?q?w=20hidden=EC=9D=84=20=ED=86=B5=ED=95=B4=20translateX=20?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98=EB=8A=94=20=EB=8A=90?= =?UTF-8?q?=EB=82=8C=EC=9D=84=20=EC=A3=BC=EB=8F=84=EB=A1=9D=20=ED=96=88?= =?UTF-8?q?=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileDetail.tsx | 292 +++++++++++++++++ .../userProfile/UserProfileOverlay.tsx | 89 ++++++ .../userProfile/UserProfileOverlayHeader.tsx | 103 ++++++ .../userProfile/UserTravelTabMenu.tsx | 297 ++++++++++++++++++ 4 files changed, 781 insertions(+) create mode 100644 src/components/userProfile/UserProfileDetail.tsx create mode 100644 src/components/userProfile/UserProfileOverlay.tsx create mode 100644 src/components/userProfile/UserProfileOverlayHeader.tsx create mode 100644 src/components/userProfile/UserTravelTabMenu.tsx diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx new file mode 100644 index 00000000..eb1e8154 --- /dev/null +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -0,0 +1,292 @@ +"use client"; +import { myPageStore } from "@/store/client/myPageStore"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; +import React, { useEffect, useState } from "react"; + +import useViewTransition from "@/hooks/useViewTransition"; +import CloverIcon from "../icons/CloverIcon"; +import RoundedImage from "../designSystem/profile/RoundedImage"; +import Badge from "../designSystem/Badge"; +import { formatNumberWithComma } from "@/utils/formatNumberWithComma"; +import ProfileRightVector from "../icons/ProfileRightVector"; +import WarningIcon from "../icons/WarningIcon"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import useUserProfile from "@/hooks/userProfile/useUserProfile"; +import ArrowIcon from "../icons/ArrowIcon"; + +interface UserProfileDetailProps { + isMyPage?: boolean; +} +export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { + const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); + const { userProfileInfo, isLoadingUserProfileInfo } = useUserProfile(); + const navigateWithTransition = useViewTransition(); + const { agegroup: myAgeGroup, email: myEmail } = myPageStore(); + if (!userProfileInfo) return null; + const { name, recentReportCount, userRegDate, preferredTags, travelDistance, travelBadgeCount, visitedCountryCount } = + userProfileInfo; + + const TravelMenuList = [ + { + Icon: CloverIcon, + label: "방문한 국가", + count: visitedCountryCount, + nextLink: `/userProfile/${userProfileUserId}/log`, + }, + { + Icon: CloverIcon, + label: "여행 배지", + count: travelBadgeCount, + nextLink: `/userProfileBadge/${userProfileUserId}`, + }, + ]; + + const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; + + const moveToNextLink = (link: string) => { + navigateWithTransition(link); + setTimeout(() => { + setProfileShow(false); + }, 50); + }; + const IS_REPORTED = true; + const editMyProfileInfo = () => { + document.documentElement.style.viewTransitionName = "forward"; + navigateWithTransition("/editMyInfo"); + }; + const tempAgeGroup = "00대"; // 임시 값 + return ( + + + + + + + + + {name} + {isMyPage && } + + {isMyPage ? myEmail : userRegDate + "가입"} + + + + {cutTags.map((text: string) => ( + + ))} + {preferredTags.length > cutTags.length ? ( + + ) : null} + + + + {IS_REPORTED && ( + + + 최근 신고가 {recentReportCount}회 누적된 회원이에요 + + )} + + + 총 여행한 거리✨ + {formatNumberWithComma(travelDistance)}km + + + + {TravelMenuList.map(({ Icon, label, count, nextLink }) => ( + moveToNextLink(nextLink)}> + + + + + {label} + + + {count} + + + + + + ))} + + + ); +} +const ReportedUser = styled.div` + margin-top: 12px; + display: flex; + height: 26px; + gap: 4px; + border-radius: 20px; + padding-top: 4px; + padding-right: 12px; + padding-bottom: 4px; + padding-left: 8px; + background-color: ${palette.기본}; + color: white; + font-weight: 400; + font-size: 12px; + align-items: center; +`; +const Container = styled.div` + margin-top: 4px; +`; + +const UserInfoContainer = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +`; + +const ProfileImgContainer = styled.div` + width: 80px; + height: 80px; + border-radius: 50%; + overflow: hidden; + margin-bottom: 12px; +`; + +const ProfileImg = styled.img` + width: 100%; + height: 100%; + object-fit: cover; +`; + +const UserTextInfoContainer = styled.div` + display: flex; + flex-direction: column; + gap: 6px; +`; + +const UserNameBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +`; + +export const Name = styled.div` + font-weight: 600; + font-size: 20px; + line-height: 16px; + letter-spacing: -0.25px; + text-align: center; + color: ${palette.기본}; +`; + +export const UserInfo = styled.div` + font-weight: 400; + font-size: 12px; + line-height: 16px; + letter-spacing: -0.25px; + text-align: center; + color: ${palette.비강조2}; +`; + +export const UserTags = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 12px; +`; + +export const TravelDistanceContainer = styled.div` + margin-top: 16px; + padding: 24px; + background-color: ${palette.검색창}; + + height: 88px; + display: flex; + flex-direction: column; + gap: 8px; + border-radius: 20px; +`; + +export const Title = styled.div` + font-size: 14px; + color: #333; + margin-bottom: 4px; +`; + +export const TravelDistance = styled.div` + font-weight: 600; + font-size: 20px; + line-height: 16px; + letter-spacing: 0px; +`; + +export const TravelMenuContainer = styled.div` + display: flex; + flex-direction: column; + gap: 12px; + margin: 16px 0px; +`; +export const TravelMenu = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + padding: 9px 0px; + height: 52px; + font-weight: 400; + font-size: 16px; + cursor: pointer; +`; + +export const TitleBox = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; + +export const IconWrapper = styled.div` + width: 34; + height: 34; + border-radius: 12px; + background-color: ${palette.검색창}; + display: flex; + justify-content: center; + align-items: center; + padding: 8px; +`; + +export const Subtitle = styled.div` + color: ${palette.기본}; +`; + +export const NavigateBox = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; +export const VectorBox = styled.div` + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; +`; +export const CountryCount = styled.div` + color: ${palette.비강조}; +`; diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx new file mode 100644 index 00000000..9b8ff6ae --- /dev/null +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -0,0 +1,89 @@ +"use client"; +import { myPageStore } from "@/store/client/myPageStore"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; +import React, { useEffect, useRef, useState } from "react"; + +import useViewTransition from "@/hooks/useViewTransition"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import { keyframes } from "@emotion/react"; +import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; +import UserProfileDetail from "./UserProfileDetail"; +import UserTravelTabMenu from "./UserTravelTabMenu"; + +export default function UserProfileOverlay() { + const { setProfileShow, profileShow } = userProfileOverlayStore(); + // const navigateWithTransition = useViewTransition() + const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); + + useEffect(() => { + if (isClickedCloseBtn) { + setTimeout(() => { + setProfileShow(false); + setIsClickedCloseBtn(false); + }, 300); + } + }, [isClickedCloseBtn]); + + const bottomRef = useRef(null); + const [height, setHeight] = useState(0); + useEffect(() => { + console.log(bottomRef.current, "존재"); + if (bottomRef.current) { + const bottom = bottomRef.current.getBoundingClientRect().bottom; + setHeight(bottom); + } + }, [profileShow]); + + return ( + <> + {profileShow && ( + + + + +
{/* 마지막 요소 */} +
+ )} + + ); +} + +const slideUp = keyframes` + from { + transform: translate(-50%, 100%); + opacity: 0; + } + to { + transform: translate(-50%, 0%); + opacity: 1; + } +`; + +const slideDown = keyframes` + from { + transform: translate(-50%, 0%); + opacity: 1; + } + to { + transform: translate(-50%, 100%); + opacity: 0; + } +`; +const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number }>` + padding: 0px 24px; + position: absolute; + z-index: 1001; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: white; + height: ${({ height }) => height}px; + @media (min-width: 440px) { + width: 390px; + left: 50%; + } + left: 50%; + animation: ${(props) => (props.isClickedCloseBtn ? slideDown : slideUp)} 0.3s ease-out forwards; +`; diff --git a/src/components/userProfile/UserProfileOverlayHeader.tsx b/src/components/userProfile/UserProfileOverlayHeader.tsx new file mode 100644 index 00000000..12489466 --- /dev/null +++ b/src/components/userProfile/UserProfileOverlayHeader.tsx @@ -0,0 +1,103 @@ +"use client"; +import styled from "@emotion/styled"; +import TripDetailHeader from "@/page/TripDetail/TripDetailHeader"; +import { palette } from "@/styles/palette"; + +import { useHeaderNavigation } from "@/hooks/useHeaderNavigation"; +import { useRouter, useSearchParams } from "next/navigation"; +import Link from "next/link"; +import { createTripStore } from "@/store/client/createTripStore"; +import CloseIcon from "../icons/CloseIcon"; +import MoreIcon from "../icons/MoreIcon"; +import ProfileMoreIcon from "../icons/ProfileMoreIcon"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import ReportModal from "../designSystem/modal/ReportModal"; +import { useEffect, useState } from "react"; +import useViewTransition from "@/hooks/useViewTransition"; + +interface UserProfileOverlayHeaderProps { + setIsClickedCloseBtn: React.Dispatch>; +} + +const UserProfileOverlayHeader = ({ setIsClickedCloseBtn }: UserProfileOverlayHeaderProps) => { + const searchParams = useSearchParams(); + const router = useRouter(); + const { setProfileShow } = userProfileOverlayStore(); + + // const handleNotification = () => { + // setNotification(checkRoute.exact(ROUTES.MY.PAGE) ? ROUTES.MY.PAGE : ROUTES.MY.TRIP); + // router.push("/notification"); + // }; + + // const headerBackgroundColorIsGrey = () => { + // return ( + // checkRoute.exact(ROUTES.HOME) || checkRoute.exact(ROUTES.MY.TRIP) || checkRoute.startsWith(ROUTES.REQUESTED_TRIP) + // ); + // }; + const closeOverlay = () => { + setIsClickedCloseBtn(true); + }; + const [isReportBtnClicked, setIsReportBtnClicked] = useState(false); + const [reportThreeDotsClick, setReportThreeDotsClick] = useState(false); + const [userNumber, setUserNumber] = useState(1); + const navigateWithTransition = useViewTransition(); + useEffect(() => { + if (isReportBtnClicked) { + setIsReportBtnClicked(false); + setIsClickedCloseBtn(true); + setUserNumber(userNumber); + document.documentElement.style.viewTransitionName = "forward"; + + navigateWithTransition(`/report/userProfile/${userNumber}`); + } + }, [isReportBtnClicked]); + return ( + + + + + + + setReportThreeDotsClick(true)}> + + + + + + ); +}; + +// button에 cursor pointer 추가 +const ButtonContainer = styled.button` + cursor: pointer; +`; + +// header container +// 상단 헤더 스타일 +const HeaderContainer = styled.header<{ isBackGroundColorIsGrey: boolean; isBottomBorder: boolean }>` + display: flex; + padding: 52px 0px 16px 0px; + height: 116px; + align-items: center; + gap: 22px; + position: sticky; + top: 0px; + background-color: white; + z-index: 1000; + justify-content: space-between; + width: 100%; + border-bottom: ${(props) => (props.isBottomBorder ? "1px" : "0")} solid ${palette.비강조3}; +`; + +const RightFlex = styled.div` + display: flex; + align-items: center; + width: 100%; + justify-content: space-between; +`; + +export default UserProfileOverlayHeader; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx new file mode 100644 index 00000000..c13d9925 --- /dev/null +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -0,0 +1,297 @@ +"use client"; +import { myPageStore } from "@/store/client/myPageStore"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; +import React, { useEffect, useState } from "react"; + +import useViewTransition from "@/hooks/useViewTransition"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import { keyframes } from "@emotion/react"; +import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; +import UserProfileDetail from "./UserProfileDetail"; +import HorizonBoxLayout from "../HorizonBoxLayout"; +import { daysAgo } from "@/utils/time"; +import dayjs from "dayjs"; +import { useInView } from "react-intersection-observer"; +import useUserProfile from "@/hooks/userProfile/useUserProfile"; +import useInfiniteScroll from "@/hooks/useInfiniteScroll"; +import { IUserRelatedTravelList } from "@/model/userProfile"; +import RoundedImage from "../designSystem/profile/RoundedImage"; + +export default function UserTravelTabMenu() { + const { setProfileShow, profileShow } = userProfileOverlayStore(); + const navigateWithTransition = useViewTransition(); + const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); + const [selectedTab, setSelectedTab] = useState(0); + + // 스크롤 감지 ref 선언 + const [createdTravelsRef, createdTravelsInView] = useInView(); + const [appliedTravelsRef, appliedTravelsInView] = useInView(); + + const { + userProfileCreatedTravelsData, + isUserProfileCreatedTravelsLoading, + fetchNextUserProfileCreatedTravelsPage, + isUserProfileCreatedTravelsFetching, + hasNextUserProfileCreatedTravelsPage, + + userProfileAppliedTravelsData, + isUserProfileAppliedTravelsLoading, + fetchNextUserProfileAppliedTravelsPage, + isUserProfileAppliedTravelsFetching, + hasNextUserProfileAppliedTravelsPage, + + userProfileInfo, + } = useUserProfile(); + + useEffect(() => { + if (isClickedCloseBtn) { + setTimeout(() => { + setProfileShow(false); + setIsClickedCloseBtn(false); + }, 300); + } + }, [isClickedCloseBtn]); + + if (isUserProfileCreatedTravelsLoading || isUserProfileAppliedTravelsLoading) { + return null; + } + + useInfiniteScroll(() => { + if (createdTravelsInView) { + !isUserProfileCreatedTravelsFetching && + hasNextUserProfileCreatedTravelsPage && + fetchNextUserProfileCreatedTravelsPage(); + } + }, [ + createdTravelsInView, + !isUserProfileCreatedTravelsFetching, + fetchNextUserProfileCreatedTravelsPage, + hasNextUserProfileCreatedTravelsPage, + ]); + + useInfiniteScroll(() => { + if (appliedTravelsInView) { + !isUserProfileAppliedTravelsFetching && + hasNextUserProfileAppliedTravelsPage && + fetchNextUserProfileAppliedTravelsPage(); + } + }, [ + appliedTravelsInView, + !isUserProfileAppliedTravelsFetching, + fetchNextUserProfileAppliedTravelsPage, + hasNextUserProfileAppliedTravelsPage, + ]); + + const userProfileCreatedTravels = + (userProfileCreatedTravelsData?.pages[0].content as IUserRelatedTravelList["content"]) ?? []; + + const userProfileAppliedTravels = + (userProfileAppliedTravelsData?.pages[0].content as IUserRelatedTravelList["content"]) ?? []; + + const isCreatedTravelsNoData = userProfileCreatedTravels.length === 0; + const isAppliedTravelsNoData = userProfileAppliedTravels.length === 0; + + const clickTrip = (travelNumber: number) => { + navigateWithTransition(`/trip/detail/${travelNumber}`); + setTimeout(() => { + setProfileShow(false); + }, 50); + }; + + return ( + + + setSelectedTab(0)}> + 만든 여행 + {userProfileInfo?.createdTravelCount} + + setSelectedTab(1)}> + 참가한 여행 + {userProfileInfo?.participatedTravelCount} + + + {/* 조건부 */} + {/* 0 이 되면 왼쪽으로 이동 1이 되면 오른쪽으로 이동. */} + + + + {isCreatedTravelsNoData && ( + + + +
아직 만든 여행이 없어요
+
+
+ )} + {!isUserProfileCreatedTravelsLoading && + userProfileCreatedTravelsData && + userProfileCreatedTravelsData.pages.map((page, pageIndex) => ( + + {page.content?.map( + ({ travelNumber, location, userName, title, tags, maxPerson, createdAt, nowPerson }) => ( + clickTrip(travelNumber)}> + + + ) + )} + + ))} +
+ + + + {isAppliedTravelsNoData && ( + + + +
아직 만든 여행이 없어요
+
+
+ )} + {!isUserProfileAppliedTravelsLoading && + userProfileAppliedTravelsData && + userProfileAppliedTravelsData.pages.map((page, pageIndex) => ( + + {page.content?.map( + ({ travelNumber, location, userName, title, tags, maxPerson, createdAt, nowPerson }) => ( + clickTrip(travelNumber)}> + + + ) + )} + + ))} +
+ + + + + ); +} +const NoData = styled.div` + margin-top: 16px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + font-family: Pretendard; + font-size: 16px; + font-weight: 600; + line-height: 22.4px; + letter-spacing: -0.025em; + text-align: center; + color: ${palette.기본}; +`; +const Empty = styled.div` + position: fixed; + top: 0; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100svh; +`; +const Container = styled.div` + width: 100%; + display: flex; + flex-direction: column; +`; + +const TabMenuContainer = styled.div` + position: sticky; + top: 100px; + z-index: 1002; + background-color: white; + display: flex; + justify-content: space-between; + border-bottom: 1px solid #e0e0e0; + margin: 0px -24px; +`; + +interface TabMenuProps { + isSelected: boolean; +} + +const TabMenu = styled.button` + flex: 1; + padding: 16px 0; + background: none; + border: none; + cursor: pointer; + border-bottom: ${({ isSelected }) => (isSelected ? `2px solid ${palette.기본}` : `1px solid ${palette.비강조3}`)}; + color: ${({ isSelected }) => (isSelected ? palette.기본 : palette.비강조2)}; + font-weight: 600; + display: flex; + justify-content: center; + gap: 4px; + transition: all 0.4s ease; + + font-size: 14px; +`; + +const HostTravel = styled.div` + font-size: 14px; +`; +const ParticipantTravel = styled.div``; + +const Count = styled.div` + color: ${({ isSelected }) => (isSelected ? palette.keycolor : palette.비강조2)}; +`; + +interface TravelListBoxProps { + selectedTab: number; +} + +export const TravelListBox = styled.div` + width: 100%; + overflow-x: hidden; + position: relative; +`; + +export const InnerSlider = styled.div` + display: flex; + width: 200%; // 두 개 탭이니까 두 배 + transition: transform 0.3s ease-in-out; + transform: ${({ selectedTab }) => (selectedTab === 0 ? "translateX(0%)" : "translateX(-100%)")}; +`; +export const HostTravelList = styled.div` + width: 100%; + flex-shrink: 0; +`; + +export const ParticipantTravelList = styled.div` + width: 100%; + flex-shrink: 0; +`; + +export const Item = styled.div` + padding: 12px 0; + border-bottom: 1px solid ${palette.비강조4}; +`; From c4123ffb7ed6507e397497c4db97d9ef3898a9d6 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 12:29:35 +0900 Subject: [PATCH 08/69] =?UTF-8?q?style:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B8=80=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileOverlayHeader.tsx | 14 -------------- src/components/userProfile/UserTravelTabMenu.tsx | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlayHeader.tsx b/src/components/userProfile/UserProfileOverlayHeader.tsx index 12489466..59b92c46 100644 --- a/src/components/userProfile/UserProfileOverlayHeader.tsx +++ b/src/components/userProfile/UserProfileOverlayHeader.tsx @@ -20,20 +20,6 @@ interface UserProfileOverlayHeaderProps { } const UserProfileOverlayHeader = ({ setIsClickedCloseBtn }: UserProfileOverlayHeaderProps) => { - const searchParams = useSearchParams(); - const router = useRouter(); - const { setProfileShow } = userProfileOverlayStore(); - - // const handleNotification = () => { - // setNotification(checkRoute.exact(ROUTES.MY.PAGE) ? ROUTES.MY.PAGE : ROUTES.MY.TRIP); - // router.push("/notification"); - // }; - - // const headerBackgroundColorIsGrey = () => { - // return ( - // checkRoute.exact(ROUTES.HOME) || checkRoute.exact(ROUTES.MY.TRIP) || checkRoute.startsWith(ROUTES.REQUESTED_TRIP) - // ); - // }; const closeOverlay = () => { setIsClickedCloseBtn(true); }; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index c13d9925..5c6f8400 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -157,7 +157,7 @@ export default function UserTravelTabMenu() { -
아직 만든 여행이 없어요
+
아직 참가한 여행이 없어요
)} From 8fa8fbd43dee8c41acce0debb74327010b69dc29 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:06:51 +0900 Subject: [PATCH 09/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EB=AA=A8=EB=8B=AC=20Layout?= =?UTF-8?q?=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 564a2b80..69e8d2b2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,7 @@ import Layout from "@/components/Layout"; import Providers from "./providers"; import "./globals.css"; import { MSWComponent } from "@/context/MSWComponent"; +import UserProfileOverlay from "@/components/userProfile/UserProfileOverlay"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( @@ -9,6 +10,7 @@ export default function RootLayout({ children }: { children: React.ReactNode }) + {children}
From e2f2ea8f748b35e756e39d6534bb80d26ea7db61 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:08:19 +0900 Subject: [PATCH 10/69] =?UTF-8?q?design:=20=EC=97=AC=ED=96=89=20BoxLayout?= =?UTF-8?q?=20=EC=83=81=EB=8C=80=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=9E=AC=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20-=20daysLeft=20?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=9E=AC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9C=BC=EB=AF=80=EB=A1=9C=20=ED=95=84?= =?UTF-8?q?=EC=88=98=EA=B0=80=20=EC=95=84=EB=8B=98=EC=9C=BC=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 --- src/components/HorizonBoxLayout.tsx | 105 ++++++++++++++++++---------- 1 file changed, 70 insertions(+), 35 deletions(-) diff --git a/src/components/HorizonBoxLayout.tsx b/src/components/HorizonBoxLayout.tsx index 371350b8..4e346e8a 100644 --- a/src/components/HorizonBoxLayout.tsx +++ b/src/components/HorizonBoxLayout.tsx @@ -15,7 +15,7 @@ import { usePathname, useRouter } from "next/navigation"; import { isGuestUser } from "@/utils/user"; import { useBackPathStore } from "@/store/client/backPathStore"; interface HorizonBoxProps { - daysLeft: number; + daysLeft?: number; title: string; recruits: number; total: number; @@ -31,6 +31,7 @@ interface HorizonBoxProps { bookmarkNeed?: boolean; // false면 필요 없거나, Link에 속하지 않는 버튼을 따로 사용. bookmarked: boolean; travelNumber: number; + userProfileType?: boolean; } // 사용 방식 { @@ -63,6 +64,7 @@ const HorizonBoxLayout = ({ tags, bookmarkNeed = true, travelNumber, + userProfileType = false, }: HorizonBoxProps) => { const tagRef = useRef(null); const containerRef = useRef(null); @@ -85,31 +87,33 @@ const HorizonBoxLayout = ({ - - - - - -
{location}
-
- } - backgroundColor={palette.keycolorBG} - color={`${palette.keycolor}`} - isDueDate={false} - /> + {!userProfileType ? ( + + + + + +
{location}
+
+ } + backgroundColor={palette.keycolorBG} + color={`${palette.keycolor}`} + isDueDate={false} + /> + ) : null} {bookmarkPosition === "top" && bookmarkNeed && ( @@ -137,15 +141,46 @@ const HorizonBoxLayout = ({ {isBar && } {showTag && ( - - -
{location}
- - } - /> + {userProfileType ? ( +
+ + + + + +
{location}
+
+ } + backgroundColor={palette.keycolorBG} + color={`${palette.keycolor}`} + isDueDate={false} + /> +
+ ) : ( + + +
{location}
+ + } + /> + )} + {tagsCount.map((text: string, idx) => ( ))} From 6455e59df476361243424dd2989bea89d4fc40c6 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:09:51 +0900 Subject: [PATCH 11/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20API=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20-=20hooks,=20api,=20model=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98=20-=20=EC=83=81=EB=8C=80=EB=B0=A9=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=EC=9A=94=EC=B2=AD=20-=20=EC=83=81?= =?UTF-8?q?=EB=8C=80=EB=B0=A9=EC=9D=B4=20=EB=A7=8C=EB=93=A0=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20&=20=EC=B0=B8=EA=B0=80=ED=95=9C=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EC=9A=94=EC=B2=AD=20api=20-=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20type=20model=EC=97=90=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/userProfile.ts | 47 +++++++++++ src/hooks/userProfile/useUserProfile.ts | 101 ++++++++++++++++++++++++ src/model/userProfile.ts | 40 ++++++++++ 3 files changed, 188 insertions(+) create mode 100644 src/api/userProfile.ts create mode 100644 src/hooks/userProfile/useUserProfile.ts create mode 100644 src/model/userProfile.ts diff --git a/src/api/userProfile.ts b/src/api/userProfile.ts new file mode 100644 index 00000000..eae462d1 --- /dev/null +++ b/src/api/userProfile.ts @@ -0,0 +1,47 @@ +import { getJWTHeader } from "@/utils/user"; +import { axiosInstance, handleApiResponse } from "."; +import RequestError from "@/context/ReqeustError"; +import { IUserProfileInfo } from "@/model/userProfile"; + +export const getUserProfile = async (accessToken: string, userNumber: number): Promise => { + try { + const response = await axiosInstance.get(`/api/users/${userNumber}/profile`, { + headers: getJWTHeader(accessToken), + }); + + return handleApiResponse(response); + } catch (err: any) { + throw new RequestError(err); + } +}; +// 상대방의 만든 여행 조회 +export const getUserCreatedTravels = async (pageParam: number, accessToken: string, userNumber: number) => { + try { + const response = await axiosInstance.get(`/api/users/${userNumber}/created-travel`, { + headers: getJWTHeader(accessToken), + params: { + page: pageParam, + size: 10, + }, + }); + return handleApiResponse(response); + } catch (err: any) { + throw new RequestError(err); + } +}; +// 상대방의 참가 여행 조회. + +export const getUserAppliedTravels = async (pageParam: number, accessToken: string, userNumber: number) => { + try { + const response = await axiosInstance.get(`/api/users/${userNumber}/applied-travel`, { + headers: getJWTHeader(accessToken), + params: { + page: pageParam, + size: 10, + }, + }); + return handleApiResponse(response); + } catch (err: any) { + throw new RequestError(err); + } +}; diff --git a/src/hooks/userProfile/useUserProfile.ts b/src/hooks/userProfile/useUserProfile.ts new file mode 100644 index 00000000..90829684 --- /dev/null +++ b/src/hooks/userProfile/useUserProfile.ts @@ -0,0 +1,101 @@ +"use client"; +import { getUserProfile, getUserAppliedTravels, getUserCreatedTravels } from "@/api/userProfile"; +import { IUserProfileInfo, IUserRelatedTravelList } from "@/model/userProfile"; +import { authStore } from "@/store/client/authStore"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import { useQuery, useInfiniteQuery, InfiniteData } from "@tanstack/react-query"; + +const useUserProfile = ( + profileType: "mine" | "other" = "other" +): { + userProfileInfo: IUserProfileInfo | undefined | null; + isLoadingUserProfileInfo: boolean; +} => { + const { accessToken, userId: myUserId } = authStore(); + const { userProfileUserId } = userProfileOverlayStore(); + + const targetUserId = profileType === "mine" ? myUserId : userProfileUserId; + + const { data: userProfileInfo, isLoading: isLoadingUserProfileInfo } = useQuery({ + queryKey: ["userProfile", targetUserId], + queryFn: () => getUserProfile(accessToken!, targetUserId!), + enabled: !!accessToken && targetUserId !== -1, + retry: !!accessToken, + staleTime: 0, + }); + + const { + data: userProfileCreatedTravelsData, + isLoading: isUserProfileCreatedTravelsLoading, + error: userProfileCreatedTravelsError, + fetchNextPage: fetchNextUserProfileCreatedTravelsPage, + refetch: refetchUserProfileCreatedTravels, + isFetching: isUserProfileCreatedTravelsFetching, + hasNextPage: hasNextUserProfileCreatedTravelsPage, + } = useInfiniteQuery, [string, number]>({ + queryKey: ["userProfileCreatedTravels", userProfileUserId], + queryFn: ({ pageParam }) => { + return getUserCreatedTravels(pageParam as number, accessToken!, userProfileUserId) as any; + }, + enabled: !!accessToken && userProfileUserId !== -1, + retry: Boolean(accessToken), + staleTime: 0, + initialPageParam: 0, + getNextPageParam: (lastPage) => { + if (lastPage?.page?.number + 1 === lastPage?.page?.totalPages || lastPage.page?.totalPages === 0) { + return undefined; + } else { + if (lastPage?.page?.number + 1 === 3) return undefined; //30개까지만 요청 + return lastPage?.page?.number + 1; + } + }, + }); + + const { + data: userProfileAppliedTravelsData, + isLoading: isUserProfileAppliedTravelsLoading, + error: userProfileAppliedTravelsError, + fetchNextPage: fetchNextUserProfileAppliedTravelsPage, + refetch: refetchUserProfileAppliedTravels, + isFetching: isUserProfileAppliedTravelsFetching, + hasNextPage: hasNextUserProfileAppliedTravelsPage, + } = useInfiniteQuery, [string, number]>({ + queryKey: ["userProfileAppliedTravels", userProfileUserId], + queryFn: ({ pageParam }) => { + return getUserAppliedTravels(pageParam as number, accessToken!, userProfileUserId) as any; + }, + enabled: !!accessToken && userProfileUserId !== -1, + retry: Boolean(accessToken), + staleTime: 0, + initialPageParam: 0, + getNextPageParam: (lastPage) => { + if (lastPage?.page?.number + 1 === lastPage?.page?.totalPages || lastPage.page?.totalPages === 0) { + return undefined; + } else { + if (lastPage?.page?.number + 1 === 3) return undefined; // 30개까지만 요청 + return lastPage?.page?.number + 1; + } + }, + }); + return { + userProfileInfo, + isLoadingUserProfileInfo, + + userProfileCreatedTravelsData, + isUserProfileCreatedTravelsLoading, + userProfileCreatedTravelsError, + fetchNextUserProfileCreatedTravelsPage, + refetchUserProfileCreatedTravels, + isUserProfileCreatedTravelsFetching, + hasNextUserProfileCreatedTravelsPage, + + userProfileAppliedTravelsData, + isUserProfileAppliedTravelsLoading, + userProfileAppliedTravelsError, + fetchNextUserProfileAppliedTravelsPage, + refetchUserProfileAppliedTravels, + isUserProfileAppliedTravelsFetching, + hasNextUserProfileAppliedTravelsPage, + }; +}; +export default useUserProfile; diff --git a/src/model/userProfile.ts b/src/model/userProfile.ts new file mode 100644 index 00000000..3e8578af --- /dev/null +++ b/src/model/userProfile.ts @@ -0,0 +1,40 @@ +export interface IUserProfileInfo { + name: string; + userRegDate: string; // "2024년 12월" + preferredTags: string[]; + profileImageUrl: string; + createdTravelCount: number; // 생성한 여행 수 + participatedTravelCount: number; // 참가한 여행 수 + travelDistance: number; // 여행 거리 (단위: 리) + visitedCountryCount: number; // 방문한 국가 수 + travelBadgeCount: number; // 획득한 뱃지 수 + recentlyReported: boolean; // 최근(7일) 신고 여부 + totalReportCount: number; // 총 신고 횟수 + recentReportCount: number; // 최근(7일) 신고 횟수 +} + +export interface IUserRelatedTravel { + // 상대방의 만든 여행과 참가한 여행 데이터 타입 + travelNumber: number; + title: string; + location: string; + userNumber: number; + userName: string; + tags: string[]; + nowPerson: number; + maxPerson: number; + createdAt: string; // "2025-04-15 14:58" 형태, 필요하면 Date로 파싱 + bookmarked: boolean; +} + +interface Page { + size: number; + number: number; + totalElements: number; + totalPages: number; +} + +export interface IUserRelatedTravelList { + content: IUserRelatedTravel[]; + page: Page; +} From ac698ff1c45030b0177e25fb48810a4e5e428182 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:11:06 +0900 Subject: [PATCH 12/69] =?UTF-8?q?design:=20=ED=83=9C=EA=B7=B8=20=EB=A7=88?= =?UTF-8?q?=EC=A7=84,=20=EA=B5=B5=EA=B8=B0=20=EC=88=98=EC=A0=95=20-=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=8F=99=EC=9D=BC=ED=95=A8=EC=9D=84=20=ED=99=95=EC=9D=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/designSystem/tag/BoxLayoutTag.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/designSystem/tag/BoxLayoutTag.tsx b/src/components/designSystem/tag/BoxLayoutTag.tsx index d9e8a2cc..b6127131 100644 --- a/src/components/designSystem/tag/BoxLayoutTag.tsx +++ b/src/components/designSystem/tag/BoxLayoutTag.tsx @@ -31,8 +31,8 @@ const BoxLayoutTag = forwardRef( color: `${palette.비강조}`, borderRadius: "20px", fontSize: "12px", - fontWeight: "600", - margin: "0 6px 0 0", + fontWeight: "400", + margin: "0 8px 0 0", }, }: BoxLayoutTagProps, ref From 2fbfb27a3581ca9fac3b2cd9f0c5eb110da31ddc Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:30:01 +0900 Subject: [PATCH 13/69] =?UTF-8?q?feat:=20=EC=95=84=EC=9D=B4=EC=BD=98=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 --- src/components/icons/BadgeLockIcon.tsx | 15 ++++++++++ src/components/icons/CloseIcon.tsx | 24 +++++++++++++++ src/components/icons/CloverIcon.tsx | 29 +++++++++++++++++++ src/components/icons/ProfileMoreIcon.tsx | 24 +++++++++++++++ .../icons/ProfileRightVectorIcon.tsx | 12 ++++++++ .../userProfile/UserProfileDetail.tsx | 7 ++--- 6 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 src/components/icons/BadgeLockIcon.tsx create mode 100644 src/components/icons/CloseIcon.tsx create mode 100644 src/components/icons/CloverIcon.tsx create mode 100644 src/components/icons/ProfileMoreIcon.tsx create mode 100644 src/components/icons/ProfileRightVectorIcon.tsx diff --git a/src/components/icons/BadgeLockIcon.tsx b/src/components/icons/BadgeLockIcon.tsx new file mode 100644 index 00000000..6aca5b70 --- /dev/null +++ b/src/components/icons/BadgeLockIcon.tsx @@ -0,0 +1,15 @@ +const BadgeLockIcon = () => { + return ( + + + + + ); +}; +export default BadgeLockIcon; diff --git a/src/components/icons/CloseIcon.tsx b/src/components/icons/CloseIcon.tsx new file mode 100644 index 00000000..39dba504 --- /dev/null +++ b/src/components/icons/CloseIcon.tsx @@ -0,0 +1,24 @@ +"use client"; +import React from "react"; + +interface CloseIconProps { + width?: number; + height?: number; + stroke?: string; +} + +const CloseIcon = ({ width = 48, height = 48, stroke = "#343434" }: CloseIconProps) => { + return ( + + + + ); +}; + +export default CloseIcon; diff --git a/src/components/icons/CloverIcon.tsx b/src/components/icons/CloverIcon.tsx new file mode 100644 index 00000000..e804d936 --- /dev/null +++ b/src/components/icons/CloverIcon.tsx @@ -0,0 +1,29 @@ +"use client"; +import React from "react"; + +export default function CloverIcon() { + return ( + + + + + + + + + + ); +} diff --git a/src/components/icons/ProfileMoreIcon.tsx b/src/components/icons/ProfileMoreIcon.tsx new file mode 100644 index 00000000..7227ac70 --- /dev/null +++ b/src/components/icons/ProfileMoreIcon.tsx @@ -0,0 +1,24 @@ +export default function ProfileMoreIcon() { + return ( + + + + + + ); +} diff --git a/src/components/icons/ProfileRightVectorIcon.tsx b/src/components/icons/ProfileRightVectorIcon.tsx new file mode 100644 index 00000000..1f3abf98 --- /dev/null +++ b/src/components/icons/ProfileRightVectorIcon.tsx @@ -0,0 +1,12 @@ +"use client"; +interface VectorProps { + width?: number; + height?: number; +} +export default function ProfileRightVectorIcon({ width = 24, height = 24 }: VectorProps) { + return ( + + + + ); +} diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index eb1e8154..b05ddb4e 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -9,11 +9,10 @@ import CloverIcon from "../icons/CloverIcon"; import RoundedImage from "../designSystem/profile/RoundedImage"; import Badge from "../designSystem/Badge"; import { formatNumberWithComma } from "@/utils/formatNumberWithComma"; -import ProfileRightVector from "../icons/ProfileRightVector"; import WarningIcon from "../icons/WarningIcon"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import useUserProfile from "@/hooks/userProfile/useUserProfile"; -import ArrowIcon from "../icons/ArrowIcon"; +import ProfileRightVectorIcon from "../icons/ProfileRightVectorIcon"; interface UserProfileDetailProps { isMyPage?: boolean; @@ -66,7 +65,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai {name} - {isMyPage && } + {isMyPage && } {isMyPage ? myEmail : userRegDate + "가입"} @@ -124,7 +123,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai {count} - + From 9f652a4702ffd2c823ef73bbe356eade2e1ec0eb Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:31:19 +0900 Subject: [PATCH 14/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B1=83=EC=A7=80=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/userProfileBadge/[userId]/page.tsx | 8 ++ .../UserProfileBadge/UserProfileBadge.tsx | 79 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/app/userProfileBadge/[userId]/page.tsx create mode 100644 src/page/UserProfileBadge/UserProfileBadge.tsx diff --git a/src/app/userProfileBadge/[userId]/page.tsx b/src/app/userProfileBadge/[userId]/page.tsx new file mode 100644 index 00000000..a88ee71d --- /dev/null +++ b/src/app/userProfileBadge/[userId]/page.tsx @@ -0,0 +1,8 @@ +import { UserProfileBadge } from "@/page/UserProfileBadge/UserProfileBadge"; +import React from "react"; + +const UserProfileBadgePage = () => { + return ; +}; + +export default UserProfileBadgePage; diff --git a/src/page/UserProfileBadge/UserProfileBadge.tsx b/src/page/UserProfileBadge/UserProfileBadge.tsx new file mode 100644 index 00000000..42e07ee0 --- /dev/null +++ b/src/page/UserProfileBadge/UserProfileBadge.tsx @@ -0,0 +1,79 @@ +"use client"; + +import BadgeLockIcon from "@/components/icons/BadgeLockIcon"; +import { palette } from "@/styles/palette"; +import { useEffect } from "react"; +import styled from "styled-components"; + +export function UserProfileBadge() { + // API 요청. hooks 캐시 값 이용. + const tempBadgeArray = new Array(12).fill({ Icon: BadgeLockIcon, name: "배지 이름" }); + return ( + + + 현재 + 4 + 개의 배지를 획득했어요. + + + {tempBadgeArray.map((badge) => ( + + + {badge.name} + + ))} + + + ); +} + +export const Container = styled.div` + padding: 0px 24px; +`; + +export const Text = styled.p` + margin-top: 40px; + margin-bottom: 24px; + padding-left: 4px; + line-height: 140%; + letter-spacing: -2.5%; + color: ${palette.기본}; + font-weight: 600; + font-size: 18px; +`; + +export const BadgeCount = styled.span` + font-weight: bold; + color: ${palette.keycolor}; /* 예시: 코랄 색상 */ + margin: 0 4px; +`; + +export const BadgeGrid = styled.div` + display: grid; + grid-template-columns: repeat(3, 1fr); + + column-gap: 27px; /* 열 간 간격 */ + row-gap: 32px; /* 행 간 간격 */ + + @media (max-width: 360px) { + grid-template-columns: repeat(2, 1fr); + } +`; + +export const BadgeItem = styled.div` + width: 100%; + + border-radius: 12px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +`; + +export const BadgeName = styled.div` + text-align: center; + margin-top: 12px; + font-weight: 400; + font-size: 12px; + color: "#000000"; +`; From c05824105cb2ace3f3d2be0c7dc02e88b4246b2b Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:33:04 +0900 Subject: [PATCH 15/69] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=B3=80=EA=B2=BD=20=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20-=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A0=95=EB=B3=B4=EC=99=80=20?= =?UTF-8?q?=EC=9C=A0=EC=82=AC=ED=95=9C=20=ED=99=94=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=EB=90=A8=20=EB=B0=98=EC=98=81=20?= =?UTF-8?q?-=20myPageStore=EC=97=90=20=EC=97=AC=ED=96=89=EA=B1=B0=EB=A6=AC?= =?UTF-8?q?,=20=EB=B0=A9=EB=AC=B8=20=EA=B5=AD=EA=B0=80,=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EB=B0=B0=EC=A7=80=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20Layout=EC=97=90=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=ED=95=98=EC=97=AC=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout.tsx | 42 +++++------ src/page/MyPage/MyPage.tsx | 120 ++++++++++---------------------- src/store/client/myPageStore.ts | 19 +++++ 3 files changed, 75 insertions(+), 106 deletions(-) diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index e310a4fe..086c3b27 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -16,10 +16,15 @@ import { splashOnStore } from "@/store/client/splashOnOffStore"; import { usePathname } from "next/navigation"; import { APIProvider } from "@vis.gl/react-google-maps"; import { useHeaderNavigation } from "@/hooks/useHeaderNavigation"; +import useUserProfile from "@/hooks/userProfile/useUserProfile"; +import { IUserProfileInfo } from "@/model/userProfile"; const Layout = ({ children }: { children: React.ReactNode }) => { const pathname = usePathname(); const { userPostRefreshToken } = useAuth(); const { userId, accessToken, logoutCheck } = authStore(); + + const { userProfileInfo } = useUserProfile("mine"); + // 유저 프로필 정보 불러오기 const { addEmail, @@ -30,16 +35,13 @@ const Layout = ({ children }: { children: React.ReactNode }) => { addPreferredTags, profileUrl, addUserSocialTF, + addTravelDistance, + addVisitedCountryCount, + addTravelBadgeCount, } = myPageStore(); - const { - data, - isLoading, - profileImage, - isLoadingImage, - firstProfileImageMutation, - isFirstProfileImagePostSuccess, - } = useMyPage(); + const { data, isLoading, profileImage, isLoadingImage, firstProfileImageMutation, isFirstProfileImagePostSuccess } = + useMyPage(); console.log(data, "user data"); const isOnboarding = pathname?.startsWith("/onBoarding"); @@ -48,7 +50,8 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const myPageData: ImyPage = data as any; const profileImg: IProfileImg = profileImage as IProfileImg; - console.log(profileImg, profileImage, "프로필 이미지 get"); + const myProfileInfo: IUserProfileInfo = userProfileInfo as IUserProfileInfo; + console.log(profileImg, profileImage, myProfileInfo, "프로필"); useEffect(() => { if (!isLoading && myPageData) { addName(myPageData.name); @@ -57,6 +60,9 @@ const Layout = ({ children }: { children: React.ReactNode }) => { addPreferredTags(myPageData.preferredTags); addGender(myPageData.gender); addUserSocialTF(myPageData.userSocialTF); + addTravelDistance(myProfileInfo?.travelDistance); + addTravelBadgeCount(myProfileInfo?.travelBadgeCount); + addVisitedCountryCount(myProfileInfo?.visitedCountryCount); const tags: string[] = []; for (const tag of myPageData.preferredTags) { const text = tag.split(" "); @@ -84,11 +90,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { useEffect(() => { // 컴포넌트가 렌더링될 때마다 토큰 갱신 시도(새로고침시 토큰 사라지는 문제해결 위해) - if ( - !accessToken && - !logoutCheck && - !checkRoute.startsWith("/login/oauth") - ) { + if (!accessToken && !logoutCheck && !checkRoute.startsWith("/login/oauth")) { // 토큰이 없으면 리프레쉬 토큰 api 요청. const refreshAccessToken = async () => { userPostRefreshToken(); @@ -103,20 +105,14 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const backGroundGrey = ["/trip/detail", "/", "/myTrip", "/requestedTrip"]; useEffect(() => { if (splashOn === true) return; - let themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + const themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); if (themeColorMetaTag) { - themeColorMetaTag.setAttribute( - "content", - backGroundGrey.includes(pathname ?? "") ? "#F5F5F5" : `${palette.BG}` - ); + themeColorMetaTag.setAttribute("content", backGroundGrey.includes(pathname ?? "") ? "#F5F5F5" : `${palette.BG}`); } }, [pathname]); return ( - console.log("google map load")} - > + console.log("google map load")}> diff --git a/src/page/MyPage/MyPage.tsx b/src/page/MyPage/MyPage.tsx index cee69aef..0a81ed1f 100644 --- a/src/page/MyPage/MyPage.tsx +++ b/src/page/MyPage/MyPage.tsx @@ -5,6 +5,7 @@ import RoundedImage from "@/components/designSystem/profile/RoundedImage"; import TextButton from "@/components/designSystem/text/TextButton"; import RightVector from "@/components/icons/RightVector"; import Spacing from "@/components/Spacing"; +import UserProfileDetail from "@/components/userProfile/UserProfileDetail"; import useViewTransition from "@/hooks/useViewTransition"; import { myPageStore } from "@/store/client/myPageStore"; import { palette } from "@/styles/palette"; @@ -25,92 +26,27 @@ export default function MyPage() { }; return ( - - - - -
- {!isGuestUser() ? ( -
{ - document.documentElement.style.viewTransitionName = "forward"; - navigateWithTransition("/editMyInfo"); - }} - > - - {name} -
- -
-
- {email} - -
- -
- - {cutTags.map((text: string) => ( -
- -
- ))} - {preferredTags.length > cutTags.length ? ( - - ) : null} -
+ {!isGuestUser() ? ( + + ) : ( + <> + setShowLoginModal(true)}> + 로그인 & 회원가입 +
+
- ) : ( - <> - setShowLoginModal(true)}> - 로그인 & 회원가입 -
- -
-
- - 로그인 후 모잉에서 -
설레는 여행을 떠나보세요. -
- - )} -
- + + + 로그인 후 모잉에서 +
설레는 여행을 떠나보세요. +
+ + )} + - 모잉 소식 - - - - - - - 내 여행 현황 + 내 활동 현황 { @@ -136,7 +72,17 @@ export default function MyPage() { /> -
+ + + 모잉 소식 + + { router.push("/contact"); @@ -145,6 +91,10 @@ export default function MyPage() { isLeftVector={false} isRightVector={false} /> + + + +
@@ -167,6 +117,10 @@ export default function MyPage() { ); } +const SpaceBox = styled.div` + height: 12px; + background-color: ${palette.검색창}; +`; const ProfileImg = styled.div``; const Container = styled.div` padding: 0px 24px; diff --git a/src/store/client/myPageStore.ts b/src/store/client/myPageStore.ts index 0c38cbe6..0ba06c67 100644 --- a/src/store/client/myPageStore.ts +++ b/src/store/client/myPageStore.ts @@ -26,6 +26,13 @@ interface myPageStoreState { addIsPasswordUpdated: (isPasswordUpdated: boolean) => void; userSocialTF: boolean; addUserSocialTF: (userSocialTF: boolean) => void; + + travelDistance: number; + addTravelDistance: (travelDistance: number) => void; + visitedCountryCount: number; + addVisitedCountryCount: (visitedCountryCount: number) => void; + travelBadgeCount: number; + addTravelBadgeCount: (travelBadgeCount: number) => void; } export const myPageStore = create((set) => ({ @@ -77,4 +84,16 @@ export const myPageStore = create((set) => ({ addIsPasswordUpdated: (isPasswordUpdated) => { set((state) => ({ isPasswordUpdated })); }, + travelDistance: 0, + addTravelDistance: (travelDistance) => { + set((state) => ({ travelDistance })); + }, + visitedCountryCount: 0, + addVisitedCountryCount: (visitedCountryCount) => { + set((state) => ({ visitedCountryCount })); + }, + travelBadgeCount: 0, + addTravelBadgeCount: (travelBadgeCount) => { + set((state) => ({ travelBadgeCount })); + }, })); From 1c55618fbddbe965c5892b7eeb4a575f72c59349 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:35:20 +0900 Subject: [PATCH 16/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=ED=81=B4=EB=A6=AD=EC=8B=9C=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9D=B4=20=EB=B3=B4=EC=97=AC=EC=A7=80?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=9D=BC=EC=9A=B0=ED=8A=B8=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 --- src/components/comment/Comment.tsx | 3 ++- src/hooks/userProfile/moveToUserProfilePage.ts | 7 +++++++ src/page/TripDetail/TripDetail.tsx | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 src/hooks/userProfile/moveToUserProfilePage.ts diff --git a/src/components/comment/Comment.tsx b/src/components/comment/Comment.tsx index 6fd7b151..1ecdd25b 100644 --- a/src/components/comment/Comment.tsx +++ b/src/components/comment/Comment.tsx @@ -21,6 +21,7 @@ import { isGuestUser } from "@/utils/user"; import { reportStore } from "@/store/client/reportStore"; import NoticeModal from "../designSystem/modal/NoticeModal"; import useViewTransition from "@/hooks/useViewTransition"; +import { moveToUserProfilePage } from "@/hooks/userProfile/moveToUserProfilePage"; interface CommentProps { comment: IComment; @@ -114,7 +115,7 @@ const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentPro - + moveToUserProfilePage(userNumber)}> {relatedType === "travel" && comment.travelWriterNumber === comment.userNumber && ( { + setUserProfileUserId(userNumber); + setProfileShow(true); +}; diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index 819c3fab..76e62afe 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -41,6 +41,8 @@ import { useInView } from "react-intersection-observer"; import useInfiniteScroll from "@/hooks/useInfiniteScroll"; import EmblaCarousel from "@/components/TripCarousel"; import useComment from "@/hooks/comment/useComment"; + +import { moveToUserProfilePage } from "@/hooks/userProfile/moveToUserProfilePage"; const WEEKDAY = ["일", "월", "화", "수", "목", "금", "토"]; function verifyGenderType(genderType: string | null, gender: string) { @@ -107,6 +109,7 @@ export default function TripDetail() { setApplySuccess, profileUrl, bookmarked, + userNumber, } = tripDetailStore(); const router = useRouter(); if (isNaN(parseInt(travelNumber))) { @@ -354,7 +357,7 @@ export default function TripDetail() { > - + moveToUserProfilePage(userNumber)}> {/* 프로필 */}
From 1bfd5c1692072b459867b14b0b99a1afc72ccc4e Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:36:02 +0900 Subject: [PATCH 17/69] =?UTF-8?q?feat:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20store=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/client/userProfileOverlayStore.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/store/client/userProfileOverlayStore.ts diff --git a/src/store/client/userProfileOverlayStore.ts b/src/store/client/userProfileOverlayStore.ts new file mode 100644 index 00000000..45cba446 --- /dev/null +++ b/src/store/client/userProfileOverlayStore.ts @@ -0,0 +1,20 @@ +"use client"; +import { create } from "zustand"; + +interface IUserProfileOverlayStore { + profileShow: boolean; + setProfileShow: (bool: boolean) => void; + userProfileUserId: number; + setUserProfileUserId: (id: number) => void; +} + +export const userProfileOverlayStore = create((set) => ({ + profileShow: false, + setProfileShow: (bool) => { + set({ profileShow: bool }); + }, + userProfileUserId: -1, + setUserProfileUserId: (id) => { + set({ userProfileUserId: id }); + }, +})); From da667a4eb55e2f09f10fabd92abbb3b1fe1c7637 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:36:16 +0900 Subject: [PATCH 18/69] =?UTF-8?q?feat:=20=EA=B2=BD=EA=B3=A0=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/icons/WarningIcon.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/components/icons/WarningIcon.tsx diff --git a/src/components/icons/WarningIcon.tsx b/src/components/icons/WarningIcon.tsx new file mode 100644 index 00000000..2fabb3b4 --- /dev/null +++ b/src/components/icons/WarningIcon.tsx @@ -0,0 +1,14 @@ +"use client"; +interface WarningIconProps { + width?: number; + height?: number; +} +export default function WarningIcon({ width = 18, height = 18 }: WarningIconProps) { + return ( + + + + + + ); +} From bd7f4bb56da841a68390ce5852a275977500d1b8 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:36:43 +0900 Subject: [PATCH 19/69] =?UTF-8?q?feat:=20=EC=97=AC=ED=96=89=20=EA=B1=B0?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=9C=EB=A0=A5=20=ED=98=95=EC=8B=9D=20utils=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 --- src/utils/formatNumberWithComma.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/utils/formatNumberWithComma.ts diff --git a/src/utils/formatNumberWithComma.ts b/src/utils/formatNumberWithComma.ts new file mode 100644 index 00000000..7497f48d --- /dev/null +++ b/src/utils/formatNumberWithComma.ts @@ -0,0 +1,4 @@ +export const formatNumberWithComma = (num: number | string): string => { + const n = typeof num === "number" ? num.toString() : num; + return n.replace(/\B(?=(\d{3})+(?!\d))/g, ","); +}; From 0b2f6b98745b456c0176227e717203f3943c74a0 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 13:37:29 +0900 Subject: [PATCH 20/69] =?UTF-8?q?fix:=20=EC=8B=A0=EA=B3=A0=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EC=9D=B4=EC=A0=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?userProfile=EB=8F=84=20case=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/Report/ReportDetail.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/page/Report/ReportDetail.tsx b/src/page/Report/ReportDetail.tsx index d7c0f272..27804f57 100644 --- a/src/page/Report/ReportDetail.tsx +++ b/src/page/Report/ReportDetail.tsx @@ -14,6 +14,7 @@ import { authStore } from "@/store/client/authStore"; import { reportStore } from "@/store/client/reportStore"; import { useMutation } from "@tanstack/react-query"; import { errorStore } from "@/store/client/errorStore"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; const ReportDetail = () => { const { reportType, id, type: backType } = useParams(); @@ -75,6 +76,14 @@ const ReportDetail = () => { setReportSuccess(true); }, 300); return; + case "userProfile": + const { setProfileShow } = userProfileOverlayStore(); + setProfileShow(true); + setUserNumber(null); + setTimeout(() => { + setReportSuccess(true); + }, 300); + return; default: router.replace("/"); } From 6d855821c073d07e0ba1730fa15b2955b74d45b3 Mon Sep 17 00:00:00 2001 From: mayrang Date: Sun, 20 Apr 2025 18:27:38 +0900 Subject: [PATCH 21/69] =?UTF-8?q?Feat:=20countryName:=20=ED=95=9C=EA=B5=AD?= =?UTF-8?q?=20->=20=EB=8C=80=ED=95=9C=EB=AF=BC=EA=B5=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TripRegion.tsx | 7 +- .../CreateTripDetail/RegionWrapper.tsx | 43 ++------- src/page/TripDetail/TripDetail.tsx | 90 ++++--------------- src/page/TripDetail/TripEdit.tsx | 2 +- 4 files changed, 26 insertions(+), 116 deletions(-) diff --git a/src/components/TripRegion.tsx b/src/components/TripRegion.tsx index ad7a60fe..0991ce91 100644 --- a/src/components/TripRegion.tsx +++ b/src/components/TripRegion.tsx @@ -71,7 +71,7 @@ const TripRegion = ({ addLocationName({ locationName: keyword, mapType: "kakao", - countryName: "한국", + countryName: "대한민국", }); } else { addLocationName({ @@ -124,10 +124,7 @@ const TripRegion = ({ {showRelationList && ( <> - + )} diff --git a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx index d519a2fa..2f313593 100644 --- a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx @@ -5,12 +5,7 @@ import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; import React, { useCallback, useEffect, useState } from "react"; -import { - APIProvider, - Map, - useMap, - useMapsLibrary, -} from "@vis.gl/react-google-maps"; +import { APIProvider, Map, useMap, useMapsLibrary } from "@vis.gl/react-google-maps"; import RegionModal from "@/components/RegionModal"; interface RegionInfo { @@ -18,14 +13,7 @@ interface RegionInfo { adminArea: string | null; } -const InnerMap = ({ - locationNameStr, - locationName, - setRegionInfo, - addInitGeometry, - addLocationName, - isLoad, -}) => { +const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometry, addLocationName, isLoad }) => { const map = useMap(); const placesLib = useMapsLibrary("places"); @@ -44,10 +32,7 @@ const InnerMap = ({ service.findPlaceFromQuery(request, (results, status) => { if (status === google.maps.places.PlacesServiceStatus.OK && results) { console.log(results, "result"); - if ( - results[0].geometry?.location?.lat() && - results[0].geometry?.location?.lng() - ) { + if (results[0].geometry?.location?.lat() && results[0].geometry?.location?.lng()) { addInitGeometry({ lat: results[0].geometry?.location?.lat(), lng: results[0].geometry?.location?.lng(), @@ -55,9 +40,7 @@ const InnerMap = ({ } if (results[0]) { - const parts = results[0].formatted_address - ?.split(",") - .map((part) => part.trim()); + const parts = results[0].formatted_address?.split(",").map((part) => part.trim()); setRegionInfo({ country: parts ? parts[parts.length - 1] : null, adminArea: parts ? parts[parts.length - 2] : null, @@ -89,10 +72,7 @@ const InnerMap = ({ geocoder.addressSearch(locationNameStr, (result, status) => { console.log(result, "result"); - if ( - status === window.kakao.maps.services.Status.OK && - result.length > 0 - ) { + if (status === window.kakao.maps.services.Status.OK && result.length > 0) { if (result[0].x && result[0].y) { addInitGeometry({ lat: Number(result[0].y), @@ -100,13 +80,13 @@ const InnerMap = ({ }); } setRegionInfo({ - country: "한국", + country: "대한민국", adminArea: result[0]?.address_name ?? locationNameStr, }); addLocationName({ locationName: locationName.locationName, mapType: "kakao", - countryName: "한국", + countryName: "대한민국", }); } else { addInitGeometry(null); @@ -123,14 +103,7 @@ const InnerMap = ({ if (!isLoad) return; handleKakaoInfo(); } - }, [ - locationName.mapType, - map, - placesLib, - isLoad, - fetchPlaceInfo, - handleKakaoInfo, - ]); + }, [locationName.mapType, map, placesLib, isLoad, fetchPlaceInfo, handleKakaoInfo]); return ( (null); const [isApplyToast, setIsApplyToast] = useState(false); const [isCancelToast, setIsCancelToast] = useState(false); @@ -135,15 +133,7 @@ export default function TripDetail() { const allCompanions = (companions as any)?.data?.companions; const alreadyApplied = !!enrollmentNumber; const [ref, inView] = useInView(); - const { - data, - isLoading, - error, - fetchNextPage, - refetch, - isFetching, - hasNextPage, - } = useInfiniteQuery({ + const { data, isLoading, error, fetchNextPage, refetch, isFetching, hasNextPage } = useInfiniteQuery({ queryKey: ["plans", travelNumber], queryFn: ({ pageParam }) => { return getPlans(Number(travelNumber), pageParam) as any; @@ -158,10 +148,7 @@ export default function TripDetail() { } }, }); - const combinedPlans = data?.pages.reduce( - (acc, page) => acc.concat(page.plans), - [] - ); + const combinedPlans = data?.pages.reduce((acc, page) => acc.concat(page.plans), []); useInfiniteScroll(() => { if (inView) { !isFetching && hasNextPage && fetchNextPage(); @@ -200,7 +187,7 @@ export default function TripDetail() { addLocationName({ locationName: location, mapType: "kakao", - countryName: "", + countryName: "대한민국", }); } else { addLocationName({ @@ -321,30 +308,15 @@ export default function TripDetail() { return ( <> - + - - + + 여행 날짜 - {startDate && endDate - ? formatDateRange(startDate, endDate) - : "날짜를 선택하세요."} + {startDate && endDate ? formatDateRange(startDate, endDate) : "날짜를 선택하세요."} @@ -513,9 +483,7 @@ export default function TripDetail() { startDate={startDate} setOpenItemIndex={setOpenItemIndex} openItemIndex={openItemIndex} - inView={ -
- } + inView={
} slides={combinedPlans} // 모든 데이터를 하나의 슬라이드 컴포넌트에 전달 /> )} @@ -524,12 +492,7 @@ export default function TripDetail() { ) : ( <> - 댓글이 없습니다 + 댓글이 없습니다 등록된 일정이 없어요 @@ -584,21 +547,12 @@ export default function TripDetail() { } > - + {isCommentUpdated ? ( - + - + @@ -641,13 +588,7 @@ export default function TripDetail() { ) : ( - + ` - padding-top: ${(props) => - `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; + padding-top: ${(props) => `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; min-height: 100svh; transition: padding-top 0.3s ease-out; overscroll-behavior: none; diff --git a/src/page/TripDetail/TripEdit.tsx b/src/page/TripDetail/TripEdit.tsx index 5f9a9056..962ce025 100644 --- a/src/page/TripDetail/TripEdit.tsx +++ b/src/page/TripDetail/TripEdit.tsx @@ -140,7 +140,7 @@ const TripEdit = () => { addLocationName({ locationName: location, mapType: "kakao", - countryName: "한국", + countryName: "대한민국", }); } else { addLocationName({ From 18cd2f32b2ebf809c92eef26f88e8240ee1e59cb Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 19:17:43 +0900 Subject: [PATCH 22/69] =?UTF-8?q?fix:=20ageGroup=20=EC=83=81=EB=8C=80?= =?UTF-8?q?=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20api=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20=EB=B0=98=EC=98=81=20=3D>=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=EC=97=90=EB=8F=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=83=81=EB=8C=80=EB=B0=A9=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20api=20=EC=9E=AC=ED=99=9C=EC=9A=A9=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=ED=96=88=EB=8D=98=20=EB=B6=80=EB=B6=84=20?= =?UTF-8?q?->=20=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4=EC=A7=80=20api=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EA=B0=92=20=EC=B6=94=EA=B0=80=EB=A1=9C=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20store,=20model=20=EB=93=B1=EC=9D=84=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/components/Layout.tsx | 9 ++-- .../userProfile/UserProfileDetail.tsx | 45 +++++++++++++------ src/hooks/userProfile/useUserProfile.ts | 14 +++--- src/model/myPages.ts | 4 ++ src/model/userProfile.ts | 1 + 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 086c3b27..135e7ed0 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -50,8 +50,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const myPageData: ImyPage = data as any; const profileImg: IProfileImg = profileImage as IProfileImg; - const myProfileInfo: IUserProfileInfo = userProfileInfo as IUserProfileInfo; - console.log(profileImg, profileImage, myProfileInfo, "프로필"); + console.log(profileImg, profileImage, "프로필"); useEffect(() => { if (!isLoading && myPageData) { addName(myPageData.name); @@ -60,9 +59,9 @@ const Layout = ({ children }: { children: React.ReactNode }) => { addPreferredTags(myPageData.preferredTags); addGender(myPageData.gender); addUserSocialTF(myPageData.userSocialTF); - addTravelDistance(myProfileInfo?.travelDistance); - addTravelBadgeCount(myProfileInfo?.travelBadgeCount); - addVisitedCountryCount(myProfileInfo?.visitedCountryCount); + addTravelDistance(myPageData.travelDistance); + addTravelBadgeCount(myPageData.travelBadgeCount); + addVisitedCountryCount(myPageData.visitedCountryCount); const tags: string[] = []; for (const tag of myPageData.preferredTags) { const text = tag.split(" "); diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index b05ddb4e..7c2fec35 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -21,27 +21,46 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); const { userProfileInfo, isLoadingUserProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); - const { agegroup: myAgeGroup, email: myEmail } = myPageStore(); + if (!userProfileInfo) return null; - const { name, recentReportCount, userRegDate, preferredTags, travelDistance, travelBadgeCount, visitedCountryCount } = - userProfileInfo; + const { + ageGroup, + name, + recentReportCount, + userRegDate, + preferredTags, + travelDistance, + travelBadgeCount, + visitedCountryCount, + } = userProfileInfo; + const { + name: myName, + agegroup: myAgeGroup, + email: myEmail, + preferredTags: myPreferredTags, + travelDistance: myTravelDistance, + travelBadgeCount: myTravelBageCount, + visitedCountryCount: myVisitedCountryCount, + } = myPageStore(); const TravelMenuList = [ { Icon: CloverIcon, label: "방문한 국가", - count: visitedCountryCount, + count: isMyPage ? myVisitedCountryCount : visitedCountryCount, nextLink: `/userProfile/${userProfileUserId}/log`, }, { Icon: CloverIcon, label: "여행 배지", - count: travelBadgeCount, + count: isMyPage ? myTravelBageCount : travelBadgeCount, nextLink: `/userProfileBadge/${userProfileUserId}`, }, ]; - const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; + const preferredTagsTarget = isMyPage ? myPreferredTags : preferredTags; + + const cutTags = preferredTagsTarget.length > 2 ? preferredTagsTarget.slice(0, 2) : preferredTagsTarget; const moveToNextLink = (link: string) => { navigateWithTransition(link); @@ -49,12 +68,12 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai setProfileShow(false); }, 50); }; - const IS_REPORTED = true; + const IS_REPORTED = recentReportCount > 0; const editMyProfileInfo = () => { document.documentElement.style.viewTransitionName = "forward"; navigateWithTransition("/editMyInfo"); }; - const tempAgeGroup = "00대"; // 임시 값 + return ( @@ -64,7 +83,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai - {name} + {isMyPage ? myName : name} {isMyPage && } {isMyPage ? myEmail : userRegDate + "가입"} @@ -75,7 +94,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai fontWeight="600" color={palette.keycolor} backgroundColor={palette.keycolorBG} - text={isMyPage ? myAgeGroup : tempAgeGroup} + text={isMyPage ? myAgeGroup : ageGroup} /> {cutTags.map((text: string) => ( ))} - {preferredTags.length > cutTags.length ? ( + {preferredTagsTarget.length > cutTags.length ? ( - {IS_REPORTED && ( + {IS_REPORTED && !isMyPage && ( 최근 신고가 {recentReportCount}회 누적된 회원이에요 @@ -108,7 +127,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai 총 여행한 거리✨ - {formatNumberWithComma(travelDistance)}km + {formatNumberWithComma(isMyPage ? myTravelDistance : travelDistance)}km diff --git a/src/hooks/userProfile/useUserProfile.ts b/src/hooks/userProfile/useUserProfile.ts index 90829684..6597e5c5 100644 --- a/src/hooks/userProfile/useUserProfile.ts +++ b/src/hooks/userProfile/useUserProfile.ts @@ -5,21 +5,17 @@ import { authStore } from "@/store/client/authStore"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import { useQuery, useInfiniteQuery, InfiniteData } from "@tanstack/react-query"; -const useUserProfile = ( - profileType: "mine" | "other" = "other" -): { +const useUserProfile = (): { userProfileInfo: IUserProfileInfo | undefined | null; isLoadingUserProfileInfo: boolean; } => { - const { accessToken, userId: myUserId } = authStore(); + const { accessToken } = authStore(); const { userProfileUserId } = userProfileOverlayStore(); - const targetUserId = profileType === "mine" ? myUserId : userProfileUserId; - const { data: userProfileInfo, isLoading: isLoadingUserProfileInfo } = useQuery({ - queryKey: ["userProfile", targetUserId], - queryFn: () => getUserProfile(accessToken!, targetUserId!), - enabled: !!accessToken && targetUserId !== -1, + queryKey: ["userProfile", userProfileUserId], + queryFn: () => getUserProfile(accessToken!, userProfileUserId!), + enabled: !!accessToken && userProfileUserId !== -1, retry: !!accessToken, staleTime: 0, }); diff --git a/src/model/myPages.ts b/src/model/myPages.ts index c8e3e6ae..5d09234c 100644 --- a/src/model/myPages.ts +++ b/src/model/myPages.ts @@ -6,6 +6,10 @@ export interface ImyPage { proIntroduce: string; userSocialTF: boolean; preferredTags: string[]; + userRegDate: string; + travelDistance: number; + visitedCountryCount: number; + travelBadgeCount: number; } export interface IProfileImg { diff --git a/src/model/userProfile.ts b/src/model/userProfile.ts index 3e8578af..27ad7e1e 100644 --- a/src/model/userProfile.ts +++ b/src/model/userProfile.ts @@ -11,6 +11,7 @@ export interface IUserProfileInfo { recentlyReported: boolean; // 최근(7일) 신고 여부 totalReportCount: number; // 총 신고 횟수 recentReportCount: number; // 최근(7일) 신고 횟수 + ageGroup: string; } export interface IUserRelatedTravel { From 1921a04ba993159a83a475c5f4c060d2ba48913d Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 19:59:24 +0900 Subject: [PATCH 23/69] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout.tsx | 2 -- src/hooks/userProfile/useUserProfile.ts | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 135e7ed0..89b1dfa6 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -23,8 +23,6 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const { userPostRefreshToken } = useAuth(); const { userId, accessToken, logoutCheck } = authStore(); - const { userProfileInfo } = useUserProfile("mine"); - // 유저 프로필 정보 불러오기 const { addEmail, diff --git a/src/hooks/userProfile/useUserProfile.ts b/src/hooks/userProfile/useUserProfile.ts index 6597e5c5..bd9da517 100644 --- a/src/hooks/userProfile/useUserProfile.ts +++ b/src/hooks/userProfile/useUserProfile.ts @@ -5,10 +5,7 @@ import { authStore } from "@/store/client/authStore"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import { useQuery, useInfiniteQuery, InfiniteData } from "@tanstack/react-query"; -const useUserProfile = (): { - userProfileInfo: IUserProfileInfo | undefined | null; - isLoadingUserProfileInfo: boolean; -} => { +const useUserProfile = () => { const { accessToken } = authStore(); const { userProfileUserId } = userProfileOverlayStore(); From 2e5e3f157da7b96a98af0b36fe58cf68fa89d608 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 20:02:34 +0900 Subject: [PATCH 24/69] =?UTF-8?q?fix:=20=EB=AA=A8=EB=93=88=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/UserProfileBadge/UserProfileBadge.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page/UserProfileBadge/UserProfileBadge.tsx b/src/page/UserProfileBadge/UserProfileBadge.tsx index 42e07ee0..a44433c3 100644 --- a/src/page/UserProfileBadge/UserProfileBadge.tsx +++ b/src/page/UserProfileBadge/UserProfileBadge.tsx @@ -3,7 +3,7 @@ import BadgeLockIcon from "@/components/icons/BadgeLockIcon"; import { palette } from "@/styles/palette"; import { useEffect } from "react"; -import styled from "styled-components"; +import styled from "@emotion/styled"; export function UserProfileBadge() { // API 요청. hooks 캐시 값 이용. From e049bb30dba55c678b98f8b96a8de001b168f00a Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 20 Apr 2025 20:08:39 +0900 Subject: [PATCH 25/69] =?UTF-8?q?fix:=20deploy=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EC=A4=91=EB=B3=B5=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=20=EB=B6=80=EB=B6=84=EC=9D=B4=20=EC=9B=90=EC=9D=B8=20?= =?UTF-8?q?-=20=EA=B8=B0=ED=83=80=20=EB=B6=80=EB=B6=84=EC=9D=80=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HorizonBoxLayout.tsx | 3 +-- src/components/Layout.tsx | 11 +------- .../userProfile/UserProfileDetail.tsx | 10 ++------ .../userProfile/UserProfileOverlay.tsx | 3 --- .../userProfile/UserProfileOverlayHeader.tsx | 7 ------ .../userProfile/UserTravelTabMenu.tsx | 7 +----- src/page/MyPage/MyPage.tsx | 25 ------------------- src/page/MyTrip/HostTrip.tsx | 2 -- 8 files changed, 5 insertions(+), 63 deletions(-) diff --git a/src/components/HorizonBoxLayout.tsx b/src/components/HorizonBoxLayout.tsx index 4e346e8a..3a960aad 100644 --- a/src/components/HorizonBoxLayout.tsx +++ b/src/components/HorizonBoxLayout.tsx @@ -9,11 +9,10 @@ import PlaceIcon from "./icons/PlaceIcon"; import FullHeartIcon from "./icons/FullHeartIcon"; import { useUpdateBookmark } from "@/hooks/bookmark/useUpdateBookmark"; import { authStore } from "@/store/client/authStore"; -import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import CheckingModal from "./designSystem/modal/CheckingModal"; import { usePathname, useRouter } from "next/navigation"; import { isGuestUser } from "@/utils/user"; -import { useBackPathStore } from "@/store/client/backPathStore"; interface HorizonBoxProps { daysLeft?: number; title: string; diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 874a4986..612f0b2a 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -5,7 +5,6 @@ import Header from "./Header"; import Navbar from "@/page/Home/Navbar"; import { authStore } from "@/store/client/authStore"; -import path from "path"; import { palette } from "@/styles/palette"; import useAuth from "@/hooks/user/useAuth"; import { myPageStore } from "@/store/client/myPageStore"; @@ -16,12 +15,10 @@ import { splashOnStore } from "@/store/client/splashOnOffStore"; import { usePathname } from "next/navigation"; import { APIProvider } from "@vis.gl/react-google-maps"; import { useHeaderNavigation } from "@/hooks/useHeaderNavigation"; -import useUserProfile from "@/hooks/userProfile/useUserProfile"; -import { IUserProfileInfo } from "@/model/userProfile"; const Layout = ({ children }: { children: React.ReactNode }) => { const pathname = usePathname(); const { userPostRefreshToken } = useAuth(); - const { userId, accessToken, logoutCheck } = authStore(); + const { accessToken, logoutCheck } = authStore(); // 유저 프로필 정보 불러오기 @@ -32,23 +29,17 @@ const Layout = ({ children }: { children: React.ReactNode }) => { addGender, addAgegroup, addPreferredTags, - profileUrl, addUserSocialTF, addTravelDistance, addVisitedCountryCount, addTravelBadgeCount, } = myPageStore(); - const { addEmail, addProfileUrl, addName, addGender, addAgegroup, addPreferredTags, profileUrl, addUserSocialTF } = - myPageStore(); - - const { data, isLoading, profileImage, isLoadingImage, firstProfileImageMutation, isFirstProfileImagePostSuccess } = useMyPage(); console.log(data, "user data"); const isOnboarding = pathname?.startsWith("/onBoarding"); - const isCommunityDetail = pathname?.startsWith("/community/detail"); const { ROUTES, checkRoute } = useHeaderNavigation(); const myPageData: ImyPage = data as any; diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 7c2fec35..4cfcdce1 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -2,7 +2,7 @@ import { myPageStore } from "@/store/client/myPageStore"; import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; -import React, { useEffect, useState } from "react"; +import React from "react"; import useViewTransition from "@/hooks/useViewTransition"; import CloverIcon from "../icons/CloverIcon"; @@ -19,7 +19,7 @@ interface UserProfileDetailProps { } export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); - const { userProfileInfo, isLoadingUserProfileInfo } = useUserProfile(); + const { userProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); if (!userProfileInfo) return null; @@ -186,12 +186,6 @@ const ProfileImgContainer = styled.div` margin-bottom: 12px; `; -const ProfileImg = styled.img` - width: 100%; - height: 100%; - object-fit: cover; -`; - const UserTextInfoContainer = styled.div` display: flex; flex-direction: column; diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index 9b8ff6ae..797142e9 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -1,10 +1,7 @@ "use client"; -import { myPageStore } from "@/store/client/myPageStore"; -import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; import React, { useEffect, useRef, useState } from "react"; -import useViewTransition from "@/hooks/useViewTransition"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import { keyframes } from "@emotion/react"; import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; diff --git a/src/components/userProfile/UserProfileOverlayHeader.tsx b/src/components/userProfile/UserProfileOverlayHeader.tsx index 59b92c46..a05afa32 100644 --- a/src/components/userProfile/UserProfileOverlayHeader.tsx +++ b/src/components/userProfile/UserProfileOverlayHeader.tsx @@ -1,16 +1,9 @@ "use client"; import styled from "@emotion/styled"; -import TripDetailHeader from "@/page/TripDetail/TripDetailHeader"; import { palette } from "@/styles/palette"; -import { useHeaderNavigation } from "@/hooks/useHeaderNavigation"; -import { useRouter, useSearchParams } from "next/navigation"; -import Link from "next/link"; -import { createTripStore } from "@/store/client/createTripStore"; import CloseIcon from "../icons/CloseIcon"; -import MoreIcon from "../icons/MoreIcon"; import ProfileMoreIcon from "../icons/ProfileMoreIcon"; -import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import ReportModal from "../designSystem/modal/ReportModal"; import { useEffect, useState } from "react"; import useViewTransition from "@/hooks/useViewTransition"; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 5c6f8400..151909cc 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -1,17 +1,12 @@ "use client"; -import { myPageStore } from "@/store/client/myPageStore"; import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; import React, { useEffect, useState } from "react"; import useViewTransition from "@/hooks/useViewTransition"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; -import { keyframes } from "@emotion/react"; -import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; -import UserProfileDetail from "./UserProfileDetail"; import HorizonBoxLayout from "../HorizonBoxLayout"; import { daysAgo } from "@/utils/time"; -import dayjs from "dayjs"; import { useInView } from "react-intersection-observer"; import useUserProfile from "@/hooks/userProfile/useUserProfile"; import useInfiniteScroll from "@/hooks/useInfiniteScroll"; @@ -19,7 +14,7 @@ import { IUserRelatedTravelList } from "@/model/userProfile"; import RoundedImage from "../designSystem/profile/RoundedImage"; export default function UserTravelTabMenu() { - const { setProfileShow, profileShow } = userProfileOverlayStore(); + const { setProfileShow } = userProfileOverlayStore(); const navigateWithTransition = useViewTransition(); const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); const [selectedTab, setSelectedTab] = useState(0); diff --git a/src/page/MyPage/MyPage.tsx b/src/page/MyPage/MyPage.tsx index 0a81ed1f..3eb01cfa 100644 --- a/src/page/MyPage/MyPage.tsx +++ b/src/page/MyPage/MyPage.tsx @@ -1,13 +1,10 @@ "use client"; -import Badge from "@/components/designSystem/Badge"; import CheckingModal from "@/components/designSystem/modal/CheckingModal"; -import RoundedImage from "@/components/designSystem/profile/RoundedImage"; import TextButton from "@/components/designSystem/text/TextButton"; import RightVector from "@/components/icons/RightVector"; import Spacing from "@/components/Spacing"; import UserProfileDetail from "@/components/userProfile/UserProfileDetail"; import useViewTransition from "@/hooks/useViewTransition"; -import { myPageStore } from "@/store/client/myPageStore"; import { palette } from "@/styles/palette"; import { isGuestUser } from "@/utils/user"; import styled from "@emotion/styled"; @@ -16,10 +13,8 @@ import { useState } from "react"; export default function MyPage() { const navigateWithTransition = useViewTransition(); - const { name, agegroup, email, preferredTags, profileUrl } = myPageStore(); const [showLoginModal, setShowLoginModal] = useState(false); const router = useRouter(); - const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; const onLinkAnnouncement = () => { document.documentElement.style.viewTransitionName = "forward"; navigateWithTransition("/announcement"); @@ -139,11 +134,6 @@ const UserName = styled.div` margin-right: 4px; `; -const Tags = styled.div` - display: flex; - gap: 8px; - flex-wrap: wrap; -`; const LoginInfo = styled.div` font-size: 14px; font-weight: 400; @@ -156,21 +146,6 @@ const LoginInfo = styled.div` color: ${palette.비강조}; `; -const Email = styled.div` - font-size: 14px; - font-weight: 400; - line-height: 16px; - color: ${palette.비강조}; - margin-bottom: 9px; -`; -const UserInfo = styled.div` - width: 100%; - background-color: ${palette.검색창}; - padding: 24px 16px; - gap: 16px; - border-radius: 20px; - display: flex; -`; const Menu = styled.div` margin-top: 24px; width: 100%; diff --git a/src/page/MyTrip/HostTrip.tsx b/src/page/MyTrip/HostTrip.tsx index a982bb47..ee2ed8e1 100644 --- a/src/page/MyTrip/HostTrip.tsx +++ b/src/page/MyTrip/HostTrip.tsx @@ -1,5 +1,4 @@ "use client"; -import MyTripHorizonBoxLayout from "@/components/MyTripHorizonBoxLayout"; import { useMyTrip } from "@/hooks/myTrip/useMyTrip"; import useInfiniteScroll from "@/hooks/useInfiniteScroll"; import { palette } from "@/styles/palette"; @@ -15,7 +14,6 @@ import { IMyTripList } from "@/model/myTrip"; import { daysAgo } from "@/utils/time"; import { isGuestUser } from "@/utils/user"; import LoginButtonForGuest from "@/components/LoginButtonForGuest"; -import Link from "next/link"; import { useBackPathStore } from "@/store/client/backPathStore"; import { useRouter } from "next/navigation"; import HorizonBoxLayout from "@/components/HorizonBoxLayout"; From 6e6f9137fe49e813b5b02e2b9fa6512736efb0ca Mon Sep 17 00:00:00 2001 From: mayrang Date: Sun, 20 Apr 2025 21:09:37 +0900 Subject: [PATCH 26/69] =?UTF-8?q?Fix:=20pr=20=EC=BD=94=EB=A9=98=ED=8A=B8?= =?UTF-8?q?=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/map/TravelLogMap.tsx | 35 +++++++---------- .../{AriaDropdown.tsx => AreaDropdown.tsx} | 39 ++++++++++--------- .../{AriaFilter.tsx => AreaFilter.tsx} | 2 +- src/page/TravelLog/TravelLog.tsx | 13 ++++--- 4 files changed, 42 insertions(+), 47 deletions(-) rename src/components/travellog/{AriaDropdown.tsx => AreaDropdown.tsx} (82%) rename src/components/travellog/{AriaFilter.tsx => AreaFilter.tsx} (97%) diff --git a/src/components/map/TravelLogMap.tsx b/src/components/map/TravelLogMap.tsx index 08c57b8c..30326ce7 100644 --- a/src/components/map/TravelLogMap.tsx +++ b/src/components/map/TravelLogMap.tsx @@ -61,36 +61,27 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 }); geoJsonLayer.addGeoJson(type === "국내" ? sigoonGeoJsonData : countryGeoJsonData); + // 고차 함수로 사용 + const createHighlighter = (highlightedRegions, cityDistricts) => (regionName) => + highlightedRegions.includes(regionName) || + highlightedRegions.some((region) => cityDistricts[region]?.includes(regionName)); + // 하이라이트 함수 만들기 + const isHighlighted = createHighlighter(highlightedRegions, cityDistricts); + + //스타일 적용 geoJsonLayer.setStyle((feature) => { - const regionName: any = - feature.getProperty("name_ko") || // 대륙/국가에 사용될 수 있는 속성명 - feature.getProperty("CTP_KOR_NM") || // 한국 시도 속성명 - feature.getProperty("SIG_KOR_NM"); // 한국 시군구 속성명 - - // 하이랑이트 함수 - - const shouldHighlight = () => { - // 1. 직접 일치 (시/군/구명) - if (highlightedRegions.includes(regionName)) return true; - - // 2. cityDistricts의 key(예: "서울")가 하이라이트 대상인 경우 - for (const region of highlightedRegions) { - if (cityDistricts[region]?.includes(regionName)) { - return true; - } - } - return false; - }; + const regionName = + feature.getProperty("name_ko") || feature.getProperty("CTP_KOR_NM") || feature.getProperty("SIG_KOR_NM"); - const isHighlighted = shouldHighlight(); + const highlighted = isHighlighted(regionName); return { strokeColor: "#fff", strokeWeight: 1, strokeOpacity: 1, - fillColor: isHighlighted ? "#3366FF" : "#FFFFFF", // 하이라이트된 지역은 파란색 - fillOpacity: isHighlighted ? 1 : 0, // 하이라이트된 지역만 채우기 표시 + fillColor: highlighted ? "#3366FF" : "#FFFFFF", + fillOpacity: highlighted ? 1 : 0, }; }); }, [map]); diff --git a/src/components/travellog/AriaDropdown.tsx b/src/components/travellog/AreaDropdown.tsx similarity index 82% rename from src/components/travellog/AriaDropdown.tsx rename to src/components/travellog/AreaDropdown.tsx index cb42457c..a3d633f7 100644 --- a/src/components/travellog/AriaDropdown.tsx +++ b/src/components/travellog/AreaDropdown.tsx @@ -8,7 +8,7 @@ import BottomModal from "../BottomModal"; import ButtonContainer from "../ButtonContainer"; import Button from "../designSystem/Buttons/Button"; -interface AriaDropdownProps { +interface AreaDropdownProps { data: { [key: string]: { locationName?: string; @@ -19,7 +19,7 @@ interface AriaDropdownProps { setTarget: React.Dispatch>; } -const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { +const AreaDropdown = ({ data, setTarget }: AreaDropdownProps) => { const [showModal, setShowModal] = useState(false); const [targetData, setTargetData] = useState<{ locationName?: string; @@ -44,22 +44,7 @@ const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { {targetData?.visitDates.map((date) => ( - - - - - - +
{dayjs(date).format("YY.MM.DD")}
))} @@ -106,6 +91,22 @@ const AriaDropdown = ({ data, setTarget }: AriaDropdownProps) => { ); }; +const ClockIcon = () => { + return ( + + + + + + + ); +}; + const Container = styled.div` padding: 0 24px; `; @@ -183,4 +184,4 @@ const VisitItem = styled.div` line-height: 16px; font-weight: 400; `; -export default AriaDropdown; +export default AreaDropdown; diff --git a/src/components/travellog/AriaFilter.tsx b/src/components/travellog/AreaFilter.tsx similarity index 97% rename from src/components/travellog/AriaFilter.tsx rename to src/components/travellog/AreaFilter.tsx index 6f7566cf..08f80e04 100644 --- a/src/components/travellog/AriaFilter.tsx +++ b/src/components/travellog/AreaFilter.tsx @@ -10,7 +10,7 @@ const FILTER_LIST = [ { value: "국내", title: "국내" }, ] as const; -export default function AriaFilter() { +export default function AreaFilter() { const searchParams = useSearchParams(); const filter = searchParams.get("filter") ?? "세계"; const router = useRouter(); diff --git a/src/page/TravelLog/TravelLog.tsx b/src/page/TravelLog/TravelLog.tsx index 07824f3e..b9b439c2 100644 --- a/src/page/TravelLog/TravelLog.tsx +++ b/src/page/TravelLog/TravelLog.tsx @@ -2,8 +2,10 @@ import { getUserTravelLog } from "@/api/user"; import TravelLogMap from "@/components/map/TravelLogMap"; import AllTravelCount from "@/components/travellog/AllTravelCount"; -import AriaDropdown from "@/components/travellog/AriaDropdown"; -import AriaFilter from "@/components/travellog/AriaFilter"; +import AreaDropdown from "@/components/travellog/AreaDropdown"; + +import AreaFilter from "@/components/travellog/AreaFilter"; + import { authStore } from "@/store/client/authStore"; import { groupRegionData } from "@/utils/travellog/travelLog"; import { useQuery } from "@tanstack/react-query"; @@ -27,7 +29,8 @@ export default function TravelLog() { useEffect(() => { if (logs) { - setTarget([Object.keys(logs)[0]]); + const targetName = Object.keys(logs)[0]; + setTarget([targetName]); } }, [JSON.stringify(logs)]); @@ -36,7 +39,7 @@ export default function TravelLog() { } return !isLoading ? (
- + {logs && ( )} {data && Boolean(data?.visitedCountriesCount > 0) && } - {logs && } + {logs && }
) : ( <> From 6619c385b7d9394f57a3f3befe6e234541bb15d8 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 08:12:45 +0900 Subject: [PATCH 27/69] =?UTF-8?q?fix:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B2=8C=EC=8A=A4=ED=8A=B8=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=ED=99=94=EB=A9=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/MyPage/MyPage.tsx | 42 ++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/page/MyPage/MyPage.tsx b/src/page/MyPage/MyPage.tsx index 3eb01cfa..12e445fa 100644 --- a/src/page/MyPage/MyPage.tsx +++ b/src/page/MyPage/MyPage.tsx @@ -1,5 +1,6 @@ "use client"; import CheckingModal from "@/components/designSystem/modal/CheckingModal"; +import RoundedImage from "@/components/designSystem/profile/RoundedImage"; import TextButton from "@/components/designSystem/text/TextButton"; import RightVector from "@/components/icons/RightVector"; import Spacing from "@/components/Spacing"; @@ -24,21 +25,27 @@ export default function MyPage() { {!isGuestUser() ? ( ) : ( - <> - setShowLoginModal(true)}> - 로그인 & 회원가입 -
- -
-
- - 로그인 후 모잉에서 -
설레는 여행을 떠나보세요. -
- + + + + +
+ setShowLoginModal(true)}> + 로그인 & 회원가입 +
+ +
+
+ + 로그인 후 모잉에서 +
설레는 여행을 떠나보세요. +
+
+
)} - + {!isGuestUser() && } + 내 활동 현황 @@ -117,6 +124,15 @@ const SpaceBox = styled.div` background-color: ${palette.검색창}; `; const ProfileImg = styled.div``; + +const UserInfo = styled.div` + width: 100%; + background-color: ${palette.검색창}; + padding: 24px 16px; + gap: 16px; + border-radius: 20px; + display: flex; +`; const Container = styled.div` padding: 0px 24px; margin-top: 8px; From 54c5e2106cad8bd0d7f7393005bd14902d979a33 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 08:16:13 +0900 Subject: [PATCH 28/69] =?UTF-8?q?fix:=20=EB=B9=8C=EB=93=9C=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/MyPage/MyPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page/MyPage/MyPage.tsx b/src/page/MyPage/MyPage.tsx index 12e445fa..e5b617ce 100644 --- a/src/page/MyPage/MyPage.tsx +++ b/src/page/MyPage/MyPage.tsx @@ -27,7 +27,7 @@ export default function MyPage() { ) : ( - +
setShowLoginModal(true)}> From c8fc60b5896b1ca319b989a3914a87e6f20a1115 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 09:23:36 +0900 Subject: [PATCH 29/69] =?UTF-8?q?fix:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=A0=8C=EB=8D=94=EB=A7=81=20null=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?-=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=9E=AC=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=EC=9D=84=20=ED=86=B5=ED=95=B4=20isMyPage=EA=B0=80=20t?= =?UTF-8?q?rue=EB=A9=B4=20null=EA=B0=80=20=EB=B0=98=ED=99=98=ED=95=B4?= =?UTF-8?q?=EB=B2=84=EB=A6=AC=EB=8A=94=20=EA=B2=83=EC=9D=B4=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20-=20=EB=B6=84=EA=B8=B0=EC=B2=98=EB=A6=AC=EB=A5=BC?= =?UTF-8?q?=20=ED=86=B5=ED=95=B4=20=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A9=B4=20myPageStore=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=A5=BC,=20=EC=95=84=EB=8B=88=EB=A9=B4=20api=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileDetail.tsx | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 4cfcdce1..4e9e5154 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -13,6 +13,7 @@ import WarningIcon from "../icons/WarningIcon"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import useUserProfile from "@/hooks/userProfile/useUserProfile"; import ProfileRightVectorIcon from "../icons/ProfileRightVectorIcon"; +import { authStore } from "@/store/client/authStore"; interface UserProfileDetailProps { isMyPage?: boolean; @@ -22,7 +23,32 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai const { userProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); - if (!userProfileInfo) return null; + if (!isMyPage && !userProfileInfo) return null; + + const profileData = isMyPage + ? { + ageGroup: myPageStore().agegroup, + name: myPageStore().name, + recentReportCount: 0, + userRegDate: "", + preferredTags: myPageStore().preferredTags, + travelDistance: myPageStore().travelDistance, + travelBadgeCount: myPageStore().travelBadgeCount, + visitedCountryCount: myPageStore().visitedCountryCount, + profileImageUrl: myPageStore().profileUrl, + } + : { + ageGroup: userProfileInfo!.ageGroup, + name: userProfileInfo!.name, + recentReportCount: userProfileInfo!.recentReportCount, + userRegDate: userProfileInfo!.userRegDate, + preferredTags: userProfileInfo!.preferredTags, + travelDistance: userProfileInfo!.travelDistance, + travelBadgeCount: userProfileInfo!.travelBadgeCount, + visitedCountryCount: userProfileInfo!.visitedCountryCount, + profileImageUrl: userProfileInfo!.profileImageUrl, + }; + const { ageGroup, name, @@ -32,35 +58,25 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai travelDistance, travelBadgeCount, visitedCountryCount, - } = userProfileInfo; - const { - name: myName, - agegroup: myAgeGroup, - email: myEmail, - preferredTags: myPreferredTags, - travelDistance: myTravelDistance, - travelBadgeCount: myTravelBageCount, - visitedCountryCount: myVisitedCountryCount, - } = myPageStore(); + profileImageUrl, + } = profileData; const TravelMenuList = [ { Icon: CloverIcon, label: "방문한 국가", - count: isMyPage ? myVisitedCountryCount : visitedCountryCount, - nextLink: `/userProfile/${userProfileUserId}/log`, + count: visitedCountryCount, + nextLink: `/userProfile/${isMyPage ? authStore().userId : userProfileUserId}/log`, }, { Icon: CloverIcon, label: "여행 배지", - count: isMyPage ? myTravelBageCount : travelBadgeCount, - nextLink: `/userProfileBadge/${userProfileUserId}`, + count: travelBadgeCount, + nextLink: `/userProfileBadge/${isMyPage ? authStore().userId : userProfileUserId}`, }, ]; - const preferredTagsTarget = isMyPage ? myPreferredTags : preferredTags; - - const cutTags = preferredTagsTarget.length > 2 ? preferredTagsTarget.slice(0, 2) : preferredTagsTarget; + const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; const moveToNextLink = (link: string) => { navigateWithTransition(link); @@ -78,15 +94,15 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai - + - {isMyPage ? myName : name} + {name} {isMyPage && } - {isMyPage ? myEmail : userRegDate + "가입"} + {isMyPage ? myPageStore().email : userRegDate + "가입"} {cutTags.map((text: string) => ( ))} - {preferredTagsTarget.length > cutTags.length ? ( + {preferredTags.length > cutTags.length ? ( 총 여행한 거리✨ - {formatNumberWithComma(isMyPage ? myTravelDistance : travelDistance)}km + {formatNumberWithComma(travelDistance)}km From ad545f3cc2a177952cae11903893cdaca442d1fc Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 09:45:53 +0900 Subject: [PATCH 30/69] =?UTF-8?q?fix:=20=EC=97=AC=ED=96=89=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EA=B0=9C=EC=88=98=20=EC=9E=84=EC=8B=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=84=A3=EC=9D=80=20=EB=B6=80=EB=B6=84=20?= =?UTF-8?q?=3D>=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileDetail.tsx | 2 +- .../UserProfileBadge/UserProfileBadge.tsx | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 4e9e5154..42173e3a 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -20,7 +20,7 @@ interface UserProfileDetailProps { } export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); - const { userProfileInfo } = useUserProfile(); + const navigateWithTransition = useViewTransition(); if (!isMyPage && !userProfileInfo) return null; diff --git a/src/page/UserProfileBadge/UserProfileBadge.tsx b/src/page/UserProfileBadge/UserProfileBadge.tsx index a44433c3..ca34658c 100644 --- a/src/page/UserProfileBadge/UserProfileBadge.tsx +++ b/src/page/UserProfileBadge/UserProfileBadge.tsx @@ -4,15 +4,35 @@ import BadgeLockIcon from "@/components/icons/BadgeLockIcon"; import { palette } from "@/styles/palette"; import { useEffect } from "react"; import styled from "@emotion/styled"; +import { useParams } from "next/navigation"; +import { myPageStore } from "@/store/client/myPageStore"; +import { authStore } from "@/store/client/authStore"; +import useUserProfile from "@/hooks/userProfile/useUserProfile"; export function UserProfileBadge() { // API 요청. hooks 캐시 값 이용. const tempBadgeArray = new Array(12).fill({ Icon: BadgeLockIcon, name: "배지 이름" }); + const params = useParams(); + const ID = params.userId as string; // 혹은 params['id' + const { userProfileInfo } = useUserProfile(); + + // params에서 userId가 내 꺼랑 같으면 배지 그거 쓰고, 아니라면 userProfile()쓰기. + + const profileData = + ID === authStore().userId?.toString() + ? { + travelBadgeCount: myPageStore().travelBadgeCount, + } + : { + travelBadgeCount: userProfileInfo!.travelBadgeCount, + }; + + const { travelBadgeCount } = profileData; return ( 현재 - 4 + {travelBadgeCount} 개의 배지를 획득했어요. From a4697238ce674556234baf3289ceee446e45897d Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 09:47:04 +0900 Subject: [PATCH 31/69] =?UTF-8?q?docs:=20=EC=98=A4=ED=83=80=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/components/userProfile/UserProfileDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 42173e3a..4e9e5154 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -20,7 +20,7 @@ interface UserProfileDetailProps { } export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); - + const { userProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); if (!isMyPage && !userProfileInfo) return null; From c63a742fd9d93dec8be1c6878dcd19c8af529ecf Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 10:08:09 +0900 Subject: [PATCH 32/69] =?UTF-8?q?design:=20>=20=EC=95=84=EC=9D=B4=EC=BD=98?= =?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/components/icons/ProfileRightVectorIcon.tsx | 15 ++++++++++++--- src/components/userProfile/UserProfileDetail.tsx | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/components/icons/ProfileRightVectorIcon.tsx b/src/components/icons/ProfileRightVectorIcon.tsx index 1f3abf98..5ac2c630 100644 --- a/src/components/icons/ProfileRightVectorIcon.tsx +++ b/src/components/icons/ProfileRightVectorIcon.tsx @@ -1,12 +1,21 @@ "use client"; + +import { palette } from "@/styles/palette"; + interface VectorProps { width?: number; height?: number; } -export default function ProfileRightVectorIcon({ width = 24, height = 24 }: VectorProps) { +export default function ProfileRightVectorIcon({ width = 17, height = 24 }: VectorProps) { return ( - - + + ); } diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 4e9e5154..c325abf1 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -100,7 +100,7 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai {name} - {isMyPage && } + {isMyPage && } {isMyPage ? myPageStore().email : userRegDate + "가입"} From 9bff6d846e2fe0aa7f43dbc000b71e617c5c9201 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 10:19:49 +0900 Subject: [PATCH 33/69] =?UTF-8?q?design:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=84=B8?= =?UTF-8?q?=EB=A1=9C=EC=B6=95=20=EC=A0=95=EB=A0=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserProfileDetail.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index c325abf1..ccc4e420 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -216,6 +216,8 @@ const UserNameBox = styled.div` `; export const Name = styled.div` + display: flex; + align-items: center; font-weight: 600; font-size: 20px; line-height: 16px; From 3f0a78bbe42d0220baffa41cd1f92f7a3590d09a Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 17:55:34 +0900 Subject: [PATCH 34/69] =?UTF-8?q?fix:=20moveToUserProfilePage=20use=20clie?= =?UTF-8?q?nt=20=EC=B6=94=EA=B0=80(=EC=B5=9C=EC=A2=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/tripDetail.ts | 63 ++++++++++++++----- .../userProfile/moveToUserProfilePage.ts | 1 + 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/api/tripDetail.ts b/src/api/tripDetail.ts index 6785915e..4ffc17be 100644 --- a/src/api/tripDetail.ts +++ b/src/api/tripDetail.ts @@ -4,11 +4,17 @@ import { ITripDetail } from "@/model/tripDetail"; import RequestError from "@/context/ReqeustError"; import { UpdateTripReqData } from "@/model/trip"; -export async function getTripDetail(travelNumber: number, accessToken: string | null) { +export async function getTripDetail( + travelNumber: number, + accessToken: string | null +) { try { - const response = await axiosInstance.get(`/api/travel/detail/${travelNumber}`, { - ...(accessToken && { headers: getJWTHeader(accessToken) }), - }); + const response = await axiosInstance.get( + `/api/travel/detail/${travelNumber}`, + { + ...(accessToken && { headers: getJWTHeader(accessToken) }), + } + ); return handleApiResponse(response); } catch (err: any) { throw new RequestError(err); @@ -16,40 +22,63 @@ export async function getTripDetail(travelNumber: number, accessToken: string | } // 현재 신청한 사람 수 조회 -export async function getTripEnrollmentCount(travelNumber: number, accessToken: string | null) { +export async function getTripEnrollmentCount( + travelNumber: number, + accessToken: string | null +) { try { - const response = await axiosInstance.get(`/api/travel/${travelNumber}/enrollmentCount`, { - ...(accessToken && { headers: getJWTHeader(accessToken) }), - }); + const response = await axiosInstance.get( + `/api/travel/${travelNumber}/enrollmentCount`, + { + ...(accessToken && { headers: getJWTHeader(accessToken) }), + } + ); return handleApiResponse(response); } catch (err: any) { throw new RequestError(err); } } // 모집한 인원 목록 조회 -export async function getCompanions(travelNumber: number, accessToken: string | null) { +export async function getCompanions( + travelNumber: number, + accessToken: string | null +) { try { - const response = await axiosInstance.get(`/api/travel/${travelNumber}/companions`, { - ...(accessToken && { headers: getJWTHeader(accessToken) }), - }); + const response = await axiosInstance.get( + `/api/travel/${travelNumber}/companions`, + { + ...(accessToken && { headers: getJWTHeader(accessToken) }), + } + ); return handleApiResponse(response); } catch (err: any) { throw new RequestError(err); } } -export async function updateTripDetail(travelNumber: number, data: UpdateTripReqData, accessToken: string | null) { +export async function updateTripDetail( + travelNumber: number, + data: UpdateTripReqData, + accessToken: string | null +) { try { if (!accessToken) throw new Error("로그인을 해주세요."); - const response = await axiosInstance.put(`/api/travel/${travelNumber}`, data, { - headers: getJWTHeader(accessToken), - }); + const response = await axiosInstance.put( + `/api/travel/${travelNumber}`, + data, + { + headers: getJWTHeader(accessToken), + } + ); return handleApiResponse(response); } catch (err: any) { throw new RequestError(err); } } -export async function deleteTripDetail(travelNumber: number, accessToken: string | null) { +export async function deleteTripDetail( + travelNumber: number, + accessToken: string | null +) { try { if (!accessToken) throw new Error("로그인을 해주세요."); const response = await axiosInstance.delete(`/api/travel/${travelNumber}`, { diff --git a/src/hooks/userProfile/moveToUserProfilePage.ts b/src/hooks/userProfile/moveToUserProfilePage.ts index 83d3ec9d..47482925 100644 --- a/src/hooks/userProfile/moveToUserProfilePage.ts +++ b/src/hooks/userProfile/moveToUserProfilePage.ts @@ -1,3 +1,4 @@ +"use client"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); From 43668d73eb485c701983557bb295e1b66380650f Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 18:00:39 +0900 Subject: [PATCH 35/69] =?UTF-8?q?Fix:=20moveToUserProfilePage=20store=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=95=88=EC=9C=BC=EB=A1=9C=20=EB=84=A3?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/tripDetail.ts | 2 +- src/hooks/userProfile/moveToUserProfilePage.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/api/tripDetail.ts b/src/api/tripDetail.ts index 4ffc17be..337203b7 100644 --- a/src/api/tripDetail.ts +++ b/src/api/tripDetail.ts @@ -17,7 +17,7 @@ export async function getTripDetail( ); return handleApiResponse(response); } catch (err: any) { - throw new RequestError(err); + // throw new RequestError(err); } } diff --git a/src/hooks/userProfile/moveToUserProfilePage.ts b/src/hooks/userProfile/moveToUserProfilePage.ts index 47482925..a39923fb 100644 --- a/src/hooks/userProfile/moveToUserProfilePage.ts +++ b/src/hooks/userProfile/moveToUserProfilePage.ts @@ -1,8 +1,9 @@ "use client"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; -const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); export const moveToUserProfilePage = (userNumber: number) => { + const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); + setUserProfileUserId(userNumber); setProfileShow(true); }; From 48e9b4761339df5e1777b9fa9bce1ba9f85bb09b Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 18:25:14 +0900 Subject: [PATCH 36/69] =?UTF-8?q?Fix:=20moveToUserProfilePage=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=97=90=EC=84=9C=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/comment/Comment.tsx | 110 ++++++++++++++---- .../userProfile/moveToUserProfilePage.ts | 9 -- src/page/TripDetail/TripDetail.tsx | 101 +++++++++++++--- 3 files changed, 172 insertions(+), 48 deletions(-) delete mode 100644 src/hooks/userProfile/moveToUserProfilePage.ts diff --git a/src/components/comment/Comment.tsx b/src/components/comment/Comment.tsx index 60ef5c88..294f59ff 100644 --- a/src/components/comment/Comment.tsx +++ b/src/components/comment/Comment.tsx @@ -21,7 +21,7 @@ import { isGuestUser } from "@/utils/user"; import { reportStore } from "@/store/client/reportStore"; import NoticeModal from "../designSystem/modal/NoticeModal"; import useViewTransition from "@/hooks/useViewTransition"; -import { moveToUserProfilePage } from "@/hooks/userProfile/moveToUserProfilePage"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; interface CommentProps { comment: IComment; @@ -30,23 +30,41 @@ interface CommentProps { userNumber: number; } -const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentProps) => { +const Comment = ({ + comment, + relatedType, + relatedNumber, + userNumber, +}: CommentProps) => { const { accessToken, userId } = authStore(); const [isEditBtnClicked, setIsEditBtnClicked] = useState(false); const [isDeleteBtnClicked, setIsDeleteBtnClicked] = useState(false); const [isReportBtnClicked, setIsReportBtnClicked] = useState(false); const [isResultModalOpen, setIsResultModalOpen] = useState(false); + const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); + const [checkingModalClicked, setCheckingModalClicked] = useState(false); const [successEdit, setSuccessEdit] = useState(false); const [isToastShow, setIsToastShow] = useState(false); // 삭제 완료 메시지. const [threeDotsClick, setThreeDotsClick] = useState(false); const [reportThreeDotsClick, setReportThreeDotsClick] = useState(false); - const { reportSuccess, setReportSuccess, setDetailId, setUserNumber } = reportStore(); + const { reportSuccess, setReportSuccess, setDetailId, setUserNumber } = + reportStore(); const navigateWithTransition = useViewTransition(); - const { setOpenEdit, setParentNumber, setCommentNumber, isEdit, isReply, parentNumber, commentNumber } = - commentStore(); - const { removeMutation, remove, like, unlike, updateMutation } = useComment(relatedType, relatedNumber); + const { + setOpenEdit, + setParentNumber, + setCommentNumber, + isEdit, + isReply, + parentNumber, + commentNumber, + } = commentStore(); + const { removeMutation, remove, like, unlike, updateMutation } = useComment( + relatedType, + relatedNumber + ); useEffect(() => { if (updateMutation.isSuccess) { @@ -87,10 +105,18 @@ const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentPro setIsToastShow(true); } } - }, [isDeleteBtnClicked, isEditBtnClicked, checkingModalClicked, isReportBtnClicked]); + }, [ + isDeleteBtnClicked, + isEditBtnClicked, + checkingModalClicked, + isReportBtnClicked, + ]); const onClickThreeDots = () => { - if (comment.userNumber === userId || comment.travelWriterNumber === userId) { + if ( + comment.userNumber === userId || + comment.travelWriterNumber === userId + ) { setThreeDotsClick(true); } else { setReportThreeDotsClick(true); @@ -111,6 +137,11 @@ const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentPro } }; + const moveToUserProfilePage = (userNumber: number) => { + setUserProfileUserId(userNumber); + setProfileShow(true); + }; + return ( moveToUserProfilePage(userNumber)}> - {relatedType === "travel" && comment.travelWriterNumber === comment.userNumber && ( - - - - )} + {relatedType === "travel" && + comment.travelWriterNumber === comment.userNumber && ( + + + + )} {comment.writer} · @@ -152,20 +190,33 @@ const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentPro {comment.parentNumber === 0 && !isGuestUser() && ( - {comment.repliesCount > 0 ?
{`답글 ${comment.repliesCount}`}
:
답글달기
} + {comment.repliesCount > 0 ? ( +
{`답글 ${comment.repliesCount}`}
+ ) : ( +
답글달기
+ )} )} @@ -194,17 +245,30 @@ const Comment = ({ comment, relatedType, relatedNumber, userNumber }: CommentPro modalTitle={"신고 완료"} setModalOpen={setReportSuccess} /> - +
); }; -const Container = styled.div<{ isChild: boolean; isEdit: boolean; relatedType: "community" | "travel" }>` +const Container = styled.div<{ + isChild: boolean; + isEdit: boolean; + relatedType: "community" | "travel"; +}>` padding: 16px 0; padding-left: ${(props) => (props.isChild ? "40px" : "0")}; border-bottom: 1px solid ${palette.비강조4}; background-color: ${(props) => - props.isEdit ? "rgba(227, 239, 217, 0.3)" : props.relatedType === "community" ? "#f5f5f5" : palette.BG}; + props.isEdit + ? "rgba(227, 239, 217, 0.3)" + : props.relatedType === "community" + ? "#f5f5f5" + : palette.BG}; `; const TopContainer = styled.div` diff --git a/src/hooks/userProfile/moveToUserProfilePage.ts b/src/hooks/userProfile/moveToUserProfilePage.ts deleted file mode 100644 index a39923fb..00000000 --- a/src/hooks/userProfile/moveToUserProfilePage.ts +++ /dev/null @@ -1,9 +0,0 @@ -"use client"; -import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; - -export const moveToUserProfilePage = (userNumber: number) => { - const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); - - setUserProfileUserId(userNumber); - setProfileShow(true); -}; diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index 1ac27e65..6300bf7e 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -41,8 +41,8 @@ import { useInView } from "react-intersection-observer"; import useInfiniteScroll from "@/hooks/useInfiniteScroll"; import EmblaCarousel from "@/components/TripCarousel"; import useComment from "@/hooks/comment/useComment"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; -import { moveToUserProfilePage } from "@/hooks/userProfile/moveToUserProfilePage"; const WEEKDAY = ["일", "월", "화", "수", "목", "금", "토"]; function verifyGenderType(genderType: string | null, gender: string) { @@ -70,10 +70,13 @@ export default function TripDetail() { const [showApplyModal, setShowApplyModal] = useState(false); const [showCancelModal, setShowCancelModal] = useState(false); const [showLoginModal, setShowLoginModal] = useState(false); - const [modalTextForLogin, setModalTextForLogin] = useState(LOGIN_ASKING_FOR_WATCHING_COMMENT); + const [modalTextForLogin, setModalTextForLogin] = useState( + LOGIN_ASKING_FOR_WATCHING_COMMENT + ); const detailRef = useRef(null); const [isApplyToast, setIsApplyToast] = useState(false); const [isCancelToast, setIsCancelToast] = useState(false); + const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); // 신청 대기 모달 const [noticeModal, setNoticeModal] = useState(false); @@ -136,7 +139,15 @@ export default function TripDetail() { const allCompanions = (companions as any)?.data?.companions; const alreadyApplied = !!enrollmentNumber; const [ref, inView] = useInView(); - const { data, isLoading, error, fetchNextPage, refetch, isFetching, hasNextPage } = useInfiniteQuery({ + const { + data, + isLoading, + error, + fetchNextPage, + refetch, + isFetching, + hasNextPage, + } = useInfiniteQuery({ queryKey: ["plans", travelNumber], queryFn: ({ pageParam }) => { return getPlans(Number(travelNumber), pageParam) as any; @@ -151,7 +162,10 @@ export default function TripDetail() { } }, }); - const combinedPlans = data?.pages.reduce((acc, page) => acc.concat(page.plans), []); + const combinedPlans = data?.pages.reduce( + (acc, page) => acc.concat(page.plans), + [] + ); useInfiniteScroll(() => { if (inView) { !isFetching && hasNextPage && fetchNextPage(); @@ -284,6 +298,12 @@ export default function TripDetail() { } } }; + + const moveToUserProfilePage = (userNumber: number) => { + setUserProfileUserId(userNumber); + setProfileShow(true); + }; + useEffect(() => { if (cancelMutation.isSuccess) { setIsCancelToast(true); @@ -311,15 +331,30 @@ export default function TripDetail() { return ( <> - + - - + + - moveToUserProfilePage(userNumber)}> + moveToUserProfilePage(userNumber)} + > {/* 프로필 */}
@@ -437,7 +474,9 @@ export default function TripDetail() { 여행 날짜 - {startDate && endDate ? formatDateRange(startDate, endDate) : "날짜를 선택하세요."} + {startDate && endDate + ? formatDateRange(startDate, endDate) + : "날짜를 선택하세요."} @@ -486,7 +525,9 @@ export default function TripDetail() { startDate={startDate} setOpenItemIndex={setOpenItemIndex} openItemIndex={openItemIndex} - inView={
} + inView={ +
+ } slides={combinedPlans} // 모든 데이터를 하나의 슬라이드 컴포넌트에 전달 /> )} @@ -495,7 +536,12 @@ export default function TripDetail() { ) : ( <> - 댓글이 없습니다 + 댓글이 없습니다 등록된 일정이 없어요 @@ -550,12 +596,21 @@ export default function TripDetail() { } > - + {isCommentUpdated ? ( - + - + @@ -591,7 +653,13 @@ export default function TripDetail() { ) : ( - + ` - padding-top: ${(props) => `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; + padding-top: ${(props) => + `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; min-height: 100svh; transition: padding-top 0.3s ease-out; overscroll-behavior: none; From bea92ea09db7c3b15188579dc94958a538545cfc Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 18:30:44 +0900 Subject: [PATCH 37/69] =?UTF-8?q?Fix:=20api=20=ED=98=B8=EC=B6=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/tripDetail.ts | 2 +- src/api/user.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/api/tripDetail.ts b/src/api/tripDetail.ts index 337203b7..4ffc17be 100644 --- a/src/api/tripDetail.ts +++ b/src/api/tripDetail.ts @@ -17,7 +17,7 @@ export async function getTripDetail( ); return handleApiResponse(response); } catch (err: any) { - // throw new RequestError(err); + throw new RequestError(err); } } diff --git a/src/api/user.ts b/src/api/user.ts index 8355d3fb..6b8f99a5 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -73,7 +73,11 @@ export async function checkEmail(email: string) { } } -export const getToken = async (domain: "naver" | "kakao" | "google", code: string, state: string) => { +export const getToken = async ( + domain: "naver" | "kakao" | "google", + code: string, + state: string +) => { try { const url = domain === "kakao" @@ -98,10 +102,13 @@ export const getToken = async (domain: "naver" | "kakao" | "google", code: strin } }; -export async function getUserTravelLog(userNumber: number, accessToken: string | null) { +export async function getUserTravelLog( + userNumber: number, + accessToken: string | null +) { try { - const response = await axios.get( - `http://localhost:9999/api/users//${userNumber}/visited-countries`, + const response = await axiosInstance.get( + `/api/users//${userNumber}/visited-countries`, { ...(accessToken && { headers: getJWTHeader(accessToken) }), From 07a306c19015a85362cfa23b5097d474971aacf7 Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 18:34:17 +0900 Subject: [PATCH 38/69] =?UTF-8?q?Fix:=20=EC=98=A4=ED=83=80=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/user.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/user.ts b/src/api/user.ts index 6b8f99a5..27e8b220 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -108,7 +108,7 @@ export async function getUserTravelLog( ) { try { const response = await axiosInstance.get( - `/api/users//${userNumber}/visited-countries`, + `/api/users/${userNumber}/visited-countries`, { ...(accessToken && { headers: getJWTHeader(accessToken) }), From 4f897ce31e067b90b465ab3de1d30430dd419dce Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 19:20:16 +0900 Subject: [PATCH 39/69] =?UTF-8?q?fix:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=ED=83=AD=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EC=95=88=EB=B3=B4=EC=9D=B4=EB=8A=94?= =?UTF-8?q?=20=EB=AC=B8=EC=A0=9C=20->=20=EB=B0=B0=EA=B2=BD=EC=83=89?= =?UTF-8?q?=EC=9D=84=20=EC=A3=BC=EC=96=B4=EC=84=9C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?-=20=EA=B0=90=EC=8B=B8=EB=8A=94=20div=EC=9D=98=20Height=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/components/userProfile/UserProfileDetail.tsx | 1 + src/components/userProfile/UserProfileOverlay.tsx | 4 ++-- src/components/userProfile/UserTravelTabMenu.tsx | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index ccc4e420..0fb52c29 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -185,6 +185,7 @@ const ReportedUser = styled.div` `; const Container = styled.div` margin-top: 4px; + background-color: white; `; const UserInfoContainer = styled.div` diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index 797142e9..7df84baa 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -27,8 +27,8 @@ export default function UserProfileOverlay() { useEffect(() => { console.log(bottomRef.current, "존재"); if (bottomRef.current) { - const bottom = bottomRef.current.getBoundingClientRect().bottom; - setHeight(bottom); + const overLayWrapperHeight = bottomRef.current.parentElement!.scrollHeight; + setHeight(overLayWrapperHeight); } }, [profileShow]); diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 151909cc..8d2ac039 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -217,6 +217,7 @@ const Container = styled.div` width: 100%; display: flex; flex-direction: column; + background-color: white; `; const TabMenuContainer = styled.div` From 555a8d63ba59ba3ecd50337a9750c7d2654c330c Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 19:47:11 +0900 Subject: [PATCH 40/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20height=20=EC=88=98=EC=A0=95=20-=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EB=A1=9C,=20=EC=B0=B8=EA=B0=80=ED=95=9C=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EA=B3=BC=20=EB=A7=8C=EB=93=A0=20=EC=97=AC=ED=96=89?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=EC=9D=B4=20=EC=97=86=EC=9D=84=20=EC=8B=9C,=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=20=ED=99=94=EB=A9=B4=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EA=B2=83=EC=9C=BC=EB=A1=9C=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 --- .../userProfile/UserProfileOverlay.tsx | 16 +++++++++++----- src/components/userProfile/UserTravelTabMenu.tsx | 9 ++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index 7df84baa..f46edc02 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -25,10 +25,16 @@ export default function UserProfileOverlay() { const bottomRef = useRef(null); const [height, setHeight] = useState(0); useEffect(() => { - console.log(bottomRef.current, "존재"); - if (bottomRef.current) { - const overLayWrapperHeight = bottomRef.current.parentElement!.scrollHeight; - setHeight(overLayWrapperHeight); + if (bottomRef.current?.parentElement) { + const scrollHeight = bottomRef.current.parentElement.scrollHeight; + const windowHeight = window.innerHeight; + + const newHeight = Math.max(scrollHeight, windowHeight); + + console.log("scrollHeight:", scrollHeight); + console.log("window.innerHeight:", windowHeight); + + setHeight(newHeight); } }, [profileShow]); @@ -68,6 +74,7 @@ const slideDown = keyframes` } `; const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number }>` + min-height: 100vh; padding: 0px 24px; position: absolute; z-index: 1001; @@ -79,7 +86,6 @@ const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number } height: ${({ height }) => height}px; @media (min-width: 440px) { width: 390px; - left: 50%; } left: 50%; animation: ${(props) => (props.isClickedCloseBtn ? slideDown : slideUp)} 0.3s ease-out forwards; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 8d2ac039..ffcbd79f 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -49,7 +49,14 @@ export default function UserTravelTabMenu() { }, [isClickedCloseBtn]); if (isUserProfileCreatedTravelsLoading || isUserProfileAppliedTravelsLoading) { - return null; + return ( + + + +
데이터를 불러오는데 실패했어요.
+ + + ); } useInfiniteScroll(() => { From 877ee16f38abcf9750b037a6998fa77984dab3d9 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 20:17:05 +0900 Subject: [PATCH 41/69] =?UTF-8?q?fix:=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=EC=8B=9C,=20=EC=83=81=EB=8C=80=EB=B0=A9=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=20=ED=99=94=EB=A9=B4=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EB=8B=AB=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileOverlay.tsx | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index f46edc02..e37f4759 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -38,6 +38,19 @@ export default function UserProfileOverlay() { } }, [profileShow]); + useEffect(() => { + const handlePopState = () => { + // 뒤로가기 하면 프로필 모달 화면 닫기. + setProfileShow(false); + }; + + window.addEventListener("popstate", handlePopState); + + return () => { + window.removeEventListener("popstate", handlePopState); + }; + }, []); + return ( <> {profileShow && ( @@ -54,22 +67,22 @@ export default function UserProfileOverlay() { const slideUp = keyframes` from { - transform: translate(-50%, 100%); + transform: translateY(100%); opacity: 0; } to { - transform: translate(-50%, 0%); + transform: translateY(0%); opacity: 1; } `; const slideDown = keyframes` - from { - transform: translate(-50%, 0%); + from { + transform: translateY(0%); opacity: 1; } to { - transform: translate(-50%, 100%); + transform: translateY(100%); opacity: 0; } `; @@ -79,7 +92,6 @@ const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number } position: absolute; z-index: 1001; top: 0; - left: 0; right: 0; bottom: 0; background-color: white; @@ -88,5 +100,6 @@ const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number } width: 390px; } left: 50%; + transform: translateX(-50%); animation: ${(props) => (props.isClickedCloseBtn ? slideDown : slideUp)} 0.3s ease-out forwards; `; From 6413fcae27f326129d5fbef9ba21d75ebcc4a0fa Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 20:17:27 +0900 Subject: [PATCH 42/69] =?UTF-8?q?fix:=20=EB=8B=A4=EC=8B=9C=20=EC=9B=90?= =?UTF-8?q?=EB=9E=98=20=EC=BD=94=EB=93=9C=EB=A1=9C=20=EB=90=98=EB=8F=8C?= =?UTF-8?q?=EB=A6=BC.=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserTravelTabMenu.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index ffcbd79f..8d2ac039 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -49,14 +49,7 @@ export default function UserTravelTabMenu() { }, [isClickedCloseBtn]); if (isUserProfileCreatedTravelsLoading || isUserProfileAppliedTravelsLoading) { - return ( - - - -
데이터를 불러오는데 실패했어요.
-
-
- ); + return null; } useInfiniteScroll(() => { From f705b1040ca8b00ddbed1ae24add83f22dfbf0cd Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 20:26:04 +0900 Subject: [PATCH 43/69] =?UTF-8?q?design:=20=EC=83=81=EC=84=B8=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=8C=93=EA=B8=80=20=EC=A1=B0=ED=9A=8C=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20z-index=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/TripDetail/TripDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index 6300bf7e..cc14915b 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -845,7 +845,7 @@ const IconContainer = styled.button<{ rotated: boolean; right: string }>` align-items: center; color: white; background-color: ${palette.기본}; - z-index: 1003; + z-index: 1000; font-size: 32px; @media (max-width: 390px) { right: ${(props) => props.right}; From 33e7c3dd113968be29968b33d0f164e49eba1bac Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 20:35:19 +0900 Subject: [PATCH 44/69] =?UTF-8?q?fix:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?= =?UTF-8?q?=ED=8B=B0=EC=97=90=EC=84=9C=20=EA=B8=80=EC=93=B4=EC=9D=B4=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=84=A0=ED=83=9D=EC=8B=9C=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=ED=99=94=EB=A9=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/community/CommunityPost.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/community/CommunityPost.tsx b/src/components/community/CommunityPost.tsx index 08a6e65c..4854e20d 100644 --- a/src/components/community/CommunityPost.tsx +++ b/src/components/community/CommunityPost.tsx @@ -17,9 +17,11 @@ import { isGuestUser } from "@/utils/user"; import { useState } from "react"; import CheckingModal from "../designSystem/modal/CheckingModal"; import { useBackPathStore } from "@/store/client/backPathStore"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; const CommunityPost = () => { const params = useParams(); + const { setProfileShow, setUserProfileUserId } = userProfileOverlayStore(); const communityNumber = params?.communityNumber as string; const { editToastShow, setEditToastShow } = editStore(); const [showLoginModal, setShowLoginModal] = useState(false); @@ -48,6 +50,11 @@ const CommunityPost = () => { } }; console.log("date", daysAgoFormatted(data?.regDate)); + + const moveToUserProfilePage = (userNumber: number) => { + setUserProfileUserId(userNumber); + setProfileShow(true); + }; return ( <> { fontWeight="600" /> - + moveToUserProfilePage(data.userNumber)}> {/* 프로필 */}
From 65e4ad973fea15649589532ff626b2f22ff694c8 Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 20:37:59 +0900 Subject: [PATCH 45/69] =?UTF-8?q?Fix:=20countryName=20=EB=82=98=EB=9D=BC?= =?UTF-8?q?=EB=A7=8C=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8F=84=EB=A1=9D=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/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx index 2f313593..3056830a 100644 --- a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx @@ -59,7 +59,7 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr addLocationName({ locationName: locationName.locationName, mapType: "google", - countryName: locationNameStr, + countryName: locationNameStr ? locationNameStr.split(" ")[0] : "", }); } }); From 917938c53a319a0fb2db7ae2b8e7dd784b1845d4 Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 20:41:53 +0900 Subject: [PATCH 46/69] =?UTF-8?q?Fix:=20=EC=9E=98=EB=AA=BB=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=ED=95=9C=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx index 3056830a..f396a7a3 100644 --- a/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/RegionWrapper.tsx @@ -48,7 +48,7 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr addLocationName({ locationName: locationName.locationName, mapType: "google", - countryName: parts ? parts[parts.length - 1] : "", + countryName: parts ? parts[parts.length - 1].split(" ")[0] : "", }); } } else { @@ -59,7 +59,7 @@ const InnerMap = ({ locationNameStr, locationName, setRegionInfo, addInitGeometr addLocationName({ locationName: locationName.locationName, mapType: "google", - countryName: locationNameStr ? locationNameStr.split(" ")[0] : "", + countryName: locationNameStr, }); } }); From ca2c5923ab6e640668c30a37db57fd1fc4a44b72 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 20:55:12 +0900 Subject: [PATCH 47/69] =?UTF-8?q?fix:=20=EC=95=84=EB=9E=98=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9C=84=EB=A1=9C=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EB=AA=A8=EB=8B=AC=20=EC=95=A0?= =?UTF-8?q?=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=88=98=EC=A0=95,=20?= =?UTF-8?q?=EC=97=AC=ED=96=89=20=EC=83=81=EC=84=B8=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20z-index=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileOverlay.tsx | 11 ++- src/page/TripDetail/TripDetail.tsx | 83 ++++--------------- 2 files changed, 19 insertions(+), 75 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index e37f4759..bedeea6c 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -67,22 +67,22 @@ export default function UserProfileOverlay() { const slideUp = keyframes` from { - transform: translateY(100%); + transform: translate(-50%, 100%); opacity: 0; } to { - transform: translateY(0%); + transform: translate(-50%, 0%); opacity: 1; } `; const slideDown = keyframes` - from { - transform: translateY(0%); + from { + transform: translate(-50%, 0%); opacity: 1; } to { - transform: translateY(100%); + transform: translate(-50%, 100%); opacity: 0; } `; @@ -100,6 +100,5 @@ const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number } width: 390px; } left: 50%; - transform: translateX(-50%); animation: ${(props) => (props.isClickedCloseBtn ? slideDown : slideUp)} 0.3s ease-out forwards; `; diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index cc14915b..fe420d29 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -70,9 +70,7 @@ export default function TripDetail() { const [showApplyModal, setShowApplyModal] = useState(false); const [showCancelModal, setShowCancelModal] = useState(false); const [showLoginModal, setShowLoginModal] = useState(false); - const [modalTextForLogin, setModalTextForLogin] = useState( - LOGIN_ASKING_FOR_WATCHING_COMMENT - ); + const [modalTextForLogin, setModalTextForLogin] = useState(LOGIN_ASKING_FOR_WATCHING_COMMENT); const detailRef = useRef(null); const [isApplyToast, setIsApplyToast] = useState(false); const [isCancelToast, setIsCancelToast] = useState(false); @@ -139,15 +137,7 @@ export default function TripDetail() { const allCompanions = (companions as any)?.data?.companions; const alreadyApplied = !!enrollmentNumber; const [ref, inView] = useInView(); - const { - data, - isLoading, - error, - fetchNextPage, - refetch, - isFetching, - hasNextPage, - } = useInfiniteQuery({ + const { data, isLoading, error, fetchNextPage, refetch, isFetching, hasNextPage } = useInfiniteQuery({ queryKey: ["plans", travelNumber], queryFn: ({ pageParam }) => { return getPlans(Number(travelNumber), pageParam) as any; @@ -162,10 +152,7 @@ export default function TripDetail() { } }, }); - const combinedPlans = data?.pages.reduce( - (acc, page) => acc.concat(page.plans), - [] - ); + const combinedPlans = data?.pages.reduce((acc, page) => acc.concat(page.plans), []); useInfiniteScroll(() => { if (inView) { !isFetching && hasNextPage && fetchNextPage(); @@ -331,30 +318,15 @@ export default function TripDetail() { return ( <> - + - - + + - moveToUserProfilePage(userNumber)} - > + moveToUserProfilePage(userNumber)}> {/* 프로필 */}
@@ -474,9 +444,7 @@ export default function TripDetail() { 여행 날짜 - {startDate && endDate - ? formatDateRange(startDate, endDate) - : "날짜를 선택하세요."} + {startDate && endDate ? formatDateRange(startDate, endDate) : "날짜를 선택하세요."} @@ -525,9 +493,7 @@ export default function TripDetail() { startDate={startDate} setOpenItemIndex={setOpenItemIndex} openItemIndex={openItemIndex} - inView={ -
- } + inView={
} slides={combinedPlans} // 모든 데이터를 하나의 슬라이드 컴포넌트에 전달 /> )} @@ -536,12 +502,7 @@ export default function TripDetail() { ) : ( <> - 댓글이 없습니다 + 댓글이 없습니다 등록된 일정이 없어요 @@ -596,10 +557,7 @@ export default function TripDetail() { } > - + @@ -637,14 +595,7 @@ export default function TripDetail() { strokeLinecap="round" strokeLinejoin="round" /> - + @@ -653,13 +604,7 @@ export default function TripDetail() { ) : ( - + ` From ca1a8a9d213be1ad4fbb2d13f8b6fdce8dc639dd Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 21:05:59 +0900 Subject: [PATCH 48/69] =?UTF-8?q?design:=20=EB=AA=A8=EB=B0=94=EC=9D=BC=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A2=81=EC=95=84=EC=A7=80=EB=8A=94=20=EB=B6=80=EB=B6=84=20wid?= =?UTF-8?q?th=EC=A4=98=EC=84=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserProfileOverlay.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index bedeea6c..954dda6e 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -87,6 +87,7 @@ const slideDown = keyframes` } `; const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number }>` + width: 100%; min-height: 100vh; padding: 0px 24px; position: absolute; From 212a3eb7679f1be9c2c6a4b050e96af182addab8 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 21:20:00 +0900 Subject: [PATCH 49/69] =?UTF-8?q?feat:=20=EC=97=AC=ED=96=89=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=ED=99=94=EB=A9=B4=20=EB=98=90=EB=8A=94=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EB=A1=9C=EA=B7=B8=20=ED=99=94=EB=A9=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=ED=95=98?= =?UTF-8?q?=EB=A9=B4=20=EB=8B=A4=EC=8B=9C=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=8F=8C=EC=95=84=EC=98=A4=EB=8F=84=EB=A1=9D=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 --- src/hooks/useHeaderNavigation.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index a68b9406..328756ac 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -7,6 +7,7 @@ import { useTransitionRouter } from "next-view-transitions"; import { tripDetailStore } from "@/store/client/tripDetailStore"; import { createTripStore } from "@/store/client/createTripStore"; import { editTripStore } from "@/store/client/editTripStore"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; const ROUTES = { REGISTER: "/register", @@ -68,6 +69,7 @@ const ROUTES = { BLOCK: "/block", EXPLANATION: "/explanation", USER_TRAVEL_LOG: "/userProfile/:userId/log", + USER_PROFILE_BADGE: "/userProfileBadge/:userId", }; export const useHeaderNavigation = () => { @@ -75,6 +77,7 @@ export const useHeaderNavigation = () => { const router = useTransitionRouter(); const { resetCreateTripDetail } = createTripStore(); const { resetEditTripDetail } = editTripStore(); + const { setProfileShow } = userProfileOverlayStore(); const { searchTravel, setSearchTravel, @@ -383,6 +386,20 @@ export const useHeaderNavigation = () => { router.push(`/community/detail/${id}`); }, }, + { + // 상대방 프로필 화면의 여행 뱃지 화면 + condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), + action: () => { + setProfileShow(true); + }, + }, + { + // 상대방 프로필 화면의 여행 로그 화면, + condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), + action: () => { + setProfileShow(true); + }, + }, ]; }; From 4f017cd78643897bdbe2673c9f1e43ae3d4b6d0c Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 21:38:12 +0900 Subject: [PATCH 50/69] =?UTF-8?q?fix:=20=EC=97=AC=ED=96=89=20=EB=B1=83?= =?UTF-8?q?=EA=B8=B0=20=EB=98=90=EB=8A=94=20=EB=A1=9C=EA=B7=B8=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20,=20=ED=94=84=EB=A1=9C=ED=95=84=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EC=BC=9C=EC=A7=90=20=EB=AC=B4=ED=95=9C=20=EA=B5=B4?= =?UTF-8?q?=EB=A0=88=20=EB=AC=B8=EC=A0=9C=20-=20=ED=95=B4=EB=8B=B9=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=92=A4=EB=A1=9C?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=ED=95=98=EB=A9=B4=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EB=AA=A8=EB=8B=AC=20=ED=99=94=EB=A9=B4=EC=9D=B4=20?= =?UTF-8?q?=EB=B3=B4=EC=9D=B4=EC=A7=80=EB=A7=8C,=20router.back=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=20=EC=9D=B4=EC=A0=84=20=ED=99=94=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B9=A0=EC=A0=B8=EB=82=98=EA=B0=88=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=98=90=EB=A1=9D=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useHeaderNavigation.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index 328756ac..491d4938 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -390,6 +390,7 @@ export const useHeaderNavigation = () => { // 상대방 프로필 화면의 여행 뱃지 화면 condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), action: () => { + router.back(); setProfileShow(true); }, }, @@ -397,6 +398,7 @@ export const useHeaderNavigation = () => { // 상대방 프로필 화면의 여행 로그 화면, condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), action: () => { + router.back(); setProfileShow(true); }, }, From 5a9f20c49c1190bf3e96b4ec84b9b8d6e5bb6228 Mon Sep 17 00:00:00 2001 From: mayrang Date: Mon, 21 Apr 2025 21:42:13 +0900 Subject: [PATCH 51/69] =?UTF-8?q?Fix:=20VisitContainer=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=8B=A4=EB=85=80=EC=98=A8=20=EC=97=AC=ED=96=89=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20=EB=8B=A4=20=EC=95=88=EB=B3=B4=EC=9D=B4=EB=8A=94=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/travellog/AreaDropdown.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/travellog/AreaDropdown.tsx b/src/components/travellog/AreaDropdown.tsx index a3d633f7..554e4e3f 100644 --- a/src/components/travellog/AreaDropdown.tsx +++ b/src/components/travellog/AreaDropdown.tsx @@ -173,6 +173,8 @@ const VisitContainer = styled.div` padding: 4px; display: flex; flex-direction: column; + max-height: calc(40svh - 212px); + overflow-y: auto; gap: 8px; `; const VisitItem = styled.div` From f91ad042b451746e8c0bbf3cd361c7aba4233f91 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 21 Apr 2025 22:28:46 +0900 Subject: [PATCH 52/69] =?UTF-8?q?fix:=20=EC=97=AC=ED=96=89=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80,=20=EB=A1=9C=EA=B7=B8=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0?= =?UTF-8?q?=EC=8B=9C,=20=EB=AA=A8=EB=8B=AC=20=EB=B3=B4=EC=9D=B4=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20setTimeout=ED=85=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.=20=ED=95=9C=EB=B2=88=EC=97=90=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EB=92=A4=EB=A1=9C=EA=B0=80=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useHeaderNavigation.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index 491d4938..f110241a 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -391,7 +391,7 @@ export const useHeaderNavigation = () => { condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), action: () => { router.back(); - setProfileShow(true); + setTimeout(() => setProfileShow(true), 100); }, }, { @@ -399,7 +399,7 @@ export const useHeaderNavigation = () => { condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), action: () => { router.back(); - setProfileShow(true); + setTimeout(() => setProfileShow(true), 100); }, }, ]; From 3fe35d4a8c380ba44ce24a6d8d00c82c9cced2d8 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Wed, 23 Apr 2025 19:46:52 +0900 Subject: [PATCH 53/69] =?UTF-8?q?fix:=20API=20URL=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/userProfile.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/userProfile.ts b/src/api/userProfile.ts index eae462d1..2ad85569 100644 --- a/src/api/userProfile.ts +++ b/src/api/userProfile.ts @@ -17,7 +17,7 @@ export const getUserProfile = async (accessToken: string, userNumber: number): P // 상대방의 만든 여행 조회 export const getUserCreatedTravels = async (pageParam: number, accessToken: string, userNumber: number) => { try { - const response = await axiosInstance.get(`/api/users/${userNumber}/created-travel`, { + const response = await axiosInstance.get(`/api/users/${userNumber}/created-travels`, { headers: getJWTHeader(accessToken), params: { page: pageParam, @@ -33,7 +33,7 @@ export const getUserCreatedTravels = async (pageParam: number, accessToken: stri export const getUserAppliedTravels = async (pageParam: number, accessToken: string, userNumber: number) => { try { - const response = await axiosInstance.get(`/api/users/${userNumber}/applied-travel`, { + const response = await axiosInstance.get(`/api/users/${userNumber}/applied-travels`, { headers: getJWTHeader(accessToken), params: { page: pageParam, From 2406ead7d79b5daacd45414f487e9fe8e83a0cc7 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Wed, 23 Apr 2025 20:25:43 +0900 Subject: [PATCH 54/69] =?UTF-8?q?fix:=20react#310=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EA=B0=80=20=EB=A0=8C=EB=8D=94=EB=A7=81=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=8F=99=EC=95=88=20=EB=8B=A4=EB=A5=B8=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=9D=98=20=EC=83=81=ED=83=9C=EB=A5=BC=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=ED=95=98=EB=A0=A4=EA=B3=A0?= =?UTF-8?q?=20=ED=95=A0=20=EB=95=8C=20=EB=B0=9C=EC=83=9D=EC=9D=B4=20?= =?UTF-8?q?=EC=9B=90=EC=9D=B8=20-=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EB=B0=B0=EC=97=B4=EC=97=90=20=EB=B6=80=EC=A0=95=20=EC=97=B0?= =?UTF-8?q?=EC=82=B0=EC=9E=90=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EA=B3=84=EC=86=8D=20=EB=A0=8C=EB=8D=94=EB=A7=81?= =?UTF-8?q?=EC=9D=84=20=EC=9C=A0=EB=8F=84=ED=95=98=EB=8A=94=20=EA=B2=83?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=98=EC=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserTravelTabMenu.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 8d2ac039..57ff36e6 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -48,10 +48,6 @@ export default function UserTravelTabMenu() { } }, [isClickedCloseBtn]); - if (isUserProfileCreatedTravelsLoading || isUserProfileAppliedTravelsLoading) { - return null; - } - useInfiniteScroll(() => { if (createdTravelsInView) { !isUserProfileCreatedTravelsFetching && @@ -60,7 +56,7 @@ export default function UserTravelTabMenu() { } }, [ createdTravelsInView, - !isUserProfileCreatedTravelsFetching, + isUserProfileCreatedTravelsFetching, fetchNextUserProfileCreatedTravelsPage, hasNextUserProfileCreatedTravelsPage, ]); @@ -73,11 +69,14 @@ export default function UserTravelTabMenu() { } }, [ appliedTravelsInView, - !isUserProfileAppliedTravelsFetching, + isUserProfileAppliedTravelsFetching, fetchNextUserProfileAppliedTravelsPage, hasNextUserProfileAppliedTravelsPage, ]); + if (isUserProfileCreatedTravelsLoading || isUserProfileAppliedTravelsLoading) { + return null; + } const userProfileCreatedTravels = (userProfileCreatedTravelsData?.pages[0].content as IUserRelatedTravelList["content"]) ?? []; From 5891cccc764ed38b05caaeb506f56d2e83abf237 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Thu, 24 Apr 2025 09:17:42 +0900 Subject: [PATCH 55/69] =?UTF-8?q?fix=20&=20design:=20=EC=83=81=EB=8C=80?= =?UTF-8?q?=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?height=20=EB=8F=99=EC=A0=81=20=EC=A1=B0=EC=A0=88=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=ED=83=AD=20=EB=A9=94=EB=89=B4=EB=A5=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=ED=95=A0=20=EB=95=8C=20=EB=A7=88=EB=8B=A4,?= =?UTF-8?q?=20height=EB=A5=BC=20=EC=A1=B0=EC=A0=88=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EA=B2=83=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userProfile/UserProfileOverlay.tsx | 39 ++++++++++++------- .../userProfile/UserProfileOverlayHeader.tsx | 4 +- .../userProfile/UserTravelTabMenu.tsx | 17 +++++++- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index 954dda6e..fa2a9588 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -8,6 +8,8 @@ import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; import UserProfileDetail from "./UserProfileDetail"; import UserTravelTabMenu from "./UserTravelTabMenu"; +const HEADER_DETAIL_HEIGHT = 564; +const TAB_NAVBAR_HEIGHT = 62; export default function UserProfileOverlay() { const { setProfileShow, profileShow } = userProfileOverlayStore(); // const navigateWithTransition = useViewTransition() @@ -22,21 +24,28 @@ export default function UserProfileOverlay() { } }, [isClickedCloseBtn]); - const bottomRef = useRef(null); + // const bottomRef = useRef(null); + const [selectedTab, setSelectedTab] = useState(0); + const [tabHeight, setTabHeight] = useState(0); + const [height, setHeight] = useState(0); - useEffect(() => { - if (bottomRef.current?.parentElement) { - const scrollHeight = bottomRef.current.parentElement.scrollHeight; - const windowHeight = window.innerHeight; + // useEffect(() => { + // const parent = bottomRef.current?.parentElement; + // if (!parent) return; - const newHeight = Math.max(scrollHeight, windowHeight); + // const observer = new ResizeObserver(() => { + // const scrollHeight = parent.scrollHeight; + // const windowHeight = window.innerHeight; + // const newHeight = Math.max(scrollHeight, windowHeight); + // setHeight(newHeight); + // }); - console.log("scrollHeight:", scrollHeight); - console.log("window.innerHeight:", windowHeight); + // observer.observe(parent); - setHeight(newHeight); - } - }, [profileShow]); + // return () => { + // observer.disconnect(); + // }; + // }, []); useEffect(() => { const handlePopState = () => { @@ -51,14 +60,18 @@ export default function UserProfileOverlay() { }; }, []); + useEffect(() => { + setHeight(tabHeight + HEADER_DETAIL_HEIGHT + TAB_NAVBAR_HEIGHT); + }, [tabHeight]); + return ( <> {profileShow && ( - -
{/* 마지막 요소 */} + + {/*
*/} )} diff --git a/src/components/userProfile/UserProfileOverlayHeader.tsx b/src/components/userProfile/UserProfileOverlayHeader.tsx index a05afa32..949ca41d 100644 --- a/src/components/userProfile/UserProfileOverlayHeader.tsx +++ b/src/components/userProfile/UserProfileOverlayHeader.tsx @@ -59,8 +59,8 @@ const ButtonContainer = styled.button` // 상단 헤더 스타일 const HeaderContainer = styled.header<{ isBackGroundColorIsGrey: boolean; isBottomBorder: boolean }>` display: flex; - padding: 52px 0px 16px 0px; - height: 116px; + padding: 40px 0px 16px 0px; + height: 100px; align-items: center; gap: 22px; position: sticky; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 57ff36e6..2a90e98a 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -13,11 +13,16 @@ import useInfiniteScroll from "@/hooks/useInfiniteScroll"; import { IUserRelatedTravelList } from "@/model/userProfile"; import RoundedImage from "../designSystem/profile/RoundedImage"; -export default function UserTravelTabMenu() { +interface UserTravelTabMenu { + setTabHeight: React.Dispatch>; + setSelectedTab: React.Dispatch>; + selectedTab: number; +} +const BOX_LAYOUT_HEIGHT = 115; +export default function UserTravelTabMenu({ setTabHeight, selectedTab, setSelectedTab }: UserTravelTabMenu) { const { setProfileShow } = userProfileOverlayStore(); const navigateWithTransition = useViewTransition(); const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); - const [selectedTab, setSelectedTab] = useState(0); // 스크롤 감지 ref 선언 const [createdTravelsRef, createdTravelsInView] = useInView(); @@ -48,6 +53,14 @@ export default function UserTravelTabMenu() { } }, [isClickedCloseBtn]); + useEffect(() => { + if (selectedTab === 0 && userProfileInfo) { + setTabHeight(userProfileInfo?.createdTravelCount * BOX_LAYOUT_HEIGHT); + } else if (selectedTab === 1 && userProfileInfo) { + setTabHeight(userProfileInfo?.participatedTravelCount * BOX_LAYOUT_HEIGHT); + } + }, [selectedTab, isUserProfileAppliedTravelsLoading, isUserProfileCreatedTravelsLoading]); + useInfiniteScroll(() => { if (createdTravelsInView) { !isUserProfileCreatedTravelsFetching && From 1571fb8d349afa50576c98a0fb9feecf761b88e5 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Thu, 24 Apr 2025 12:04:08 +0900 Subject: [PATCH 56/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=ED=83=AD=EB=A9=94=EB=89=B4=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?-=20=EC=83=81=EB=8C=80=EC=A0=81=EC=9C=BC=EB=A1=9C=20height?= =?UTF-8?q?=EA=B0=80=20=EC=9E=91=EC=9D=80=20=ED=83=AD=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=EC=9D=98=20=EA=B2=BD=EC=9A=B0=20=EB=B6=80=EB=AA=A8=EB=8A=94=20?= =?UTF-8?q?overflow=EA=B0=80=20=EB=90=98=EC=96=B4=20UI=EC=97=90=20?= =?UTF-8?q?=EB=92=B7=EB=B0=B0=EA=B2=BD=EC=9D=B4=20=EB=B3=B4=EC=9D=B4?= =?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 --- .../userProfile/UserProfileOverlay.tsx | 17 ++++++++++++- .../userProfile/UserProfileOverlayHeader.tsx | 4 +-- .../userProfile/UserTravelTabMenu.tsx | 25 +++++++++++++++---- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index 954dda6e..66327ebd 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -8,6 +8,9 @@ import UserProfileOverlayHeader from "./UserProfileOverlayHeader"; import UserProfileDetail from "./UserProfileDetail"; import UserTravelTabMenu from "./UserTravelTabMenu"; +const HEADER_DETAIL_HEIGHT = 529; +const TAB_NAVBAR_HEIGHT = 52; + export default function UserProfileOverlay() { const { setProfileShow, profileShow } = userProfileOverlayStore(); // const navigateWithTransition = useViewTransition() @@ -24,6 +27,9 @@ export default function UserProfileOverlay() { const bottomRef = useRef(null); const [height, setHeight] = useState(0); + const [selectedTab, setSelectedTab] = useState(0); + const [tabHeight, setTabHeight] = useState(0); + useEffect(() => { if (bottomRef.current?.parentElement) { const scrollHeight = bottomRef.current.parentElement.scrollHeight; @@ -51,13 +57,22 @@ export default function UserProfileOverlay() { }; }, []); + useEffect(() => { + setHeight(tabHeight + HEADER_DETAIL_HEIGHT + TAB_NAVBAR_HEIGHT); + }, [tabHeight]); + return ( <> {profileShow && ( - +
{/* 마지막 요소 */}
)} diff --git a/src/components/userProfile/UserProfileOverlayHeader.tsx b/src/components/userProfile/UserProfileOverlayHeader.tsx index a05afa32..949ca41d 100644 --- a/src/components/userProfile/UserProfileOverlayHeader.tsx +++ b/src/components/userProfile/UserProfileOverlayHeader.tsx @@ -59,8 +59,8 @@ const ButtonContainer = styled.button` // 상단 헤더 스타일 const HeaderContainer = styled.header<{ isBackGroundColorIsGrey: boolean; isBottomBorder: boolean }>` display: flex; - padding: 52px 0px 16px 0px; - height: 116px; + padding: 40px 0px 16px 0px; + height: 100px; align-items: center; gap: 22px; position: sticky; diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 57ff36e6..de81ef04 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -13,11 +13,17 @@ import useInfiniteScroll from "@/hooks/useInfiniteScroll"; import { IUserRelatedTravelList } from "@/model/userProfile"; import RoundedImage from "../designSystem/profile/RoundedImage"; -export default function UserTravelTabMenu() { +interface UserTravelTabMenu { + tabHeight: number; + setTabHeight: React.Dispatch>; + setSelectedTab: React.Dispatch>; + selectedTab: number; +} +const BOX_LAYOUT_HEIGHT = 115; +export default function UserTravelTabMenu({ setTabHeight, selectedTab, setSelectedTab }: UserTravelTabMenu) { const { setProfileShow } = userProfileOverlayStore(); const navigateWithTransition = useViewTransition(); const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); - const [selectedTab, setSelectedTab] = useState(0); // 스크롤 감지 ref 선언 const [createdTravelsRef, createdTravelsInView] = useInView(); @@ -48,6 +54,14 @@ export default function UserTravelTabMenu() { } }, [isClickedCloseBtn]); + useEffect(() => { + if (selectedTab === 0 && hasNextUserProfileCreatedTravelsPage && userProfileInfo) { + setTabHeight(userProfileInfo?.createdTravelCount * BOX_LAYOUT_HEIGHT); + } else if (selectedTab === 1 && hasNextUserProfileAppliedTravelsPage && userProfileInfo) { + setTabHeight(userProfileInfo?.participatedTravelCount * BOX_LAYOUT_HEIGHT); + } + }, [selectedTab, isUserProfileAppliedTravelsLoading, isUserProfileCreatedTravelsLoading]); + useInfiniteScroll(() => { if (createdTravelsInView) { !isUserProfileCreatedTravelsFetching && @@ -107,7 +121,7 @@ export default function UserTravelTabMenu() { {/* 조건부 */} {/* 0 이 되면 왼쪽으로 이동 1이 되면 오른쪽으로 이동. */} - + {isCreatedTravelsNoData && ( @@ -261,13 +275,14 @@ const Count = styled.div` `; interface TravelListBoxProps { - selectedTab: number; + listBoxHeight: number; } export const TravelListBox = styled.div` width: 100%; - overflow-x: hidden; + overflow: hidden; position: relative; + height: ${({ listBoxHeight }) => listBoxHeight}px; `; export const InnerSlider = styled.div` From 095ca0dcaa89b09218a5dfead7174b4f031b9eab Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Thu, 24 Apr 2025 12:11:07 +0900 Subject: [PATCH 57/69] =?UTF-8?q?docs:=20=EC=98=A4=ED=83=80=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/components/userProfile/UserTravelTabMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 1db04b43..1dc00dd5 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -20,7 +20,7 @@ interface UserTravelTabMenu { selectedTab: number; } const BOX_LAYOUT_HEIGHT = 115; -export default function UserTravelTabMenu({ setTabHeight, selectedTab, setSelectedTab }: UserTravelTabMenu) { +export default function UserTravelTabMenu({ tabHeight, setTabHeight, selectedTab, setSelectedTab }: UserTravelTabMenu) { const { setProfileShow } = userProfileOverlayStore(); const navigateWithTransition = useViewTransition(); const [isClickedCloseBtn, setIsClickedCloseBtn] = useState(false); @@ -121,7 +121,7 @@ export default function UserTravelTabMenu({ setTabHeight, selectedTab, setSelect {/* 조건부 */} {/* 0 이 되면 왼쪽으로 이동 1이 되면 오른쪽으로 이동. */} - + {isCreatedTravelsNoData && ( From f4610dce50db2fdfc12b0c969912098927d84da1 Mon Sep 17 00:00:00 2001 From: mayrang Date: Fri, 25 Apr 2025 13:45:18 +0900 Subject: [PATCH 58/69] =?UTF-8?q?Fix:=20=EB=82=A0=EC=A7=9C=EA=B0=80=20?= =?UTF-8?q?=EC=95=88=EB=82=98=EC=98=A4=EB=8A=94=20=EB=AC=B8=EC=A0=9C=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/components/travellog/AreaDropdown.tsx | 39 ++++-- src/utils/travellog/travelLog.ts | 143 +++++++++++++++++----- 2 files changed, 146 insertions(+), 36 deletions(-) diff --git a/src/components/travellog/AreaDropdown.tsx b/src/components/travellog/AreaDropdown.tsx index a3d633f7..4fc3428f 100644 --- a/src/components/travellog/AreaDropdown.tsx +++ b/src/components/travellog/AreaDropdown.tsx @@ -40,9 +40,11 @@ const AreaDropdown = ({ data, setTarget }: AreaDropdownProps) => { {showModal && ( - {targetData?.locationName ?? targetData?.countryName} + + {targetData?.locationName ?? targetData?.countryName} + - {targetData?.visitDates.map((date) => ( + {[...(targetData?.visitDates ?? [])].reverse().map((date) => (
{dayjs(date).format("YY.MM.DD")}
@@ -63,9 +65,15 @@ const AreaDropdown = ({ data, setTarget }: AreaDropdownProps) => { count={data[item].length} id={item} key={item} - handleOpen={() => setTarget((prev) => (prev ? [...prev, item] : [item]))} + handleOpen={() => + setTarget((prev) => (prev ? [...prev, item] : [item])) + } handleClose={() => - setTarget((prev) => (prev && prev?.length > 1 ? prev.filter((prevItem) => prevItem !== item) : null)) + setTarget((prev) => + prev && prev?.length > 1 + ? prev.filter((prevItem) => prevItem !== item) + : null + ) } paddingTop="0" paddingBottom="13px" @@ -79,8 +87,12 @@ const AreaDropdown = ({ data, setTarget }: AreaDropdownProps) => { {index + 1} {region.locationName ?? region.countryName} - {dayjs(region.visitDates[0]).format("YY.MM.DD")}{" "} - {region.visitDates.length > 1 && +{region.visitDates.length}} + {dayjs( + region.visitDates[region.visitDates.length - 1] + ).format("YY.MM.DD")} + {region.visitDates.length > 1 && ( + +{region.visitDates.length} + )} ))} @@ -93,7 +105,13 @@ const AreaDropdown = ({ data, setTarget }: AreaDropdownProps) => { const ClockIcon = () => { return ( - + { strokeLinecap="round" strokeLinejoin="round" /> - + ); diff --git a/src/utils/travellog/travelLog.ts b/src/utils/travellog/travelLog.ts index 895b5af5..1f4639fb 100644 --- a/src/utils/travellog/travelLog.ts +++ b/src/utils/travellog/travelLog.ts @@ -773,7 +773,7 @@ export function groupRegionData(regionList, filter) { // 새 지역이면 새 객체 추가 result[province].push({ locationName: item.locationName, - visitDates: [item.visitDates], + visitDates: [...item.visitDates], }); }); return result; @@ -804,7 +804,7 @@ export function groupRegionData(regionList, filter) { // 새 국가면 새 객체 추가 result[continent].push({ locationName: item.locationName, - visitDates: [item.visitDates], + visitDates: [...item.visitDates], }); }); console.log("result", result); @@ -868,28 +868,82 @@ export function getContinentToKorean(continent) { return continents[continent] ?? continent; } -export function getMapLocation(regionName, type = "세계"): { center: { lat: number; lng: number }; zoom: number } { +export function getMapLocation( + regionName, + type = "세계" +): { center: { lat: number; lng: number }; zoom: number } { const koreaProvinceMap = { // 특별시/광역시 - 서울: { center: { lat: 37.58173594222202, lng: 126.985998568865 }, zoom: 9.947500000000002 }, - 부산: { center: { lat: 35.18315517373206, lng: 129.0726844486296 }, zoom: 9.291000000000002 }, - 대구: { center: { lat: 35.95919713591124, lng: 128.574964694497 }, zoom: 9.2105 }, - 인천: { center: { lat: 37.524425826055186, lng: 126.63029203685825 }, zoom: 9.618999999999998 }, - 광주: { center: { lat: 35.18920001776509, lng: 126.83198162677726 }, zoom: 9.80326025411579 }, - 대전: { center: { lat: 36.35209940241832, lng: 127.38354429838299 }, zoom: 9.55526025411579 }, - 울산: { center: { lat: 35.59655811994434, lng: 129.25517245372515 }, zoom: 9.34476025411579 }, - 세종: { center: { lat: 36.58542068981106, lng: 127.27664536552678 }, zoom: 9.772009006540346 }, + 서울: { + center: { lat: 37.58173594222202, lng: 126.985998568865 }, + zoom: 9.947500000000002, + }, + 부산: { + center: { lat: 35.18315517373206, lng: 129.0726844486296 }, + zoom: 9.291000000000002, + }, + 대구: { + center: { lat: 35.95919713591124, lng: 128.574964694497 }, + zoom: 9.2105, + }, + 인천: { + center: { lat: 37.524425826055186, lng: 126.63029203685825 }, + zoom: 9.618999999999998, + }, + 광주: { + center: { lat: 35.18920001776509, lng: 126.83198162677726 }, + zoom: 9.80326025411579, + }, + 대전: { + center: { lat: 36.35209940241832, lng: 127.38354429838299 }, + zoom: 9.55526025411579, + }, + 울산: { + center: { lat: 35.59655811994434, lng: 129.25517245372515 }, + zoom: 9.34476025411579, + }, + 세종: { + center: { lat: 36.58542068981106, lng: 127.27664536552678 }, + zoom: 9.772009006540346, + }, // 도 - 경기도: { center: { lat: 37.60895466900079, lng: 127.1944183885365 }, zoom: 8.088009006540348 }, - 강원도: { center: { lat: 37.72514188695451, lng: 128.3332311928536 }, zoom: 7.667009006540349 }, - 충청북도: { center: { lat: 36.85381270643817, lng: 127.8898851561579 }, zoom: 8.036967300227136 }, - 충청남도: { center: { lat: 36.622012144213706, lng: 126.94344474914972 }, zoom: 8.247467300227136 }, - 전라북도: { center: { lat: 35.792690108435174, lng: 127.00282931707038 }, zoom: 8.6 }, - 전라남도: { center: { lat: 34.99788106591206, lng: 126.85226587959508 }, zoom: 7.8264673002271365 }, - 경상북도: { center: { lat: 36.378470931118585, lng: 128.94802933065174 }, zoom: 7.737000000000002 }, - 경상남도: { center: { lat: 35.591692023475694, lng: 128.4420038910309 }, zoom: 7.8264673002271365 }, - 제주도: { center: { lat: 33.48009045318337, lng: 126.5989149757934 }, zoom: 8.247467300227136 }, + 경기도: { + center: { lat: 37.60895466900079, lng: 127.1944183885365 }, + zoom: 8.088009006540348, + }, + 강원도: { + center: { lat: 37.72514188695451, lng: 128.3332311928536 }, + zoom: 7.667009006540349, + }, + 충청북도: { + center: { lat: 36.85381270643817, lng: 127.8898851561579 }, + zoom: 8.036967300227136, + }, + 충청남도: { + center: { lat: 36.622012144213706, lng: 126.94344474914972 }, + zoom: 8.247467300227136, + }, + 전라북도: { + center: { lat: 35.792690108435174, lng: 127.00282931707038 }, + zoom: 8.6, + }, + 전라남도: { + center: { lat: 34.99788106591206, lng: 126.85226587959508 }, + zoom: 7.8264673002271365, + }, + 경상북도: { + center: { lat: 36.378470931118585, lng: 128.94802933065174 }, + zoom: 7.737000000000002, + }, + 경상남도: { + center: { lat: 35.591692023475694, lng: 128.4420038910309 }, + zoom: 7.8264673002271365, + }, + 제주도: { + center: { lat: 33.48009045318337, lng: 126.5989149757934 }, + zoom: 8.247467300227136, + }, // 기본값 (한국 전체) 한국: { center: { lat: 35.8, lng: 127.99041015624999 }, zoom: 6 }, @@ -897,13 +951,31 @@ export function getMapLocation(regionName, type = "세계"): { center: { lat: nu const continentMap = { ASIA: { center: { lat: 34.0479, lng: 100.6197 }, zoom: 2.5 }, - EUROPE: { center: { lat: 64.17276952464238, lng: 27.652766547066758 }, zoom: 2.315999999999999 }, - NORTH_AMERICA: { center: { lat: 52.069594198692165, lng: -110.51614311403729 }, zoom: 2.1579999999999995 }, - SOUTH_AMERICA: { center: { lat: -2.4270880873045857, lng: -63.56696056699926 }, zoom: 2.1579999999999995 }, - AFRICA: { center: { lat: 0.05846521546760099, lng: 21.559422572779557 }, zoom: 2.736999999999999 }, - OCEANIA: { center: { lat: -25.031694745465103, lng: 146.175979749393 }, zoom: 2.9474999999999993 }, + EUROPE: { + center: { lat: 64.17276952464238, lng: 27.652766547066758 }, + zoom: 2.315999999999999, + }, + NORTH_AMERICA: { + center: { lat: 52.069594198692165, lng: -110.51614311403729 }, + zoom: 2.1579999999999995, + }, + SOUTH_AMERICA: { + center: { lat: -2.4270880873045857, lng: -63.56696056699926 }, + zoom: 2.1579999999999995, + }, + AFRICA: { + center: { lat: 0.05846521546760099, lng: 21.559422572779557 }, + zoom: 2.736999999999999, + }, + OCEANIA: { + center: { lat: -25.031694745465103, lng: 146.175979749393 }, + zoom: 2.9474999999999993, + }, ANTARCTICA: { center: { lat: -90.0, lng: 0.0 }, zoom: 3 }, - 기타: { center: { lat: 35.95985150233884, lng: 164.13703818135662 }, zoom: 0.579 }, + 기타: { + center: { lat: 35.95985150233884, lng: 164.13703818135662 }, + zoom: 0.579, + }, }; if (type === "국내") { return koreaProvinceMap[regionName] || koreaProvinceMap["한국"]; @@ -976,7 +1048,16 @@ export const cityDistricts = { "인천 강화군", "인천 옹진군", ], - 대구: ["대구 남구", "대구 달서구", "대구 동구", "대구 북구", "대구 서구", "대구 수성구", "대구 중구", "대구 달성군"], + 대구: [ + "대구 남구", + "대구 달서구", + "대구 동구", + "대구 북구", + "대구 서구", + "대구 수성구", + "대구 중구", + "대구 달성군", + ], 광주: ["광주 광산구", "광주 남구", "광주 동구", "광주 북구", "광주 서구"], 대전: ["대전 대덕구", "대전 동구", "대전 서구", "대전 유성구", "대전 중구"], 울산: ["울산 남구", "울산 동구", "울산 북구", "울산 중구", "울산 울주군"], @@ -990,7 +1071,13 @@ export const cityDistricts = { 안양: ["안양시만안구", "안양시동안구"], 천안: ["천안시서북구", "천안시동남구"], - 창원: ["창원시 의창구", "창원시 성산구", "창원시 마산합포구", "창원시 마산회원구", "창원시 진해구"], + 창원: [ + "창원시 의창구", + "창원시 성산구", + "창원시 마산합포구", + "창원시 마산회원구", + "창원시 진해구", + ], // 충청북도 청주: ["청주시 상당구", "청주시 서원구", "청주시 흥덕구", "청주시 청원구"], From 0c6fb0637b783ae4ff8cce87ea9ddd58c1b557f1 Mon Sep 17 00:00:00 2001 From: mayrang Date: Fri, 25 Apr 2025 14:41:04 +0900 Subject: [PATCH 59/69] =?UTF-8?q?=EB=8B=A4=EB=85=80=EC=98=A8=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EA=B5=AD=EB=82=B4=20=EB=B6=80=EB=B6=84=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=95=88=EC=A0=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/travellog/travelLog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/travellog/travelLog.ts b/src/utils/travellog/travelLog.ts index 1f4639fb..92fdb440 100644 --- a/src/utils/travellog/travelLog.ts +++ b/src/utils/travellog/travelLog.ts @@ -1,4 +1,4 @@ -export function groupRegionData(regionList, filter) { +export function groupRegionData(regionList: any[] = [], filter: string) { // 한국의 도/광역시/시군구 정보 const koreaRegions = { // 서울특별시 From 0b23f513610f280b7539c6f1c4ebc60b3adea71b Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sat, 26 Apr 2025 18:36:28 +0900 Subject: [PATCH 60/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EA=B0=80=20=EC=97=86=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9D=B4=20=EB=82=98=EC=98=A4=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserTravelTabMenu.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 1dc00dd5..5e25b980 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -100,6 +100,14 @@ export default function UserTravelTabMenu({ tabHeight, setTabHeight, selectedTab const isCreatedTravelsNoData = userProfileCreatedTravels.length === 0; const isAppliedTravelsNoData = userProfileAppliedTravels.length === 0; + console.log( + "만든 여행, 참가한 여행 데이 존재 여부", + isCreatedTravelsNoData, + isAppliedTravelsNoData, + userProfileCreatedTravelsData, + userProfileCreatedTravels, + userProfileAppliedTravels + ); const clickTrip = (travelNumber: number) => { navigateWithTransition(`/trip/detail/${travelNumber}`); setTimeout(() => { From 67f424b90cb951ae9964fbe96b1793db256aa060 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sat, 26 Apr 2025 21:16:57 +0900 Subject: [PATCH 61/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C=20-=20?= =?UTF-8?q?=EC=B0=B8=EA=B0=80=ED=95=9C=20=EC=97=AC=ED=96=89=20=EB=98=90?= =?UTF-8?q?=EB=8A=94=20=EB=A7=8C=EB=93=A0=20=EC=97=AC=ED=96=89=20count=200?= =?UTF-8?q?=EC=9D=BC=20=EB=95=8C,=20=EB=8C=80=EC=B2=B4=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B0=80=EB=A0=A4=EC=A7=80=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserTravelTabMenu.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 5e25b980..77d3518a 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -115,6 +115,12 @@ export default function UserTravelTabMenu({ tabHeight, setTabHeight, selectedTab }, 50); }; + const travelListHeight = () => { + const MINIMUM_HEIGHT = 200; + const isTravelCountZero = tabHeight === 0; + return isTravelCountZero ? MINIMUM_HEIGHT : tabHeight; + }; + return ( @@ -129,7 +135,7 @@ export default function UserTravelTabMenu({ tabHeight, setTabHeight, selectedTab {/* 조건부 */} {/* 0 이 되면 왼쪽으로 이동 1이 되면 오른쪽으로 이동. */} - + {isCreatedTravelsNoData && ( @@ -232,7 +238,7 @@ const Empty = styled.div` flex-direction: column; align-items: center; justify-content: center; - height: 100svh; + margin-top: 80px; `; const Container = styled.div` width: 100%; @@ -295,7 +301,6 @@ export const TravelListBox = styled.div` export const InnerSlider = styled.div` display: flex; - width: 200%; // 두 개 탭이니까 두 배 transition: transform 0.3s ease-in-out; transform: ${({ selectedTab }) => (selectedTab === 0 ? "translateX(0%)" : "translateX(-100%)")}; `; From 4784e658b8eddf385e63a3b7c94dc83921fb14a5 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sat, 26 Apr 2025 21:41:12 +0900 Subject: [PATCH 62/69] =?UTF-8?q?fix&design:=20=EC=83=81=EB=8C=80=EB=B0=A9?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A1=B0=ED=9A=8C,=20?= =?UTF-8?q?=EC=B0=B8=EA=B0=80=ED=95=9C=20=EC=97=AC=ED=96=89=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=ED=95=9C=20=EC=97=AC=ED=96=89=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=200=EA=B0=9C=20=EC=9D=BC=20=EB=95=8C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=88=98=EC=A0=95=20-=20margin,=20=EC=B5=9C?= =?UTF-8?q?=EC=86=8C=20=EC=A1=B0=ED=9A=8C=20=EB=AA=A8=EB=8B=AC=EC=9D=98=20?= =?UTF-8?q?height=EB=A5=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserProfileOverlay.tsx | 10 +++++++++- src/components/userProfile/UserTravelTabMenu.tsx | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index d9b0e2fb..a42b6c7b 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -10,6 +10,7 @@ import UserTravelTabMenu from "./UserTravelTabMenu"; const HEADER_DETAIL_HEIGHT = 529; const TAB_NAVBAR_HEIGHT = 52; +const NO_DATA_COMPONENT_HEIGHT = 256; export default function UserProfileOverlay() { const { setProfileShow, profileShow } = userProfileOverlayStore(); @@ -63,7 +64,14 @@ export default function UserProfileOverlay() { }, []); useEffect(() => { - setHeight(tabHeight + HEADER_DETAIL_HEIGHT + TAB_NAVBAR_HEIGHT); + const BASIC_HEIGHT = tabHeight + HEADER_DETAIL_HEIGHT + TAB_NAVBAR_HEIGHT; + const NO_DATA_INCLUDE_HEIGHT = BASIC_HEIGHT + NO_DATA_COMPONENT_HEIGHT; + const isNoData = tabHeight === 0; + if (isNoData) { + setHeight(NO_DATA_INCLUDE_HEIGHT); + } else { + setHeight(BASIC_HEIGHT); + } }, [tabHeight]); return ( diff --git a/src/components/userProfile/UserTravelTabMenu.tsx b/src/components/userProfile/UserTravelTabMenu.tsx index 77d3518a..6535d2d8 100644 --- a/src/components/userProfile/UserTravelTabMenu.tsx +++ b/src/components/userProfile/UserTravelTabMenu.tsx @@ -116,7 +116,7 @@ export default function UserTravelTabMenu({ tabHeight, setTabHeight, selectedTab }; const travelListHeight = () => { - const MINIMUM_HEIGHT = 200; + const MINIMUM_HEIGHT = 256; const isTravelCountZero = tabHeight === 0; return isTravelCountZero ? MINIMUM_HEIGHT : tabHeight; }; @@ -239,6 +239,7 @@ const Empty = styled.div` align-items: center; justify-content: center; margin-top: 80px; + margin-bottom: 88px; `; const Container = styled.div` width: 100%; From 9d0f5e18733e00edd7c869a3533d44e8387c8472 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 28 Apr 2025 06:37:26 +0900 Subject: [PATCH 63/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EA=B0=80=EB=A1=9C=EC=B6=95=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EC=9D=B4=20=EC=83=9D=EA=B8=B0?= =?UTF-8?q?=EB=8A=94=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95=20-=20?= =?UTF-8?q?=ED=99=88=ED=99=94=EB=A9=B4=20=EA=B0=80=EB=A1=9C=EC=B6=95=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=83=9D=EA=B8=B0=EB=8A=94=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=EB=8F=84=20=EA=B0=99=EC=9D=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EB=90=A8=20-=20=EB=A7=8E=EC=9D=80=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=EC=9D=B4=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EA=B2=BD=EC=9A=B0,=20=EC=9E=90=EB=8F=99?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=95=84=EB=9E=98=EB=A1=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EB=82=B4=EB=A0=A4=EA=B0=80=EB=8A=94=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=EB=8F=84=20=EA=B0=99=EC=9D=B4=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/app/globals.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/globals.css b/src/app/globals.css index 5424eefe..50425cb1 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -166,6 +166,7 @@ body { line-height: 1; font-family: "Pretendard", sans-serif; letter-spacing: -0.4px !important; + overflow-x: hidden; } ol, ul { From 62df080cdfed024947139940884eda17a5c3dcc9 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Mon, 28 Apr 2025 07:17:36 +0900 Subject: [PATCH 64/69] =?UTF-8?q?fix&Design=20:=20=EB=AA=A8=EB=B0=94?= =?UTF-8?q?=EC=9D=BC=20=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=20=EC=A4=91=EA=B0=84=EC=AF=A4=20=ED=8A=95?= =?UTF-8?q?=EA=B8=B0=EB=A5=BC=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/userProfile/UserProfileOverlay.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/userProfile/UserProfileOverlay.tsx b/src/components/userProfile/UserProfileOverlay.tsx index a42b6c7b..c4e105b8 100644 --- a/src/components/userProfile/UserProfileOverlay.tsx +++ b/src/components/userProfile/UserProfileOverlay.tsx @@ -116,7 +116,6 @@ const slideDown = keyframes` `; const OverlayWrapper = styled.div<{ isClickedCloseBtn: boolean; height: number }>` width: 100%; - min-height: 100vh; padding: 0px 24px; position: absolute; z-index: 1001; From d2c92307fdb5b778364a5165d19a5bfda76bc9de Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 25 May 2025 20:38:39 +0900 Subject: [PATCH 65/69] =?UTF-8?q?fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B1=83=EC=A7=80,=20=EC=97=AC?= =?UTF-8?q?=ED=96=89=20=EB=A1=9C=EA=B7=B8=20=ED=99=94=EB=A9=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=EC=8B=9C,=20?= =?UTF-8?q?=EC=83=81=EB=8C=80=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=98=A4=EB=B2=84=EB=A0=88=EC=9D=B4=EA=B0=80=20=EC=BC=9C?= =?UTF-8?q?=EC=A7=80=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useHeaderNavigation.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index f110241a..259911cb 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -8,6 +8,7 @@ import { tripDetailStore } from "@/store/client/tripDetailStore"; import { createTripStore } from "@/store/client/createTripStore"; import { editTripStore } from "@/store/client/editTripStore"; import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; +import { authStore } from "@/store/client/authStore"; const ROUTES = { REGISTER: "/register", @@ -77,7 +78,8 @@ export const useHeaderNavigation = () => { const router = useTransitionRouter(); const { resetCreateTripDetail } = createTripStore(); const { resetEditTripDetail } = editTripStore(); - const { setProfileShow } = userProfileOverlayStore(); + const { userId } = authStore(); + const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); const { searchTravel, setSearchTravel, @@ -391,7 +393,10 @@ export const useHeaderNavigation = () => { condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), action: () => { router.back(); - setTimeout(() => setProfileShow(true), 100); + if (userProfileUserId !== userId) { + // 마이페이지가 아닌 페이지에서 접속 했을시, 뒤로 가기 해도 프로필 overlay화면 + setTimeout(() => setProfileShow(true), 100); + } }, }, { @@ -399,7 +404,9 @@ export const useHeaderNavigation = () => { condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), action: () => { router.back(); - setTimeout(() => setProfileShow(true), 100); + if (userProfileUserId !== userId) { + setTimeout(() => setProfileShow(true), 100); + } }, }, ]; From b941529437d0d6df1dcf6ef7f0b098dd3afdd035 Mon Sep 17 00:00:00 2001 From: "sominan8744@gmail.com" Date: Sun, 25 May 2025 20:54:23 +0900 Subject: [PATCH 66/69] =?UTF-8?q?fix:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=A0=91=EC=86=8D=EC=8B=9C,=20=EC=83=81?= =?UTF-8?q?=EB=8C=80=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84(=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=ED=94=84=EB=A1=9C=ED=95=84)=20id=EB=A5=BC=20userId?= =?UTF-8?q?=EC=99=80=20=EB=8F=99=EC=9D=BC=ED=95=98=EA=B2=8C=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useHeaderNavigation.tsx | 1 + src/page/MyPage/MyPage.tsx | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index 259911cb..7cad438f 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -404,6 +404,7 @@ export const useHeaderNavigation = () => { condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), action: () => { router.back(); + console.log(userProfileUserId); if (userProfileUserId !== userId) { setTimeout(() => setProfileShow(true), 100); } diff --git a/src/page/MyPage/MyPage.tsx b/src/page/MyPage/MyPage.tsx index e5b617ce..e8dd159c 100644 --- a/src/page/MyPage/MyPage.tsx +++ b/src/page/MyPage/MyPage.tsx @@ -6,11 +6,13 @@ import RightVector from "@/components/icons/RightVector"; import Spacing from "@/components/Spacing"; import UserProfileDetail from "@/components/userProfile/UserProfileDetail"; import useViewTransition from "@/hooks/useViewTransition"; +import { authStore } from "@/store/client/authStore"; +import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore"; import { palette } from "@/styles/palette"; import { isGuestUser } from "@/utils/user"; import styled from "@emotion/styled"; import { useRouter } from "next/navigation"; -import { useState } from "react"; +import { useEffect, useState } from "react"; export default function MyPage() { const navigateWithTransition = useViewTransition(); @@ -20,6 +22,11 @@ export default function MyPage() { document.documentElement.style.viewTransitionName = "forward"; navigateWithTransition("/announcement"); }; + const { userId } = authStore(); + const { setUserProfileUserId } = userProfileOverlayStore(); + useEffect(() => { + setUserProfileUserId(userId!); + }, []); return ( {!isGuestUser() ? ( From 87c376d655473070baf2f4d82b61251a1cf130c2 Mon Sep 17 00:00:00 2001 From: mayrang Date: Wed, 28 May 2025 12:44:32 +0900 Subject: [PATCH 67/69] =?UTF-8?q?Fix:=20=EC=A0=84=EC=B2=B4=EC=A0=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=ED=81=B4=EB=A6=AC=EC=BB=A4=EB=B8=94?= =?UTF-8?q?=ED=95=9C=20cursor=20pointer=20=EC=B6=94=EA=B0=80,=20=EC=B4=9D?= =?UTF-8?q?=20=EC=97=AC=ED=96=89=EA=B1=B0=EB=A6=AC=20=EC=98=AC=EB=A6=BC?= =?UTF-8?q?=EC=9C=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/components/Header.tsx | 1 + src/components/HorizonBoxLayout.tsx | 80 ++++++++++-- src/components/Terms.tsx | 121 +++++++++--------- src/components/calendar/CalendarView.tsx | 29 ++++- src/components/community/AddImage.tsx | 27 ++-- src/components/community/CategoryList.tsx | 23 ++-- .../designSystem/Buttons/CloseButton.tsx | 15 ++- .../Buttons/EditAndDeleteButton.tsx | 47 ++++--- .../designSystem/Buttons/FilterButton.tsx | 71 +++++----- .../designSystem/Buttons/ReportButton.tsx | 4 +- .../designSystem/modal/CheckingModal.tsx | 15 ++- .../designSystem/modal/EditAndDeleteModal.tsx | 6 +- .../designSystem/modal/NoticeModal.tsx | 38 +++++- .../designSystem/modal/ResultModal.tsx | 17 ++- .../relationKeyword/RelationKeywordList.tsx | 42 +++--- src/components/travellog/AreaDropdown.tsx | 1 + src/components/travellog/AreaFilter.tsx | 14 +- src/components/triplist/TripInfiniteList.tsx | 25 +++- .../userProfile/UserProfileDetail.tsx | 16 ++- src/page/CreateTrip/CalendarClient.tsx | 12 +- .../CreateTripDetail/CalendarWrapper.tsx | 22 +++- .../CreateTripDetail/CreateScheduleItem.tsx | 75 +++++++++-- .../CreateTripDetail/InfoWrapper.tsx | 5 +- .../CreateTripDetail/RecruitingWrapper.tsx | 5 +- .../CreateTripDetail/search/SearchItem.tsx | 2 + .../CreateTripDetail/search/SearchPlace.tsx | 1 + src/page/CreateTrip/CreateTripInfo.tsx | 27 +++- src/page/CreateTrip/component/TagList.tsx | 13 +- src/page/Home/ContentTitleContainer.tsx | 7 +- src/page/Home/CreateTripButton.tsx | 2 + src/page/Home/TripAvailable.tsx | 13 +- src/page/MyPage/EditMyTag.tsx | 45 +++++-- src/page/Register/RegisterAge.tsx | 34 ++++- src/page/Register/RegisterGender.tsx | 46 ++++++- src/page/Register/RegisterTripStyle.tsx | 46 +++++-- 35 files changed, 667 insertions(+), 280 deletions(-) diff --git a/src/components/Header.tsx b/src/components/Header.tsx index dc0f1b55..6a4e3134 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -165,6 +165,7 @@ const Alarm = styled.div` width: 48px; height: 48px; display: flex; + cursor: pointer; align-items: center; justify-content: center; `; diff --git a/src/components/HorizonBoxLayout.tsx b/src/components/HorizonBoxLayout.tsx index 3a960aad..be75b12d 100644 --- a/src/components/HorizonBoxLayout.tsx +++ b/src/components/HorizonBoxLayout.tsx @@ -68,7 +68,12 @@ const HorizonBoxLayout = ({ const tagRef = useRef(null); const containerRef = useRef(null); - const cutTags = tags.length >= 2 ? (isBookmark ? tags.slice(0, 1) : tags.slice(0, 2)) : tags; + const cutTags = + tags.length >= 2 + ? isBookmark + ? tags.slice(0, 1) + : tags.slice(0, 2) + : tags; const [tagsCount, setTagsCount] = useState(cutTags); console.log(tagsCount, "tagsCount"); @@ -78,20 +83,35 @@ const HorizonBoxLayout = ({ setTagsCount((prev) => (prev.length > 1 ? prev.slice(0, -1) : [])); } } - }, [tagRef.current, showTag, tagsCount.length, containerRef?.current?.getBoundingClientRect().width]); + }, [ + tagRef.current, + showTag, + tagsCount.length, + containerRef?.current?.getBoundingClientRect().width, + ]); return ( {/* */} - + {!userProfileType ? ( - +
+ {bookmarkPosition === "top" && bookmarkNeed && ( - + )}
@@ -145,8 +169,16 @@ const HorizonBoxLayout = ({ - +
+ {bookmarkPosition === "middle" && bookmarkNeed && ( - + )} ); @@ -210,11 +246,19 @@ interface BookmarkButtonProps { travelNumber: number; bookmarkPosition?: "top" | "middle"; } -const BookmarkButton = ({ bookmarked, travelNumber, bookmarkPosition }: BookmarkButtonProps) => { +const BookmarkButton = ({ + bookmarked, + travelNumber, + bookmarkPosition, +}: BookmarkButtonProps) => { const { accessToken, userId } = authStore(); const [showLoginModal, setShowLoginModal] = useState(false); const router = useRouter(); - const { postBookmarkMutation, deleteBookmarkMutation } = useUpdateBookmark(accessToken!, userId!, travelNumber); + const { postBookmarkMutation, deleteBookmarkMutation } = useUpdateBookmark( + accessToken!, + userId!, + travelNumber + ); const pathname = usePathname(); const bookmarkClickHandler = (e: React.MouseEvent) => { @@ -244,11 +288,18 @@ const BookmarkButton = ({ bookmarked, travelNumber, bookmarkPosition }: Bookmark modalButtonText="로그인" setModalOpen={setShowLoginModal} /> -
)} - {(isEdit ? editImages.filter((img) => img.status !== "d") : images.filter((img) => img.isSelected)).map( - (image) => ( - - onRemoveImage(image.imageNumber)}> - - - - ) - )} + {(isEdit + ? editImages.filter((img) => img.status !== "d") + : images.filter((img) => img.isSelected) + ).map((image) => ( + + onRemoveImage(image.imageNumber)}> + + + + ))} ); }; @@ -127,6 +133,7 @@ const RemoveButton = styled.button` display: block; position: absolute; top: -4px; + cursor: pointer; width: 16px; height: 16px; right: -4px; diff --git a/src/components/community/CategoryList.tsx b/src/components/community/CategoryList.tsx index 2fce2f94..7836804f 100644 --- a/src/components/community/CategoryList.tsx +++ b/src/components/community/CategoryList.tsx @@ -1,12 +1,12 @@ -'use client' -import styled from '@emotion/styled' -import React from 'react' -import SearchFilterTag from '../designSystem/tag/SearchFilterTag' +"use client"; +import styled from "@emotion/styled"; +import React from "react"; +import SearchFilterTag from "../designSystem/tag/SearchFilterTag"; interface CategoryListProps { - list: string[] - type: string - setType: (type: string) => void + list: string[]; + type: string; + setType: (type: string) => void; } const CategoryList = ({ list, type, setType }: CategoryListProps) => { @@ -14,6 +14,7 @@ const CategoryList = ({ list, type, setType }: CategoryListProps) => { {list.map((keyword, idx) => ( { /> ))} - ) -} + ); +}; const TagContainer = styled.div` display: flex; align-items: center; gap: 8px; justify-content: space-around; -` +`; -export default CategoryList +export default CategoryList; diff --git a/src/components/designSystem/Buttons/CloseButton.tsx b/src/components/designSystem/Buttons/CloseButton.tsx index 77075bb4..08da60b7 100644 --- a/src/components/designSystem/Buttons/CloseButton.tsx +++ b/src/components/designSystem/Buttons/CloseButton.tsx @@ -1,17 +1,18 @@ -'use client' -import { palette } from '@/styles/palette' -import styled from '@emotion/styled' -import React from 'react' +"use client"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; +import React from "react"; interface CloseButtonProps { - setIsOpen: React.Dispatch> + setIsOpen: React.Dispatch>; } export default function CloseButton({ setIsOpen }: CloseButtonProps) { - return setIsOpen(false)}>닫기 + return setIsOpen(false)}>닫기; } const CloseBtn = styled.button` display: flex; + cursor: pointer; justify-content: center; align-items: center; @media (max-width: 390px) { @@ -34,4 +35,4 @@ const CloseBtn = styled.button` &:active { background-color: ${palette.비강조3}; } -` +`; diff --git a/src/components/designSystem/Buttons/EditAndDeleteButton.tsx b/src/components/designSystem/Buttons/EditAndDeleteButton.tsx index 4c64fad4..bb41d8c7 100644 --- a/src/components/designSystem/Buttons/EditAndDeleteButton.tsx +++ b/src/components/designSystem/Buttons/EditAndDeleteButton.tsx @@ -1,35 +1,31 @@ -'use client' -import { palette } from '@/styles/palette' -import styled from '@emotion/styled' -import React from 'react' +"use client"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; +import React from "react"; interface EditAndDeleteButtonProps { - isOpen: boolean - isMyApplyTrip?: boolean // 여행 참가 취소 버튼에도 공용으로 쓰기 위함. - editClickHandler: (event: React.MouseEvent) => void - deleteClickHandler: (event: React.MouseEvent) => void - deleteText?: string + isOpen: boolean; + isMyApplyTrip?: boolean; // 여행 참가 취소 버튼에도 공용으로 쓰기 위함. + editClickHandler: (event: React.MouseEvent) => void; + deleteClickHandler: (event: React.MouseEvent) => void; + deleteText?: string; } export default function EditAndDeleteButton({ editClickHandler, deleteClickHandler, isMyApplyTrip = false, - deleteText = '삭제하기', - isOpen + deleteText = "삭제하기", + isOpen, }: EditAndDeleteButtonProps) { return ( - + {!isMyApplyTrip && 수정하기} - + {deleteText} - ) + ); } const BtnBox = styled.div<{ isMyApplyTrip: boolean; isOpen: boolean }>` @@ -39,15 +35,17 @@ const BtnBox = styled.div<{ isMyApplyTrip: boolean; isOpen: boolean }>` align-items: center; background-color: #f0f0f0; border-radius: 20px; - height: ${props => (props.isMyApplyTrip ? '52px' : '104px')}; + height: ${(props) => (props.isMyApplyTrip ? "52px" : "104px")}; - transform: ${props => (props.isOpen ? 'translateY(-5%)' : 'translateY(20%)')}; + transform: ${(props) => + props.isOpen ? "translateY(-5%)" : "translateY(20%)"}; transition: transform 0.5s ease; -` +`; const EditBtn = styled.button` height: 50%; + cursor: pointer; @media (max-width: 390px) { width: 100%; } @@ -73,9 +71,10 @@ const EditBtn = styled.button` background-color: ${palette.비강조3}; border-radius: 20px 20px 0px 0px; } -` +`; const DeleteBtn = styled.button<{ isMyApplyTrip: boolean }>` - height: ${props => (props.isMyApplyTrip ? '100%' : '50%')}; + height: ${(props) => (props.isMyApplyTrip ? "100%" : "50%")}; + cursor: pointer; @media (max-width: 390px) { width: 100%; } @@ -96,4 +95,4 @@ const DeleteBtn = styled.button<{ isMyApplyTrip: boolean }>` background-color: ${palette.비강조3}; border-radius: 0px 0px 20px 20px; } -` +`; diff --git a/src/components/designSystem/Buttons/FilterButton.tsx b/src/components/designSystem/Buttons/FilterButton.tsx index 795ef863..6a63e4f3 100644 --- a/src/components/designSystem/Buttons/FilterButton.tsx +++ b/src/components/designSystem/Buttons/FilterButton.tsx @@ -1,20 +1,20 @@ -'use client' -import ResetIcon from '@/components/icons/ResetIcon' -import { palette } from '@/styles/palette' -import styled from '@emotion/styled' +"use client"; +import ResetIcon from "@/components/icons/ResetIcon"; +import { palette } from "@/styles/palette"; +import styled from "@emotion/styled"; interface FilterButtonProps { - text: string + text: string; addStyle?: { - backgroundColor?: string - color?: string - boxShadow?: string - weight?: 'regular' | 'medium' | 'semiBold' | 'bold' - } - type?: 'button' | 'reset' | 'submit' | undefined - children?: React.ReactNode - disabled?: boolean - onClick?: (event: React.MouseEvent) => void - intializeOnClick?: (event: React.MouseEvent) => void + backgroundColor?: string; + color?: string; + boxShadow?: string; + weight?: "regular" | "medium" | "semiBold" | "bold"; + }; + type?: "button" | "reset" | "submit" | undefined; + children?: React.ReactNode; + disabled?: boolean; + onClick?: (event: React.MouseEvent) => void; + intializeOnClick?: (event: React.MouseEvent) => void; } // 사용 방식 { @@ -26,24 +26,29 @@ interface FilterButtonProps { // 다음, 로그인 등에 쓰이는 버튼. const FilterButton = ({ - text = '다음', - type = 'submit', + text = "다음", + type = "submit", addStyle = { - backgroundColor: 'rgba(62, 141, 0, 1)', - color: 'white', - boxShadow: '-2px 4px 5px 0px rgba(170, 170, 170, 0.14)', - weight: 'semiBold' + backgroundColor: "rgba(62, 141, 0, 1)", + color: "white", + boxShadow: "-2px 4px 5px 0px rgba(170, 170, 170, 0.14)", + weight: "semiBold", }, onClick = () => {}, intializeOnClick = () => {}, disabled = false, - children + children, }: FilterButtonProps) => { return ( + style={!disabled ? addStyle : {}} + > {text} {children} - ) -} + ); +}; const FilterButtonWrapper = styled.div` width: 100%; @@ -66,7 +72,7 @@ const FilterButtonWrapper = styled.div` display: flex; align-items: center; gap: 16px; -` +`; const ButtonContainer = styled.button<{ disabled: boolean }>` @media (max-width: 390px) { width: 100%; @@ -74,6 +80,7 @@ const ButtonContainer = styled.button<{ disabled: boolean }>` @media (min-width: 390px) { width: 342px; } + height: 48px; border-radius: 40px; cursor: pointer; @@ -82,9 +89,9 @@ const ButtonContainer = styled.button<{ disabled: boolean }>` padding: 10px 20px 10px 20px; display: flex; align-items: center; - background-color: ${props => props.disabled && 'rgba(220, 220, 220, 1)'}; - color: ${props => props.disabled && palette.비강조}; + background-color: ${(props) => props.disabled && "rgba(220, 220, 220, 1)"}; + color: ${(props) => props.disabled && palette.비강조}; border: none; -` +`; -export default FilterButton +export default FilterButton; diff --git a/src/components/designSystem/Buttons/ReportButton.tsx b/src/components/designSystem/Buttons/ReportButton.tsx index d9f08080..6ef9821a 100644 --- a/src/components/designSystem/Buttons/ReportButton.tsx +++ b/src/components/designSystem/Buttons/ReportButton.tsx @@ -31,13 +31,15 @@ const BtnBox = styled.div<{ isOpen: boolean }>` border-radius: 20px; height: 52px; - transform: ${(props) => (props.isOpen ? "translateY(-5%)" : "translateY(20%)")}; + transform: ${(props) => + props.isOpen ? "translateY(-5%)" : "translateY(20%)"}; transition: transform 0.5s ease; `; const ReportBtn = styled.button` height: 100%; + cursor: pointer; @media (max-width: 390px) { width: 100%; } diff --git a/src/components/designSystem/modal/CheckingModal.tsx b/src/components/designSystem/modal/CheckingModal.tsx index f26d496c..d64b043e 100644 --- a/src/components/designSystem/modal/CheckingModal.tsx +++ b/src/components/designSystem/modal/CheckingModal.tsx @@ -8,7 +8,9 @@ interface CheckingModalProps { modalMsg: string; modalTitle: string; modalButtonText: string; - setModalOpen: React.Dispatch> | ((bool: boolean) => void); + setModalOpen: + | React.Dispatch> + | ((bool: boolean) => void); setIsSelected?: React.Dispatch>; onClick?: () => void; } @@ -44,7 +46,11 @@ export default function CheckingModal({ return createPortal( - e.stopPropagation()} ref={modalRef} isModalOpen={isModalOpen}> + e.stopPropagation()} + ref={modalRef} + isModalOpen={isModalOpen} + > {modalTitle} {modalMsg} @@ -91,6 +97,7 @@ const CloseBtn = styled.button` text-align: center; color: ${palette.비강조2}; display: flex; + cursor: pointer; justify-content: center; align-items: center; width: 50%; @@ -102,6 +109,7 @@ const SelectBtn = styled.button` font-size: 16px; font-weight: 600; line-height: 16px; + cursor: pointer; text-align: center; color: ${palette.keycolor}; display: flex; @@ -151,7 +159,8 @@ const Modal = styled.div<{ isModalOpen: boolean }>` gap: 16px; border-radius: 20px; opacity: 0px; - transform: ${({ isModalOpen }) => (isModalOpen ? "translateY(0)" : "translateY(30%)")}; + transform: ${({ isModalOpen }) => + isModalOpen ? "translateY(0)" : "translateY(30%)"}; transition: transform 0.3s ease-in-out; `; const DarkWrapper = styled.div` diff --git a/src/components/designSystem/modal/EditAndDeleteModal.tsx b/src/components/designSystem/modal/EditAndDeleteModal.tsx index 4b305e05..05b33213 100644 --- a/src/components/designSystem/modal/EditAndDeleteModal.tsx +++ b/src/components/designSystem/modal/EditAndDeleteModal.tsx @@ -46,7 +46,11 @@ export default function EditAndDeleteModal({ if (!isListening) return null; return createPortal( - 390 ? 390 : window.innerWidth}> + 390 ? 390 : window.innerWidth} + > {!isMyApplyTrip ? ( > | ((bool: boolean) => void); + setModalOpen: + | React.Dispatch> + | ((bool: boolean) => void); } -export default function NoticeModal({ isModalOpen, modalMsg, modalTitle, setModalOpen }: ResultModalProps) { +export default function NoticeModal({ + isModalOpen, + modalMsg, + modalTitle, + setModalOpen, +}: ResultModalProps) { const modalRef = useRef(null); // 모달 참조 const [isListening, setIsListening] = useState(false); // 모달 창이 열리고, 이벤트 등록이 동기적으로 일어나도록 제한. useEffect(() => { const handleClickOutside = (event: MouseEvent) => { - if (isListening && modalRef.current && !modalRef.current.contains(event.target as Node)) { + if ( + isListening && + modalRef.current && + !modalRef.current.contains(event.target as Node) + ) { setModalOpen(false); // 외부 클릭 시 모달 닫기 } }; @@ -41,10 +52,23 @@ export default function NoticeModal({ isModalOpen, modalMsg, modalTitle, setModa
- + - + ` gap: 16px; border-radius: 20px; opacity: 0px; - transform: ${({ isModalOpen }) => (isModalOpen ? "translateY(0)" : "translateY(30%)")}; + transform: ${({ isModalOpen }) => + isModalOpen ? "translateY(0)" : "translateY(30%)"}; transition: transform 0.3s ease-in-out; `; const DarkWrapper = styled.div` diff --git a/src/components/designSystem/modal/ResultModal.tsx b/src/components/designSystem/modal/ResultModal.tsx index 062e46cf..03a65442 100644 --- a/src/components/designSystem/modal/ResultModal.tsx +++ b/src/components/designSystem/modal/ResultModal.tsx @@ -11,14 +11,23 @@ interface ResultModalProps { modalTitle: string; setModalOpen: React.Dispatch>; } -export default function ResultModal({ isModalOpen, modalMsg, modalTitle, setModalOpen }: ResultModalProps) { +export default function ResultModal({ + isModalOpen, + modalMsg, + modalTitle, + setModalOpen, +}: ResultModalProps) { const modalRef = useRef(null); // 모달 참조 const [isListening, setIsListening] = useState(false); // 모달 창이 열리고, 이벤트 등록이 동기적으로 일어나도록 제한. useEffect(() => { const handleClickOutside = (event: MouseEvent) => { - if (isListening && modalRef.current && !modalRef.current.contains(event.target as Node)) { + if ( + isListening && + modalRef.current && + !modalRef.current.contains(event.target as Node) + ) { setModalOpen(false); // 외부 클릭 시 모달 닫기 } }; @@ -87,6 +96,7 @@ const CloseBtn = styled.button` font-weight: 400; line-height: 16px; text-align: center; + cursor: pointer; color: ${palette.비강조2}; display: flex; justify-content: center; @@ -138,7 +148,8 @@ const Modal = styled.div<{ isModalOpen: boolean }>` gap: 16px; border-radius: 20px; opacity: 0px; - transform: ${({ isModalOpen }) => (isModalOpen ? "translateY(0)" : "translateY(30%)")}; + transform: ${({ isModalOpen }) => + isModalOpen ? "translateY(0)" : "translateY(30%)"}; transition: transform 0.3s ease-in-out; `; const DarkWrapper = styled.div` diff --git a/src/components/relationKeyword/RelationKeywordList.tsx b/src/components/relationKeyword/RelationKeywordList.tsx index 91dbecc9..475b8675 100644 --- a/src/components/relationKeyword/RelationKeywordList.tsx +++ b/src/components/relationKeyword/RelationKeywordList.tsx @@ -1,45 +1,43 @@ -'use client' -import useRelationKeyword from '@/hooks/search/useRelationKeyword' -import styled from '@emotion/styled' -import RelationKeyword from './RelationKeyword' +"use client"; +import useRelationKeyword from "@/hooks/search/useRelationKeyword"; +import styled from "@emotion/styled"; +import RelationKeyword from "./RelationKeyword"; interface RelationKeywordListProps { - keyword: string - onClick: (keyword: string) => void + keyword: string; + onClick: (keyword: string) => void; } const RelationKeywordList = ({ keyword, - onClick + onClick, }: RelationKeywordListProps) => { - const { data, isLoading, error } = useRelationKeyword(keyword) + const { data, isLoading, error } = useRelationKeyword(keyword); if (isLoading) { - return null + return null; } if (error) { - return null + return null; } - console.log(data, '관련 키워드.') + console.log(data, "관련 키워드."); return ( {data && data.suggestions.length > 0 && - data?.suggestions?.map(data => ( + data?.suggestions?.map((data) => ( ))} - ) -} + ); +}; -const Contianer = styled.div`` +const Contianer = styled.div``; -export default RelationKeywordList +export default RelationKeywordList; diff --git a/src/components/travellog/AreaDropdown.tsx b/src/components/travellog/AreaDropdown.tsx index 92b19dfd..158837cd 100644 --- a/src/components/travellog/AreaDropdown.tsx +++ b/src/components/travellog/AreaDropdown.tsx @@ -139,6 +139,7 @@ const ItemContainer = styled.div` align-items: center; justify-content: space-between; width: 100%; + cursor: pointer; padding: 18px 0; gap: 8px; `; diff --git a/src/components/travellog/AreaFilter.tsx b/src/components/travellog/AreaFilter.tsx index 08f80e04..09f1e73e 100644 --- a/src/components/travellog/AreaFilter.tsx +++ b/src/components/travellog/AreaFilter.tsx @@ -31,10 +31,15 @@ export default function AreaFilter() { {FILTER_LIST.map(({ title, value }, idx) => ( ))} diff --git a/src/components/triplist/TripInfiniteList.tsx b/src/components/triplist/TripInfiniteList.tsx index 5be9d53e..f4bfde09 100644 --- a/src/components/triplist/TripInfiniteList.tsx +++ b/src/components/triplist/TripInfiniteList.tsx @@ -32,7 +32,8 @@ const TripInfiniteList = () => { return value; })(); - const { data, isFetching, hasNextPage, fetchNextPage, isLoading } = useTripList(engSort); + const { data, isFetching, hasNextPage, fetchNextPage, isLoading } = + useTripList(engSort); useInfiniteScroll(() => { if (inView) { !isFetching && hasNextPage && fetchNextPage(); @@ -53,7 +54,10 @@ const TripInfiniteList = () => { {page.content.map((content, itemIndex) => ( -
clickTrip(content.travelNumber)}> +
clickTrip(content.travelNumber)} + > { total={content.maxPerson} location={content.location} daysAgo={daysAgo(content.createdAt)} - daysLeft={dayjs(content.registerDue, "YYYY-MM-DD").diff(dayjs().startOf("day"), "day")} + daysLeft={dayjs(content.registerDue, "YYYY-MM-DD").diff( + dayjs().startOf("day"), + "day" + )} recruits={content.nowPerson} />
@@ -85,7 +92,11 @@ const BookmarkButton = ({ bookmarked, travelNumber }: BookmarkButtonProps) => { const [showLoginModal, setShowLoginModal] = useState(false); const pathname = usePathname(); const router = useRouter(); - const { postBookmarkMutation, deleteBookmarkMutation } = useUpdateBookmark(accessToken!, userId!, travelNumber); + const { postBookmarkMutation, deleteBookmarkMutation } = useUpdateBookmark( + accessToken!, + userId!, + travelNumber + ); const bookmarkClickHandler = (e: React.MouseEvent) => { e.stopPropagation(); if (isGuestUser()) { @@ -117,7 +128,11 @@ const BookmarkButton = ({ bookmarked, travelNumber }: BookmarkButtonProps) => { {bookmarked ? ( ) : ( - + )} diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index 0fb52c29..a312040c 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -18,7 +18,9 @@ import { authStore } from "@/store/client/authStore"; interface UserProfileDetailProps { isMyPage?: boolean; } -export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { +export default function UserProfileDetail({ + isMyPage = false, +}: UserProfileDetailProps) { const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); const { userProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); @@ -76,7 +78,8 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai }, ]; - const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; + const cutTags = + preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; const moveToNextLink = (link: string) => { navigateWithTransition(link); @@ -102,7 +105,9 @@ export default function UserProfileDetail({ isMyPage = false }: UserProfileDetai {name} {isMyPage && } - {isMyPage ? myPageStore().email : userRegDate + "가입"} + + {isMyPage ? myPageStore().email : userRegDate + "가입"} + 총 여행한 거리✨ - {formatNumberWithComma(travelDistance)}km + + {formatNumberWithComma(Math.ceil(travelDistance))}km + @@ -224,6 +231,7 @@ export const Name = styled.div` line-height: 16px; letter-spacing: -0.25px; text-align: center; + cursor: pointer; color: ${palette.기본}; `; diff --git a/src/page/CreateTrip/CalendarClient.tsx b/src/page/CreateTrip/CalendarClient.tsx index a54c411c..a2a754ce 100644 --- a/src/page/CreateTrip/CalendarClient.tsx +++ b/src/page/CreateTrip/CalendarClient.tsx @@ -49,7 +49,11 @@ const CalendarClient: React.FC = ({ holidaysArray }) => { return ( <> - + @@ -67,7 +71,9 @@ const CalendarClient: React.FC = ({ holidaysArray }) => { - {date ? formatDateRange(date.startDate, date.endDate) : "날짜를 선택하세요."} + {date + ? formatDateRange(date.startDate, date.endDate) + : "날짜를 선택하세요."}
@@ -150,7 +156,7 @@ const DuedateBtn = styled.button` padding: 12px 16px; gap: 0px; border-radius: 20px; - + cursor: pointer; opacity: 0px; `; diff --git a/src/page/CreateTrip/CreateTripDetail/CalendarWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/CalendarWrapper.tsx index c725dd68..31d51b7e 100644 --- a/src/page/CreateTrip/CreateTripDetail/CalendarWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/CalendarWrapper.tsx @@ -15,13 +15,24 @@ const CalendarWrapper = ({ startDate: string; endDate: string; } | null; - addDate: ({ startDate, endDate }: { startDate: string; endDate: string }) => void; + addDate: ({ + startDate, + endDate, + }: { + startDate: string; + endDate: string; + }) => void; }) => { const [showModal, setShowModal] = useState(false); return ( <> - + setShowModal(true)}> @@ -29,7 +40,11 @@ const CalendarWrapper = ({ 여행 날짜 - {date ? formatDateRange(date?.startDate ?? "", date?.endDate ?? "") : "날짜를 선택하세요."} + + {date + ? formatDateRange(date?.startDate ?? "", date?.endDate ?? "") + : "날짜를 선택하세요."} + @@ -43,6 +58,7 @@ const Container = styled.div` padding: 11px 0; padding-left: 8px; display: flex; + cursor: pointer; align-items: center; justify-content: space-between; `; diff --git a/src/page/CreateTrip/CreateTripDetail/CreateScheduleItem.tsx b/src/page/CreateTrip/CreateTripDetail/CreateScheduleItem.tsx index 6578c5c6..90204037 100644 --- a/src/page/CreateTrip/CreateTripDetail/CreateScheduleItem.tsx +++ b/src/page/CreateTrip/CreateTripDetail/CreateScheduleItem.tsx @@ -6,7 +6,14 @@ import { tripPlanStore } from "@/store/client/tripPlanStore"; import { palette } from "@/styles/palette"; import styled from "@emotion/styled"; import { useRouter } from "next/navigation"; -import React, { DragEvent, ForwardedRef, forwardRef, useEffect, useRef, useState } from "react"; +import React, { + DragEvent, + ForwardedRef, + forwardRef, + useEffect, + useRef, + useState, +} from "react"; const CreateScheduleItem = ({ title, @@ -35,11 +42,20 @@ const CreateScheduleItem = ({ }[] ) => void; }) => { - const { scrollTop, addScrollTop, planIndex, addPlanIndex, isChange, addIsChange } = tripPlanStore(); + const { + scrollTop, + addScrollTop, + planIndex, + addPlanIndex, + isChange, + addIsChange, + } = tripPlanStore(); const [contentHeight, setContentHeight] = useState(0); const router = useRouter(); const contentRef = useRef(null); // 콘텐츠 참조 추가 - const plan = plans.find((plan) => plan.planOrder === (type === "create" ? idx : idx + 1)); + const plan = plans.find( + (plan) => plan.planOrder === (type === "create" ? idx : idx + 1) + ); const count = plan?.spots?.length ?? 0; useEffect(() => { if (contentRef.current) { @@ -51,7 +67,9 @@ const CreateScheduleItem = ({ if (scrollTop > 0 && isChange) { console.log("scrollTop", scrollTop); document.getElementById("container-scroll")?.scrollTo({ - top: scrollTop + (document.getElementById("top-scroll")?.clientHeight ?? 0), + top: + scrollTop + + (document.getElementById("top-scroll")?.clientHeight ?? 0), }); setTimeout(() => { addScrollTop(0); @@ -61,16 +79,28 @@ const CreateScheduleItem = ({ }, [scrollTop]); const clickPlans = () => { - console.log("plancheck", idx, document.getElementById("container-scroll")?.scrollTop); + console.log( + "plancheck", + idx, + document.getElementById("container-scroll")?.scrollTop + ); addScrollTop(document.getElementById("container-scroll")?.scrollTop ?? 0); addPlanIndex(idx); - router.push(`/search/place/${idx}?type=${type}${type === "edit" ? `&travelNumber=${travelNumber}` : ""}`); + router.push( + `/search/place/${idx}?type=${type}${type === "edit" ? `&travelNumber=${travelNumber}` : ""}` + ); }; return ( - + Day {idx + 1} @@ -79,8 +109,20 @@ const CreateScheduleItem = ({ {count > 0 && {count}} - - + + @@ -90,7 +132,13 @@ const CreateScheduleItem = ({ isChecked={isOpen} contentHeight={contentHeight} // 동적으로 계산된 높이 전달 > - {plan?.planOrder !== undefined && } + {plan?.planOrder !== undefined && ( + + )} @@ -172,6 +220,7 @@ const Button = styled.button` border-radius: 40px; width: 100%; height: 42px; + cursor: pointer; background-color: ${palette.비강조4}; color: ${palette.비강조}; font-size: 14px; @@ -186,10 +235,12 @@ const Content = styled.div<{ }>` height: ${(props) => (props.isChecked ? `${props.contentHeight}px` : "0")}; overflow: hidden; - border-bottom: ${(props) => (props.tabBorder ? "1px solid rgba(240, 240, 240, 1)" : "none")}; + border-bottom: ${(props) => + props.tabBorder ? "1px solid rgba(240, 240, 240, 1)" : "none"}; padding: ${(props) => (props.isChecked ? `16px 6px 16px 6px` : `0 0 0 0`)}; - transform: ${(props) => (props.isChecked ? "translateY(0)" : `translateY(${props.paddingTop})`)}; + transform: ${(props) => + props.isChecked ? "translateY(0)" : `translateY(${props.paddingTop})`}; transition: height 0.4s ease-in-out, padding 0.4s ease-in-out, diff --git a/src/page/CreateTrip/CreateTripDetail/InfoWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/InfoWrapper.tsx index 8190f4b6..71bd9227 100644 --- a/src/page/CreateTrip/CreateTripDetail/InfoWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/InfoWrapper.tsx @@ -175,6 +175,7 @@ const GenderItem = styled.div<{ isSelected: boolean }>` display: flex; flex-direction: column; align-items: center; + cursor: pointer; gap: 4px; justify-content: center; background-color: ${(props) => @@ -198,6 +199,7 @@ const CountContainer = styled.div` const PlusButton = styled.button` width: 42px; height: 42px; + cursor: pointer; border-radius: 50%; position: relative; background-color: ${palette.비강조}; @@ -232,7 +234,7 @@ const MinusButton = styled.button` border-radius: 50%; position: relative; background-color: ${palette.비강조}; - + cursor: pointer; &::before { content: ""; width: 16px; @@ -302,6 +304,7 @@ const Count = styled.div` const Container = styled.div` padding: 11px 0; + cursor: pointer; padding-left: 8px; display: flex; align-items: center; diff --git a/src/page/CreateTrip/CreateTripDetail/RecruitingWrapper.tsx b/src/page/CreateTrip/CreateTripDetail/RecruitingWrapper.tsx index d1646b49..b0c56215 100644 --- a/src/page/CreateTrip/CreateTripDetail/RecruitingWrapper.tsx +++ b/src/page/CreateTrip/CreateTripDetail/RecruitingWrapper.tsx @@ -147,6 +147,7 @@ const PlusButton = styled.button` width: 42px; height: 42px; border-radius: 50%; + cursor: pointer; position: relative; background-color: ${palette.비강조}; &::after { @@ -180,7 +181,7 @@ const MinusButton = styled.button` border-radius: 50%; position: relative; background-color: ${palette.비강조}; - + cursor: pointer; &::before { content: ""; width: 16px; @@ -257,7 +258,7 @@ const RecruitingBtn = styled.button` align-items: center; justify-content: space-between; margin-top: 8px; - + cursor: pointer; height: 48px; padding: 12px 16px; gap: 0px; diff --git a/src/page/CreateTrip/CreateTripDetail/search/SearchItem.tsx b/src/page/CreateTrip/CreateTripDetail/search/SearchItem.tsx index 9939531a..07f13374 100644 --- a/src/page/CreateTrip/CreateTripDetail/search/SearchItem.tsx +++ b/src/page/CreateTrip/CreateTripDetail/search/SearchItem.tsx @@ -133,6 +133,7 @@ const Container = styled.div` height: 69px; width: 100%; gap: 4px; + cursor: pointer; border-bottom: 1px solid #e7e7e7; `; @@ -160,6 +161,7 @@ const AddButton = styled.button` background-color: ${palette.비강조5}; color: ${palette.기본}; line-height: 14px; + cursor: pointer; font-size: 12px; font-weight: 600; padding: 6px 10px; diff --git a/src/page/CreateTrip/CreateTripDetail/search/SearchPlace.tsx b/src/page/CreateTrip/CreateTripDetail/search/SearchPlace.tsx index a7b0702c..106fd32e 100644 --- a/src/page/CreateTrip/CreateTripDetail/search/SearchPlace.tsx +++ b/src/page/CreateTrip/CreateTripDetail/search/SearchPlace.tsx @@ -331,6 +331,7 @@ const HeaderTitle = styled.div` const IconContainer = styled.div` width: 48px; + cursor: pointer; height: 48px; display: flex; align-items: center; diff --git a/src/page/CreateTrip/CreateTripInfo.tsx b/src/page/CreateTrip/CreateTripInfo.tsx index ce262b34..7a71266f 100644 --- a/src/page/CreateTrip/CreateTripInfo.tsx +++ b/src/page/CreateTrip/CreateTripInfo.tsx @@ -15,9 +15,18 @@ import useViewTransition from "@/hooks/useViewTransition"; import { useRouter } from "next/navigation"; import { isGuestUser } from "@/utils/user"; export const selections = [ - { gender: "모두", icon: (isSelect: boolean) => }, - { gender: "남자만", icon: (isSelect: boolean) => }, - { gender: "여자만", icon: (isSelect: boolean) => }, + { + gender: "모두", + icon: (isSelect: boolean) => , + }, + { + gender: "남자만", + icon: (isSelect: boolean) => , + }, + { + gender: "여자만", + icon: (isSelect: boolean) => , + }, ]; const CreateTripInfo = () => { @@ -52,7 +61,10 @@ const CreateTripInfo = () => { 성별 선택 {selections.map((item) => ( - clickGender(item.gender)}> + clickGender(item.gender)} + > {item.icon(genderType === item.gender)} {item.gender} @@ -109,12 +121,15 @@ const GenderList = styled.div` const GenderItem = styled.div<{ isSelected: boolean }>` display: flex; + cursor: pointer; flex-direction: column; align-items: center; gap: 4px; justify-content: center; - background-color: ${(props) => (props.isSelected ? palette.keycolorBG : palette.검색창)}; - border: ${(props) => (props.isSelected ? `1px solid ${palette.keycolor}` : "0px")}; + background-color: ${(props) => + props.isSelected ? palette.keycolorBG : palette.검색창}; + border: ${(props) => + props.isSelected ? `1px solid ${palette.keycolor}` : "0px"}; border-radius: 20px; width: 90px; height: 84px; diff --git a/src/page/CreateTrip/component/TagList.tsx b/src/page/CreateTrip/component/TagList.tsx index 141bc804..9ab76346 100644 --- a/src/page/CreateTrip/component/TagList.tsx +++ b/src/page/CreateTrip/component/TagList.tsx @@ -23,15 +23,22 @@ const TagList = ({ taggedArray, clickTag }: TagListProps) => { key={tag} idx={idx} addStyle={{ - backgroundColor: isActive(idx) ? "rgba(227, 239, 217, 1)" : " rgba(240, 240, 240, 1)", - color: isActive(idx) ? `${palette.keycolor}` : "rgba(52, 52, 52, 1)", + backgroundColor: isActive(idx) + ? "rgba(227, 239, 217, 1)" + : " rgba(240, 240, 240, 1)", + color: isActive(idx) + ? `${palette.keycolor}` + : "rgba(52, 52, 52, 1)", - border: isActive(idx) ? `1px solid ${palette.keycolor}` : `1px solid ${palette.검색창}`, + border: isActive(idx) + ? `1px solid ${palette.keycolor}` + : `1px solid ${palette.검색창}`, borderRadius: "30px", padding: "10px 20px", fontWeight: isActive(idx) ? "600" : "400", lineHeight: "22px", }} + style={{ cursor: "pointer" }} text={tag} onClick={() => clickTag(idx)} /> diff --git a/src/page/Home/ContentTitleContainer.tsx b/src/page/Home/ContentTitleContainer.tsx index 1363197f..417a555a 100644 --- a/src/page/Home/ContentTitleContainer.tsx +++ b/src/page/Home/ContentTitleContainer.tsx @@ -7,7 +7,11 @@ interface TitleContainerProps { minWidth?: string; detailLink?: string; } -const TitleContainer = ({ text, minWidth = "auto", detailLink = "/" }: TitleContainerProps) => { +const TitleContainer = ({ + text, + minWidth = "auto", + detailLink = "/", +}: TitleContainerProps) => { const router = useRouter(); const clickHandler = () => router.push(`${detailLink}`); // 후에 보여줄 페이지 부분. return ( @@ -36,6 +40,7 @@ const More = styled.div` width: 48px; height: 48px; display: flex; + cursor: pointer; align-items: center; justify-content: center; `; diff --git a/src/page/Home/CreateTripButton.tsx b/src/page/Home/CreateTripButton.tsx index 0777c473..8f908c50 100644 --- a/src/page/Home/CreateTripButton.tsx +++ b/src/page/Home/CreateTripButton.tsx @@ -156,6 +156,7 @@ const CreateBtn = styled.button<{ right: string; isClicked: boolean }>` height: 48px; padding: 14px 24px; border-radius: 20px; + cursor: pointer; background-color: white; display: flex; justify-content: center; @@ -181,6 +182,7 @@ const IconContainer = styled.button<{ rotated: boolean; right: string }>` pointer-events: auto; right: 24px; bottom: 124px; + cursor: pointer; width: 70px; height: 70px; border-radius: 50%; diff --git a/src/page/Home/TripAvailable.tsx b/src/page/Home/TripAvailable.tsx index f143ebb7..6a082b48 100644 --- a/src/page/Home/TripAvailable.tsx +++ b/src/page/Home/TripAvailable.tsx @@ -43,7 +43,13 @@ const TripAvailable = () => { cutTrips?.map((post, idx) => { return ( - +
clickTrip(post.travelNumber)}> { userName={post.userName} tags={post.tags} daysAgo={daysAgo(post?.createdAt)} - daysLeft={dayjs(post.registerDue, "YYYY-MM-DD").diff(dayjs().startOf("day"), "day")} + daysLeft={dayjs(post.registerDue, "YYYY-MM-DD").diff( + dayjs().startOf("day"), + "day" + )} title={post.title} recruits={post.nowPerson} total={post.maxPerson} diff --git a/src/page/MyPage/EditMyTag.tsx b/src/page/MyPage/EditMyTag.tsx index cf8490eb..1e3a7bc8 100644 --- a/src/page/MyPage/EditMyTag.tsx +++ b/src/page/MyPage/EditMyTag.tsx @@ -38,7 +38,13 @@ const TAG_LIST = [ const AGE_LIST = ["10대", "20대", "30대", "40대", "50대 이상"]; export default function EditMyTag() { const [isChanged, setIsChanged] = useState(false); - const { agegroup, addPreferredTags, addAgegroup, preferredTags, addIsTagUpdated } = myPageStore(); + const { + agegroup, + addPreferredTags, + addAgegroup, + preferredTags, + addIsTagUpdated, + } = myPageStore(); console.log(agegroup, preferredTags, "나이, 태그"); const { updateMyPageMutation, isUpdatedSuccess } = useMyPage(); const [taggedArray, setTaggedArray] = useState(preferredTags); @@ -75,7 +81,9 @@ export default function EditMyTag() { return; } } - const newArray = taggedArray.includes(tag) ? taggedArray.filter((v) => v !== tag) : [...taggedArray, tag]; + const newArray = taggedArray.includes(tag) + ? taggedArray.filter((v) => v !== tag) + : [...taggedArray, tag]; if (JSON.stringify(newArray) !== JSON.stringify(taggedArray)) { setIsChanged(true); } @@ -103,19 +111,27 @@ export default function EditMyTag() { {AGE_LIST.map((ageValue, idx) => ( handleClickage(ageValue)} text={ageValue} key={ageValue} + style={{ cursor: "pointer" }} /> ))} @@ -133,8 +149,12 @@ export default function EditMyTag() { key={tag} idx={idx} addStyle={{ - backgroundColor: isActive(tag.split(" ")[1]) ? "rgba(227, 239, 217, 1)" : " rgba(240, 240, 240, 1)", - color: isActive(tag.split(" ")[1]) ? `${palette.keycolor}` : "rgba(52, 52, 52, 1)", + backgroundColor: isActive(tag.split(" ")[1]) + ? "rgba(227, 239, 217, 1)" + : " rgba(240, 240, 240, 1)", + color: isActive(tag.split(" ")[1]) + ? `${palette.keycolor}` + : "rgba(52, 52, 52, 1)", border: isActive(tag.split(" ")[1]) ? `1px solid ${palette.keycolor}` : `1px solid ${palette.검색창}`, @@ -144,6 +164,7 @@ export default function EditMyTag() { padding: "10px 20px", fontWeight: isActive(tag.split(" ")[1]) ? "600" : "400", }} + style={{ cursor: "pointer" }} text={tag} onClick={() => clickTag(tag.split(" ")[1])} /> @@ -159,8 +180,14 @@ export default function EditMyTag() { text="완료" onClick={completeClickHandler} addStyle={{ - backgroundColor: taggedArray.length > 0 ? "rgba(62, 141, 0, 1)" : "rgba(220, 220, 220, 1)", - color: taggedArray.length > 0 ? "rgba(240, 240, 240, 1)" : palette.비강조, + backgroundColor: + taggedArray.length > 0 + ? "rgba(62, 141, 0, 1)" + : "rgba(220, 220, 220, 1)", + color: + taggedArray.length > 0 + ? "rgba(240, 240, 240, 1)" + : palette.비강조, boxShadow: "rgba(170, 170, 170, 0.1)", }} /> diff --git a/src/page/Register/RegisterAge.tsx b/src/page/Register/RegisterAge.tsx index 4a856960..3a69a02c 100644 --- a/src/page/Register/RegisterAge.tsx +++ b/src/page/Register/RegisterAge.tsx @@ -15,7 +15,9 @@ type RegisterAgeContextType = { setGenderCheck: (value: boolean) => void; }; -export const RegisterAgeContext = createContext(undefined); +export const RegisterAgeContext = createContext< + RegisterAgeContextType | undefined +>(undefined); export const useRegisterAge = () => { const context = useContext(RegisterAgeContext); @@ -29,7 +31,16 @@ const AGE_LIST = ["10대", "20대", "30대", "40대", "50대 이상"]; const RegisterAge = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); - const { agegroup, addAgegroup, email, name, resetForm, resetName, socialLogin, setSocialLogin } = userStore(); + const { + agegroup, + addAgegroup, + email, + name, + resetForm, + resetName, + socialLogin, + setSocialLogin, + } = userStore(); const [genderCheck, setGenderCheck] = useState(false); const isEmailRegister = socialLogin === null; const isSocialLoginKakao = socialLogin === "kakao"; @@ -40,7 +51,10 @@ const RegisterAge = ({ children }: { children: React.ReactNode }) => { if (location.pathname == "/registerAge") { console.log(1); router.push("/registerAge/registerGender"); - } else if (genderCheck && location.pathname == "/registerAge/registerGender") { + } else if ( + genderCheck && + location.pathname == "/registerAge/registerGender" + ) { document.documentElement.style.viewTransitionName = "forward"; navigateWithTransition("/registerTripStyle"); } @@ -79,14 +93,22 @@ const RegisterAge = ({ children }: { children: React.ReactNode }) => { {AGE_LIST.map((age, idx) => ( handleClickage(age)} text={age} diff --git a/src/page/Register/RegisterGender.tsx b/src/page/Register/RegisterGender.tsx index 9428e918..5f5b5afd 100644 --- a/src/page/Register/RegisterGender.tsx +++ b/src/page/Register/RegisterGender.tsx @@ -8,8 +8,18 @@ import { useRouter } from "next/navigation"; const RegisterGender = () => { const { setGenderCheck } = useRegisterAge(); - const { sex, addSex, name, email, agegroup, resetAge, resetName, resetForm, socialLogin, setSocialLogin } = - userStore(); + const { + sex, + addSex, + name, + email, + agegroup, + resetAge, + resetName, + resetForm, + socialLogin, + setSocialLogin, + } = userStore(); const [maleClicked, setMaleClicked] = useState(sex == "M" ? true : false); const [femaleClicked, setFemaleClicked] = useState(sex == "F" ? true : false); const router = useRouter(); @@ -78,18 +88,40 @@ const RegisterGender = () => { -

남자

+

+ 남자 +

-

+

여자

@@ -133,6 +165,7 @@ const MaleBox = styled.div` flex-direction: column; align-items: center; font-weight: 500; + cursor: pointer; p { margin-top: 8px; font-size: 18px; @@ -143,6 +176,7 @@ const FemaleBox = styled.div` flex-direction: column; align-items: center; font-weight: 500; + cursor: pointer; p { margin-top: 8px; font-size: 18px; diff --git a/src/page/Register/RegisterTripStyle.tsx b/src/page/Register/RegisterTripStyle.tsx index 01a1f360..f2393cca 100644 --- a/src/page/Register/RegisterTripStyle.tsx +++ b/src/page/Register/RegisterTripStyle.tsx @@ -39,7 +39,11 @@ const RegisterTripStyle = () => { const { registerEmail, registerEmailMutation: { isSuccess, isPending }, - registerSocialMutation: { isSuccess: isSocialSuccess, isError: isSocialError, isPaused: isSocialPending }, + registerSocialMutation: { + isSuccess: isSocialSuccess, + isError: isSocialError, + isPaused: isSocialPending, + }, registerSocial, } = useAuth(); @@ -114,7 +118,11 @@ const RegisterTripStyle = () => { resetGender(); router.push("/login"); } else { - if (isRegisterEmail && !isSuccess && (!email || !name || !agegroup || !sex)) { + if ( + isRegisterEmail && + !isSuccess && + (!email || !name || !agegroup || !sex) + ) { resetName(); sessionStorage.removeItem("sessionToken"); resetForm(); @@ -152,15 +160,20 @@ const RegisterTripStyle = () => { }, [isSocialError, isSocialSuccess]); // 버튼 활성화상태. - const [activeStates, setActiveStates] = useState(new Array(TAGCOUNT).fill(false)); + const [activeStates, setActiveStates] = useState( + new Array(TAGCOUNT).fill(false) + ); // 최종적으로 선택된 여행 스타일 담은 배열 - const tripStyleArray = categoryButtonTextArray.filter((_, idx) => activeStates[idx]).map((item) => item.value); + const tripStyleArray = categoryButtonTextArray + .filter((_, idx) => activeStates[idx]) + .map((item) => item.value); // 버튼 클릭 핸들러 const handleButtonClick: MouseEventHandler = (e) => { const newActiveStates = [...activeStates]; - newActiveStates[parseInt(e.currentTarget.id)] = !newActiveStates[parseInt(e.currentTarget.id)]; // 토글 + newActiveStates[parseInt(e.currentTarget.id)] = + !newActiveStates[parseInt(e.currentTarget.id)]; // 토글 const activeArray = newActiveStates.filter((v) => v === true); if (activeArray.length <= 5) { @@ -226,15 +239,22 @@ const RegisterTripStyle = () => { key={item.label} idx={idx} addStyle={{ - backgroundColor: isActive(idx) ? "rgba(227, 239, 217, 1)" : " rgba(240, 240, 240, 1)", - color: isActive(idx) ? `${palette.keycolor}` : "rgba(52, 52, 52, 1)", - border: isActive(idx) ? `1px solid ${palette.keycolor}` : `1px solid ${palette.검색창}`, + backgroundColor: isActive(idx) + ? "rgba(227, 239, 217, 1)" + : " rgba(240, 240, 240, 1)", + color: isActive(idx) + ? `${palette.keycolor}` + : "rgba(52, 52, 52, 1)", + border: isActive(idx) + ? `1px solid ${palette.keycolor}` + : `1px solid ${palette.검색창}`, borderRadius: "30px", fontSize: "16", lineHeight: "22px", padding: "10px 20px", fontWeight: isActive(idx) ? "600" : "400", }} + style={{ cursor: "pointer" }} text={item.label} onClick={handleButtonClick} /> @@ -248,8 +268,14 @@ const RegisterTripStyle = () => { text="다음" onClick={completeHandler} addStyle={{ - backgroundColor: tripStyleArray.length > 0 ? "rgba(62, 141, 0, 1)" : "rgba(220, 220, 220, 1)", - color: tripStyleArray.length > 0 ? "rgba(240, 240, 240, 1)" : palette.비강조, + backgroundColor: + tripStyleArray.length > 0 + ? "rgba(62, 141, 0, 1)" + : "rgba(220, 220, 220, 1)", + color: + tripStyleArray.length > 0 + ? "rgba(240, 240, 240, 1)" + : palette.비강조, boxShadow: "rgba(170, 170, 170, 0.1)", }} /> From 2602df8bff4dc8de36174c760a11d37b06f766d3 Mon Sep 17 00:00:00 2001 From: mayrang Date: Thu, 29 May 2025 01:48:14 +0900 Subject: [PATCH 68/69] =?UTF-8?q?Fix:=20travellogmap=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20=EB=B0=A9=EB=AC=B8=20=EA=B5=AD=EA=B0=80?= =?UTF-8?q?=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=A1=9C=EC=A7=81=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/components/map/TravelLogMap.tsx | 82 ++++++++++--------- .../userProfile/UserProfileDetail.tsx | 20 ++--- src/hooks/useHeaderNavigation.tsx | 9 +- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/components/map/TravelLogMap.tsx b/src/components/map/TravelLogMap.tsx index 30326ce7..b205afc7 100644 --- a/src/components/map/TravelLogMap.tsx +++ b/src/components/map/TravelLogMap.tsx @@ -1,6 +1,6 @@ "use client"; import { APIProvider, Map, MapCameraChangedEvent, useMap } from "@vis.gl/react-google-maps"; -import React, { useEffect, useRef } from "react"; +import React, { useCallback, useEffect, useMemo, useRef } from "react"; import sigoonGeoJsonData from "../../../public/geojson/korea.json"; import countryGeoJsonData from "../../../public/geojson/country.json"; import { cityDistricts, getMapLocation } from "@/utils/travellog/travelLog"; @@ -16,26 +16,29 @@ const TravelLogMap = ({ }) => { const { center, zoom } = getMapLocation(target, type); + const mapStyle = useMemo(() => { + if (type === "국내") { + return { width: "100%", height: 418 }; + } + return target ? { width: "100%", height: 400 } : { width: "100%", height: 192 }; + }, [type, target]); + + const onCameraChanged = useCallback((ev: MapCameraChangedEvent) => { + console.log("camera changed:", ev.detail.center, ev.detail.zoom); + }, []); + return ( - console.log("camera changed:", ev.detail.center, ev.detail.zoom) - } + onCameraChanged={onCameraChanged} > @@ -46,35 +49,16 @@ const TravelLogMap = ({ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내"; highlightedRegions?: string[] }) => { const map = useMap(); - useEffect(() => { - if (!map) return; - - const geoJsonLayer = new google.maps.Data({ map }); - - geoJsonLayer.addGeoJson(type === "국내" ? sigoonGeoJsonData : countryGeoJsonData); - - geoJsonLayer.setStyle({ - strokeColor: "#fff", - strokeWeight: 1, - strokeOpacity: 1, - fillOpacity: 0, // 투명한 채우기 - }); + const geoJsonData = useMemo(() => (type === "국내" ? sigoonGeoJsonData : countryGeoJsonData), [type]); - geoJsonLayer.addGeoJson(type === "국내" ? sigoonGeoJsonData : countryGeoJsonData); - // 고차 함수로 사용 - const createHighlighter = (highlightedRegions, cityDistricts) => (regionName) => - highlightedRegions.includes(regionName) || - highlightedRegions.some((region) => cityDistricts[region]?.includes(regionName)); + const isHighlighted = useMemo(() => createHighlighter(highlightedRegions, cityDistricts), [highlightedRegions]); - // 하이라이트 함수 만들기 - const isHighlighted = createHighlighter(highlightedRegions, cityDistricts); - - //스타일 적용 - geoJsonLayer.setStyle((feature) => { + const getFeatureStyle = useCallback( + (feature: google.maps.Data.Feature) => { const regionName = feature.getProperty("name_ko") || feature.getProperty("CTP_KOR_NM") || feature.getProperty("SIG_KOR_NM"); - const highlighted = isHighlighted(regionName); + const highlighted = isHighlighted(regionName as string); return { strokeColor: "#fff", @@ -83,12 +67,32 @@ const TravelLog = ({ type, highlightedRegions = [] }: { type: "세계" | "국내 fillColor: highlighted ? "#3366FF" : "#FFFFFF", fillOpacity: highlighted ? 1 : 0, }; - }); - }, [map]); + }, + [isHighlighted] + ); + + useEffect(() => { + if (!map) return; + + const geoJsonLayer = new google.maps.Data({ map }); + + geoJsonLayer.addGeoJson(geoJsonData); + + geoJsonLayer.setStyle(getFeatureStyle); + + return () => { + geoJsonLayer.setMap(null); + }; + }, [map, geoJsonData, getFeatureStyle]); return null; }; +const createHighlighter = + (highlightedRegions: string[], cityDistricts: Record) => (regionName: string) => + highlightedRegions.includes(regionName) || + highlightedRegions.some((region) => cityDistricts[region]?.includes(regionName)); + // 더미 함수 클릭이나 출처 표시 함수 // function createAttribution() { // const attributionLabel = document.createElement("div"); diff --git a/src/components/userProfile/UserProfileDetail.tsx b/src/components/userProfile/UserProfileDetail.tsx index a312040c..3f302b6b 100644 --- a/src/components/userProfile/UserProfileDetail.tsx +++ b/src/components/userProfile/UserProfileDetail.tsx @@ -14,17 +14,16 @@ import { userProfileOverlayStore } from "@/store/client/userProfileOverlayStore" import useUserProfile from "@/hooks/userProfile/useUserProfile"; import ProfileRightVectorIcon from "../icons/ProfileRightVectorIcon"; import { authStore } from "@/store/client/authStore"; +import { usePathname } from "next/navigation"; interface UserProfileDetailProps { isMyPage?: boolean; } -export default function UserProfileDetail({ - isMyPage = false, -}: UserProfileDetailProps) { +export default function UserProfileDetail({ isMyPage = false }: UserProfileDetailProps) { const { setProfileShow, userProfileUserId } = userProfileOverlayStore(); const { userProfileInfo } = useUserProfile(); const navigateWithTransition = useViewTransition(); - + const pathname = usePathname(); if (!isMyPage && !userProfileInfo) return null; const profileData = isMyPage @@ -78,10 +77,11 @@ export default function UserProfileDetail({ }, ]; - const cutTags = - preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; + const cutTags = preferredTags.length > 2 ? preferredTags.slice(0, 2) : preferredTags; const moveToNextLink = (link: string) => { + localStorage.setItem("profilePath", pathname); + navigateWithTransition(link); setTimeout(() => { setProfileShow(false); @@ -105,9 +105,7 @@ export default function UserProfileDetail({ {name} {isMyPage && } - - {isMyPage ? myPageStore().email : userRegDate + "가입"} - + {isMyPage ? myPageStore().email : userRegDate + "가입"} 총 여행한 거리✨ - - {formatNumberWithComma(Math.ceil(travelDistance))}km - + {formatNumberWithComma(Math.ceil(travelDistance))}km diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index 7cad438f..67f28879 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -392,7 +392,14 @@ export const useHeaderNavigation = () => { // 상대방 프로필 화면의 여행 뱃지 화면 condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), action: () => { - router.back(); + const profilePath = localStorage.getItem("profilePath"); + if (profilePath) { + router.push(profilePath); + } else { + router.back(); + } + localStorage.removeItem("profilePath"); + if (userProfileUserId !== userId) { // 마이페이지가 아닌 페이지에서 접속 했을시, 뒤로 가기 해도 프로필 overlay화면 setTimeout(() => setProfileShow(true), 100); From 2c10eb057fc30aa609de2163cbe2deddcdb3c87a Mon Sep 17 00:00:00 2001 From: mayrang Date: Thu, 29 May 2025 02:35:00 +0900 Subject: [PATCH 69/69] =?UTF-8?q?Fix:=20=EB=AA=87=EB=AA=87=20cursor=20poin?= =?UTF-8?q?ter=20=EC=B6=94=EA=B0=80,=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designSystem/tag/SearchFilterTag.tsx | 1 + src/hooks/useHeaderNavigation.tsx | 18 +++++++++--------- src/page/Home/Home.tsx | 1 + src/page/TripDetail/TripDetail.tsx | 12 +++--------- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/components/designSystem/tag/SearchFilterTag.tsx b/src/components/designSystem/tag/SearchFilterTag.tsx index 245f6aa3..e7705819 100644 --- a/src/components/designSystem/tag/SearchFilterTag.tsx +++ b/src/components/designSystem/tag/SearchFilterTag.tsx @@ -92,6 +92,7 @@ const SearchFilterTagContainer = styled.button<{ isCreateTrip: boolean }>` align-items: center; box-sizing: border-box; gap: 8px; + cursor: pointer; transition: width, background-color 0.3s ease-in-out; diff --git a/src/hooks/useHeaderNavigation.tsx b/src/hooks/useHeaderNavigation.tsx index 67f28879..8f8d7a94 100644 --- a/src/hooks/useHeaderNavigation.tsx +++ b/src/hooks/useHeaderNavigation.tsx @@ -392,14 +392,7 @@ export const useHeaderNavigation = () => { // 상대방 프로필 화면의 여행 뱃지 화면 condition: () => checkRoute.exact(ROUTES.USER_PROFILE_BADGE), action: () => { - const profilePath = localStorage.getItem("profilePath"); - if (profilePath) { - router.push(profilePath); - } else { - router.back(); - } - localStorage.removeItem("profilePath"); - + router.back(); if (userProfileUserId !== userId) { // 마이페이지가 아닌 페이지에서 접속 했을시, 뒤로 가기 해도 프로필 overlay화면 setTimeout(() => setProfileShow(true), 100); @@ -410,7 +403,14 @@ export const useHeaderNavigation = () => { // 상대방 프로필 화면의 여행 로그 화면, condition: () => checkRoute.exact(ROUTES.USER_TRAVEL_LOG), action: () => { - router.back(); + const profilePath = localStorage.getItem("profilePath"); + if (profilePath) { + router.push(profilePath); + } else { + router.back(); + } + localStorage.removeItem("profilePath"); + console.log(userProfileUserId); if (userProfileUserId !== userId) { setTimeout(() => setProfileShow(true), 100); diff --git a/src/page/Home/Home.tsx b/src/page/Home/Home.tsx index a17198fe..6f78c73a 100644 --- a/src/page/Home/Home.tsx +++ b/src/page/Home/Home.tsx @@ -171,6 +171,7 @@ const Alarm = styled.div` width: 48px; height: 48px; display: flex; + cursor: pointer; align-items: center; justify-content: center; `; diff --git a/src/page/TripDetail/TripDetail.tsx b/src/page/TripDetail/TripDetail.tsx index fe420d29..c5a4275c 100644 --- a/src/page/TripDetail/TripDetail.tsx +++ b/src/page/TripDetail/TripDetail.tsx @@ -562,13 +562,7 @@ export default function TripDetail() { {isCommentUpdated ? ( - + ` - padding-top: ${(props) => - `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; + padding-top: ${(props) => `${props.isMapFull ? 32 : props.topModalHeight + 32}px`}; min-height: 100svh; transition: padding-top 0.3s ease-out; overscroll-behavior: none; @@ -835,6 +828,7 @@ const PlaceIconContainer = styled.div` const InfoContainer = styled.div` padding: 11px 0; padding-left: 8px; + cursor: pointer; display: flex; align-items: center; justify-content: space-between;