fix(payment): portal checkout dialogs to viewport
Docker Image / Build and Push Docker Image (push) Successful in 3m32s
Docker Image / Build and Push Docker Image (push) Successful in 3m32s
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useId, type ReactNode } from "react";
|
||||
import { QRCodeSVG } from "qrcode.react";
|
||||
|
||||
import { ModalPortal } from "@/app/_components/core/modal-portal";
|
||||
import type { PaymentLaunchFlow } from "@/app/_hooks/use-payment-launch-flow";
|
||||
|
||||
import { LazyStripePaymentDialog } from "./lazy-stripe-payment-dialog";
|
||||
@@ -111,60 +112,61 @@ function QrisPaymentDialog({
|
||||
const statusMessage = qrisStatusMessage(status, errorMessage);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.overlay}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby={titleId}
|
||||
<ModalPortal
|
||||
open
|
||||
persistent
|
||||
onClose={onClose}
|
||||
scrimClassName={styles.overlay}
|
||||
panelClassName={styles.dialog}
|
||||
scrimOpacity={0.5}
|
||||
ariaLabelledBy={titleId}
|
||||
>
|
||||
<div className={styles.dialog}>
|
||||
<div className={`${styles.header} text-center`}>
|
||||
<h2 id={titleId} className={styles.title}>
|
||||
Scan to pay with QRIS
|
||||
</h2>
|
||||
<p className={styles.content}>
|
||||
Open a QRIS-compatible banking or wallet app and scan this code.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mb-4 flex min-h-64 items-center justify-center rounded-2xl bg-white p-4">
|
||||
{payment.qrData ? (
|
||||
<QRCodeSVG
|
||||
value={payment.qrData}
|
||||
title="QRIS payment QR code"
|
||||
size={256}
|
||||
level="M"
|
||||
marginSize={2}
|
||||
className="h-auto w-full max-w-64"
|
||||
/>
|
||||
) : (
|
||||
<p className={styles.error} role="alert">
|
||||
QRIS data is unavailable. Please close this dialog and try again.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="mb-4 flex flex-col gap-2 text-center">
|
||||
<p className={styles.content}>Order No. {payment.orderId}</p>
|
||||
<p className="m-0 text-xl font-bold text-text-foreground">
|
||||
{formatQrisAmount(payment.amountCents, payment.currency)}
|
||||
</p>
|
||||
<p
|
||||
className={status === "failed" || status === "expired" ? styles.error : styles.content}
|
||||
role="status"
|
||||
>
|
||||
{statusMessage}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.button} ${styles.secondary}`}
|
||||
onClick={onClose}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
<div className={`${styles.header} text-center`}>
|
||||
<h2 id={titleId} className={styles.title}>
|
||||
Scan to pay with QRIS
|
||||
</h2>
|
||||
<p className={styles.content}>
|
||||
Open a QRIS-compatible banking or wallet app and scan this code.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4 flex min-h-64 items-center justify-center rounded-2xl bg-white p-4">
|
||||
{payment.qrData ? (
|
||||
<QRCodeSVG
|
||||
value={payment.qrData}
|
||||
title="QRIS payment QR code"
|
||||
size={256}
|
||||
level="M"
|
||||
marginSize={2}
|
||||
className="h-auto w-full max-w-64"
|
||||
/>
|
||||
) : (
|
||||
<p className={styles.error} role="alert">
|
||||
QRIS data is unavailable. Please close this dialog and try again.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="mb-4 flex flex-col gap-2 text-center">
|
||||
<p className={styles.content}>Order No. {payment.orderId}</p>
|
||||
<p className="m-0 text-xl font-bold text-text-foreground">
|
||||
{formatQrisAmount(payment.amountCents, payment.currency)}
|
||||
</p>
|
||||
<p
|
||||
className={status === "failed" || status === "expired" ? styles.error : styles.content}
|
||||
role="status"
|
||||
>
|
||||
{statusMessage}
|
||||
</p>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.button} ${styles.secondary}`}
|
||||
onClick={onClose}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</ModalPortal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,41 +190,43 @@ function EzpayRedirectConfirmDialog({
|
||||
const titleId = useId();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.overlay}
|
||||
<ModalPortal
|
||||
open
|
||||
persistent
|
||||
onClose={onCancel}
|
||||
scrimClassName={styles.overlay}
|
||||
panelClassName={styles.dialog}
|
||||
scrimOpacity={0.5}
|
||||
role="alertdialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby={titleId}
|
||||
ariaLabelledBy={titleId}
|
||||
>
|
||||
<div className={styles.dialog}>
|
||||
<div className={styles.header}>
|
||||
<h2 id={titleId} className={styles.title}>
|
||||
Continue to payment?
|
||||
</h2>
|
||||
<p className={styles.content}>{description}</p>
|
||||
<p className={styles.content}>Order No. {orderId}</p>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.button} ${styles.secondary}`}
|
||||
disabled={isConfirming}
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-analytics-key={externalCheckoutAnalyticsKey}
|
||||
data-analytics-label="Continue to external checkout"
|
||||
className={`${styles.button} ${styles.primary}`}
|
||||
disabled={isConfirming}
|
||||
onClick={onConfirm}
|
||||
>
|
||||
{isConfirming ? "Opening..." : "Continue"}
|
||||
</button>
|
||||
</div>
|
||||
<div className={styles.header}>
|
||||
<h2 id={titleId} className={styles.title}>
|
||||
Continue to payment?
|
||||
</h2>
|
||||
<p className={styles.content}>{description}</p>
|
||||
<p className={styles.content}>Order No. {orderId}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.button} ${styles.secondary}`}
|
||||
disabled={isConfirming}
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-analytics-key={externalCheckoutAnalyticsKey}
|
||||
data-analytics-label="Continue to external checkout"
|
||||
className={`${styles.button} ${styles.primary}`}
|
||||
disabled={isConfirming}
|
||||
onClick={onConfirm}
|
||||
>
|
||||
{isConfirming ? "Opening..." : "Continue"}
|
||||
</button>
|
||||
</div>
|
||||
</ModalPortal>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user