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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const CartList = ({ cart, storeId }: Props) => {
className="py-5 border-none"
>
메뉴 추가하기
<span className="w-4 h-4">
<span className="flex justify-center items-center w-4 h-4">
<Add />
</span>
</SmallActionButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { Button } from "@repo/ui";
import {
createReservation,
getMyReservations,
getStore,
} from "../../../api/reservation";
import PageFooterButton from "../../../components/order/PageFooterButton";
import useThrottle from "../../../hooks/useThrottle";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import BackOnlyHeader from "../../../components/BackOnlyHeader";
import { WAITING_GUIDE } from "../../../constants/guides";
import FullPageLoader from "../../../components/FullPageLoader";
import LoadingSpinner from "../../../components/LoadingSpinner";
import useModal from "../../../hooks/useModal";
import Portal from "../../../components/common/modal/Portal";
import MaxReservationModal from "./components/MaxReservationModal";
import WaitingGuide from "./components/WaitingGuide";
import WaitingStoreSummary from "./components/WaitingStoreSummary";
import { useWaitingSummary } from "./hooks/useWaitingSummary";

const WaitingSummaryPage = () => {
const navigate = useNavigate();
Expand All @@ -23,41 +19,32 @@ const WaitingSummaryPage = () => {
const partySize = Number(searchParams.get("partySize"));
const [reservationIsLoading, setReservationIsLoading] = useState(false);
const modal = useModal();
const MAX_RESERVATIONS = 3;

const {
store,
isStoreLoading,
myReservations,
canCreateReservation,
createWaiting,
MAX_RESERVATIONS,
} = useWaitingSummary(storeId);

const { data: store, isLoading } = useQuery({
queryKey: ["store", storeId],
queryFn: () => getStore(storeId!),
select: (data) => data?.response,
});

const { data: myReservations } = useQuery({
queryKey: ["myReservations"],
queryFn: getMyReservations,
select: (data) => data.response,
});

const handleSubmitReservation = useThrottle(async () => {
if (myReservations?.length >= MAX_RESERVATIONS) {
const handleSubmit = useThrottle(async () => {
if (!canCreateReservation) {
modal.open();
return;
}

try {
setReservationIsLoading(true);
const payload = {
partySize,
};
const res = await createReservation(Number(store?.storeId!), payload);
console.log(res, "예약 응답");
await createWaiting(partySize);
navigate(`/store/${storeId}/waiting/success`, { replace: true });
} catch (error) {
console.log(error);
} finally {
setReservationIsLoading(false);
}
}, 3000);

if (isLoading) return <FullPageLoader />;
if (isStoreLoading) return <FullPageLoader />;

return (
<>
Expand All @@ -71,46 +58,16 @@ const WaitingSummaryPage = () => {
<br />
대기하고 있어요
</h1>
<div className="p-5.5 rounded-2xl bg-black-10 mb-[30px]">
<div className="flex justify-between items-start mb-2.5 ">
<p className="text-16-semibold text-black-50">부스</p>
<div className="max-w-[205px] text-16-medium text-black-90 text-right break-keep">
<p className="inline">{store?.name} / </p>
<span
className={`${
store!.departmentName.length > 14 ? "block" : "inline"
} w-full truncate`}
>
{store?.departmentName}
</span>
</div>
</div>
<div className="flex justify-between items-center">
<p className="text-16-semibold text-black-50">입장 인원</p>
<p className="text-16-medium text-black-90">{partySize}명</p>
</div>
</div>
</div>
<div className="bg-black-10 px-5 py-[30px] grow">
<h1 className="text-title-14-semibold text-black-80 mb-3">
대기 등록 전 꼭 확인해주세요
</h1>
<ul>
{WAITING_GUIDE.map((guide, i) => {
return (
<li
key={i}
className="text-[14px] text-regular text-black-60 mb-3 whitespace-pre-line break-keep list-disc ml-6"
>
{guide.description}
</li>
);
})}
</ul>
<WaitingStoreSummary
name={store!.name}
departmentName={store!.departmentName}
partySize={partySize}
/>
</div>
<WaitingGuide />
</div>
<PageFooterButton background="transparent">
<Button onClick={handleSubmitReservation}>
<Button onClick={handleSubmit}>
{reservationIsLoading ? (
<LoadingSpinner loadingType="dotsWhite" />
) : (
Expand All @@ -120,26 +77,12 @@ const WaitingSummaryPage = () => {
</PageFooterButton>
</div>
{modal.isOpen && myReservations.length >= MAX_RESERVATIONS && (
<Portal>
<div
className="fixed inset-0 z-50 bg-black/50"
onClick={() => modal.close()}
>
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 min-w-[calc(100%-40px)] max-w-[430px] bg-white rounded-[20px] px-[22px] pt-[30px] pb-[22px]">
<h1 className="text-title-20-bold text-black-90 text-center mb-5 break-keep">
주점 웨이팅은 <br />
{MAX_RESERVATIONS}개까지 가능 합니다
</h1>
<Button
backgroundColor="#F4F4F4"
textColor="#666666"
onClick={() => navigate(`/store/${storeId}`, { replace: true })}
>
홈으로 가기
</Button>
</div>
</div>
</Portal>
<MaxReservationModal
isOpen={modal.isOpen}
max={MAX_RESERVATIONS}
onClose={modal.close}
onGoHome={() => navigate(`/store/${storeId}`, { replace: true })}
/>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Portal from "../../../../components/common/modal/Portal";
import { Button } from "@repo/ui";

interface Props {
isOpen: boolean;
max: number;
onClose: () => void;
onGoHome: () => void;
}

const MaxReservationModal = ({ isOpen, max, onClose, onGoHome }: Props) => {
if (!isOpen) return null;

return (
<Portal>
<div className="fixed inset-0 z-50 bg-black/50" onClick={onClose}>
<div
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
min-w-[calc(100%-40px)] max-w-[430px] bg-white rounded-[20px]
px-[22px] pt-[30px] pb-[22px]"
onClick={(e) => e.stopPropagation()}
>
<h1 className="text-title-20-bold text-black-90 text-center mb-5">
주점 웨이팅은 <br />
{max}개까지 가능 합니다
</h1>

<Button backgroundColor="#F4F4F4" textColor="#666666" onClick={onGoHome}>
홈으로 가기
</Button>
</div>
</div>
</Portal>
);
};

export default MaxReservationModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { WAITING_GUIDE } from "../../../../constants/guides";

const WaitingGuide = () => {
return (
<div className="bg-black-10 px-5 py-[30px] grow">
<h1 className="text-title-14-semibold text-black-80 mb-3">
대기 등록 전 꼭 확인해주세요
</h1>
<ul>
{WAITING_GUIDE.map((guide, i) => (
<li
key={i}
className="text-[14px] text-regular text-black-60 mb-3 whitespace-pre-line break-keep list-disc ml-6"
>
{guide.description}
</li>
))}
</ul>
</div>
);
};

export default WaitingGuide;
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
interface Props {
name: string;
departmentName: string;
partySize: number;
}

const WaitingStoreSummary = ({ name, departmentName, partySize }: Props) => {
return (
<div className="p-5.5 rounded-2xl bg-black-10 mb-[30px]">
<div className="flex justify-between items-start mb-2.5">
<p className="text-16-semibold text-black-50">부스</p>
<div className="max-w-[205px] text-16-medium text-black-90 text-right break-keep">
<p className="inline">{name} / </p>
<span
className={`${departmentName.length > 14 ? "block" : "inline"} truncate`}
>
{departmentName}
</span>
</div>
</div>

<div className="flex justify-between items-center">
<p className="text-16-semibold text-black-50">입장 인원</p>
<p className="text-16-medium text-black-90">{partySize}명</p>
</div>
</div>
);
};

export default WaitingStoreSummary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useQuery } from "@tanstack/react-query";
import {
createReservation,
getMyReservations,
getStore,
} from "../../../../api/reservation";

const MAX_RESERVATIONS = 3;

export const useWaitingSummary = (storeId: string | undefined) => {
const storeQuery = useQuery({
queryKey: ["store", storeId],
queryFn: () => getStore(storeId!),
select: (data) => data?.response,
enabled: !!storeId,
});

const myReservationsQuery = useQuery({
queryKey: ["myReservations"],
queryFn: getMyReservations,
select: (data) => data?.response,
});

const canCreateReservation =
(myReservationsQuery.data?.length ?? 0) < MAX_RESERVATIONS;

const createWaiting = (partySize: number) => {
return createReservation(Number(storeQuery.data?.storeId!), { partySize });
};

return {
store: storeQuery.data,
isStoreLoading: storeQuery.isLoading,
myReservations: myReservationsQuery.data,
canCreateReservation,
createWaiting,
MAX_RESERVATIONS,
};
};
4 changes: 3 additions & 1 deletion apps/nowait-user/src/pages/waiting/bookmark/BookmarkPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getBookmark } from "../../../api/reservation";
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";
import BookmarkListItemSkeleton from "./components/BookmarkListItemSkeleton";
import NotFound from "../../NotFound/NotFound";

const BookmarkPage = () => {
const { id: storeId } = useParams();
Expand All @@ -19,7 +20,8 @@ const BookmarkPage = () => {
select: (data) => data.response,
});

if (!bookmarkList && !isLoading && isError) return <div>에러....</div>;
if (!bookmarkList && !isLoading && isError) return <NotFound />;

return (
<div>
<HomeHeader />
Expand Down
Loading