diff --git a/frontend/app/workspaces/[id]/page.tsx b/frontend/app/workspaces/[id]/page.tsx index 217aece..6ae3857 100644 --- a/frontend/app/workspaces/[id]/page.tsx +++ b/frontend/app/workspaces/[id]/page.tsx @@ -1,7 +1,8 @@ "use client"; -import { use } from "react"; +import { use, useState } from "react"; import Link from "next/link"; +import { useRouter } from "next/navigation"; import DashboardLayout from "@/components/dashboard/DashboardLayout"; import { useGetWorkspaceById } from "@/lib/react-query/hooks/workspaces/useGetWorkspaceById"; import { @@ -12,6 +13,7 @@ import { CalendarPlus, AlertCircle, RefreshCcw, + Loader2, } from "lucide-react"; const TYPE_LABELS: Record = { @@ -31,6 +33,17 @@ export default function WorkspaceDetailPage({ const { data, isLoading, isError, refetch } = useGetWorkspaceById(id); const workspace = data?.data; + // #351: track in-flight booking navigation so the CTA is disabled, shows a + // spinner, and duplicate requests are prevented while the booking form loads. + const router = useRouter(); + const [bookingPending, setBookingPending] = useState(false); + + function handleBookWorkspace() { + if (bookingPending || !workspace) return; + setBookingPending(true); + router.push(`/bookings/new?workspaceId=${workspace.id}`); + } + const hourlyNaira = workspace ? (workspace.hourlyRate / 100).toLocaleString("en-NG", { style: "currency", @@ -213,13 +226,25 @@ export default function WorkspaceDetailPage({ {workspace.isActive ? ( - - - Book this space - + {bookingPending ? ( + <> +