diff --git a/public/svgs/Ic_All.svg b/public/svgs/common/Ic_All.svg similarity index 100% rename from public/svgs/Ic_All.svg rename to public/svgs/common/Ic_All.svg diff --git a/public/svgs/Ic_Arrow_Left.svg b/public/svgs/common/Ic_Arrow_Left.svg similarity index 100% rename from public/svgs/Ic_Arrow_Left.svg rename to public/svgs/common/Ic_Arrow_Left.svg diff --git a/public/svgs/Ic_Heart-Empty.svg b/public/svgs/common/Ic_Heart-Empty.svg similarity index 100% rename from public/svgs/Ic_Heart-Empty.svg rename to public/svgs/common/Ic_Heart-Empty.svg diff --git a/public/svgs/Ic_Heart_Fill.svg b/public/svgs/common/Ic_Heart_Fill.svg similarity index 100% rename from public/svgs/Ic_Heart_Fill.svg rename to public/svgs/common/Ic_Heart_Fill.svg diff --git a/public/svgs/Ic_X.svg b/public/svgs/common/Ic_X.svg similarity index 100% rename from public/svgs/Ic_X.svg rename to public/svgs/common/Ic_X.svg diff --git a/public/svgs/Ic_X_Btn.svg b/public/svgs/common/Ic_X_Btn.svg similarity index 100% rename from public/svgs/Ic_X_Btn.svg rename to public/svgs/common/Ic_X_Btn.svg diff --git a/public/svgs/favicon.svg b/public/svgs/common/favicon.svg similarity index 100% rename from public/svgs/favicon.svg rename to public/svgs/common/favicon.svg diff --git a/src/pages/join/SignUp.jsx b/src/pages/join/SignUp.jsx index f4e38d9..0a86dd2 100644 --- a/src/pages/join/SignUp.jsx +++ b/src/pages/join/SignUp.jsx @@ -8,6 +8,7 @@ import LocationStep from "./components/LocationStep"; import OwnerStep from "./components/OwnerStep"; import GoHome from "./components/GoHome"; import { signup } from "@apis/member/signup"; +import useAuthStore from "@/store/authStore"; const SignUpPage = () => { const [step, setStep] = useState(1); @@ -37,6 +38,7 @@ const SignUpPage = () => { }; try { await signup(finalData); + useAuthStore.getState().completeSignup(); setStep((prev) => prev + 1); } catch (error) { console.error("회원가입 실패:", error); diff --git a/src/pages/join/components/GoHome.jsx b/src/pages/join/components/GoHome.jsx index 6e5d7e1..775c4ac 100644 --- a/src/pages/join/components/GoHome.jsx +++ b/src/pages/join/components/GoHome.jsx @@ -1,5 +1,5 @@ import { ImgDone } from "@assets/svgs/signup"; -import BackIcon from "/svgs/Ic_Arrow_Left.svg"; +import BackIcon from "/svgs/common/Ic_Arrow_Left.svg"; const GoHome = ({ onNext, onBack }) => { const handleSubmit = () => { diff --git a/src/pages/join/components/LocationStep.jsx b/src/pages/join/components/LocationStep.jsx index 86b5b95..3e85bf2 100644 --- a/src/pages/join/components/LocationStep.jsx +++ b/src/pages/join/components/LocationStep.jsx @@ -1,6 +1,6 @@ import { useState, useRef } from "react"; -import XIcon from "/svgs/Ic_X_Btn.svg"; -import BackIcon from "/svgs/Ic_Arrow_Left.svg"; +import XIcon from "/svgs/common/Ic_X_Btn.svg"; +import BackIcon from "/svgs/common/Ic_Arrow_Left.svg"; import { IcCheck, IcNonCheck } from "@assets/svgs/signup"; import useBottomOffset from "../hooks/useBottomOffset"; diff --git a/src/pages/join/components/NameStep.jsx b/src/pages/join/components/NameStep.jsx index 32d3f2f..2668c96 100644 --- a/src/pages/join/components/NameStep.jsx +++ b/src/pages/join/components/NameStep.jsx @@ -1,6 +1,6 @@ import { useState, useRef } from "react"; -import XIcon from "/svgs/Ic_X_Btn.svg"; -import BackIcon from "/svgs/Ic_Arrow_Left.svg"; +import XIcon from "/svgs/common/Ic_X_Btn.svg"; +import BackIcon from "/svgs/common/Ic_Arrow_Left.svg"; import useBottomOffset from "../hooks/useBottomOffset"; const NameStep = ({ onNext, onBack }) => { @@ -21,13 +21,11 @@ const NameStep = ({ onNext, onBack }) => { onSubmit={handleSubmit} className="flex flex-col justify-start mt-48 bg-white h-screen overflow-auto relative" > - +
+ +

이름을 입력해주세요.

@@ -79,9 +77,7 @@ const NameStep = ({ onNext, onBack }) => { type="submit" disabled={!name.trim()} className={`w-full py-6 text-center b1 ${ - name.trim() - ? "bg-primary-8 text-white" - : "bg-gray-4 text-white" + name.trim() ? "bg-primary-8 text-white" : "bg-gray-4 text-white" }`} > 확인 diff --git a/src/pages/join/components/OwnerStep.jsx b/src/pages/join/components/OwnerStep.jsx index ddb903a..5b98dca 100644 --- a/src/pages/join/components/OwnerStep.jsx +++ b/src/pages/join/components/OwnerStep.jsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import BackIcon from "/svgs/Ic_Arrow_Left.svg"; +import BackIcon from "/svgs/common/Ic_Arrow_Left.svg"; import { IcCheck, IcUnselected } from "@assets/svgs/signup"; const OwnerStep = ({ onNext, onBack }) => { diff --git a/src/pages/join/components/ProfileImageStep.jsx b/src/pages/join/components/ProfileImageStep.jsx index fb1d04d..2d2dff8 100644 --- a/src/pages/join/components/ProfileImageStep.jsx +++ b/src/pages/join/components/ProfileImageStep.jsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import BackIcon from "/svgs/Ic_Arrow_Left.svg"; +import BackIcon from "/svgs/common/Ic_Arrow_Left.svg"; import { IcCheck, ImgOrange, diff --git a/src/pages/kakaoAuth/kakaoAuth.jsx b/src/pages/kakaoAuth/kakaoAuth.jsx index 70a0d4e..4d747f5 100644 --- a/src/pages/kakaoAuth/kakaoAuth.jsx +++ b/src/pages/kakaoAuth/kakaoAuth.jsx @@ -24,6 +24,7 @@ const KakaoAuth = () => { if (isNewUser) { navigate("/signup"); } else { + useAuthStore.getState().completeSignup(); // 기존 유저라면 바로 가입 완료 navigate("/"); } } catch (err) { diff --git a/src/pages/map/MapPage.jsx b/src/pages/map/MapPage.jsx index 250d943..406f644 100644 --- a/src/pages/map/MapPage.jsx +++ b/src/pages/map/MapPage.jsx @@ -160,7 +160,15 @@ const MapPage = () => { const handleMarkerClick = async (place) => { try { const preview = await getCompanyPreview(place.id); - setSelectedPlace({ ...place, ...preview }); + + let liked = false; + const isAuthenticated = await useAuthStore.getState().checkAuth(); + if (isAuthenticated) { + const likedList = await getLikedCompanies(); + liked = likedList.some((c) => c.companyId === place.id); + } + + setSelectedPlace({ ...place, ...preview, liked }); } catch (err) { console.error("프리뷰 불러오기 실패:", err); } @@ -190,8 +198,8 @@ const MapPage = () => { 찜 필터 { aria-label="닫기" > 닫기 diff --git a/src/pages/map/components/PlaceBottomSheet.jsx b/src/pages/map/components/PlaceBottomSheet.jsx index aa7e5da..0b5bb95 100644 --- a/src/pages/map/components/PlaceBottomSheet.jsx +++ b/src/pages/map/components/PlaceBottomSheet.jsx @@ -155,14 +155,17 @@ const PlaceBottomSheet = ({ className="absolute top-3 right-3 p-2 z-10" aria-label="닫기" > - 닫기 버튼 + 닫기 버튼 )} diff --git a/src/pages/map/components/PlaceContent.jsx b/src/pages/map/components/PlaceContent.jsx index 74807c5..e58e80a 100644 --- a/src/pages/map/components/PlaceContent.jsx +++ b/src/pages/map/components/PlaceContent.jsx @@ -127,11 +127,9 @@ const PlaceContent = ({ place, onToggleLike, showMapLink = true }) => {

- {temperature}도 - - - 방문자 리뷰 {reviewCount} + {temperature.toFixed(0)}도 + 방문자 리뷰 {reviewCount}

@@ -176,7 +174,11 @@ const PlaceContent = ({ place, onToggleLike, showMapLink = true }) => { className="w-14 h-14 flex items-center justify-center rounded-md bg-gray-2" > 좋아요 버튼 diff --git a/src/pages/map/hooks/useToggleLike.js b/src/pages/map/hooks/useToggleLike.js index 79afefa..8782344 100644 --- a/src/pages/map/hooks/useToggleLike.js +++ b/src/pages/map/hooks/useToggleLike.js @@ -28,33 +28,21 @@ export const useToggleLike = ({ return; } - const currentPlace = placesWithDistance.find((p) => p.id === targetId); + const currentPlace = + placesWithDistance.find((p) => p.id === targetId) || selectedPlace; + if (!currentPlace || isProcessing) return; setIsProcessing(true); setLoading(true); try { - // 서버 liked 상태 확인 (불일치 방지용) + // 서버 liked 상태 확인 const likedList = await getLikedCompanies(); const isActuallyLiked = likedList.some( (c) => String(c.companyId) === String(targetId), ); - // 로컬 상태와 서버 상태 불일치 시 보정 - if (currentPlace.liked !== isActuallyLiked) { - const corrected = placesWithDistance.map((p) => - p.id === targetId ? { ...p, liked: isActuallyLiked } : p, - ); - setPlacesWithDistance(corrected); - if (selectedPlace?.id === targetId) { - setSelectedPlace({ - ...selectedPlace, - liked: isActuallyLiked, - }); - } - } - // 서버 상태 기준으로 실제 토글 실행 if (isActuallyLiked) { await unlikeCompany(targetId); @@ -69,12 +57,13 @@ export const useToggleLike = ({ setPlacesWithDistance(updated); if (selectedPlace?.id === targetId) { - setSelectedPlace({ + const newSelected = { ...selectedPlace, liked: !isActuallyLiked, distance: currentPlace.distance, formattedDistance: currentPlace.formattedDistance, - }); + }; + requestAnimationFrame(() => setSelectedPlace(newSelected)); } if (setFilteredPlaces) { diff --git a/src/pages/search/SearchPage.jsx b/src/pages/search/SearchPage.jsx index 993b4d5..5ac22f2 100644 --- a/src/pages/search/SearchPage.jsx +++ b/src/pages/search/SearchPage.jsx @@ -8,10 +8,11 @@ import { formatDistance } from "../map/utils/formatDistance"; import { getCompanyPreview } from "@apis/company/getCompanyPreview"; import { useCompanyData } from "./hooks/useCompanyData"; import { useUserCoords } from "./hooks/useUserCoords"; -import useAuthStore from "@/store/authStore"; import HaveToLoginModal from "@components/common/HaveToLoginModal"; import MapViewer from "./components/MapViewer"; import { useToggleLike } from "../map/hooks/useToggleLike"; +import useAuthStore from "@/store/authStore"; +import { getLikedCompanies } from "@/apis/company/getLikedCompanies"; const LOCAL_STORAGE_KEY = "recentSearches"; @@ -21,7 +22,6 @@ const SearchPage = () => { const [isSearched, setIsSearched] = useState(false); const [selectedPlace, setSelectedPlace] = useState(null); const [moveToCurrentLocation, setMoveToCurrentLocation] = useState(false); - const [isBottomSheetExpanded, setIsBottomSheetExpanded] = useState(false); const [isBottomSheetVisible, setIsBottomSheetVisible] = useState(false); const [step, setStep] = useState(1); @@ -29,24 +29,22 @@ const SearchPage = () => { const [bottomSheetHeight, setBottomSheetHeight] = useState(220); const [isDesktop, setIsDesktop] = useState(false); + const { companies: allPlaces } = useCompanyData(); + const userCoords = useUserCoords(); + useEffect(() => { - const updateSize = () => { - setIsDesktop(window.innerWidth >= 1024); - }; + const updateSize = () => setIsDesktop(window.innerWidth >= 1024); updateSize(); window.addEventListener("resize", updateSize); return () => window.removeEventListener("resize", updateSize); }, []); - const { companies: allPlaces, loading: isCompanyLoading } = useCompanyData(); - const userCoords = useUserCoords(); - const isLoggedIn = useAuthStore((state) => state.isLoggedIn); - useEffect(() => { const stored = localStorage.getItem(LOCAL_STORAGE_KEY); if (stored) { - setRecentSearches(JSON.parse(stored)); - setStep(JSON.parse(stored).length > 0 ? 2 : 1); + const parsed = JSON.parse(stored); + setRecentSearches(parsed); + setStep(parsed.length > 0 ? 2 : 1); } }, []); @@ -63,7 +61,6 @@ const SearchPage = () => { const filteredPlaces = useMemo(() => { if (!isSearched || !keyword.trim()) return []; - const searchText = keyword.toLowerCase(); return allPlaces @@ -91,10 +88,7 @@ const SearchPage = () => { }; }) .filter(Boolean) - .sort((a, b) => { - if (a.distance == null || b.distance == null) return 0; - return a.distance - b.distance; - }); + .sort((a, b) => (a.distance ?? 0) - (b.distance ?? 0)); }, [allPlaces, keyword, isSearched, userCoords]); useEffect(() => { @@ -118,7 +112,6 @@ const SearchPage = () => { setKeyword(text); setIsSearched(true); setStep(4); - setSelectedPlace(null); setIsBottomSheetVisible(false); setIsBottomSheetExpanded(false); @@ -130,15 +123,24 @@ const SearchPage = () => { const handleSelectPlace = async (place) => { try { const preview = await getCompanyPreview(place.id); + + // 찜 여부 재확인 + let liked = false; + const isAuthenticated = await useAuthStore.getState().checkAuth(); + if (isAuthenticated) { + const likedList = await getLikedCompanies(); + liked = likedList.some((c) => c.companyId === place.id); + } + const enriched = { ...place, ...preview, - liked: preview.isSaved ?? false, + liked, }; setSelectedPlace(enriched); setIsBottomSheetVisible(true); setIsBottomSheetExpanded(false); - setStep?.(5); // SearchPage인 경우 + setStep?.(5); } catch (err) { console.error("기업 상세 정보 불러오기 실패:", err); } @@ -223,6 +225,7 @@ const SearchPage = () => { showEmptyMessage={true} /> )} + {step === 5 && (
{ }} > 삭제 diff --git a/src/pages/search/components/SearchBar.jsx b/src/pages/search/components/SearchBar.jsx index 5a98a5a..d2bf170 100644 --- a/src/pages/search/components/SearchBar.jsx +++ b/src/pages/search/components/SearchBar.jsx @@ -6,7 +6,7 @@ const SearchBar = ({ keyword, setKeyword, onSearch, onFocus }) => { return (
diff --git a/src/pages/search/hooks/useMapViewer.js b/src/pages/search/hooks/useMapViewer.js index 773c8bc..2f80405 100644 --- a/src/pages/search/hooks/useMapViewer.js +++ b/src/pages/search/hooks/useMapViewer.js @@ -40,6 +40,7 @@ const useMapViewer = ({ } onMarkerClick?.(place); + console.log("marker"); }, [onMarkerClick, showOnlyLiked], ); @@ -79,20 +80,8 @@ const useMapViewer = ({ window.naver.maps.Event.addListener(marker, "click", () => { handleMarkerClick(place); - console.log("marker"); }); }); - - if (markerPosition) { - new window.naver.maps.Marker({ - position: new window.naver.maps.LatLng( - markerPosition.lat, - markerPosition.lng, - ), - map: mapInstance.current, - icon: createMarkerIcon(true), - }); - } }); }, [ userCoords, diff --git a/src/pages/support/components/ConsumerTab.jsx b/src/pages/support/components/ConsumerTab.jsx index fd57efa..33cdff0 100644 --- a/src/pages/support/components/ConsumerTab.jsx +++ b/src/pages/support/components/ConsumerTab.jsx @@ -68,7 +68,11 @@ const ConsumerTab = () => { onClick={() => navigate("/consumer/list")} >

전체 보기

- 전체 보기 + 전체 보기
{topCategory && ( diff --git a/src/store/authStore.js b/src/store/authStore.js index 346066c..53780e4 100644 --- a/src/store/authStore.js +++ b/src/store/authStore.js @@ -3,8 +3,10 @@ import { getMyProfile } from "@apis/member/auth"; const useAuthStore = create((set) => ({ isLoggedIn: false, + isSignedUp: false, login: () => set({ isLoggedIn: true }), logout: () => set({ isLoggedIn: false }), + completeSignup: () => set({ isSignedUp: true }), checkAuth: async () => { try { const profile = await getMyProfile();