diff --git a/src/apis/booth.js b/src/apis/booth.js index ea439f1..ccbcecd 100644 --- a/src/apis/booth.js +++ b/src/apis/booth.js @@ -11,13 +11,16 @@ export const getBoothList = async ( let params = []; // 각 필터가 값이 있을 때만 쿼리 파라미터에 추가 - if (day) params.push(`day=${day}`); - if (category) params.push(`category=${category}`); - if (location) params.push(`location=${location}`); + + if (day !== undefined) params.push(`day=${day}`); + if (category !== undefined) params.push(`category=${category}`); + if (location !== undefined) params.push(`location=${location}`); + // is_night와 is_reservable은 boolean 값으로 처리 (undefined와 null 제외) if (is_night !== null && is_night !== undefined) params.push(`is_night=${is_night}`); if (is_reservable !== null && is_reservable !== undefined) + params.push(`is_reservable=${is_reservable}`); // 쿼리 파라미터가 있을 경우 URL에 추가 diff --git a/src/boothdata/Boothdata.js b/src/boothdata/Boothdata.js index 344056b..acdbe8b 100644 --- a/src/boothdata/Boothdata.js +++ b/src/boothdata/Boothdata.js @@ -20,8 +20,8 @@ const BoothData = [ filters: { time: "낮", type: "주점", - location: "팔정도" - } + location: "팔정도", + }, }, { id: 2, @@ -39,8 +39,8 @@ const BoothData = [ filters: { time: "밤", type: "주점", - location: "만해광장" - } + location: "만해광장", + }, }, { id: 3, @@ -58,8 +58,8 @@ const BoothData = [ filters: { time: "낮", type: "기타", - location: "팔정도" - } + location: "팔정도", + }, }, { id: 4, @@ -77,9 +77,9 @@ const BoothData = [ filters: { time: "밤", type: "기타", - location: "만해광장" - } - } + location: "만해광장", + }, + }, ]; export default BoothData; diff --git a/src/pages/booth/BoothPage.jsx b/src/pages/booth/BoothPage.jsx index 48ef7bd..df44054 100644 --- a/src/pages/booth/BoothPage.jsx +++ b/src/pages/booth/BoothPage.jsx @@ -1,11 +1,12 @@ -import React, { useState, useEffect, useRef } from "react"; import * as S from "./Styled"; +import React, { useState, useEffect, useRef } from "react"; import { RxDoubleArrowDown, RxDoubleArrowUp } from "react-icons/rx"; import { TopBar } from "@components/topBar/TopBar"; import { Modal } from "@components/modal/Modal"; import { useBoothData } from "../../hook/useBooth"; + +import { BoothDetail } from "@components/common/BoothDetail/BoothDetail"; import BoothData from "../../../src/boothdata/Boothdata"; -import LinenowLogo from "../../assets/images/LinenowLogo.png"; import nonselect_GI from "../../assets/images/nonselect_GI.png"; import nonselect_JU from "../../assets/images/nonselect_JU.png"; import select_GI from "../../assets/images/select_GI.png"; @@ -16,19 +17,45 @@ export const BoothPage = () => { const [isModalOpen, setIsModalOpen] = useState(false); const openModal = () => setIsModalOpen(true); const closeModal = () => setIsModalOpen(false); + // 날짜 선택 + const getDayFromDate = (dateString) => { + const dayPart = dateString.split("(")[1]; // 요일 부분 추출 + return dayPart ? dayPart.replace(")", "") : ""; // ")" 기호 제거 후 반환 + }; + // 해당 요일의 영어 이름 반환 + const translateDayToEnglish = (day) => { + const dayMap = { + 월: "Mon", + 화: "Tue", + 수: "Wed", + 목: "Thu", + 금: "Fri", + 토: "Sat", + 일: "Sun", + }; + return dayMap[day] || ""; + }; - const { boothData } = useBoothData(); - - // 초기 날짜 선택 용 - const [selectedDate, setSelectedDate] = useState('10/7(월)'); + const [selectedDate, setSelectedDate] = useState("10/7(월)"); + const dayInKorean = getDayFromDate(selectedDate); // "월" 추출 + const dayInEnglish = translateDayToEnglish(dayInKorean); // "Mon"으로 변환 + //목록리스트 API + const { boothData } = useBoothData({ + day: dayInEnglish, + }); + console.log("boothpage:", boothData); + if (!boothData) { + // 데이터가 없을 경우 처리 + return
Loading...
; // 또는 placeholder 컴포넌트 + } // 부스 리스트를 띄울 지 말지 const [isBoothListOpen, setIsBoothListOpen] = useState(true); // 부스 필터링 용 - const [selectedTime, setSelectedTime] = useState('시간'); - const [selectedType, setSelectedType] = useState('유형'); - const [selectedLocation, setSelectedLocation] = useState('위치'); + const [selectedTime, setSelectedTime] = useState("시간"); + const [selectedType, setSelectedType] = useState("유형"); + const [selectedLocation, setSelectedLocation] = useState("위치"); const [isDropdownOpen, setIsDropdownOpen] = useState({ time: false, type: false, @@ -42,7 +69,6 @@ export const BoothPage = () => { const [highlightedBooth, setHighlightedBooth] = useState(null); const boothRefs = useRef({}); - // 마킹 용 배열 const mapRef = useRef(null); const markersRef = useRef([]); @@ -53,7 +79,6 @@ export const BoothPage = () => { const [userLocation, setUserLocation] = useState(null); // 현위치 토글링 용 const [followUser, setFollowUser] = useState(false); - const toggleDropdown = (type) => { setIsDropdownOpen((prevState) => { @@ -67,20 +92,20 @@ export const BoothPage = () => { // 선택한 필터만 열고 나머지는 닫히도록 const handleSelect = (type, value) => { - if (type === 'time') setSelectedTime(value); - if (type === 'type') setSelectedType(value); - if (type === 'location') setSelectedLocation(value); + if (type === "time") setSelectedTime(value); + if (type === "type") setSelectedType(value); + if (type === "location") setSelectedLocation(value); setIsDropdownOpen((prevState) => ({ ...prevState, - [type]: prevState[type], // 선택 후 필터를 닫는 겁니다아 + [type]: prevState[type], // 선택 후 필터를 닫는 겁니다아 })); }; const resetFilters = (e) => { - setSelectedTime('시간'); - setSelectedType('유형'); - setSelectedLocation('위치'); + setSelectedTime("시간"); + setSelectedType("유형"); + setSelectedLocation("위치"); setIsDropdownOpen({ time: false, @@ -90,12 +115,12 @@ export const BoothPage = () => { const button = e.currentTarget; - button.style.transform = 'rotate(0deg)'; - button.style.transition = 'none'; - + button.style.transform = "rotate(0deg)"; + button.style.transition = "none"; + setTimeout(() => { - button.style.transition = 'transform 1s ease'; - button.style.transform = 'rotate(-360deg)'; + button.style.transition = "transform 1s ease"; + button.style.transform = "rotate(-360deg)"; }, 10); }; @@ -103,7 +128,7 @@ export const BoothPage = () => { const handleBoothLocation = (boothId) => { const booth = BoothData.find((booth) => booth.id === boothId); setHighlightedBooth(booth); - } + }; // 날짜 선택 용 const handleDateChange = (date) => { @@ -122,9 +147,13 @@ export const BoothPage = () => { }; const filteredBooths = BoothData.filter((booth) => { - const timeMatch = selectedTime === '시간' || booth.filters.time === selectedTime; - const typeMatch = selectedType === '유형' || booth.filters.type === selectedType; - const locationMatch = selectedLocation === '위치' || booth.filters.location === selectedLocation; + const timeMatch = + selectedTime === "시간" || booth.filters.time === selectedTime; + const typeMatch = + selectedType === "유형" || booth.filters.type === selectedType; + const locationMatch = + selectedLocation === "위치" || + booth.filters.location === selectedLocation; // 모든 필터 조건을 만족하는 부스만 반환 return timeMatch && typeMatch && locationMatch; @@ -132,21 +161,25 @@ export const BoothPage = () => { // 부스 유형에 따른 초기 마커 이미지 설정 함수 const getInitialMarkerImage = (booth) => { - let markerImage = booth.filters.type === '주점' ? nonselect_JU : nonselect_GI; + let markerImage = + booth.filters.type === "주점" ? nonselect_JU : nonselect_GI; - return new window.kakao.maps.MarkerImage(markerImage, new window.kakao.maps.Size(30, 36)); + return new window.kakao.maps.MarkerImage( + markerImage, + new window.kakao.maps.Size(30, 36) + ); }; // 카카오맵 마커 생성 useEffect(() => { - const script = document.createElement('script'); + const script = document.createElement("script"); script.src = `https://dapi.kakao.com/v2/maps/sdk.js?appkey=972351b156b1bdfe825cb095c12d1e56&autoload=false`; script.async = true; document.head.appendChild(script); script.onload = () => { window.kakao.maps.load(() => { - const container = document.getElementById('map'); + const container = document.getElementById("map"); const options = { center: new window.kakao.maps.LatLng(37.5577, 127.00099), level: 3, @@ -155,7 +188,10 @@ export const BoothPage = () => { // 초기 마커 생성 filteredBooths.forEach((booth) => { - const markerPosition = new window.kakao.maps.LatLng(booth.latitude, booth.longitude); + const markerPosition = new window.kakao.maps.LatLng( + booth.latitude, + booth.longitude + ); const markerImage = getInitialMarkerImage(booth); // 유형에 따라 초기 마커 이미지 설정 const marker = new window.kakao.maps.Marker({ position: markerPosition, @@ -164,7 +200,7 @@ export const BoothPage = () => { }); // 마커 클릭 이벤트 설정 - window.kakao.maps.event.addListener(marker, 'click', () => { + window.kakao.maps.event.addListener(marker, "click", () => { handleBoothLocation(booth.id); // 부스 선택 }); @@ -179,13 +215,12 @@ export const BoothPage = () => { }; }, []); - // 선택된 부스에 따라 마커 이미지 변경 useEffect(() => { // 선택된 부스가 없으면 모든 마커를 초기화 if (!highlightedBooth) { markersRef.current.forEach(({ marker, boothId }) => { - const booth = BoothData.find(b => b.id === boothId); // 해당 부스 데이터 찾기 + const booth = BoothData.find((b) => b.id === boothId); // 해당 부스 데이터 찾기 if (booth) { // 초기 마커 이미지로 변경 const initialImage = getInitialMarkerImage(booth); @@ -197,28 +232,35 @@ export const BoothPage = () => { if (highlightedBooth && mapRef.current) { // 선택된 부스의 위치 좌표로 맵의 중심 이동 - const newCenter = new window.kakao.maps.LatLng(highlightedBooth.latitude, highlightedBooth.longitude); + const newCenter = new window.kakao.maps.LatLng( + highlightedBooth.latitude, + highlightedBooth.longitude + ); mapRef.current.panTo(newCenter); } - + // 선택된 부스가 있을 경우, 해당 마커만 업데이트 markersRef.current.forEach(({ boothId, marker }) => { const isHighlighted = highlightedBooth && highlightedBooth.id === boothId; - + // 선택된 부스의 마커를 변경 if (isHighlighted) { let markerImage; - if (highlightedBooth.filters.type === '주점') { + if (highlightedBooth.filters.type === "주점") { markerImage = select_JU; // 선택된 주점일 경우 - } else if (highlightedBooth.filters.type === '기타') { + } else if (highlightedBooth.filters.type === "기타") { markerImage = select_GI; // 선택된 기타일 경우 } else { - } - marker.setImage(new window.kakao.maps.MarkerImage(markerImage, new window.kakao.maps.Size(32, 40))); + marker.setImage( + new window.kakao.maps.MarkerImage( + markerImage, + new window.kakao.maps.Size(32, 40) + ) + ); } else { // 선택되지 않은 부스는 초기 이미지로 유지 - const booth = BoothData.find(b => b.id === boothId); // 해당 부스 데이터 찾기 + const booth = BoothData.find((b) => b.id === boothId); // 해당 부스 데이터 찾기 if (booth) { const initialImage = getInitialMarkerImage(booth); marker.setImage(initialImage); @@ -229,7 +271,10 @@ export const BoothPage = () => { useEffect(() => { if (highlightedBooth && boothRefs.current[highlightedBooth.id]) { - boothRefs.current[highlightedBooth.id].scrollIntoView({ behavior: 'smooth', block: 'start' }); + boothRefs.current[highlightedBooth.id].scrollIntoView({ + behavior: "smooth", + block: "start", + }); } }, [highlightedBooth]); @@ -243,10 +288,13 @@ export const BoothPage = () => { mapRef.current.relayout(); setTimeout(() => { - window.kakao.maps.event.trigger(mapRef.current, 'resize'); + window.kakao.maps.event.trigger(mapRef.current, "resize"); if (highlightedBooth) { - const newCenter = new window.kakao.maps.LatLng(highlightedBooth.latitude, highlightedBooth.longitude); + const newCenter = new window.kakao.maps.LatLng( + highlightedBooth.latitude, + highlightedBooth.longitude + ); mapRef.current.panTo(newCenter); } }, 200); @@ -254,29 +302,31 @@ export const BoothPage = () => { } }, [isBoothListOpen, selectBooth, highlightedBooth]); - useEffect(() => { let watchId; let userMarker = null; // 사용자 위치 마커를 저장할 변수 - + if (navigator.geolocation && followUser) { // 위치 변경 감지하여 실시간 위치 추적 watchId = navigator.geolocation.watchPosition( (position) => { const { latitude, longitude } = position.coords; - + // 사용자 위치 업데이트 setUserLocation({ latitude, longitude }); - + // 카카오맵 SDK가 로드되고 mapRef가 정의된 이후에만 실행 if (window.kakao && window.kakao.maps && mapRef.current) { // 기존 마커가 존재하면 삭제 if (userMarker) { userMarker.setMap(null); } - + // 새로운 사용자 위치 마커 생성 - const userPosition = new window.kakao.maps.LatLng(latitude, longitude); + const userPosition = new window.kakao.maps.LatLng( + latitude, + longitude + ); userMarker = new window.kakao.maps.Marker({ position: userPosition, map: mapRef.current, @@ -288,7 +338,7 @@ export const BoothPage = () => { { offset: new window.kakao.maps.Point(12, 12) } // 마커 중앙 위치 설정 ), }); - + // 지도 중심을 새로운 사용자 위치로 이동 mapRef.current.setCenter(userPosition); } @@ -303,7 +353,7 @@ export const BoothPage = () => { } ); } - + return () => { if (watchId) { navigator.geolocation.clearWatch(watchId); // 위치 추적 멈추기 @@ -313,28 +363,30 @@ export const BoothPage = () => { } }; }, [mapRef.current, followUser]); // 토글링을 넣어서 껐다켰다 가능. - - return ( <> - + {/* 카카오맵 자리 */} - + {/* 상단 날짜 선택 버튼 */} handleDateChange('10/7(월)')} + $active={selectedDate === "10/7(월)"} + onClick={() => handleDateChange("10/7(월)")} > 10/7(월) handleDateChange('10/8(화)')} + $active={selectedDate === "10/8(화)"} + onClick={() => handleDateChange("10/8(화)")} > 10/8(화) @@ -345,49 +397,104 @@ export const BoothPage = () => { - {/* 부스 리스트 */} - {isBoothListOpen ? : } + + {isBoothListOpen ? : } + {/* 필터 섹션 (부스 리스트 안에) */} - toggleDropdown('time')}> + toggleDropdown("time")} + > {selectedTime} - + + + {isDropdownOpen.time && ( - handleSelect('time', '시간')}>전체 - handleSelect('time', '낮')}>낮 - handleSelect('time', '밤')}>밤 + handleSelect("time", "시간")} + > + 전체 + + handleSelect("time", "낮")}> + 낮 + + handleSelect("time", "밤")}> + 밤 + )} - toggleDropdown('type')}> + toggleDropdown("type")} + > {selectedType} - + + + {isDropdownOpen.type && ( - handleSelect('type', '유형')}>전체 - handleSelect('type', '푸드트럭')}>푸드트럭 - handleSelect('type', '주점')}>주점 - handleSelect('type', '기타')}>기타 + handleSelect("type", "유형")} + > + 전체 + + handleSelect("type", "푸드트럭")} + > + 푸드트럭 + + handleSelect("type", "주점")} + > + 주점 + + handleSelect("type", "기타")} + > + 기타 + )} - toggleDropdown('location')}> + toggleDropdown("location")} + > {selectedLocation} - + + + {isDropdownOpen.location && ( - handleSelect('location', '위치')}>전체 - handleSelect('location', '팔정도')}>팔정도 - handleSelect('location', '만해광장')}>만해광장 + handleSelect("location", "위치")} + > + 전체 + + handleSelect("location", "팔정도")} + > + 팔정도 + + handleSelect("location", "만해광장")} + > + 만해광장 + )} @@ -399,13 +506,17 @@ export const BoothPage = () => { {/* 부스 리스트 */} - 부스 클릭 시 테이블링 예약 링크로 이동 가능합니다. + + 부스 클릭 시 테이블링 예약 링크로 이동 가능합니다. + {filteredBooths.length > 0 ? ( filteredBooths.map((booth) => ( boothRefs.current[booth.id] = el} // 각 부스에 ref 추가 - $isColored={highlightedBooth && highlightedBooth.id === booth.id} + ref={(el) => (boothRefs.current[booth.id] = el)} // 각 부스에 ref 추가 + $isColored={ + highlightedBooth && highlightedBooth.id === booth.id + } onClick={() => handleSelectBooth(booth)} > {/* 나중에 좋아요순으로 수정 */} @@ -416,27 +527,30 @@ export const BoothPage = () => { {booth.owner} - { - e.stopPropagation(); - handleBoothLocation(booth.id) - }}> + { + e.stopPropagation(); + handleBoothLocation(booth.id); + }} + > 위치 보기 )) ) : ( - - 현재 운영중인 부스가 없어요! - + 현재 운영중인 부스가 없어요! )} {/* 선택한 부스 디테일 */} {selectBooth && ( - <> - {/* setSelectBooth(null)} /> */} + setSelectBooth(null)} + /> + /* setSelectBooth(null)} /> setSelectBooth(null)}>X @@ -503,7 +617,7 @@ export const BoothPage = () => { - + */ )} {isModalOpen && }