diff --git a/src/app/subscription/page.tsx b/src/app/subscription/page.tsx index 452dfc6c..0398bf63 100644 --- a/src/app/subscription/page.tsx +++ b/src/app/subscription/page.tsx @@ -1,19 +1,53 @@ -import { Suspense } from "react"; +import type { PayChannel } from "@/data/dto/payment"; +import { + PAYMENT_ANALYTICS_ENTRY_PARAM, + PAYMENT_ANALYTICS_REASON_PARAM, + parsePaymentAnalyticsContext, +} from "@/lib/analytics/payment_analytics_context"; -import { PageLoadingFallback } from "@/app/_components/core"; +import { + SubscriptionScreen, + type SubscriptionType, +} from "./subscription-screen"; -import { SubscriptionPageClient } from "./subscription-page-client"; +type SubscriptionSearchParams = Record; + +export default async function SubscriptionPage({ + searchParams, +}: { + searchParams: Promise; +}) { + const query = await searchParams; + const subscriptionType = toSubscriptionType(firstSearchParam(query.type)); + const analyticsContext = parsePaymentAnalyticsContext({ + entryPoint: firstSearchParam(query[PAYMENT_ANALYTICS_ENTRY_PARAM]), + triggerReason: firstSearchParam(query[PAYMENT_ANALYTICS_REASON_PARAM]), + subscriptionType, + }); -export default function SubscriptionPage() { return ( - }> - - + ); } -function SubscriptionFallback() { - return ( - Loading subscription... - ); +function firstSearchParam(value: string | string[] | undefined): string | null { + return Array.isArray(value) ? (value[0] ?? null) : (value ?? null); +} + +function toSubscriptionType(value: string | null): SubscriptionType { + return value === "topup" ? "topup" : "vip"; +} + +function toReturnTo(value: string | null): "chat" | null { + return value === "chat" ? "chat" : null; +} + +function toPayChannel(value: string | null): PayChannel | null { + return value === "ezpay" || value === "stripe" ? value : null; } diff --git a/src/app/subscription/subscription-page-client.tsx b/src/app/subscription/subscription-page-client.tsx deleted file mode 100644 index e7011df5..00000000 --- a/src/app/subscription/subscription-page-client.tsx +++ /dev/null @@ -1,51 +0,0 @@ -"use client"; - -import { useSearchParams } from "next/navigation"; - -import type { PayChannel } from "@/data/dto/payment"; -import { - PAYMENT_ANALYTICS_ENTRY_PARAM, - PAYMENT_ANALYTICS_REASON_PARAM, - parsePaymentAnalyticsContext, -} from "@/lib/analytics"; - -import { - SubscriptionScreen, - type SubscriptionType, -} from "./subscription-screen"; - -function toSubscriptionType(value: string | null): SubscriptionType { - return value === "topup" ? "topup" : "vip"; -} - -function toReturnTo(value: string | null): "chat" | null { - return value === "chat" ? "chat" : null; -} - -function toPayChannel(value: string | null): PayChannel | null { - if (value === "ezpay" || value === "stripe") return value; - return null; -} - -export function SubscriptionPageClient() { - const searchParams = useSearchParams(); - const subscriptionType = toSubscriptionType(searchParams.get("type")); - const shouldResumePendingOrder = searchParams.get("paymentReturn") === "1"; - const returnTo = toReturnTo(searchParams.get("returnTo")); - const initialPayChannel = toPayChannel(searchParams.get("payChannel")); - const analyticsContext = parsePaymentAnalyticsContext({ - entryPoint: searchParams.get(PAYMENT_ANALYTICS_ENTRY_PARAM), - triggerReason: searchParams.get(PAYMENT_ANALYTICS_REASON_PARAM), - subscriptionType, - }); - - return ( - - ); -} diff --git a/src/app/tip/page.tsx b/src/app/tip/page.tsx index 312fba44..f8d0077e 100644 --- a/src/app/tip/page.tsx +++ b/src/app/tip/page.tsx @@ -1,21 +1,37 @@ -import { Suspense } from "react"; +import type { PayChannel } from "@/data/dto/payment"; +import { + DEFAULT_TIP_COFFEE_TYPE, + resolveTipCoffeeType, + TIP_COFFEE_TYPE_PARAM, +} from "@/lib/tip/tip_coffee"; -import { PageLoadingFallback } from "@/app/_components/core"; +import { TipScreen } from "./tip-screen"; -import { TipPageClient } from "./tip-page-client"; +type TipSearchParams = Record; + +export default async function TipPage({ + searchParams, +}: { + searchParams: Promise; +}) { + const query = await searchParams; + const coffeeType = + resolveTipCoffeeType(firstSearchParam(query[TIP_COFFEE_TYPE_PARAM])) ?? + DEFAULT_TIP_COFFEE_TYPE; -export default function TipPage() { return ( - }> - - + ); } -function TipFallback() { - return ( - - Loading tip... - - ); +function firstSearchParam(value: string | string[] | undefined): string | null { + return Array.isArray(value) ? (value[0] ?? null) : (value ?? null); +} + +function toPayChannel(value: string | null): PayChannel | null { + return value === "ezpay" || value === "stripe" ? value : null; } diff --git a/src/app/tip/tip-page-client.tsx b/src/app/tip/tip-page-client.tsx deleted file mode 100644 index 4922f659..00000000 --- a/src/app/tip/tip-page-client.tsx +++ /dev/null @@ -1,32 +0,0 @@ -"use client"; - -import { useSearchParams } from "next/navigation"; - -import type { PayChannel } from "@/data/dto/payment"; -import { - DEFAULT_TIP_COFFEE_TYPE, - resolveTipCoffeeType, - TIP_COFFEE_TYPE_PARAM, -} from "@/lib/tip/tip_coffee"; - -import { TipScreen } from "./tip-screen"; - -function toPayChannel(value: string | null): PayChannel | null { - if (value === "ezpay" || value === "stripe") return value; - return null; -} - -export function TipPageClient() { - const searchParams = useSearchParams(); - const coffeeType = - resolveTipCoffeeType(searchParams.get(TIP_COFFEE_TYPE_PARAM)) ?? - DEFAULT_TIP_COFFEE_TYPE; - - return ( - - ); -}