refactor(payment): unify method selector visibility
This commit is contained in:
@@ -7,8 +7,11 @@ describe("PaymentMethodSelector", () => {
|
||||
it("orders the default channel first and renders page analytics", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<PaymentMethodSelector
|
||||
config={{
|
||||
canChoosePaymentMethod: true,
|
||||
initialPayChannel: "ezpay",
|
||||
}}
|
||||
value="ezpay"
|
||||
defaultChannel="ezpay"
|
||||
caption="GCash by default"
|
||||
analyticsKey="tip.payment_method"
|
||||
onChange={() => undefined}
|
||||
@@ -40,6 +43,10 @@ describe("PaymentMethodSelector", () => {
|
||||
it("disables both payment methods while payment is busy", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<PaymentMethodSelector
|
||||
config={{
|
||||
canChoosePaymentMethod: true,
|
||||
initialPayChannel: "stripe",
|
||||
}}
|
||||
value="stripe"
|
||||
disabled
|
||||
analyticsKey="subscription.payment_method"
|
||||
@@ -52,4 +59,20 @@ describe("PaymentMethodSelector", () => {
|
||||
'data-analytics-key="subscription.payment_method"',
|
||||
);
|
||||
});
|
||||
|
||||
it("does not render when payment method selection is unavailable", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<PaymentMethodSelector
|
||||
config={{
|
||||
canChoosePaymentMethod: false,
|
||||
initialPayChannel: "stripe",
|
||||
}}
|
||||
value="stripe"
|
||||
analyticsKey="tip.payment_method"
|
||||
onChange={() => undefined}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(html).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import Image from "next/image";
|
||||
|
||||
import type { PayChannel } from "@/data/schemas/payment";
|
||||
import type { PaymentMethodConfig } from "@/lib/payment/payment_method";
|
||||
|
||||
const PAYMENT_METHODS: readonly {
|
||||
channel: PayChannel;
|
||||
@@ -21,24 +22,28 @@ const PAYMENT_METHODS: readonly {
|
||||
];
|
||||
|
||||
export interface PaymentMethodSelectorProps {
|
||||
config: PaymentMethodConfig;
|
||||
value: PayChannel;
|
||||
defaultChannel?: PayChannel;
|
||||
disabled?: boolean;
|
||||
caption?: string;
|
||||
className?: string;
|
||||
analyticsKey: string;
|
||||
onChange: (channel: PayChannel) => void;
|
||||
}
|
||||
|
||||
export function PaymentMethodSelector({
|
||||
config,
|
||||
value,
|
||||
defaultChannel = "stripe",
|
||||
disabled = false,
|
||||
caption = "Stripe by default",
|
||||
className,
|
||||
analyticsKey,
|
||||
onChange,
|
||||
}: PaymentMethodSelectorProps) {
|
||||
if (!config.canChoosePaymentMethod) return null;
|
||||
|
||||
const paymentMethods =
|
||||
defaultChannel === "ezpay"
|
||||
config.initialPayChannel === "ezpay"
|
||||
? [...PAYMENT_METHODS].sort((a, b) =>
|
||||
a.channel === "ezpay" ? -1 : b.channel === "ezpay" ? 1 : 0,
|
||||
)
|
||||
@@ -46,7 +51,7 @@ export function PaymentMethodSelector({
|
||||
|
||||
return (
|
||||
<section
|
||||
className="flex flex-col gap-[clamp(8px,1.852vw,10px)]"
|
||||
className={`flex flex-col gap-[clamp(8px,1.852vw,10px)] ${className ?? ""}`.trim()}
|
||||
aria-labelledby="payment-method-title"
|
||||
>
|
||||
<div className="flex items-baseline justify-between gap-sm px-xs">
|
||||
|
||||
@@ -224,18 +224,15 @@ export function SubscriptionScreen({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{paymentMethodConfig.canChoosePaymentMethod ? (
|
||||
<section className={styles.paymentMethodSlot}>
|
||||
<PaymentMethodSelector
|
||||
value={payment.payChannel}
|
||||
defaultChannel={paymentMethodConfig.initialPayChannel}
|
||||
disabled={isPaymentBusy}
|
||||
caption="GCash by default in the Philippines"
|
||||
analyticsKey="subscription.payment_method"
|
||||
onChange={handlePaymentMethodChange}
|
||||
/>
|
||||
</section>
|
||||
) : null}
|
||||
<PaymentMethodSelector
|
||||
config={paymentMethodConfig}
|
||||
value={payment.payChannel}
|
||||
disabled={isPaymentBusy}
|
||||
caption="GCash by default in the Philippines"
|
||||
className={styles.paymentMethodSlot}
|
||||
analyticsKey="subscription.payment_method"
|
||||
onChange={handlePaymentMethodChange}
|
||||
/>
|
||||
|
||||
<div className={styles.ctaSlot}>
|
||||
<SubscriptionCheckoutButton
|
||||
|
||||
@@ -284,18 +284,15 @@ export function TipScreen({
|
||||
/>
|
||||
</section>
|
||||
|
||||
{paymentMethodConfig.canChoosePaymentMethod ? (
|
||||
<section className={styles.paymentMethodSlot}>
|
||||
<PaymentMethodSelector
|
||||
value={payment.payChannel}
|
||||
defaultChannel={paymentMethodConfig.initialPayChannel}
|
||||
disabled={isPaymentBusy}
|
||||
caption="GCash by default in the Philippines"
|
||||
analyticsKey="tip.payment_method"
|
||||
onChange={handlePaymentMethodChange}
|
||||
/>
|
||||
</section>
|
||||
) : null}
|
||||
<PaymentMethodSelector
|
||||
config={paymentMethodConfig}
|
||||
value={payment.payChannel}
|
||||
disabled={isPaymentBusy}
|
||||
caption="GCash by default in the Philippines"
|
||||
className={styles.paymentMethodSlot}
|
||||
analyticsKey="tip.payment_method"
|
||||
onChange={handlePaymentMethodChange}
|
||||
/>
|
||||
|
||||
{showMissingPlan ? (
|
||||
<p className={styles.statusMessage} role="alert">
|
||||
|
||||
Reference in New Issue
Block a user