diff --git a/ticketping/package.json b/ticketping/package.json index 4ece80a..4bab163 100644 --- a/ticketping/package.json +++ b/ticketping/package.json @@ -7,6 +7,7 @@ "axios": "^1.7.9", "axios-hooks": "^5.0.2", "cra-template": "1.2.0", + "dayjs": "^1.11.13", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^6.28.0", diff --git a/ticketping/src/component/EnterQueue.js b/ticketping/src/component/EnterQueue.js index 8504bac..4e421de 100644 --- a/ticketping/src/component/EnterQueue.js +++ b/ticketping/src/component/EnterQueue.js @@ -11,11 +11,14 @@ export const useEnterQueue = (setIsModalVisible) => { const enterQueue = async (performanceId) => { try { - await axiosInstance.get(`/api/v1/waiting-queue?performanceId=${performanceId}`, { headers }); - - // 이미 대기열에 있는 인원 - setIsModalVisible(true); + const response = await axiosInstance.get(`/api/v1/waiting-queue?performanceId=${performanceId}`, { headers }); + const tokenStatus = response.data.data.tokenStatus; + if (tokenStatus === "WAITING") { + setIsModalVisible(true); + } else if (tokenStatus === "WORKING") { + navigate(`/performance/${performanceId}/schedule`); + } } catch (error) { // 대기열에 없는 인원 diff --git a/ticketping/src/component/QueueInfoModal.js b/ticketping/src/component/QueueInfoModal.js index e89a1d8..950b283 100644 --- a/ticketping/src/component/QueueInfoModal.js +++ b/ticketping/src/component/QueueInfoModal.js @@ -17,14 +17,11 @@ const QueueInfoModal = ({ visible, onClose, performanceId }) => { const fetchQueueInfo = async () => { try { const response = await axiosInstance.get(`/api/v1/waiting-queue?performanceId=${performanceId}`, { headers }); - - console.log(response); - setTokenStatus(response.data.data.tokenStatus); setPosition(response.data.data.position); setTotalUsers(response.data.data.totalUsers); - if (response.data.data.tokenStatus === "WORKING") { + if (tokenStatus === "WORKING") { navigate(`/performance/${performanceId}/schedule`); } } catch (error) { diff --git a/ticketping/src/pages/SelectSchedule.js b/ticketping/src/pages/SelectSchedule.js index 1a7569f..835bc66 100644 --- a/ticketping/src/pages/SelectSchedule.js +++ b/ticketping/src/pages/SelectSchedule.js @@ -1,5 +1,114 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; +import { useParams, useNavigate } from "react-router-dom"; +import { axiosInstance } from "../api"; +import { useAppContext } from "../store"; +import { Calendar, Button } from 'antd'; +import dayjs from 'dayjs'; +import "../style/SelectSchedule.css"; export default function SelectSchedule() { - return

일정 선택 페이지

; + const { id } = useParams(); + const navigate = useNavigate(); + const { store: { jwtToken } } = useAppContext(); + const headers = { Authorization: jwtToken }; + + const [schedules, setSchedules] = useState([]); + const [selectedDateId, setSelectedDateId] = useState(null); + + useEffect(() => { + const fetchSchedules = async () => { + try { + const response = await axiosInstance.get(`/api/v1/performances/${id}/schedules`, { headers }); + setSchedules(response.data.data.content); + } catch (err) { + + } + }; + + fetchSchedules(); + }, [id, headers]); + + const disabledDate = (current) => { + const hasSchedule = schedules.some(schedule => schedule.startTime.startsWith(current.format('YYYY-MM-DD'))); + return !hasSchedule; + }; + + const monthCellRender = (value) => { + const month = value.month(); + const year = value.year(); + + const daysWithSchedules = schedules + .filter(schedule => { + const scheduleDate = dayjs(schedule.startTime); + return ( + scheduleDate.year() === year && + scheduleDate.month() === month + ); + }) + .map(schedule => schedule.date()); + + return ( +
+ {daysWithSchedules.length > 0 && daysWithSchedules.map((currentDay) => ( +
+ {currentDay} +
+ ))} +
+ ); + }; + + const headerRender = ({ value, onChange }) => { + return ( +
+ {dayjs(value).format('MMMM YYYY')} +
+ onChange(value.subtract(1, 'month'))}>< + onChange(value.add(1, 'month'))}>> +
+
+ ); + }; + + const handleDateSelect = () => { + if (selectedDateId) { + console.log(`공연 id: ${id}`); + console.log(`선택된 스케줄 id: ${selectedDateId}`); + + // 좌석 선점 페이지 이동 + navigate('/'); + } else { + + } + }; + + const onDateSelect = (date) => { + const schedule = schedules.find(schedule => schedule.startTime.startsWith(date.format('YYYY-MM-DD'))); + if (schedule) { + setSelectedDateId(schedule.id); + } + }; + + return ( +
+

일정 선택

+
+ +
+
+ +
+
+ ); } diff --git a/ticketping/src/style/AppLayout.css b/ticketping/src/style/AppLayout.css index c8545da..d2c0fa0 100644 --- a/ticketping/src/style/AppLayout.css +++ b/ticketping/src/style/AppLayout.css @@ -12,8 +12,9 @@ display: flex; justify-content: space-between; align-items: center; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06), 0 4px 8px rgba(0, 0, 0, 0.1); border-bottom: 1px solid white; + position: relative; } .page-title { @@ -21,6 +22,7 @@ font-family: 'Poppins', sans-serif; display: flex; align-items: center; + margin-top: 17px; } .topnav { diff --git a/ticketping/src/style/SelectSchedule.css b/ticketping/src/style/SelectSchedule.css new file mode 100644 index 0000000..640e44d --- /dev/null +++ b/ticketping/src/style/SelectSchedule.css @@ -0,0 +1,55 @@ +.container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + background-color: #f9f9f9; + border-radius: 10px; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); +} + +h1 { + text-align: center; + color: #333; + margin-top: 0px; + margin-bottom: 24px; +} + +.calendar-container { + background-color: white; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + padding: 20px; +} + +.dates { + display: flex; + flex-wrap: wrap; +} + +.day { + display: inline-block; + width: 30px; + text-align: center; + margin: 2px; + font-size: 18px; +} + +.calendar-header { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 18px; + margin-bottom: 10px; +} + +.calendar-header a { + cursor: pointer; + margin: 0 10px; +} + +.button-container { + display: flex; + justify-content: center; + margin-top: 20px; + margin-bottom: -10px +}