add payment success and failure pages with environment variable support

This commit is contained in:
Marshal
2026-06-17 17:13:19 +00:00
parent 3798b28bcd
commit 5b9fed57fe
6 changed files with 126 additions and 7 deletions

View File

@@ -36,6 +36,8 @@ import EditBookingPage from "./pages/bookings/EditBookingPage";
import MyBookings from "./pages/bookings/MyBookings";
import NewBookingPage from "./pages/bookings/NewBookingPage";
import CheckPaymentPage from "./pages/payments/CheckPaymentPage";
import PaymentSuccessPage from "./pages/payments/PaymentSuccessPage";
import PaymentFailurePage from "./pages/payments/PaymentFailurePage";
import TrackingPage from "./pages/tracking/TrackingPage";
function FullScreenSpinner() {
@@ -158,6 +160,9 @@ const App = () => {
path="/booking/check-status/:orderId"
element={<CheckPaymentPage />}
/>
{/* Payment provider browser redirects (PAYMENT_RETURN_URL / PAYMENT_FAILURE_URL) */}
<Route path="/payment/success" element={<PaymentSuccessPage />} />
<Route path="/payment/failure" element={<PaymentFailurePage />} />
{/* Auth pages — inaccessible once logged in */}
<Route element={<RedirectIfAuthed />}>

View File

@@ -0,0 +1,43 @@
import { XCircle } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { Button } from "@edr/ui-common";
/**
* Public page the payment provider redirects the browser to after a failed or
* cancelled payment (PAYMENT_FAILURE_URL). Generic — it explains nothing was
* charged and sends the customer back to their bookings to retry from "Pay now".
*/
export default function PaymentFailurePage() {
const navigate = useNavigate();
return (
<div className="flex min-h-screen items-center justify-center bg-background p-4">
<div className="w-full max-w-md rounded-2xl border border-border bg-card p-8 text-center shadow-sm">
<div className="flex flex-col items-center gap-4">
<div className="flex size-16 items-center justify-center rounded-full bg-destructive/10">
<XCircle className="size-9 text-destructive" />
</div>
<p className="text-xl font-bold text-foreground">
Payment was not completed
</p>
<p className="text-sm text-muted-foreground">
Your payment didn't go through and you haven't been charged. You can
try again from your booking using "Pay now".
</p>
<div className="mt-2 flex w-full flex-col gap-2">
<Button type="button" onClick={() => navigate("/bookings")}>
Back to My Bookings
</Button>
<Button
type="button"
variant="outline"
onClick={() => navigate("/")}
>
Back to home
</Button>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,43 @@
import { CheckCircle2 } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { Button } from "@edr/ui-common";
/**
* Public page the payment provider redirects the browser to after a successful
* payment (PAYMENT_RETURN_URL). Generic — it confirms success and points the
* customer back to their bookings, where the booking reflects the paid state.
*/
export default function PaymentSuccessPage() {
const navigate = useNavigate();
return (
<div className="flex min-h-screen items-center justify-center bg-background p-4">
<div className="w-full max-w-md rounded-2xl border border-border bg-card p-8 text-center shadow-sm">
<div className="flex flex-col items-center gap-4">
<div className="flex size-16 items-center justify-center rounded-full bg-primary/10">
<CheckCircle2 className="size-9 text-primary" />
</div>
<p className="text-xl font-bold text-foreground">
Payment successful
</p>
<p className="text-sm text-muted-foreground">
Thank you your payment has been received. Your booking will be
updated shortly and is now confirmed for scheduling.
</p>
<div className="mt-2 flex w-full flex-col gap-2">
<Button type="button" onClick={() => navigate("/bookings")}>
Go to My Bookings
</Button>
<Button
type="button"
variant="outline"
onClick={() => navigate("/")}
>
Back to home
</Button>
</div>
</div>
</div>
</div>
);
}