9121b50e02
Docker Image / Build and Push Docker Image (push) Successful in 3m1s
(cherry picked from commit ef9b79bc83)
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import type { CommercialOfferSummary } from "@/data/schemas/payment";
|
|
|
|
export type ChatSupportCtaKind =
|
|
| "support"
|
|
| "firstRecharge"
|
|
| "commercialOffer";
|
|
|
|
export interface ChatSupportCtaView {
|
|
kind: ChatSupportCtaKind;
|
|
label: string;
|
|
commercialOfferId: string | null;
|
|
planId: string | null;
|
|
expiresAt: string | null;
|
|
}
|
|
|
|
export function deriveChatSupportCta(input: {
|
|
isFirstRecharge: boolean;
|
|
commercialOffer: CommercialOfferSummary | null;
|
|
nowMs: number;
|
|
}): ChatSupportCtaView {
|
|
if (input.isFirstRecharge) {
|
|
return {
|
|
kind: "firstRecharge",
|
|
label: "Support me · 50% OFF · First recharge",
|
|
commercialOfferId: null,
|
|
planId: null,
|
|
expiresAt: null,
|
|
};
|
|
}
|
|
|
|
const offer = input.commercialOffer;
|
|
const expiresAtMs = offer ? Date.parse(offer.expiresAt) : Number.NaN;
|
|
if (offer?.enabled && Number.isFinite(expiresAtMs) && expiresAtMs > input.nowMs) {
|
|
return {
|
|
kind: "commercialOffer",
|
|
label: `Support me · ${offer.discountPercent}% OFF · ${formatOfferCountdown(expiresAtMs, input.nowMs)}`,
|
|
commercialOfferId: offer.commercialOfferId,
|
|
planId: offer.planId,
|
|
expiresAt: offer.expiresAt,
|
|
};
|
|
}
|
|
|
|
return {
|
|
kind: "support",
|
|
label: "Support me",
|
|
commercialOfferId: null,
|
|
planId: null,
|
|
expiresAt: null,
|
|
};
|
|
}
|
|
|
|
export function formatOfferCountdown(expiresAtMs: number, nowMs: number): string {
|
|
const totalSeconds = Math.max(
|
|
0,
|
|
Math.ceil((expiresAtMs - nowMs) / 1000) - 1,
|
|
);
|
|
const hours = Math.floor(totalSeconds / 3600);
|
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
const seconds = totalSeconds % 60;
|
|
return [hours, minutes, seconds]
|
|
.map((value) => String(value).padStart(2, "0"))
|
|
.join(":");
|
|
}
|