feat(tip): support tiered coffee gifts
This commit is contained in:
@@ -8,7 +8,12 @@ import { CharacterAvatar } from "@/app/_components";
|
||||
import { MobileShell } from "@/app/_components/core";
|
||||
import { usePaymentOrderLifecycle } from "@/app/_hooks/use-payment-order-lifecycle";
|
||||
import type { PayChannel } from "@/data/dto/payment";
|
||||
import { ROUTES } from "@/router/routes";
|
||||
import {
|
||||
buildTipCoffeePath,
|
||||
DEFAULT_TIP_COFFEE_TYPE,
|
||||
getTipCoffeeOption,
|
||||
type TipCoffeeType,
|
||||
} from "@/lib/tip/tip_coffee";
|
||||
import { useAppNavigator } from "@/router/use-app-navigator";
|
||||
import { useAuthState } from "@/stores/auth/auth-context";
|
||||
import {
|
||||
@@ -25,11 +30,13 @@ import {
|
||||
import styles from "./tip-screen.module.css";
|
||||
|
||||
export interface TipScreenProps {
|
||||
coffeeType?: TipCoffeeType;
|
||||
shouldResumePendingOrder?: boolean;
|
||||
initialPayChannel?: PayChannel | null;
|
||||
}
|
||||
|
||||
export function TipScreen({
|
||||
coffeeType = DEFAULT_TIP_COFFEE_TYPE,
|
||||
shouldResumePendingOrder = false,
|
||||
initialPayChannel = null,
|
||||
}: TipScreenProps) {
|
||||
@@ -38,14 +45,16 @@ export function TipScreen({
|
||||
const payment = usePaymentState();
|
||||
const paymentDispatch = usePaymentDispatch();
|
||||
const initialPayChannelAppliedRef = useRef(false);
|
||||
const coffeeOption = getTipCoffeeOption(coffeeType);
|
||||
const returnPath = buildTipCoffeePath(coffeeType);
|
||||
const resolvedInitialPayChannel =
|
||||
initialPayChannel ?? navigator.getDefaultPayChannel();
|
||||
|
||||
const coffeePlan = useMemo(
|
||||
() => findTipCoffeePlan(payment.plans),
|
||||
[payment.plans],
|
||||
() => findTipCoffeePlan(payment.plans, coffeeType),
|
||||
[coffeeType, payment.plans],
|
||||
);
|
||||
const priceLabel = formatTipPrice(coffeePlan);
|
||||
const priceLabel = formatTipPrice(coffeePlan, coffeeType);
|
||||
const isPaymentBusy =
|
||||
payment.isCreatingOrder || payment.isPollingOrder || payment.isPaid;
|
||||
const canCreateOrder =
|
||||
@@ -127,7 +136,7 @@ export function TipScreen({
|
||||
const handleOrder = () => {
|
||||
if (isAuthLoading) return;
|
||||
if (!isRealLoginStatus(authState.loginStatus)) {
|
||||
navigator.openAuth(ROUTES.tip);
|
||||
navigator.openAuth(returnPath);
|
||||
return;
|
||||
}
|
||||
if (!canCreateOrder) return;
|
||||
@@ -198,7 +207,7 @@ export function TipScreen({
|
||||
Coffee Gift
|
||||
</span>
|
||||
<h2 className={styles.productName}>
|
||||
{coffeePlan?.planName || "Latte"}
|
||||
{coffeePlan?.planName || coffeeOption.fallbackName}
|
||||
</h2>
|
||||
<p className={styles.productPrice}>{priceLabel}</p>
|
||||
</div>
|
||||
@@ -231,12 +240,14 @@ export function TipScreen({
|
||||
|
||||
<div className={styles.checkoutSlot}>
|
||||
<TipCheckoutButton
|
||||
coffeeType={coffeeType}
|
||||
disabled={
|
||||
showMissingPlan ||
|
||||
(!canCreateOrder && isRealLoginStatus(authState.loginStatus))
|
||||
}
|
||||
isAuthLoading={isAuthLoading}
|
||||
onOrder={handleOrder}
|
||||
returnPath={returnPath}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user