feat(payment): add chat support discounts and gratitude
Docker Image / Build and Push Docker Image (push) Successful in 2m14s
Docker Image / Build and Push Docker Image (push) Successful in 2m14s
(cherry picked from commit ef9b79bc83)
This commit is contained in:
@@ -9,10 +9,10 @@ import { usePaymentPlanAnalytics } from "@/app/_hooks/use-payment-plan-analytics
|
||||
import type { PayChannel } from "@/data/schemas/payment";
|
||||
import type { SubscriptionReturnTo } from "@/lib/navigation/subscription_exit";
|
||||
import {
|
||||
DEFAULT_CHARACTER,
|
||||
DEFAULT_CHARACTER_SLUG,
|
||||
getCharacterBySlug,
|
||||
} from "@/data/constants/character";
|
||||
import { useCharacterCatalog } from "@/providers/character-catalog-provider";
|
||||
import {
|
||||
behaviorAnalytics,
|
||||
getDefaultPaymentAnalyticsContext,
|
||||
@@ -51,7 +51,7 @@ export interface SubscriptionScreenProps {
|
||||
returnTo?: SubscriptionReturnTo;
|
||||
initialPayChannel?: PayChannel | null;
|
||||
analyticsContext?: PaymentAnalyticsContext;
|
||||
sourceCharacterSlug?: string;
|
||||
sourceCharacterSlug?: string | null;
|
||||
initialPlanId?: string | null;
|
||||
initialAutoRenew?: boolean | null;
|
||||
commercialOfferId?: string | null;
|
||||
@@ -80,9 +80,15 @@ export function SubscriptionScreen({
|
||||
const [paymentIssueNotice, setPaymentIssueNotice] = useState<string | null>(
|
||||
null,
|
||||
);
|
||||
const characterCatalog = useCharacterCatalog();
|
||||
const [selectedSupportCharacterSlug, setSelectedSupportCharacterSlug] =
|
||||
useState<string | null>(() =>
|
||||
getCharacterBySlug(sourceCharacterSlug)?.slug ?? null,
|
||||
);
|
||||
const userState = useUserState();
|
||||
const sourceCharacter =
|
||||
getCharacterBySlug(sourceCharacterSlug) ?? DEFAULT_CHARACTER;
|
||||
const sourceCharacter = characterCatalog.getBySlug(
|
||||
selectedSupportCharacterSlug,
|
||||
);
|
||||
const hasHydrated = useHasHydrated();
|
||||
const countryCode = userState.currentUser?.countryCode;
|
||||
const paymentMethodConfig = getPaymentMethodConfig({
|
||||
@@ -102,7 +108,7 @@ export function SubscriptionScreen({
|
||||
subscriptionType,
|
||||
shouldResumePendingOrder,
|
||||
returnTo,
|
||||
sourceCharacterSlug,
|
||||
sourceCharacterSlug: sourceCharacter?.slug ?? null,
|
||||
initialPayChannel: paymentMethodConfig.initialPayChannel,
|
||||
initialPlanId,
|
||||
initialAutoRenew,
|
||||
@@ -163,6 +169,7 @@ export function SubscriptionScreen({
|
||||
(plan) => plan.id === payment.selectedPlanId,
|
||||
);
|
||||
const canActivate =
|
||||
sourceCharacter !== null &&
|
||||
selectedPlan !== null &&
|
||||
canCheckoutSubscriptionPlan({
|
||||
selectedPlanId: payment.selectedPlanId,
|
||||
@@ -271,7 +278,36 @@ export function SubscriptionScreen({
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{chatActionId ? (
|
||||
<section className={styles.supportCharacterSelector}>
|
||||
<h2>
|
||||
{sourceCharacter
|
||||
? `Supporting ${sourceCharacter.shortName}`
|
||||
: "Choose who you want to support"}
|
||||
</h2>
|
||||
<p>
|
||||
Your VIP or credit purchase supports the character you choose, and
|
||||
they will thank you after the payment and benefits are confirmed.
|
||||
</p>
|
||||
<div className={styles.supportCharacterOptions}>
|
||||
{characterCatalog.characters.map((character) => (
|
||||
<button
|
||||
key={character.id}
|
||||
type="button"
|
||||
className={
|
||||
sourceCharacter?.id === character.id
|
||||
? styles.supportCharacterOptionActive
|
||||
: styles.supportCharacterOption
|
||||
}
|
||||
aria-pressed={sourceCharacter?.id === character.id}
|
||||
onClick={() => setSelectedSupportCharacterSlug(character.slug)}
|
||||
>
|
||||
{character.shortName}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{chatActionId && sourceCharacter ? (
|
||||
<section
|
||||
className={styles.characterSupportBanner}
|
||||
aria-label={`Support ${sourceCharacter.displayName}`}
|
||||
@@ -287,7 +323,7 @@ export function SubscriptionScreen({
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
{payment.commercialOffer && !hasFirstRechargeOffer ? (
|
||||
{payment.commercialOffer && !hasFirstRechargeOffer && sourceCharacter ? (
|
||||
<section
|
||||
className={styles.firstRechargeBanner}
|
||||
aria-label={`${sourceCharacter.shortName} private offer`}
|
||||
@@ -339,7 +375,7 @@ export function SubscriptionScreen({
|
||||
disabled={!canActivate}
|
||||
subscriptionType={subscriptionType}
|
||||
returnTo={returnTo}
|
||||
sourceCharacterSlug={sourceCharacterSlug}
|
||||
sourceCharacterSlug={sourceCharacter?.slug ?? DEFAULT_CHARACTER_SLUG}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -364,7 +400,7 @@ export function SubscriptionScreen({
|
||||
orderId={payment.currentOrderId}
|
||||
payChannel={payment.payChannel}
|
||||
countryCode={countryCode}
|
||||
characterId={sourceCharacterSlug}
|
||||
characterId={sourceCharacter?.id ?? ""}
|
||||
onClose={() => setShowPaymentIssueDialog(false)}
|
||||
onSubmitted={setPaymentIssueNotice}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user