diff --git a/src/assets/nullImg.png b/src/assets/nullImg.png new file mode 100644 index 00000000..0fc7368b Binary files /dev/null and b/src/assets/nullImg.png differ diff --git a/src/components/CandidatesMap/CandidatesMapBody/CandidatesMapBody.tsx b/src/components/CandidatesMap/CandidatesMapBody/CandidatesMapBody.tsx index dc788f80..ac0ca40c 100644 --- a/src/components/CandidatesMap/CandidatesMapBody/CandidatesMapBody.tsx +++ b/src/components/CandidatesMap/CandidatesMapBody/CandidatesMapBody.tsx @@ -8,16 +8,16 @@ import CandidatesSlide from '../CandidatesSlide/CandidatesSlide'; import MapPinActive from '../MapPins/MapPinActive'; import MapPinCommon from '../MapPins/MapPinCommon'; -import {CandidatesInfo, LatLng} from '@/types/vote'; +import {CandidatesMapBodyProps, LatLng} from '@/types/vote'; -const CandidatesMapBody = ({candidates}: {candidates: CandidatesInfo[]}) => { - const [centerMarker, setCenterMarker] = useState(candidates[0].placeInfo.latLng); +const CandidatesMapBody = ({candidates}: CandidatesMapBodyProps) => { + const [centerMarker, setCenterMarker] = useState(candidates[0].placeInfo.latLng); const [selectedPinIndex, setSelectedPinIndex] = useState(0); const swiperRef = useRef(null); useEffect(() => { setCenterMarker(candidates[0].placeInfo.latLng); - }, []); + }, [candidates]); const handleMapMarkerClick = (latLng: LatLng, i: number) => { setCenterMarker(latLng); @@ -37,7 +37,11 @@ const CandidatesMapBody = ({candidates}: {candidates: CandidatesInfo[]}) => { className={`pin ${selectedPinIndex === i ? 'active' : ''}`} onClick={() => handleMapMarkerClick(candidate.placeInfo.latLng, i)} > - {selectedPinIndex === i ? : } + {selectedPinIndex === i ? ( + + ) : ( + + )} ))} diff --git a/src/components/CandidatesMap/CandidatesSlide/CandidatesSlide.tsx b/src/components/CandidatesMap/CandidatesSlide/CandidatesSlide.tsx index f9c44f0c..5adaf649 100644 --- a/src/components/CandidatesMap/CandidatesSlide/CandidatesSlide.tsx +++ b/src/components/CandidatesMap/CandidatesSlide/CandidatesSlide.tsx @@ -1,5 +1,3 @@ -import {useLocation} from 'react-router-dom'; -import {useRecoilValue} from 'recoil'; import {Swiper, SwiperClass, SwiperSlide} from 'swiper/react'; import 'swiper/scss'; import 'swiper/scss/navigation'; @@ -8,14 +6,12 @@ import styles from './CandidatesSlide.module.scss'; import CandidateCard from '@/components/Vote/VoteContent/CandidateCard/CandidateCard'; -import {isShowResultsState} from '@/recoil/vote/showResults'; - import {CandidatesSlideProps} from '@/types/vote'; const CandidatesSlide = ({candidates, setSelectedPinIndex, setCenterMarker, swiperRef}: CandidatesSlideProps) => { - const location = useLocation(); - const voteId = Number(location.pathname.split('/')[4]); - const showResults = useRecoilValue(isShowResultsState(voteId)); + // const location = useLocation(); + // const voteId = Number(location.pathname.split('/')[4]); + // const showResults = useRecoilValue(isShowResultsState(voteId)); const handleSlideChange = (swiper: SwiperClass) => { const activeCandidate = candidates[swiper.activeIndex]; @@ -23,8 +19,6 @@ const CandidatesSlide = ({candidates, setSelectedPinIndex, setCenterMarker, swip setSelectedPinIndex(swiper.activeIndex); }; - console.log('showResults', showResults); - return (
{candidates.map((candidate, i) => ( - + ))} diff --git a/src/components/CandidatesMap/MapPins/MapPinActive.tsx b/src/components/CandidatesMap/MapPins/MapPinActive.tsx index 35519c73..9181d50f 100644 --- a/src/components/CandidatesMap/MapPins/MapPinActive.tsx +++ b/src/components/CandidatesMap/MapPins/MapPinActive.tsx @@ -2,11 +2,11 @@ import styles from './MapPinActive.module.scss'; import ActiveIcon from '@/assets/voteIcons/map_pin_active.svg?react'; -const MapPinActive = ({number}: {number: number}) => { +const MapPinActive = ({number}: {number: number | undefined}) => { return (
-

{number}

+ {number &&

{number}

}
); }; diff --git a/src/components/CandidatesMap/MapPins/MapPinCommon.tsx b/src/components/CandidatesMap/MapPins/MapPinCommon.tsx index be2f5b38..d259feb9 100644 --- a/src/components/CandidatesMap/MapPins/MapPinCommon.tsx +++ b/src/components/CandidatesMap/MapPins/MapPinCommon.tsx @@ -1,11 +1,7 @@ import styles from './MapPinCommon.module.scss'; -const MapPinCommon = ({number}: {number: number}) => { - return ( -
-

{number}

-
- ); +const MapPinCommon = ({number}: {number: number | undefined}) => { + return
{number &&

{number}

}
; }; export default MapPinCommon; diff --git a/src/components/Vote/VoteBottomSlideContent/AddToJourney/AddToJourney.tsx b/src/components/Vote/VoteBottomSlideContent/AddToJourney/AddToJourney.tsx index 56163bf5..1819200a 100644 --- a/src/components/Vote/VoteBottomSlideContent/AddToJourney/AddToJourney.tsx +++ b/src/components/Vote/VoteBottomSlideContent/AddToJourney/AddToJourney.tsx @@ -16,7 +16,7 @@ const AddToJourney = ({placeId}: {placeId: number}) => { const navigate = useNavigate(); const location = useLocation(); const spaceId = Number(location.pathname.split('/')[2]); - const journeyAtom = useRecoilValue(journeyState); + const journeyAtom = useRecoilValue(journeyState(spaceId)); const setIsBTOpen = useSetRecoilState(isBottomSlideOpenState); const days = journeyAtom.journeys.length; const [selectedDays, setSelectedDays] = useState(Array(days).fill(false)); diff --git a/src/components/Vote/VoteContent/CandidateCard/CandidateCard.tsx b/src/components/Vote/VoteContent/CandidateCard/CandidateCard.tsx index 317d64ff..bc09c7c2 100644 --- a/src/components/Vote/VoteContent/CandidateCard/CandidateCard.tsx +++ b/src/components/Vote/VoteContent/CandidateCard/CandidateCard.tsx @@ -1,6 +1,6 @@ import {useEffect, useState} from 'react'; import {FaRegStar, FaStar} from 'react-icons/fa'; -import {useLocation, useNavigate, useParams} from 'react-router-dom'; +import {useLocation, useNavigate} from 'react-router-dom'; import {useRecoilValue} from 'recoil'; import styles from './CandidateCard.module.scss'; @@ -9,13 +9,14 @@ import {usePostVoting} from '@/hooks/Votes/vote'; import CustomToast from '@/components/CustomToast/CustomToast'; -import nullImg from '@/assets/homeIcons/search/nullImg.svg'; +import nullImg from '@/assets/nullImg.png'; import FirstIcon from '@/assets/voteIcons/rank_1.svg?react'; import SecondIcon from '@/assets/voteIcons/rank_2.svg?react'; import ThirdIcon from '@/assets/voteIcons/rank_3.svg?react'; import AddDayIcon from '@/assets/voteIcons/vote_addDay.svg?react'; import {journeyState} from '@/recoil/vote/addToJourney'; import {isCandidateSelectingState} from '@/recoil/vote/alertModal'; +import {isShowResultsState} from '@/recoil/vote/showResults'; import {translateAreaCode, translateCategoryName} from '@/utils/translateSearchData'; import AddToJourney from '../../VoteBottomSlideContent/AddToJourney/AddToJourney'; @@ -23,15 +24,15 @@ import VotedUserList from '../../VoteBottomSlideContent/VotedUserList/VotedUserL import {CandidateCardProps, ResultCandidatesInfo} from '@/types/vote'; -const CandidateCard = ({onBottomSlideOpen, candidate, isMapStyle, index, showResults}: CandidateCardProps) => { +const CandidateCard = ({onBottomSlideOpen, candidate, isMapStyle, index}: CandidateCardProps) => { const navigate = useNavigate(); const location = useLocation(); const spaceId = Number(location.pathname.split('/')[2]); - + const voteId = Number(location.pathname.split('/')[4]); const [starIcon, setStarIcon] = useState(); const isCandidateSelecting = useRecoilValue(isCandidateSelectingState); - const journeyAtom = useRecoilValue(journeyState); - const {id: voteId} = useParams(); + const showResults = useRecoilValue(isShowResultsState(voteId)); + const journeyAtom = useRecoilValue(journeyState(spaceId)); const {mutateAsync: votingMutateAsync} = usePostVoting(); const showToast = CustomToast(); const placeInfo = candidate.placeInfo; @@ -109,7 +110,9 @@ const CandidateCard = ({onBottomSlideOpen, candidate, isMapStyle, index, showRes
) : ( - )}
- +

{title}

{category}·{location} diff --git a/src/components/Vote/VoteContent/VoteRecommendList/VoteRecommendList.tsx b/src/components/Vote/VoteContent/VoteRecommendList/VoteRecommendList.tsx index 81d0b9fd..3fbbe330 100644 --- a/src/components/Vote/VoteContent/VoteRecommendList/VoteRecommendList.tsx +++ b/src/components/Vote/VoteContent/VoteRecommendList/VoteRecommendList.tsx @@ -14,21 +14,13 @@ import {translateCategoryName} from '@/utils/translateSearchData'; import VoteRecommendItem from './VoteRecommendItem/VoteRecommendItem'; import {SearchItemType} from '@/types/home'; +import {VoteRecommendListProps} from '@/types/vote'; -// 후보지&여행지 X -> 상품 추천 없음 -interface PropsType { - state: string; - isCandidateSelecting: boolean; - categoryCode: string; -} - -const VoteRecommendList = ({state, isCandidateSelecting, categoryCode}: PropsType) => { +const VoteRecommendList = ({state, isCandidateSelecting, onBottomSlideOpen, categoryCode}: VoteRecommendListProps) => { const [data, setData] = useState(); const [slideLocation, setSlideLocation] = useState(0); const [componentRef, size] = useComponentSize(); const category = translateCategoryName(categoryCode); - // 저 keyword자리에 A5480380 이런 것을 넣고 categorycode를 keywordSearch의 '카페'자리에 넣어주시고 title에 이런 ${category}는 어때요? 해주시면 완성되는 로직... - // const categoryCode = translateCategoryName(keyword); async function getData() { const fetchData = await keywordSearch(category, '전국', '인기순', 0, 5); @@ -62,23 +54,12 @@ const VoteRecommendList = ({state, isCandidateSelecting, categoryCode}: PropsTyp left: slideLocation + 'px', }} > - {data && data.map((data) => )} + {data && + data.map((data) => ( + + ))}

- {/* - - - - - - - - - - - - - */}
); }; diff --git a/src/components/Vote/VoteHeader/VoteHeader.tsx b/src/components/Vote/VoteHeader/VoteHeader.tsx index 74b9f5af..ecde76b2 100644 --- a/src/components/Vote/VoteHeader/VoteHeader.tsx +++ b/src/components/Vote/VoteHeader/VoteHeader.tsx @@ -45,10 +45,18 @@ const VoteHeader = ({onBottomSlideOpen, title, isZeroCandidates}: VoteHeaderProp } }; + const handleBackClick = () => { + if (path === 'map') { + navigate(-1); + } else { + navigate(`/trip/${spaceId}`); + } + }; + return (
-

{title}

diff --git a/src/pages/CandidatesMap/CandidatesMap.tsx b/src/pages/CandidatesMap/CandidatesMap.tsx index 0f907dc7..f101ae24 100644 --- a/src/pages/CandidatesMap/CandidatesMap.tsx +++ b/src/pages/CandidatesMap/CandidatesMap.tsx @@ -1,20 +1,35 @@ +import {useEffect, useState} from 'react'; import {useLocation} from 'react-router-dom'; +import {useRecoilValue} from 'recoil'; import styles from './CandidatesMap.module.scss'; -import {useGetVotesInfo} from '@/hooks/Votes/vote'; +import {useGetVotesInfo, useGetVotesResults} from '@/hooks/Votes/vote'; import CandidatesMapBody from '@/components/CandidatesMap/CandidatesMapBody/CandidatesMapBody'; import VoteHeader from '@/components/Vote/VoteHeader/VoteHeader'; +import {isShowResultsState} from '@/recoil/vote/showResults'; + import {VoteInfo} from '@/types/vote'; const CandidatesMap = () => { const location = useLocation(); const voteId = Number(location.pathname.split('/')[4]); - const {data: voteInfoData} = useGetVotesInfo(voteId); const voteInfo = voteInfoData?.data as VoteInfo; + const showResults = useRecoilValue(isShowResultsState(voteId)); + const resultsInfoData = useGetVotesResults(showResults, Number(voteId)); + const resultsInfo = resultsInfoData.data?.data; + const [candidates, setCandidates] = useState(voteInfo.candidates); + + useEffect(() => { + if (resultsInfo && showResults) { + setCandidates(resultsInfo!.candidatesResponses); + } else { + setCandidates(voteInfo.candidates); + } + }, []); if (!voteInfo) { return; @@ -23,7 +38,7 @@ const CandidatesMap = () => { return (
- +
); }; diff --git a/src/pages/Trip/Trip.tsx b/src/pages/Trip/Trip.tsx index f4120d74..e00b181c 100644 --- a/src/pages/Trip/Trip.tsx +++ b/src/pages/Trip/Trip.tsx @@ -52,7 +52,7 @@ function Trip() { const [center, setCenter] = useState(getMapCenter(journeysData?.data)); const navigate = useNavigate(); const users = spaceData?.data?.members; - const SetJourneyAtom = useSetRecoilState(journeyState); + const SetJourneyAtom = useSetRecoilState(journeyState(Number(id))); if (journeysData) { SetJourneyAtom(journeysData.data); diff --git a/src/pages/Vote/Vote.tsx b/src/pages/Vote/Vote.tsx index 667de658..cd41acf1 100644 --- a/src/pages/Vote/Vote.tsx +++ b/src/pages/Vote/Vote.tsx @@ -44,7 +44,9 @@ const Vote = () => { useEffect(() => { const isShowResults = showResultIds.some((id) => id === voteId); - setShowResults(isShowResults); + if (isShowResults) { + setShowResults(isShowResults); + } setIsBTOpen(false); }, []); diff --git a/src/recoil/vote/addToJourney.ts b/src/recoil/vote/addToJourney.ts index 0bda5f23..8771c106 100644 --- a/src/recoil/vote/addToJourney.ts +++ b/src/recoil/vote/addToJourney.ts @@ -2,9 +2,10 @@ import {atom} from 'recoil'; import {Journeys} from '@/types/route'; -export const journeyState = atom({ - key: 'journeyState', - default: { - journeys: [], - }, -}); +export const journeyState = (spaceId: number) => + atom({ + key: `journeyState_${spaceId}`, + default: { + journeys: [], + }, + }); diff --git a/src/types/vote.ts b/src/types/vote.ts index 09ccb8be..53925675 100644 --- a/src/types/vote.ts +++ b/src/types/vote.ts @@ -17,6 +17,7 @@ export interface LatLng { export interface PlaceInfo { placeId: number; placeName: string; + contentTypeId: number; category: string; areaCode: string; placeImageUrl: string; @@ -98,7 +99,6 @@ export interface VoteContentProps { onBottomSlideOpen: (content: ReactNode) => void; data: VoteInfo; showResults?: boolean; - // isZeroCandidates: boolean; } export interface VoteHeaderProps { @@ -110,7 +110,6 @@ export interface VoteHeaderProps { export interface CandidateCardProps { onBottomSlideOpen?: (content: ReactNode) => void | undefined; candidate: CandidatesInfo; - showResults?: boolean; isMapStyle?: boolean; index?: number; } @@ -134,7 +133,6 @@ export interface AlertModalProps { export interface CandidateListProps { candidates: CandidatesInfo[]; onBottomSlideOpen: (content: ReactNode) => void; - showResults: boolean; isCandidateSelecting: boolean; } @@ -188,23 +186,20 @@ export interface PostNewCandidateProps { tagline: string; }[]; } -///// - -// export interface SearchItemType { -// id: number; -// contentTypeId: number; -// title: string; -// thumbnail: string; -// location: SearchItemLocationType; -// category: string; -// } -// export interface SearchItemLocationType { -// address: string; -// addressDetail: string; -// phone: string; -// areaCode: number; -// sigunguCode: number; -// zipCode: number; -// latitude: number; -// longitude: number; -// } + +export interface CandidatesMapBodyProps { + candidates: CandidatesInfo[] | ResultCandidatesInfo[]; +} + +export interface VoteRecommendListProps { + state: string; + isCandidateSelecting: boolean; + categoryCode: string; + onBottomSlideOpen: (content: ReactNode) => void; +} + +export interface VoteRecommendItemProps { + state: string; + data: SearchItemType; + onBottomSlideOpen: (content: ReactNode) => void; +}