roomescape-refactored/frontend/src/pages/v2/ReservationFormPage.tsx

122 lines
4.9 KiB
TypeScript

import { isLoginRequiredError } from '@_api/apiClient';
import { createPendingReservation } from '@_api/reservation/reservationAPIV2';
import '@_css/reservation-v2-1.css';
import React, { useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { formatDate, formatTime } from 'src/util/DateTimeFormatter';
const ReservationFormPage: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
const { scheduleId, theme, date, time } = location.state || {};
const [reserverName, setReserverName] = useState('');
const [reserverContact, setReserverContact] = useState('');
const [participantCount, setParticipantCount] = useState(2);
const [requirement, setRequirement] = useState('');
const handleError = (err: any) => {
if (isLoginRequiredError(err)) {
alert('로그인이 필요해요.');
navigate('/login', { state: { from: location } });
} else {
const message = err.response?.data?.message || '알 수 없는 오류가 발생했습니다.';
alert(message);
console.error(err);
}
};
const handleCountChange = (delta: number) => {
setParticipantCount(prev => Math.max(theme.minParticipants, Math.min(theme.maxParticipants, prev + delta)));
};
const handlePayment = () => {
if (!reserverName || !reserverContact) {
alert('예약자명과 연락처를 입력해주세요.');
return;
}
const reservationData = {
scheduleId,
reserverName,
reserverContact,
participantCount,
requirement,
};
createPendingReservation(reservationData)
.then(res => {
navigate('/v2-1/reservation/payment', {
state: {
reservationId: res.id,
themeName: theme.name,
date: date,
startAt: time,
price: theme.price * participantCount,
}
});
})
.catch(handleError);
};
if (!scheduleId || !theme) {
// Handle case where state is not passed correctly
return (
<div className="reservation-v21-container">
<h2 className="page-title"> </h2>
<p> . .</p>
<button onClick={() => navigate('/v2-1/reservation')} className="next-step-button"> </button>
</div>
);
}
return (
<div className="reservation-v21-container">
<h2 className="page-title"> </h2>
<div className="step-section">
<h3> </h3>
<p><strong>:</strong> {theme.name}</p>
<p><strong>:</strong> {formatDate(date)}</p>
<p><strong>:</strong> {formatTime(time)}</p>
</div>
<div className="step-section">
<h3> </h3>
<div className="form-group">
<label htmlFor="reserverName"></label>
<input type="text" id="reserverName" value={reserverName} onChange={e => setReserverName(e.target.value)} />
</div>
<div className="form-group">
<label htmlFor="reserverContact"></label>
<input type="tel" id="reserverContact" value={reserverContact} onChange={e => setReserverContact(e.target.value)} placeholder="'-' 없이 입력"/>
</div>
<div className="form-group">
<label></label>
<div className="participant-control">
<input
type="number"
value={participantCount}
onChange={e => setParticipantCount(Math.max(theme.minParticipants, Math.min(theme.maxParticipants, Number(e.target.value))))}
min={theme.minParticipants}
max={theme.maxParticipants}
/>
</div>
</div>
<div className="form-group">
<label htmlFor="requirement"></label>
<textarea id="requirement" value={requirement} onChange={e => setRequirement(e.target.value)} />
</div>
</div>
<div className="next-step-button-container">
<button onClick={handlePayment} className="next-step-button">
</button>
</div>
</div>
);
};
export default ReservationFormPage;