Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type { TabletReservationSheetProps } from './types';

type MobileStep = 'dateTime' | 'headCount';

type MobileReservationSheetProps = TabletReservationSheetProps;

export default function MobileReservationSheet({
schedules,
price,
Expand All @@ -18,7 +20,7 @@ export default function MobileReservationSheet({
onConfirm,
isAuthor = false,
isLoggedIn = true,
}: TabletReservationSheetProps) {
}: MobileReservationSheetProps) {
const [currentStep, setCurrentStep] = useState<MobileStep>('dateTime');

const {
Expand Down Expand Up @@ -52,16 +54,17 @@ export default function MobileReservationSheet({

const handleConfirm = () => {
if (selectedScheduleId && selectedDate) {
const selectedSchedule = schedules.find((s) => s.id === selectedScheduleId);
if (selectedSchedule) {
const selectedTime = availableTimes.find((t) => t.id === selectedScheduleId);
if (selectedTime) {
onConfirm({
date: selectedSchedule.date,
startTime: selectedSchedule.startTime,
endTime: selectedSchedule.endTime,
date: selectedDate,
startTime: selectedTime.startTime,
endTime: selectedTime.endTime,
headCount,
scheduleId: selectedScheduleId,
});
setCurrentStep('dateTime'); // 완료 후 초기 단계로 리셋
setCurrentStep('dateTime'); // 첫 번째 단계로 리셋
onClose(); // 시트 닫기
}
}
};
Expand All @@ -70,7 +73,8 @@ export default function MobileReservationSheet({
let buttonText = '';
if (!isLoggedIn) buttonText = '로그인 필요';
else if (isAuthor) buttonText = '예약 불가';
else buttonText = '확인';
else if (currentStep === 'dateTime') buttonText = '다음';
else buttonText = '다음';

return (
<BottomSheet.Root isOpen={isOpen} onClose={handleClose}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Button } from '@what-today/design-system';
import { useQueryClient } from '@tanstack/react-query';
import { Button, useToast } from '@what-today/design-system';

import CalendarSelector from './CalendarSelector';
import HeadCountSelector from './HeadCountSelector';
Expand All @@ -7,17 +8,40 @@ import TimeSelector from './TimeSelector';
import type { ReservationFormProps } from './types';

export default function ReservationForm({
activityId,
schedules,
price,
onReservationChange,
onSubmit,
showSubmitButton = false,
showSubmitButton = true,
isSubmitting: externalIsSubmitting,
isAuthor = false,
isLoggedIn = true,
}: ReservationFormProps) {
const { toast } = useToast();
const queryClient = useQueryClient();

const reservation = useReservation(schedules, price, {
onReservationChange,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['reservations'],
});

toast({
title: '예약 완료',
description: '마이페이지에서 예약을 확인해보세요!',
type: 'success',
});
},
onError: (error) => {
const errorMessage = error instanceof Error ? error.message : '예약 중 오류가 발생했습니다.';
toast({
title: '예약 실패',
description: errorMessage,
type: 'error',
});
},
});

const {
Expand All @@ -33,18 +57,25 @@ export default function ReservationForm({
totalPrice,
isReadyToReserve,
isSubmitting: internalIsSubmitting,
submitReservation,
} = reservation;

// 외부에서 전달받은 isSubmitting을 우선시
const isSubmitting = externalIsSubmitting ?? internalIsSubmitting;

const handleSubmit = async () => {
if (!onSubmit || !selectedScheduleId) return;
if (!selectedScheduleId) return;

await onSubmit({
scheduleId: selectedScheduleId,
headCount,
});
// onSubmit이 있으면 기존 방식 사용 (하위 호환성)
if (onSubmit) {
await onSubmit({
scheduleId: selectedScheduleId,
headCount,
});
} else {
// 기본 방식: submitReservation 사용 (자동 초기화)
await submitReservation(activityId);
}
};

// 버튼 텍스트 결정
Expand All @@ -54,7 +85,7 @@ export default function ReservationForm({
else if (isAuthor) buttonText = '예약 불가';
else buttonText = '예약하기';

return (
const content = (
<div className='flex flex-col gap-24'>
{/* 가격 표시 */}
<p className='text-xl text-[#79747E]'>
Expand Down Expand Up @@ -98,4 +129,10 @@ export default function ReservationForm({
</div>
</div>
);

return (
<section className='flex flex-col justify-between rounded-3xl border border-[#DDDDDD] p-30 shadow-sm'>
{content}
</section>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function TabletReservationSheet({
let buttonText = '';
if (!isLoggedIn) buttonText = '로그인 필요';
else if (isAuthor) buttonText = '예약 불가';
else buttonText = '확인';
else buttonText = '다음';

return (
<BottomSheet.Root isOpen={isOpen} onClose={onClose}>
Expand Down Expand Up @@ -80,15 +80,16 @@ export default function TabletReservationSheet({
variant='fill'
onClick={() => {
if (selectedScheduleId && selectedDate) {
const selectedSchedule = schedules.find((s) => s.id === selectedScheduleId);
if (selectedSchedule) {
const selectedTime = availableTimes.find((t) => t.id === selectedScheduleId);
if (selectedTime) {
onConfirm({
date: selectedSchedule.date,
startTime: selectedSchedule.startTime,
endTime: selectedSchedule.endTime,
date: selectedDate,
startTime: selectedTime.startTime,
endTime: selectedTime.endTime,
headCount,
scheduleId: selectedScheduleId,
});
onClose(); // 시트 닫기
}
}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface UseReservationReturn {
}

export interface ReservationFormProps {
activityId: number;
schedules: Schedule[];
price: number;
onReservationChange?: (summary: ReservationSummary | null) => void;
Expand All @@ -60,14 +61,6 @@ export interface ReservationFormProps {
isLoggedIn?: boolean;
}

export interface DesktopReservationProps {
activityId: number;
price: number;
schedules: Schedule[];
isAuthor?: boolean;
isLoggedIn?: boolean;
}

export interface TabletReservationSheetProps {
schedules: Schedule[];
price: number;
Expand All @@ -82,7 +75,7 @@ export interface ReservationBottomBarProps {
price: number;
reservation: Pick<ReservationSummary, 'date' | 'startTime' | 'endTime' | 'headCount'> | null;
onSelectDate: () => void;
onReserve: () => void;
onReserve?: () => void;
isSubmitting?: boolean;
isAuthor?: boolean;
isLoggedIn?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion apps/what-today/src/layouts/DefaultLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function DefaultLayout() {
const footerMarginBottom = isActivityDetailPage && !isDesktop ? 'w-full mb-125' : 'w-full';

// FloatingTranslateButton의 bottom 위치 조건부 설정
const floatingButtonClass = !isDesktop && isActivityDetailPage ? 'bottom-140' : undefined;
const floatingButtonClass = !isDesktop && isActivityDetailPage ? 'bottom-160' : undefined;

return (
<div className='flex w-full flex-col items-center gap-8 overflow-x-hidden'>
Expand Down
Loading