@hook-sdk/template 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +942 -266
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -23
- package/dist/index.d.ts +329 -23
- package/dist/index.js +968 -309
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -46,10 +46,26 @@ __export(index_exports, {
|
|
|
46
46
|
OnboardingFlow: () => OnboardingFlow,
|
|
47
47
|
PaymentReturnHandler: () => PaymentReturnHandler,
|
|
48
48
|
Paywall: () => Paywall,
|
|
49
|
+
PaywallAnchorPrice: () => PaywallAnchorPrice,
|
|
50
|
+
PaywallContext: () => PaywallContext,
|
|
51
|
+
PaywallCountdown: () => PaywallCountdown,
|
|
49
52
|
PaywallCta: () => PaywallCta,
|
|
50
53
|
PaywallCyclePicker: () => PaywallCyclePicker,
|
|
54
|
+
PaywallEyebrow: () => PaywallEyebrow,
|
|
55
|
+
PaywallFeatures: () => PaywallFeatures,
|
|
56
|
+
PaywallFeaturesCard: () => PaywallFeaturesCard,
|
|
57
|
+
PaywallFinePrint: () => PaywallFinePrint,
|
|
58
|
+
PaywallHeadline: () => PaywallHeadline,
|
|
59
|
+
PaywallHero: () => PaywallHero,
|
|
51
60
|
PaywallMethodContent: () => PaywallMethodContent,
|
|
52
61
|
PaywallMethodTabs: () => PaywallMethodTabs,
|
|
62
|
+
PaywallPriceHeadline: () => PaywallPriceHeadline,
|
|
63
|
+
PaywallProvider: () => PaywallProvider,
|
|
64
|
+
PaywallStatsRow: () => PaywallStatsRow,
|
|
65
|
+
PaywallStickyFooter: () => PaywallStickyFooter,
|
|
66
|
+
PaywallTestimonials: () => PaywallTestimonials,
|
|
67
|
+
PaywallTrophyBadge: () => PaywallTrophyBadge,
|
|
68
|
+
PaywallTrustLine: () => PaywallTrustLine,
|
|
53
69
|
PersistenceRegistry: () => PersistenceRegistry,
|
|
54
70
|
PixWaitingPageDefault: () => PixWaitingPageDefault,
|
|
55
71
|
PreAuthShell: () => PreAuthShell,
|
|
@@ -80,6 +96,7 @@ __export(index_exports, {
|
|
|
80
96
|
useInstallPrompt: () => useInstallPrompt,
|
|
81
97
|
useLoginForm: () => useLoginForm,
|
|
82
98
|
useOnboardingStep: () => useOnboardingStep,
|
|
99
|
+
usePaywallContext: () => usePaywallContext,
|
|
83
100
|
usePaywallState: () => usePaywallState,
|
|
84
101
|
usePlan: () => usePlan,
|
|
85
102
|
usePush: () => usePush,
|
|
@@ -726,8 +743,8 @@ function usePaywallState() {
|
|
|
726
743
|
opening: submitting,
|
|
727
744
|
availableMethods: methods,
|
|
728
745
|
monthlyEquivalent,
|
|
729
|
-
|
|
730
|
-
|
|
746
|
+
// G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.
|
|
747
|
+
dismissPix: subscription.clearPixPending,
|
|
731
748
|
refreshPlan: () => {
|
|
732
749
|
}
|
|
733
750
|
};
|
|
@@ -2942,7 +2959,7 @@ function useCheckoutForm(args) {
|
|
|
2942
2959
|
const emailConfirmError = touchedEmailConfirm || formSubmitAttempted ? validateEmailConfirm : null;
|
|
2943
2960
|
const phoneError = touchedPhone || formSubmitAttempted ? validatePhone : null;
|
|
2944
2961
|
const cpfError = touchedCpf || formSubmitAttempted ? validateCpf : null;
|
|
2945
|
-
const canSubmit = name.trim().length >= 2 && EMAIL_RE.test(email) && emailConfirm === email && PHONE_RE.test(phone) && validateCpf === null && cpf.replace(/\D/g, "").length === 11 && emailStatus !== "exists" && !submitting && (method !== "card" || card.number.length >= 12 && card.ccv.length >= 3 && card.expiryMonth.length >= 1 && card.expiryYear.length >= 2 && card.holderName.length >= 1);
|
|
2962
|
+
const canSubmit = name.trim().length >= 2 && EMAIL_RE.test(email) && (emailConfirm === "" || emailConfirm === email) && (phone === "" || PHONE_RE.test(phone)) && validateCpf === null && cpf.replace(/\D/g, "").length === 11 && emailStatus !== "exists" && !submitting && (method !== "card" || card.number.length >= 12 && card.ccv.length >= 3 && card.expiryMonth.length >= 1 && card.expiryYear.length >= 2 && card.holderName.length >= 1);
|
|
2946
2963
|
const submit = (0, import_react17.useCallback)(async () => {
|
|
2947
2964
|
setFormSubmitAttempted(true);
|
|
2948
2965
|
setError(null);
|
|
@@ -2957,7 +2974,7 @@ function useCheckoutForm(args) {
|
|
|
2957
2974
|
method: "card",
|
|
2958
2975
|
name: name.trim(),
|
|
2959
2976
|
email,
|
|
2960
|
-
emailConfirm,
|
|
2977
|
+
emailConfirm: emailConfirm || email,
|
|
2961
2978
|
phone,
|
|
2962
2979
|
cpf: cpf.replace(/\D/g, ""),
|
|
2963
2980
|
cycle,
|
|
@@ -2984,7 +3001,7 @@ function useCheckoutForm(args) {
|
|
|
2984
3001
|
method: "pix-auto",
|
|
2985
3002
|
name: name.trim(),
|
|
2986
3003
|
email,
|
|
2987
|
-
emailConfirm,
|
|
3004
|
+
emailConfirm: emailConfirm || email,
|
|
2988
3005
|
phone,
|
|
2989
3006
|
cpf: cpf.replace(/\D/g, ""),
|
|
2990
3007
|
cycle
|
|
@@ -3073,13 +3090,49 @@ function readIntent() {
|
|
|
3073
3090
|
function formatBrl(cents) {
|
|
3074
3091
|
return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(cents / 100);
|
|
3075
3092
|
}
|
|
3093
|
+
function formatCardNumber(v) {
|
|
3094
|
+
const digits = v.replace(/\D/g, "").slice(0, 16);
|
|
3095
|
+
return digits.replace(/(.{4})/g, "$1 ").trim();
|
|
3096
|
+
}
|
|
3097
|
+
function formatExpiryMmAa(v) {
|
|
3098
|
+
const d = v.replace(/\D/g, "").slice(0, 4);
|
|
3099
|
+
if (d.length < 3) return d;
|
|
3100
|
+
return d.slice(0, 2) + "/" + d.slice(2);
|
|
3101
|
+
}
|
|
3102
|
+
function parseExpiryMmAa(v) {
|
|
3103
|
+
const d = v.replace(/\D/g, "");
|
|
3104
|
+
return { month: d.slice(0, 2), year: d.slice(2, 4) };
|
|
3105
|
+
}
|
|
3106
|
+
function formatCpf(v) {
|
|
3107
|
+
const d = v.replace(/\D/g, "").slice(0, 11);
|
|
3108
|
+
if (d.length <= 3) return d;
|
|
3109
|
+
if (d.length <= 6) return d.slice(0, 3) + "." + d.slice(3);
|
|
3110
|
+
if (d.length <= 9) return d.slice(0, 3) + "." + d.slice(3, 6) + "." + d.slice(6);
|
|
3111
|
+
return d.slice(0, 3) + "." + d.slice(3, 6) + "." + d.slice(6, 9) + "-" + d.slice(9);
|
|
3112
|
+
}
|
|
3113
|
+
function detectCardBrand(num) {
|
|
3114
|
+
const n = num.replace(/\s/g, "");
|
|
3115
|
+
if (/^4/.test(n)) return "VISA";
|
|
3116
|
+
if (/^(5[1-5]|2[2-7])/.test(n)) return "MASTER";
|
|
3117
|
+
if (/^3[47]/.test(n)) return "AMEX";
|
|
3118
|
+
if (/^(4011|4312|4389|4514|6011|6362|6363)/.test(n)) return "ELO";
|
|
3119
|
+
if (/^(606282|3841)/.test(n)) return "HIPER";
|
|
3120
|
+
return "";
|
|
3121
|
+
}
|
|
3076
3122
|
function CheckoutPageDefault() {
|
|
3077
3123
|
const navigate = (0, import_react_router_dom3.useNavigate)();
|
|
3078
3124
|
const plan = usePlan();
|
|
3079
3125
|
const intent = (0, import_react18.useMemo)(readIntent, []);
|
|
3080
3126
|
const defaultMethod = intent.method === "pix-auto" ? "pix-auto" : "card";
|
|
3081
|
-
const defaultCycle = intent.cycle === "
|
|
3127
|
+
const defaultCycle = intent.cycle === "MONTHLY" ? "MONTHLY" : "YEARLY";
|
|
3082
3128
|
const form = useCheckoutForm({ defaultMethod, defaultCycle });
|
|
3129
|
+
const [expiryMmAa, setExpiryMmAa] = (0, import_react18.useState)("");
|
|
3130
|
+
(0, import_react18.useEffect)(() => {
|
|
3131
|
+
const { month, year } = parseExpiryMmAa(expiryMmAa);
|
|
3132
|
+
if (month !== form.card.expiryMonth || year !== form.card.expiryYear) {
|
|
3133
|
+
form.setCard({ expiryMonth: month, expiryYear: year });
|
|
3134
|
+
}
|
|
3135
|
+
}, [expiryMmAa]);
|
|
3083
3136
|
(0, import_react18.useEffect)(() => {
|
|
3084
3137
|
if (form.emailTaken && form.loginUrl) {
|
|
3085
3138
|
const t = setTimeout(() => navigate(form.loginUrl), 1200);
|
|
@@ -3091,21 +3144,30 @@ function CheckoutPageDefault() {
|
|
|
3091
3144
|
yearlyPriceCents: plan.data.yearlyPriceCents,
|
|
3092
3145
|
trialDays: plan.data.trialDays
|
|
3093
3146
|
} : null;
|
|
3147
|
+
const annual = form.cycle === "YEARLY";
|
|
3094
3148
|
const cyclePrice = (0, import_react18.useMemo)(() => {
|
|
3095
3149
|
if (!planInfo) return null;
|
|
3096
|
-
return
|
|
3097
|
-
}, [planInfo,
|
|
3098
|
-
const
|
|
3099
|
-
if (
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
return cyclePrice
|
|
3108
|
-
}, [form.method,
|
|
3150
|
+
return annual ? planInfo.yearlyPriceCents ?? planInfo.priceCents * 12 : planInfo.priceCents;
|
|
3151
|
+
}, [planInfo, annual]);
|
|
3152
|
+
const monthlyText = (0, import_react18.useMemo)(() => {
|
|
3153
|
+
if (!planInfo) return "";
|
|
3154
|
+
const monthly = annual && planInfo.yearlyPriceCents ? Math.round(planInfo.yearlyPriceCents / 12) : planInfo.priceCents;
|
|
3155
|
+
return formatBrl(monthly);
|
|
3156
|
+
}, [planInfo, annual]);
|
|
3157
|
+
const todayCents = (0, import_react18.useMemo)(() => {
|
|
3158
|
+
if (form.method === "pix-auto") return cyclePrice ?? 0;
|
|
3159
|
+
const trialDays2 = planInfo?.trialDays ?? 0;
|
|
3160
|
+
if (trialDays2 > 0) return 0;
|
|
3161
|
+
return cyclePrice ?? 0;
|
|
3162
|
+
}, [form.method, cyclePrice, planInfo]);
|
|
3163
|
+
const todayAmount = formatBrl(todayCents);
|
|
3164
|
+
const cyclePriceText = cyclePrice !== null ? formatBrl(cyclePrice) : "";
|
|
3165
|
+
const annualSavingsCents = (0, import_react18.useMemo)(() => {
|
|
3166
|
+
if (!planInfo || !planInfo.yearlyPriceCents) return 0;
|
|
3167
|
+
return planInfo.priceCents * 12 - planInfo.yearlyPriceCents;
|
|
3168
|
+
}, [planInfo]);
|
|
3169
|
+
const trialDays = planInfo?.trialDays ?? 7;
|
|
3170
|
+
const cardBrand = detectCardBrand(form.card.number);
|
|
3109
3171
|
async function onSubmit(e) {
|
|
3110
3172
|
e.preventDefault();
|
|
3111
3173
|
const result = await form.submit();
|
|
@@ -3128,201 +3190,367 @@ function CheckoutPageDefault() {
|
|
|
3128
3190
|
}
|
|
3129
3191
|
navigate(result.redirect.replace(/^.*\/app\/[^/]+/, "") || "/");
|
|
3130
3192
|
}
|
|
3131
|
-
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 flex flex-col bg-background min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("form", { onSubmit, className: "flex-1 overflow-y-auto
|
|
3132
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("
|
|
3133
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h1", { className: "font-display text-2xl text-foreground", children: "Finalizar assinatura" }),
|
|
3134
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm text-muted-foreground", children: "Preencha seus dados pra liberar o app. Voc\xEA j\xE1 entra com acesso na hora." })
|
|
3135
|
-
] }),
|
|
3136
|
-
form.emailTaken ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { role: "alert", className: "rounded-xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20", children: [
|
|
3193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 flex flex-col bg-background min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("form", { onSubmit, className: "flex-1 overflow-y-auto", children: [
|
|
3194
|
+
form.emailTaken ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "px-5 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { role: "alert", className: "rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20", children: [
|
|
3137
3195
|
"Esse e-mail j\xE1 tem conta nesse app.",
|
|
3138
3196
|
" ",
|
|
3139
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: form.loginUrl ?? "/signin", className: "underline font-
|
|
3140
|
-
] }) : null,
|
|
3141
|
-
form.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "alert", className: "rounded-
|
|
3142
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("
|
|
3143
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: form.loginUrl ?? "/signin", className: "underline font-semibold", children: "Entrar agora" })
|
|
3198
|
+
] }) }) : null,
|
|
3199
|
+
form.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "px-5 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "alert", className: "rounded-2xl bg-destructive/10 p-4 text-sm text-destructive border border-destructive/20", children: form.error.message || "N\xE3o foi poss\xEDvel concluir o pagamento. Tente novamente." }) }) : null,
|
|
3200
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "px-5 pt-4", children: form.method === "card" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "rounded-2xl bg-card border-[1.5px] border-foreground p-3.5", children: [
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
3202
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ShieldIcon, { className: "w-4 h-4" }),
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-bold", children: "Voc\xEA N\xC3O ser\xE1 cobrada hoje" })
|
|
3204
|
+
] }),
|
|
3205
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between items-baseline text-sm text-muted-foreground", children: [
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "R$ 0,00 agora" }),
|
|
3207
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "opacity-50", children: "\xB7" }),
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { children: [
|
|
3209
|
+
monthlyText,
|
|
3210
|
+
"/m\xEAs ap\xF3s ",
|
|
3211
|
+
trialDays,
|
|
3212
|
+
" dias"
|
|
3213
|
+
] })
|
|
3214
|
+
] }),
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "mt-2.5 text-[11px] text-muted-foreground flex items-center gap-1.5", children: [
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BellIcon, { className: "w-2.5 h-2.5" }),
|
|
3217
|
+
"Avisamos por email 2 dias antes da primeira cobran\xE7a"
|
|
3218
|
+
] })
|
|
3219
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "rounded-2xl p-3.5 bg-emerald-50 border-[1.5px] border-emerald-600/60", children: [
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 mb-2 text-emerald-900", children: [
|
|
3221
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ShieldIcon, { className: "w-4 h-4" }),
|
|
3222
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-sm font-bold", children: [
|
|
3223
|
+
"Garantia incondicional de ",
|
|
3224
|
+
trialDays,
|
|
3225
|
+
" dias"
|
|
3226
|
+
] })
|
|
3227
|
+
] }),
|
|
3228
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-sm text-emerald-900 leading-snug", children: [
|
|
3229
|
+
"Voc\xEA paga ",
|
|
3230
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("b", { children: todayAmount }),
|
|
3231
|
+
" agora via Pix.",
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("br", {}),
|
|
3233
|
+
"N\xE3o gostou em ",
|
|
3234
|
+
trialDays,
|
|
3235
|
+
" dias? Devolvemos ",
|
|
3236
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("b", { children: "100%" }),
|
|
3237
|
+
" sem perguntas \u2014 direto pelo app."
|
|
3238
|
+
] })
|
|
3239
|
+
] }) }),
|
|
3240
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "px-5 pt-5", children: [
|
|
3241
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "font-display text-2xl mb-3.5 leading-tight text-foreground", children: "Quase l\xE1." }),
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "Email" }),
|
|
3155
3243
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3156
|
-
|
|
3244
|
+
FieldInput,
|
|
3157
3245
|
{
|
|
3158
|
-
label: "E-mail",
|
|
3159
3246
|
type: "email",
|
|
3160
|
-
|
|
3161
|
-
onChange: form.setEmail,
|
|
3162
|
-
onBlur: form.markEmailTouched,
|
|
3163
|
-
error: form.emailError,
|
|
3247
|
+
inputMode: "email",
|
|
3164
3248
|
autoComplete: "email",
|
|
3165
3249
|
autoCapitalize: "none",
|
|
3166
3250
|
autoCorrect: "off",
|
|
3167
3251
|
spellCheck: false,
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
label: "Confirme o e-mail",
|
|
3175
|
-
type: "email",
|
|
3176
|
-
value: form.emailConfirm,
|
|
3177
|
-
onChange: form.setEmailConfirm,
|
|
3178
|
-
onBlur: form.markEmailConfirmTouched,
|
|
3179
|
-
error: form.emailConfirmError,
|
|
3180
|
-
autoComplete: "email",
|
|
3181
|
-
autoCapitalize: "none",
|
|
3182
|
-
autoCorrect: "off",
|
|
3183
|
-
spellCheck: false
|
|
3252
|
+
placeholder: "seu@email.com",
|
|
3253
|
+
value: form.email,
|
|
3254
|
+
onChange: form.setEmail,
|
|
3255
|
+
onBlur: form.markEmailTouched,
|
|
3256
|
+
error: form.emailError,
|
|
3257
|
+
valid: form.emailStatus === "available"
|
|
3184
3258
|
}
|
|
3185
3259
|
),
|
|
3260
|
+
!form.emailError && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldHint, { children: form.emailStatus === "checking" ? "Verificando\u2026" : form.emailStatus === "available" ? "\u2713 Dispon\xEDvel" : "Voc\xEA vai usar este email para entrar no app" }),
|
|
3261
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-3" }),
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "Nome completo" }),
|
|
3186
3263
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3187
|
-
|
|
3264
|
+
FieldInput,
|
|
3188
3265
|
{
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3266
|
+
type: "text",
|
|
3267
|
+
autoComplete: "name",
|
|
3268
|
+
placeholder: "como est\xE1 no documento",
|
|
3269
|
+
value: form.name,
|
|
3270
|
+
onChange: form.setName,
|
|
3271
|
+
onBlur: form.markNameTouched,
|
|
3272
|
+
error: form.nameError,
|
|
3273
|
+
valid: !!form.name && !form.nameError
|
|
3197
3274
|
}
|
|
3198
3275
|
),
|
|
3276
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-3" }),
|
|
3277
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "CPF" }),
|
|
3199
3278
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3200
|
-
|
|
3279
|
+
FieldInput,
|
|
3201
3280
|
{
|
|
3202
|
-
label: "CPF",
|
|
3203
3281
|
type: "text",
|
|
3204
3282
|
inputMode: "numeric",
|
|
3283
|
+
placeholder: "000.000.000-00",
|
|
3205
3284
|
value: form.cpf,
|
|
3206
|
-
onChange: form.setCpf,
|
|
3285
|
+
onChange: (v) => form.setCpf(formatCpf(v)),
|
|
3207
3286
|
onBlur: form.markCpfTouched,
|
|
3208
3287
|
error: form.cpfError,
|
|
3209
|
-
|
|
3210
|
-
placeholder: "000.000.000-00"
|
|
3288
|
+
valid: !!form.cpf && !form.cpfError
|
|
3211
3289
|
}
|
|
3212
3290
|
)
|
|
3213
3291
|
] }),
|
|
3214
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "
|
|
3215
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3216
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "
|
|
3217
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.method === "card", onClick: () => form.setMethod("card"), children: "Cart\xE3o" }),
|
|
3218
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.method === "pix-auto", onClick: () => form.setMethod("pix-auto"), children: "PIX" })
|
|
3219
|
-
] }),
|
|
3220
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-2", role: "tablist", children: [
|
|
3221
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.cycle === "MONTHLY", onClick: () => form.setCycle("MONTHLY"), children: "Mensal" }),
|
|
3222
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.cycle === "YEARLY", onClick: () => form.setCycle("YEARLY"), children: "Anual" })
|
|
3223
|
-
] }),
|
|
3224
|
-
form.method === "card" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-3 rounded-xl border border-border p-4", children: [
|
|
3292
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "px-5 pt-5", children: [
|
|
3293
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "Forma de pagamento" }),
|
|
3294
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { role: "tablist", className: "flex gap-1.5 bg-muted p-1 rounded-xl", children: [
|
|
3225
3295
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3226
|
-
|
|
3296
|
+
TabButton,
|
|
3227
3297
|
{
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3298
|
+
active: form.method === "card",
|
|
3299
|
+
onClick: () => form.setMethod("card"),
|
|
3300
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CardIcon, { className: "w-3.5 h-3.5" }),
|
|
3301
|
+
label: "Cart\xE3o",
|
|
3302
|
+
subtitle: trialDays > 0 ? `${trialDays} dias gr\xE1tis` : "pague hoje",
|
|
3303
|
+
subtitleActiveClass: "text-emerald-700"
|
|
3232
3304
|
}
|
|
3233
3305
|
),
|
|
3234
3306
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3235
|
-
|
|
3307
|
+
TabButton,
|
|
3236
3308
|
{
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3309
|
+
active: form.method === "pix-auto",
|
|
3310
|
+
onClick: () => form.setMethod("pix-auto"),
|
|
3311
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PixIcon, { className: "w-3.5 h-3.5" }),
|
|
3312
|
+
label: "Pix",
|
|
3313
|
+
subtitle: `pague hoje \xB7 garantia ${trialDays}d`,
|
|
3314
|
+
subtitleActiveClass: "text-foreground/70"
|
|
3315
|
+
}
|
|
3316
|
+
)
|
|
3317
|
+
] })
|
|
3318
|
+
] }),
|
|
3319
|
+
form.method === "card" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "px-5 pt-3.5", children: [
|
|
3320
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "N\xFAmero do cart\xE3o" }),
|
|
3321
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "relative", children: [
|
|
3322
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3323
|
+
FieldInput,
|
|
3324
|
+
{
|
|
3325
|
+
type: "text",
|
|
3241
3326
|
inputMode: "numeric",
|
|
3242
|
-
|
|
3327
|
+
autoComplete: "cc-number",
|
|
3328
|
+
placeholder: "0000 0000 0000 0000",
|
|
3329
|
+
value: form.card.number,
|
|
3330
|
+
onChange: (v) => form.setCard({ number: formatCardNumber(v) }),
|
|
3331
|
+
style: cardBrand ? { paddingRight: "4.5rem" } : void 0
|
|
3243
3332
|
}
|
|
3244
3333
|
),
|
|
3245
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.
|
|
3334
|
+
cardBrand && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-[10px] font-bold tracking-wide px-1.5 py-0.5 rounded bg-muted text-muted-foreground", children: cardBrand })
|
|
3335
|
+
] }),
|
|
3336
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-3" }),
|
|
3337
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex gap-2.5", children: [
|
|
3338
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex-1", children: [
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "Validade" }),
|
|
3246
3340
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3247
|
-
|
|
3341
|
+
FieldInput,
|
|
3248
3342
|
{
|
|
3249
|
-
|
|
3250
|
-
value: form.card.expiryMonth,
|
|
3251
|
-
onChange: (v) => form.setCard({ expiryMonth: v }),
|
|
3252
|
-
autoComplete: "cc-exp-month",
|
|
3343
|
+
type: "text",
|
|
3253
3344
|
inputMode: "numeric",
|
|
3254
|
-
|
|
3345
|
+
autoComplete: "cc-exp",
|
|
3346
|
+
placeholder: "MM/AA",
|
|
3347
|
+
value: expiryMmAa,
|
|
3348
|
+
onChange: (v) => setExpiryMmAa(formatExpiryMmAa(v))
|
|
3255
3349
|
}
|
|
3256
|
-
)
|
|
3350
|
+
)
|
|
3351
|
+
] }),
|
|
3352
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex-1", children: [
|
|
3353
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "CVV" }),
|
|
3257
3354
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3258
|
-
|
|
3355
|
+
FieldInput,
|
|
3259
3356
|
{
|
|
3260
|
-
|
|
3261
|
-
value: form.card.expiryYear,
|
|
3262
|
-
onChange: (v) => form.setCard({ expiryYear: v }),
|
|
3263
|
-
autoComplete: "cc-exp-year",
|
|
3357
|
+
type: "text",
|
|
3264
3358
|
inputMode: "numeric",
|
|
3265
|
-
placeholder: "AA"
|
|
3266
|
-
}
|
|
3267
|
-
),
|
|
3268
|
-
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3269
|
-
FieldRow,
|
|
3270
|
-
{
|
|
3271
|
-
label: "CVV",
|
|
3272
|
-
value: form.card.ccv,
|
|
3273
|
-
onChange: (v) => form.setCard({ ccv: v }),
|
|
3274
3359
|
autoComplete: "cc-csc",
|
|
3275
|
-
|
|
3276
|
-
|
|
3360
|
+
placeholder: "3 d\xEDgitos",
|
|
3361
|
+
value: form.card.ccv,
|
|
3362
|
+
onChange: (v) => form.setCard({ ccv: v.replace(/\D/g, "").slice(0, 4) })
|
|
3277
3363
|
}
|
|
3278
3364
|
)
|
|
3279
3365
|
] })
|
|
3280
|
-
] })
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3366
|
+
] }),
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-3" }),
|
|
3368
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FieldLabel, { children: "Nome no cart\xE3o" }),
|
|
3369
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3370
|
+
FieldInput,
|
|
3371
|
+
{
|
|
3372
|
+
type: "text",
|
|
3373
|
+
autoComplete: "cc-name",
|
|
3374
|
+
placeholder: "como est\xE1 no cart\xE3o",
|
|
3375
|
+
value: form.card.holderName,
|
|
3376
|
+
onChange: (v) => form.setCard({ holderName: v })
|
|
3377
|
+
}
|
|
3378
|
+
)
|
|
3379
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("section", { className: "px-5 pt-3.5", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "rounded-2xl bg-card border border-border p-3.5 flex gap-3.5 items-center", children: [
|
|
3380
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "w-[72px] h-[72px] rounded-xl shrink-0 border-2 border-foreground relative overflow-hidden bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[22px] h-[22px] bg-background flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PixIcon, { className: "w-3.5 h-3.5 text-foreground" }) }) }),
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex-1", children: [
|
|
3382
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-xs font-bold uppercase tracking-wider text-muted-foreground", children: "pagamento em segundos" }),
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-sm text-foreground mt-1 leading-snug", children: [
|
|
3384
|
+
"Geramos seu ",
|
|
3385
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("b", { children: "QR Pix" }),
|
|
3386
|
+
" no pr\xF3ximo passo. Pague pelo app do banco e seu acesso libera ",
|
|
3387
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("b", { children: "imediatamente" }),
|
|
3388
|
+
"."
|
|
3389
|
+
] })
|
|
3390
|
+
] })
|
|
3391
|
+
] }) }),
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("section", { className: "px-5 pt-5", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "bg-muted rounded-2xl p-4", children: [
|
|
3393
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between mb-2.5", children: [
|
|
3394
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-semibold text-foreground", children: annual ? "Plano Anual" : "Plano Mensal" }),
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-[11px] text-muted-foreground", children: "Coach" })
|
|
3397
|
+
] }),
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-right", children: [
|
|
3399
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-sm font-bold text-foreground", children: [
|
|
3400
|
+
cyclePriceText,
|
|
3401
|
+
"/",
|
|
3402
|
+
annual ? "ano" : "m\xEAs"
|
|
3403
|
+
] }),
|
|
3404
|
+
annual && annualSavingsCents > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-[11px] text-emerald-700 font-semibold", children: [
|
|
3405
|
+
"economia ",
|
|
3406
|
+
formatBrl(annualSavingsCents)
|
|
3407
|
+
] })
|
|
3408
|
+
] })
|
|
3409
|
+
] }),
|
|
3410
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px bg-border my-3" }),
|
|
3411
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex justify-between items-baseline", children: [
|
|
3412
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { children: [
|
|
3413
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-bold text-foreground", children: "Voc\xEA paga hoje" }),
|
|
3414
|
+
form.method === "card" && trialDays > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-[11px] text-muted-foreground mt-0.5", children: [
|
|
3415
|
+
"cobran\xE7a inicia no dia ",
|
|
3416
|
+
trialDays
|
|
3417
|
+
] }),
|
|
3418
|
+
form.method === "pix-auto" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-[11px] text-emerald-700 mt-0.5 font-semibold", children: [
|
|
3419
|
+
"reembolso garantido at\xE9 o dia ",
|
|
3420
|
+
trialDays
|
|
3421
|
+
] })
|
|
3422
|
+
] }),
|
|
3423
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-2xl font-bold font-display tracking-tight text-foreground", children: todayAmount })
|
|
3424
|
+
] })
|
|
3425
|
+
] }) }),
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-4" }),
|
|
3427
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "sticky bottom-0 px-5 pt-3.5 pb-6 bg-gradient-to-b from-transparent to-background", children: [
|
|
3428
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3429
|
+
"button",
|
|
3430
|
+
{
|
|
3431
|
+
type: "submit",
|
|
3432
|
+
disabled: !form.canSubmit,
|
|
3433
|
+
className: "w-full rounded-full bg-primary text-primary-foreground min-h-14 px-5 text-base font-bold inline-flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg",
|
|
3434
|
+
children: form.submitting ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3435
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Spinner2, {}),
|
|
3436
|
+
" ",
|
|
3437
|
+
form.method === "pix-auto" ? "Gerando QR\u2026" : "Confirmando\u2026"
|
|
3438
|
+
] }) : form.method === "card" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LockIcon, { className: "w-3.5 h-3.5" }),
|
|
3440
|
+
" Confirmar e come\xE7ar gr\xE1tis"
|
|
3441
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3442
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PixIcon, { className: "w-3.5 h-3.5" }),
|
|
3443
|
+
" Gerar QR \xB7 pagar ",
|
|
3444
|
+
todayAmount
|
|
3445
|
+
] })
|
|
3446
|
+
}
|
|
3447
|
+
),
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "text-center mt-2.5 text-xs text-muted-foreground", children: [
|
|
3449
|
+
"Ao continuar, voc\xEA concorda com nossos ",
|
|
3450
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("u", { children: "Termos" }),
|
|
3451
|
+
". Pagamento seguro Asaas."
|
|
3452
|
+
] }),
|
|
3453
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "mt-3 flex items-center justify-center gap-3.5 text-[11px] text-muted-foreground", children: [
|
|
3454
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "inline-flex items-center gap-1", children: [
|
|
3455
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LockIcon, { className: "w-2.5 h-2.5 opacity-60" }),
|
|
3456
|
+
" SSL 256-bit"
|
|
3457
|
+
] }),
|
|
3458
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "w-px h-2.5 bg-border" }),
|
|
3459
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Pagamento via Asaas" }),
|
|
3460
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "w-px h-2.5 bg-border" }),
|
|
3461
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { children: [
|
|
3462
|
+
"Garantia ",
|
|
3463
|
+
trialDays,
|
|
3464
|
+
" dias"
|
|
3465
|
+
] })
|
|
3466
|
+
] })
|
|
3467
|
+
] })
|
|
3292
3468
|
] }) });
|
|
3293
3469
|
}
|
|
3294
|
-
function
|
|
3295
|
-
return /* @__PURE__ */ (0, import_jsx_runtime27.
|
|
3296
|
-
|
|
3470
|
+
function FieldLabel({ children }) {
|
|
3471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground mb-1.5", children });
|
|
3472
|
+
}
|
|
3473
|
+
function FieldInput(props) {
|
|
3474
|
+
const baseClass = "w-full px-4 rounded-xl bg-card text-base text-foreground outline-none border-[1.5px] transition-colors";
|
|
3475
|
+
const stateClass = props.error ? "border-destructive focus:border-destructive" : props.valid ? "border-emerald-600 focus:border-emerald-700" : "border-border focus:border-foreground";
|
|
3476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
3297
3477
|
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3298
3478
|
"input",
|
|
3299
3479
|
{
|
|
3300
3480
|
type: props.type ?? "text",
|
|
3301
|
-
|
|
3302
|
-
onChange: (e) => props.onChange(e.target.value),
|
|
3303
|
-
onBlur: props.onBlur,
|
|
3481
|
+
inputMode: props.inputMode,
|
|
3304
3482
|
autoComplete: props.autoComplete,
|
|
3305
3483
|
autoCapitalize: props.autoCapitalize,
|
|
3306
3484
|
autoCorrect: props.autoCorrect,
|
|
3307
3485
|
spellCheck: props.spellCheck,
|
|
3308
|
-
inputMode: props.inputMode,
|
|
3309
3486
|
placeholder: props.placeholder,
|
|
3310
|
-
|
|
3487
|
+
value: props.value,
|
|
3488
|
+
onChange: (e) => props.onChange(e.target.value),
|
|
3489
|
+
onBlur: props.onBlur,
|
|
3490
|
+
style: { height: "52px", ...props.style },
|
|
3491
|
+
className: `${baseClass} ${stateClass}`
|
|
3311
3492
|
}
|
|
3312
3493
|
),
|
|
3313
|
-
props.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("
|
|
3494
|
+
props.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-1.5 text-xs text-destructive font-medium", children: props.error }) : null
|
|
3314
3495
|
] });
|
|
3315
3496
|
}
|
|
3316
|
-
function
|
|
3317
|
-
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3497
|
+
function FieldHint({ children }) {
|
|
3498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-1.5 text-xs text-muted-foreground", children });
|
|
3499
|
+
}
|
|
3500
|
+
function TabButton({ active, onClick, icon, label, subtitle, subtitleActiveClass }) {
|
|
3501
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3318
3502
|
"button",
|
|
3319
3503
|
{
|
|
3320
3504
|
type: "button",
|
|
3321
3505
|
role: "tab",
|
|
3322
3506
|
"aria-selected": active,
|
|
3323
3507
|
onClick,
|
|
3324
|
-
className: `
|
|
3325
|
-
|
|
3508
|
+
className: `flex-1 flex flex-col items-center justify-center gap-0.5 py-2.5 px-1.5 rounded-lg text-sm font-semibold transition-colors ${active ? "bg-card text-foreground shadow-sm" : "bg-transparent text-muted-foreground"}`,
|
|
3509
|
+
style: { minHeight: 56 },
|
|
3510
|
+
children: [
|
|
3511
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
3512
|
+
icon,
|
|
3513
|
+
" ",
|
|
3514
|
+
label
|
|
3515
|
+
] }),
|
|
3516
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: `text-[10px] font-medium ${active ? subtitleActiveClass : "text-muted-foreground/70"}`, children: subtitle })
|
|
3517
|
+
]
|
|
3518
|
+
}
|
|
3519
|
+
);
|
|
3520
|
+
}
|
|
3521
|
+
function CardIcon({ className }) {
|
|
3522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
3523
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { x: "2.5", y: "5.5", width: "19", height: "13", rx: "2.5" }),
|
|
3524
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M2.5 10h19" })
|
|
3525
|
+
] });
|
|
3526
|
+
}
|
|
3527
|
+
function PixIcon({ className }) {
|
|
3528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("svg", { className, viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M12 2L2 12l10 10 10-10L12 2zm0 4.83L17.17 12 12 17.17 6.83 12 12 6.83z" }) });
|
|
3529
|
+
}
|
|
3530
|
+
function LockIcon({ className }) {
|
|
3531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2.5" }),
|
|
3533
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M7.5 10V7a4.5 4.5 0 119 0v3" })
|
|
3534
|
+
] });
|
|
3535
|
+
}
|
|
3536
|
+
function ShieldIcon({ className }) {
|
|
3537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
3538
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M12 2.5l8 3v6c0 5-3.5 8.5-8 10-4.5-1.5-8-5-8-10v-6l8-3z" }),
|
|
3539
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M9 12l2 2 4-4" })
|
|
3540
|
+
] });
|
|
3541
|
+
}
|
|
3542
|
+
function BellIcon({ className }) {
|
|
3543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
3544
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M6 17V11a6 6 0 1112 0v6l1.5 2H4.5L6 17z" }),
|
|
3545
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { d: "M10 21a2 2 0 004 0" })
|
|
3546
|
+
] });
|
|
3547
|
+
}
|
|
3548
|
+
function Spinner2() {
|
|
3549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3550
|
+
"span",
|
|
3551
|
+
{
|
|
3552
|
+
className: "w-4 h-4 rounded-full border-2 border-white/40 border-t-white",
|
|
3553
|
+
style: { animation: "spin 0.7s linear infinite" }
|
|
3326
3554
|
}
|
|
3327
3555
|
);
|
|
3328
3556
|
}
|
|
@@ -3959,25 +4187,42 @@ function useFeature(name) {
|
|
|
3959
4187
|
}
|
|
3960
4188
|
|
|
3961
4189
|
// src/components/paywall/Paywall.tsx
|
|
3962
|
-
var
|
|
4190
|
+
var import_react31 = require("react");
|
|
3963
4191
|
var import_sdk24 = require("@hook-sdk/sdk");
|
|
3964
4192
|
|
|
3965
|
-
// src/components/paywall/
|
|
4193
|
+
// src/components/paywall/PaywallProvider.tsx
|
|
4194
|
+
var import_react29 = require("react");
|
|
3966
4195
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
4196
|
+
var PaywallContext = (0, import_react29.createContext)(null);
|
|
4197
|
+
function PaywallProvider({ children }) {
|
|
4198
|
+
const state = usePaywallState();
|
|
4199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PaywallContext.Provider, { value: state, children });
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4202
|
+
// src/components/paywall/usePaywallContext.ts
|
|
4203
|
+
var import_react30 = require("react");
|
|
4204
|
+
function usePaywallContext() {
|
|
4205
|
+
const ctx = (0, import_react30.useContext)(PaywallContext);
|
|
4206
|
+
if (!ctx) {
|
|
4207
|
+
throw new Error("usePaywallContext must be used within <PaywallProvider>");
|
|
4208
|
+
}
|
|
4209
|
+
return ctx;
|
|
4210
|
+
}
|
|
4211
|
+
|
|
4212
|
+
// src/components/paywall/PaywallMethodTabs.tsx
|
|
4213
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3967
4214
|
function PaywallMethodTabs({
|
|
3968
|
-
methods,
|
|
3969
|
-
selected,
|
|
3970
|
-
onSelect,
|
|
3971
4215
|
labels,
|
|
3972
4216
|
className,
|
|
3973
4217
|
tabClassName,
|
|
3974
4218
|
tabActiveClassName
|
|
3975
4219
|
}) {
|
|
4220
|
+
const { methods, selectedMethod, selectMethod } = usePaywallContext();
|
|
3976
4221
|
if (methods.length < 2) return null;
|
|
3977
|
-
return /* @__PURE__ */ (0,
|
|
3978
|
-
const active = m ===
|
|
4222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
|
|
4223
|
+
const active = m === selectedMethod;
|
|
3979
4224
|
const label = labels[m] ?? m;
|
|
3980
|
-
return /* @__PURE__ */ (0,
|
|
4225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3981
4226
|
"button",
|
|
3982
4227
|
{
|
|
3983
4228
|
type: "button",
|
|
@@ -3985,7 +4230,7 @@ function PaywallMethodTabs({
|
|
|
3985
4230
|
"aria-selected": active,
|
|
3986
4231
|
"aria-controls": `paywall-tab-${m}`,
|
|
3987
4232
|
tabIndex: active ? 0 : -1,
|
|
3988
|
-
onClick: () =>
|
|
4233
|
+
onClick: () => selectMethod(m),
|
|
3989
4234
|
className: [tabClassName, active ? tabActiveClassName : ""].filter(Boolean).join(" "),
|
|
3990
4235
|
children: label
|
|
3991
4236
|
},
|
|
@@ -3995,36 +4240,51 @@ function PaywallMethodTabs({
|
|
|
3995
4240
|
}
|
|
3996
4241
|
|
|
3997
4242
|
// src/components/paywall/PaywallMethodContent.tsx
|
|
3998
|
-
var
|
|
3999
|
-
function PaywallMethodContent({
|
|
4000
|
-
|
|
4001
|
-
copy
|
|
4002
|
-
|
|
4003
|
-
className,
|
|
4004
|
-
rowClassName
|
|
4005
|
-
}) {
|
|
4006
|
-
const useCardConsumed = method === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
4007
|
-
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : method === "pix-auto" || method === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
4008
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tabpanel", id: `paywall-tab-${method}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: rowClassName, children: row }, i)) });
|
|
4243
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4244
|
+
function PaywallMethodContent({ copy, className, rowClassName }) {
|
|
4245
|
+
const { selectedMethod, hasConsumedTrial } = usePaywallContext();
|
|
4246
|
+
const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
4247
|
+
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
4248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: rowClassName, children: row }, i)) });
|
|
4009
4249
|
}
|
|
4010
4250
|
|
|
4011
4251
|
// src/components/paywall/PaywallCyclePicker.tsx
|
|
4012
|
-
var
|
|
4252
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4253
|
+
var VARIANT_CLASSES = {
|
|
4254
|
+
default: { card: "", cardSelected: "" },
|
|
4255
|
+
"premium-gold": {
|
|
4256
|
+
card: "",
|
|
4257
|
+
cardSelected: "border-2 border-yellow-400/80 ring-2 ring-yellow-400/20"
|
|
4258
|
+
},
|
|
4259
|
+
"pink-pill": {
|
|
4260
|
+
card: "rounded-2xl",
|
|
4261
|
+
cardSelected: "border-2 border-pink-500"
|
|
4262
|
+
}
|
|
4263
|
+
};
|
|
4013
4264
|
function PaywallCyclePicker({
|
|
4014
|
-
cycles,
|
|
4015
|
-
selected,
|
|
4016
|
-
onSelect,
|
|
4017
|
-
priceCentsByCycle,
|
|
4018
|
-
anchorCentsByCycle,
|
|
4019
|
-
monthlyEquivByCycle,
|
|
4020
4265
|
labels,
|
|
4021
4266
|
className,
|
|
4022
4267
|
cardClassName,
|
|
4023
4268
|
cardSelectedClassName,
|
|
4024
|
-
anchorClassName
|
|
4269
|
+
anchorClassName,
|
|
4270
|
+
variant = "default",
|
|
4271
|
+
render
|
|
4025
4272
|
}) {
|
|
4273
|
+
const ctx = usePaywallContext();
|
|
4274
|
+
const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
|
|
4275
|
+
const cycles = ["MONTHLY", "YEARLY"];
|
|
4276
|
+
if (render) {
|
|
4277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
|
|
4278
|
+
}
|
|
4026
4279
|
if (cycles.length < 2) return null;
|
|
4027
|
-
|
|
4280
|
+
const v = VARIANT_CLASSES[variant];
|
|
4281
|
+
const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(" ");
|
|
4282
|
+
const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName].filter(Boolean).join(" ");
|
|
4283
|
+
const monthlyCents = plan?.monthlyCents ?? 0;
|
|
4284
|
+
const yearlyCents = plan?.yearlyCents ?? 0;
|
|
4285
|
+
const anchorMonthly = plan?.anchorMonthlyCents ?? null;
|
|
4286
|
+
const anchorYearly = plan?.anchorYearlyCents ?? null;
|
|
4287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4028
4288
|
"div",
|
|
4029
4289
|
{
|
|
4030
4290
|
role: "radiogroup",
|
|
@@ -4034,21 +4294,25 @@ function PaywallCyclePicker({
|
|
|
4034
4294
|
const active = c === selected;
|
|
4035
4295
|
const label = c === "YEARLY" ? labels.annualLabel : labels.monthlyLabel;
|
|
4036
4296
|
const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
|
|
4037
|
-
const mainCents = c === "YEARLY" ?
|
|
4038
|
-
const anchorCents =
|
|
4039
|
-
return /* @__PURE__ */ (0,
|
|
4297
|
+
const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
|
|
4298
|
+
const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
|
|
4299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
4040
4300
|
"button",
|
|
4041
4301
|
{
|
|
4042
4302
|
type: "button",
|
|
4043
4303
|
role: "radio",
|
|
4044
4304
|
"aria-checked": active,
|
|
4045
|
-
onClick: () =>
|
|
4046
|
-
className: [
|
|
4305
|
+
onClick: () => setCycle(c),
|
|
4306
|
+
className: [
|
|
4307
|
+
"flex flex-col items-center gap-0.5",
|
|
4308
|
+
composedCardClassName,
|
|
4309
|
+
active ? composedCardSelectedClassName : ""
|
|
4310
|
+
].filter(Boolean).join(" "),
|
|
4047
4311
|
children: [
|
|
4048
|
-
/* @__PURE__ */ (0,
|
|
4049
|
-
/* @__PURE__ */ (0,
|
|
4050
|
-
/* @__PURE__ */ (0,
|
|
4051
|
-
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0,
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
|
|
4314
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
|
|
4315
|
+
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
|
|
4052
4316
|
]
|
|
4053
4317
|
},
|
|
4054
4318
|
c
|
|
@@ -4058,38 +4322,6 @@ function PaywallCyclePicker({
|
|
|
4058
4322
|
);
|
|
4059
4323
|
}
|
|
4060
4324
|
|
|
4061
|
-
// src/components/paywall/PaywallCta.tsx
|
|
4062
|
-
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4063
|
-
function PaywallCta({
|
|
4064
|
-
ctaLabel,
|
|
4065
|
-
loadingLabel,
|
|
4066
|
-
switchHint,
|
|
4067
|
-
trustLine,
|
|
4068
|
-
onClick,
|
|
4069
|
-
disabled = false,
|
|
4070
|
-
loading = false,
|
|
4071
|
-
className,
|
|
4072
|
-
buttonClassName,
|
|
4073
|
-
switchHintClassName,
|
|
4074
|
-
trustClassName
|
|
4075
|
-
}) {
|
|
4076
|
-
const label = loading && loadingLabel ? loadingLabel : ctaLabel;
|
|
4077
|
-
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className, children: [
|
|
4078
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4079
|
-
"button",
|
|
4080
|
-
{
|
|
4081
|
-
type: "button",
|
|
4082
|
-
onClick,
|
|
4083
|
-
disabled: disabled || loading,
|
|
4084
|
-
className: buttonClassName,
|
|
4085
|
-
children: label
|
|
4086
|
-
}
|
|
4087
|
-
),
|
|
4088
|
-
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
4089
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: trustClassName, children: trustLine })
|
|
4090
|
-
] });
|
|
4091
|
-
}
|
|
4092
|
-
|
|
4093
4325
|
// src/components/paywall/Paywall.tsx
|
|
4094
4326
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
4095
4327
|
var NBSP = "\xA0";
|
|
@@ -4098,22 +4330,43 @@ function Paywall({
|
|
|
4098
4330
|
themeClasses = {},
|
|
4099
4331
|
slots = {},
|
|
4100
4332
|
onBeforeCheckout
|
|
4333
|
+
}) {
|
|
4334
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4335
|
+
PaywallInner,
|
|
4336
|
+
{
|
|
4337
|
+
copy,
|
|
4338
|
+
themeClasses,
|
|
4339
|
+
slots,
|
|
4340
|
+
onBeforeCheckout
|
|
4341
|
+
}
|
|
4342
|
+
) });
|
|
4343
|
+
}
|
|
4344
|
+
function PaywallInner({
|
|
4345
|
+
copy,
|
|
4346
|
+
themeClasses = {},
|
|
4347
|
+
slots = {},
|
|
4348
|
+
onBeforeCheckout
|
|
4101
4349
|
}) {
|
|
4102
4350
|
const { track: track2 } = (0, import_sdk24.useHook)();
|
|
4103
|
-
const s =
|
|
4351
|
+
const s = usePaywallContext();
|
|
4104
4352
|
const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
|
|
4105
|
-
const monthlyEquivLabel = formatBRL(s.currentMonthlyEquivCents).replace(new RegExp(NBSP, "g"), " ");
|
|
4106
4353
|
const trialDaysCardLabel = String(s.trialDaysCard);
|
|
4107
|
-
const ctaLabel = (0,
|
|
4354
|
+
const ctaLabel = (0, import_react31.useMemo)(() => {
|
|
4108
4355
|
if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
|
|
4109
4356
|
if (s.selectedMethod === "card") {
|
|
4110
4357
|
if (s.hasConsumedTrial && copy.cardConsumedTrial) {
|
|
4111
|
-
return interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
4358
|
+
return interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
4359
|
+
price: priceLabel,
|
|
4360
|
+
days: trialDaysCardLabel
|
|
4361
|
+
});
|
|
4112
4362
|
}
|
|
4113
4363
|
if (s.trialDaysCard > 0) {
|
|
4114
4364
|
return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
|
|
4115
4365
|
}
|
|
4116
|
-
return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
4366
|
+
return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
4367
|
+
price: priceLabel,
|
|
4368
|
+
days: trialDaysCardLabel
|
|
4369
|
+
}) : `Assinar por ${priceLabel}`;
|
|
4117
4370
|
}
|
|
4118
4371
|
return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
|
|
4119
4372
|
}, [
|
|
@@ -4125,11 +4378,11 @@ function Paywall({
|
|
|
4125
4378
|
priceLabel,
|
|
4126
4379
|
trialDaysCardLabel
|
|
4127
4380
|
]);
|
|
4128
|
-
const switchHint = (0,
|
|
4381
|
+
const switchHint = (0, import_react31.useMemo)(() => {
|
|
4129
4382
|
if (s.methods.length < 2) return void 0;
|
|
4130
4383
|
return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
|
|
4131
4384
|
}, [s.methods.length, s.selectedMethod, copy]);
|
|
4132
|
-
(0,
|
|
4385
|
+
(0, import_react31.useEffect)(() => {
|
|
4133
4386
|
if (!s.initialLoadComplete) return;
|
|
4134
4387
|
track2("paywall_view", {
|
|
4135
4388
|
default_method: s.selectedMethod,
|
|
@@ -4162,21 +4415,6 @@ function Paywall({
|
|
|
4162
4415
|
slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4163
4416
|
PaywallCyclePicker,
|
|
4164
4417
|
{
|
|
4165
|
-
cycles: ["MONTHLY", "YEARLY"],
|
|
4166
|
-
selected: s.cycle,
|
|
4167
|
-
onSelect: s.selectCycle,
|
|
4168
|
-
priceCentsByCycle: {
|
|
4169
|
-
MONTHLY: priceCentsForCycle(s, "MONTHLY"),
|
|
4170
|
-
YEARLY: priceCentsForCycle(s, "YEARLY")
|
|
4171
|
-
},
|
|
4172
|
-
anchorCentsByCycle: {
|
|
4173
|
-
MONTHLY: anchorForCycle(s, "MONTHLY"),
|
|
4174
|
-
YEARLY: anchorForCycle(s, "YEARLY")
|
|
4175
|
-
},
|
|
4176
|
-
monthlyEquivByCycle: {
|
|
4177
|
-
MONTHLY: priceCentsForCycle(s, "MONTHLY"),
|
|
4178
|
-
YEARLY: Math.round(priceCentsForCycle(s, "YEARLY") / 12)
|
|
4179
|
-
},
|
|
4180
4418
|
labels: copy.cycle,
|
|
4181
4419
|
cardClassName: themeClasses.cycleCard,
|
|
4182
4420
|
cardSelectedClassName: themeClasses.cycleCardSelected,
|
|
@@ -4186,9 +4424,6 @@ function Paywall({
|
|
|
4186
4424
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4187
4425
|
PaywallMethodTabs,
|
|
4188
4426
|
{
|
|
4189
|
-
methods: s.methods,
|
|
4190
|
-
selected: s.selectedMethod,
|
|
4191
|
-
onSelect: s.selectMethod,
|
|
4192
4427
|
labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
|
|
4193
4428
|
className: themeClasses.tabs,
|
|
4194
4429
|
tabClassName: themeClasses.tab,
|
|
@@ -4198,7 +4433,6 @@ function Paywall({
|
|
|
4198
4433
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4199
4434
|
PaywallMethodContent,
|
|
4200
4435
|
{
|
|
4201
|
-
method: s.selectedMethod,
|
|
4202
4436
|
copy: {
|
|
4203
4437
|
pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),
|
|
4204
4438
|
card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),
|
|
@@ -4209,27 +4443,27 @@ function Paywall({
|
|
|
4209
4443
|
ctaTemplate: copy.cardConsumedTrial.ctaTemplate
|
|
4210
4444
|
} : void 0
|
|
4211
4445
|
},
|
|
4212
|
-
hasConsumedTrial: s.hasConsumedTrial,
|
|
4213
4446
|
className: themeClasses.tabContent,
|
|
4214
4447
|
rowClassName: themeClasses.tabContentRow
|
|
4215
4448
|
}
|
|
4216
4449
|
),
|
|
4217
4450
|
slots.beforeCtaSlot,
|
|
4218
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
}
|
|
4232
|
-
|
|
4451
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
|
|
4452
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4453
|
+
"button",
|
|
4454
|
+
{
|
|
4455
|
+
type: "button",
|
|
4456
|
+
onClick: () => {
|
|
4457
|
+
void handleCta();
|
|
4458
|
+
},
|
|
4459
|
+
disabled: s.submitting,
|
|
4460
|
+
className: ctaTheme,
|
|
4461
|
+
children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
|
|
4462
|
+
}
|
|
4463
|
+
),
|
|
4464
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
|
|
4465
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
|
|
4466
|
+
] })
|
|
4233
4467
|
] });
|
|
4234
4468
|
}
|
|
4235
4469
|
function interp(tpl, vars) {
|
|
@@ -4243,13 +4477,438 @@ function interpolateCopy(m, price, days) {
|
|
|
4243
4477
|
switchHint: m.switchHint
|
|
4244
4478
|
};
|
|
4245
4479
|
}
|
|
4246
|
-
|
|
4247
|
-
|
|
4480
|
+
|
|
4481
|
+
// src/components/paywall/PaywallCta.tsx
|
|
4482
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4483
|
+
function PaywallCta({
|
|
4484
|
+
ctaLabel,
|
|
4485
|
+
loadingLabel,
|
|
4486
|
+
switchHint,
|
|
4487
|
+
trustLine,
|
|
4488
|
+
className,
|
|
4489
|
+
buttonClassName,
|
|
4490
|
+
switchHintClassName,
|
|
4491
|
+
trustClassName
|
|
4492
|
+
}) {
|
|
4493
|
+
const { submit, submitting } = usePaywallContext();
|
|
4494
|
+
const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
|
|
4495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className, children: [
|
|
4496
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4497
|
+
"button",
|
|
4498
|
+
{
|
|
4499
|
+
type: "button",
|
|
4500
|
+
onClick: () => {
|
|
4501
|
+
void submit();
|
|
4502
|
+
},
|
|
4503
|
+
disabled: submitting,
|
|
4504
|
+
className: buttonClassName,
|
|
4505
|
+
children: label
|
|
4506
|
+
}
|
|
4507
|
+
),
|
|
4508
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
4509
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: trustClassName, children: trustLine })
|
|
4510
|
+
] });
|
|
4511
|
+
}
|
|
4512
|
+
|
|
4513
|
+
// src/components/paywall/blocks/PaywallEyebrow.tsx
|
|
4514
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
4515
|
+
var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
|
|
4516
|
+
function PaywallEyebrow({ text, className }) {
|
|
4517
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
4518
|
+
}
|
|
4519
|
+
|
|
4520
|
+
// src/components/paywall/blocks/PaywallHero.tsx
|
|
4521
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4522
|
+
var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
|
|
4523
|
+
function PaywallHero({
|
|
4524
|
+
src,
|
|
4525
|
+
alt = "",
|
|
4526
|
+
headline,
|
|
4527
|
+
aspectRatio = "16/9",
|
|
4528
|
+
gradientClassName,
|
|
4529
|
+
className,
|
|
4530
|
+
headlineClassName,
|
|
4531
|
+
imgClassName,
|
|
4532
|
+
render
|
|
4533
|
+
}) {
|
|
4534
|
+
if (render) {
|
|
4535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className, children: render({ src, headline }) });
|
|
4536
|
+
}
|
|
4537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
4538
|
+
"div",
|
|
4539
|
+
{
|
|
4540
|
+
className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
|
|
4541
|
+
style: { aspectRatio },
|
|
4542
|
+
children: [
|
|
4543
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4544
|
+
"img",
|
|
4545
|
+
{
|
|
4546
|
+
src,
|
|
4547
|
+
alt,
|
|
4548
|
+
className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
|
|
4549
|
+
}
|
|
4550
|
+
),
|
|
4551
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
|
|
4552
|
+
headline ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4553
|
+
"h1",
|
|
4554
|
+
{
|
|
4555
|
+
className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
|
|
4556
|
+
children: headline
|
|
4557
|
+
}
|
|
4558
|
+
) : null
|
|
4559
|
+
]
|
|
4560
|
+
}
|
|
4561
|
+
);
|
|
4562
|
+
}
|
|
4563
|
+
|
|
4564
|
+
// src/components/paywall/blocks/PaywallHeadline.tsx
|
|
4565
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
4566
|
+
var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
|
|
4567
|
+
function PaywallHeadline({ text, className, as = "h1" }) {
|
|
4568
|
+
const Tag = as;
|
|
4569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4572
|
+
// src/components/paywall/blocks/PaywallPriceHeadline.tsx
|
|
4573
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
4574
|
+
var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
|
|
4575
|
+
var CYCLE_LABEL = {
|
|
4576
|
+
MONTHLY: "mensal",
|
|
4577
|
+
YEARLY: "anual"
|
|
4578
|
+
};
|
|
4579
|
+
function PaywallPriceHeadline({
|
|
4580
|
+
template,
|
|
4581
|
+
className,
|
|
4582
|
+
as = "h1",
|
|
4583
|
+
render
|
|
4584
|
+
}) {
|
|
4585
|
+
const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();
|
|
4586
|
+
const yearlyCents = plan?.yearlyCents ?? null;
|
|
4587
|
+
const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));
|
|
4588
|
+
const monthlyEquiv = currentMonthlyEquivCents ?? 0;
|
|
4589
|
+
const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();
|
|
4590
|
+
const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
|
|
4591
|
+
if (render) {
|
|
4592
|
+
const RootTag2 = as;
|
|
4593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
|
|
4594
|
+
}
|
|
4595
|
+
const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
|
|
4596
|
+
const RootTag = as;
|
|
4597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag, { className: rootClasses, children: text });
|
|
4598
|
+
}
|
|
4599
|
+
|
|
4600
|
+
// src/components/paywall/blocks/PaywallCountdown.tsx
|
|
4601
|
+
var import_react32 = require("react");
|
|
4602
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
4603
|
+
var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
|
|
4604
|
+
function resolveDeadlineMs(deadline) {
|
|
4605
|
+
if (deadline instanceof Date) return deadline.getTime();
|
|
4606
|
+
if (typeof deadline === "string") return new Date(deadline).getTime();
|
|
4607
|
+
const { sessionStorageKey, durationMs } = deadline;
|
|
4608
|
+
if (typeof window === "undefined" || typeof window.sessionStorage === "undefined") {
|
|
4609
|
+
return Date.now() + durationMs;
|
|
4610
|
+
}
|
|
4611
|
+
const stored = window.sessionStorage.getItem(sessionStorageKey);
|
|
4612
|
+
const parsed = stored ? Number.parseInt(stored, 10) : NaN;
|
|
4613
|
+
const now = Date.now();
|
|
4614
|
+
if (!Number.isFinite(parsed) || parsed < now) {
|
|
4615
|
+
const target = now + durationMs;
|
|
4616
|
+
window.sessionStorage.setItem(sessionStorageKey, String(target));
|
|
4617
|
+
return target;
|
|
4618
|
+
}
|
|
4619
|
+
return parsed;
|
|
4620
|
+
}
|
|
4621
|
+
function computeRemaining(deadlineMs) {
|
|
4622
|
+
const diff = Math.max(0, deadlineMs - Date.now());
|
|
4623
|
+
const totalSeconds = Math.floor(diff / 1e3);
|
|
4624
|
+
const h = Math.floor(totalSeconds / 3600);
|
|
4625
|
+
const m = Math.floor(totalSeconds % 3600 / 60);
|
|
4626
|
+
const s = totalSeconds % 60;
|
|
4627
|
+
return { h, m, s, expired: diff === 0 };
|
|
4628
|
+
}
|
|
4629
|
+
function pad(n) {
|
|
4630
|
+
return String(n).padStart(2, "0");
|
|
4248
4631
|
}
|
|
4249
|
-
function
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4632
|
+
function PaywallCountdown({
|
|
4633
|
+
deadline,
|
|
4634
|
+
format = "h:m:s",
|
|
4635
|
+
onExpire,
|
|
4636
|
+
className,
|
|
4637
|
+
render
|
|
4638
|
+
}) {
|
|
4639
|
+
const deadlineMsRef = (0, import_react32.useRef)(null);
|
|
4640
|
+
if (deadlineMsRef.current === null) {
|
|
4641
|
+
deadlineMsRef.current = resolveDeadlineMs(deadline);
|
|
4642
|
+
}
|
|
4643
|
+
const [state, setState] = (0, import_react32.useState)(() => computeRemaining(deadlineMsRef.current));
|
|
4644
|
+
const expiredCalledRef = (0, import_react32.useRef)(false);
|
|
4645
|
+
(0, import_react32.useEffect)(() => {
|
|
4646
|
+
if (state.expired) {
|
|
4647
|
+
if (!expiredCalledRef.current) {
|
|
4648
|
+
expiredCalledRef.current = true;
|
|
4649
|
+
onExpire?.();
|
|
4650
|
+
}
|
|
4651
|
+
return;
|
|
4652
|
+
}
|
|
4653
|
+
const tick = () => {
|
|
4654
|
+
const next = computeRemaining(deadlineMsRef.current);
|
|
4655
|
+
setState(next);
|
|
4656
|
+
if (next.expired && !expiredCalledRef.current) {
|
|
4657
|
+
expiredCalledRef.current = true;
|
|
4658
|
+
onExpire?.();
|
|
4659
|
+
}
|
|
4660
|
+
};
|
|
4661
|
+
const id = setInterval(tick, 1e3);
|
|
4662
|
+
return () => clearInterval(id);
|
|
4663
|
+
}, [state.expired]);
|
|
4664
|
+
if (render) {
|
|
4665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: render(state) });
|
|
4666
|
+
}
|
|
4667
|
+
const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
|
|
4668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
|
|
4669
|
+
}
|
|
4670
|
+
|
|
4671
|
+
// src/components/paywall/blocks/PaywallFeatures.tsx
|
|
4672
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4673
|
+
function PaywallFeatures({
|
|
4674
|
+
items,
|
|
4675
|
+
IconComponent,
|
|
4676
|
+
className,
|
|
4677
|
+
itemClassName,
|
|
4678
|
+
iconClassName,
|
|
4679
|
+
render,
|
|
4680
|
+
renderItem
|
|
4681
|
+
}) {
|
|
4682
|
+
if (render) {
|
|
4683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: render({ items }) });
|
|
4684
|
+
}
|
|
4685
|
+
if (renderItem) {
|
|
4686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: renderItem(item, idx) }, idx)) });
|
|
4687
|
+
}
|
|
4688
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: itemClassName, children: [
|
|
4689
|
+
IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
|
|
4690
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: item })
|
|
4691
|
+
] }, idx)) });
|
|
4692
|
+
}
|
|
4693
|
+
|
|
4694
|
+
// src/components/paywall/blocks/PaywallFeaturesCard.tsx
|
|
4695
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
4696
|
+
var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
|
|
4697
|
+
function PaywallFeaturesCard({
|
|
4698
|
+
title,
|
|
4699
|
+
items,
|
|
4700
|
+
className,
|
|
4701
|
+
cardClassName,
|
|
4702
|
+
titleClassName,
|
|
4703
|
+
itemClassName,
|
|
4704
|
+
renderItem
|
|
4705
|
+
}) {
|
|
4706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
|
|
4707
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
|
|
4708
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("ul", { children: items.map(
|
|
4709
|
+
(item, idx) => renderItem ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("li", { className: itemClassName, children: [
|
|
4710
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
|
|
4711
|
+
" ",
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: item })
|
|
4713
|
+
] }, idx)
|
|
4714
|
+
) })
|
|
4715
|
+
] }) });
|
|
4716
|
+
}
|
|
4717
|
+
|
|
4718
|
+
// src/components/paywall/blocks/PaywallTrophyBadge.tsx
|
|
4719
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
4720
|
+
var DEFAULT_CHIP_CLASSES = "inline-flex items-center gap-1 px-3 py-1 rounded-full bg-yellow-100 text-yellow-900 text-sm font-medium";
|
|
4721
|
+
var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
|
|
4722
|
+
function PaywallTrophyBadge({
|
|
4723
|
+
text,
|
|
4724
|
+
className,
|
|
4725
|
+
iconClassName,
|
|
4726
|
+
floating = false,
|
|
4727
|
+
render
|
|
4728
|
+
}) {
|
|
4729
|
+
if (render) {
|
|
4730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className, children: render({ text }) });
|
|
4731
|
+
}
|
|
4732
|
+
const rootClasses = [
|
|
4733
|
+
DEFAULT_CHIP_CLASSES,
|
|
4734
|
+
floating ? FLOATING_CLASSES : "",
|
|
4735
|
+
className
|
|
4736
|
+
].filter(Boolean).join(" ");
|
|
4737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: rootClasses, children: [
|
|
4738
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
|
|
4739
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: text })
|
|
4740
|
+
] });
|
|
4741
|
+
}
|
|
4742
|
+
|
|
4743
|
+
// src/components/paywall/blocks/PaywallAnchorPrice.tsx
|
|
4744
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
4745
|
+
var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
|
|
4746
|
+
function PaywallAnchorPrice({
|
|
4747
|
+
className,
|
|
4748
|
+
render
|
|
4749
|
+
}) {
|
|
4750
|
+
const { anchorPriceCents, cycle } = usePaywallContext();
|
|
4751
|
+
if (anchorPriceCents === null || anchorPriceCents === void 0 || anchorPriceCents <= 0) {
|
|
4752
|
+
return null;
|
|
4753
|
+
}
|
|
4754
|
+
void cycle;
|
|
4755
|
+
const formatted = formatBRL(anchorPriceCents);
|
|
4756
|
+
const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
|
|
4757
|
+
if (render) {
|
|
4758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
|
|
4759
|
+
}
|
|
4760
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: rootClasses, children: formatted });
|
|
4761
|
+
}
|
|
4762
|
+
|
|
4763
|
+
// src/components/paywall/blocks/PaywallTestimonials.tsx
|
|
4764
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
4765
|
+
var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
|
|
4766
|
+
var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
|
|
4767
|
+
var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
|
|
4768
|
+
var DEFAULT_QUOTE = "text-sm leading-snug";
|
|
4769
|
+
var DEFAULT_NAME = "text-xs font-semibold opacity-80";
|
|
4770
|
+
var DEFAULT_STARS = "text-yellow-500 text-sm";
|
|
4771
|
+
function clampStars(n) {
|
|
4772
|
+
return Math.max(0, Math.min(5, Math.round(n)));
|
|
4773
|
+
}
|
|
4774
|
+
function PaywallTestimonials({
|
|
4775
|
+
items,
|
|
4776
|
+
className,
|
|
4777
|
+
cardClassName,
|
|
4778
|
+
avatarClassName,
|
|
4779
|
+
quoteClassName,
|
|
4780
|
+
nameClassName,
|
|
4781
|
+
starsClassName,
|
|
4782
|
+
renderItem
|
|
4783
|
+
}) {
|
|
4784
|
+
const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(" ");
|
|
4785
|
+
const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(" ");
|
|
4786
|
+
const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(" ");
|
|
4787
|
+
const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
|
|
4788
|
+
const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
|
|
4789
|
+
const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
|
|
4790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4791
|
+
if (renderItem) return renderItem(item, idx);
|
|
4792
|
+
const filled = clampStars(item.stars);
|
|
4793
|
+
const empty = 5 - filled;
|
|
4794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cardClasses, children: [
|
|
4795
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4796
|
+
item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
4797
|
+
"img",
|
|
4798
|
+
{
|
|
4799
|
+
src: item.avatar,
|
|
4800
|
+
alt: "",
|
|
4801
|
+
loading: "lazy",
|
|
4802
|
+
className: avatarClasses,
|
|
4803
|
+
"aria-hidden": "true"
|
|
4804
|
+
}
|
|
4805
|
+
) : null,
|
|
4806
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: nameClasses, children: item.name })
|
|
4807
|
+
] }),
|
|
4808
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
|
|
4809
|
+
"\u2605".repeat(filled),
|
|
4810
|
+
"\u2606".repeat(empty)
|
|
4811
|
+
] }),
|
|
4812
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: quoteClasses, children: item.quote })
|
|
4813
|
+
] }, idx);
|
|
4814
|
+
}) });
|
|
4815
|
+
}
|
|
4816
|
+
|
|
4817
|
+
// src/components/paywall/blocks/PaywallStatsRow.tsx
|
|
4818
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
4819
|
+
var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
|
|
4820
|
+
var DEFAULT_CELL = "flex flex-col items-center text-center";
|
|
4821
|
+
var DEFAULT_VALUE = "text-2xl font-bold";
|
|
4822
|
+
var DEFAULT_LABEL = "text-xs opacity-70";
|
|
4823
|
+
function PaywallStatsRow({
|
|
4824
|
+
stats,
|
|
4825
|
+
className,
|
|
4826
|
+
cellClassName,
|
|
4827
|
+
valueClassName,
|
|
4828
|
+
labelClassName,
|
|
4829
|
+
renderCell
|
|
4830
|
+
}) {
|
|
4831
|
+
const rootClasses = [DEFAULT_ROOT2, className].filter(Boolean).join(" ");
|
|
4832
|
+
const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
|
|
4833
|
+
const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
|
|
4834
|
+
const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
|
|
4835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
|
|
4836
|
+
if (renderCell) return renderCell(stat, idx);
|
|
4837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cellClasses, children: [
|
|
4838
|
+
stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
|
|
4839
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: valueClasses, children: stat.value }),
|
|
4840
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: labelClasses, children: stat.label })
|
|
4841
|
+
] }, idx);
|
|
4842
|
+
}) });
|
|
4843
|
+
}
|
|
4844
|
+
|
|
4845
|
+
// src/components/paywall/blocks/PaywallFinePrint.tsx
|
|
4846
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
4847
|
+
var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
|
|
4848
|
+
var CYCLE_LABEL2 = {
|
|
4849
|
+
MONTHLY: "mensal",
|
|
4850
|
+
YEARLY: "anual"
|
|
4851
|
+
};
|
|
4852
|
+
function PaywallFinePrint({
|
|
4853
|
+
template,
|
|
4854
|
+
className,
|
|
4855
|
+
render
|
|
4856
|
+
}) {
|
|
4857
|
+
const {
|
|
4858
|
+
currentPriceCents,
|
|
4859
|
+
cycle,
|
|
4860
|
+
trialDaysCard,
|
|
4861
|
+
trialDaysPix,
|
|
4862
|
+
selectedMethod
|
|
4863
|
+
} = usePaywallContext();
|
|
4864
|
+
const trialDays = selectedMethod === "card" ? trialDaysCard : trialDaysPix;
|
|
4865
|
+
const cycleLabel = CYCLE_LABEL2[cycle] ?? cycle.toLowerCase();
|
|
4866
|
+
const priceFormatted = formatBRL(currentPriceCents ?? 0);
|
|
4867
|
+
const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
|
|
4868
|
+
if (render) {
|
|
4869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: className || void 0, children: render({
|
|
4870
|
+
currentPriceCents: currentPriceCents ?? 0,
|
|
4871
|
+
cycle,
|
|
4872
|
+
trialDays: trialDays ?? 0,
|
|
4873
|
+
selectedMethod
|
|
4874
|
+
}) });
|
|
4875
|
+
}
|
|
4876
|
+
const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
|
|
4877
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: rootClasses, children: text });
|
|
4878
|
+
}
|
|
4879
|
+
|
|
4880
|
+
// src/components/paywall/blocks/PaywallTrustLine.tsx
|
|
4881
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
4882
|
+
var DEFAULT_ROOT3 = "flex items-center gap-3";
|
|
4883
|
+
var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
|
|
4884
|
+
function PaywallTrustLine({
|
|
4885
|
+
items,
|
|
4886
|
+
className,
|
|
4887
|
+
itemClassName,
|
|
4888
|
+
renderItem
|
|
4889
|
+
}) {
|
|
4890
|
+
const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
|
|
4891
|
+
const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
|
|
4892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4893
|
+
if (renderItem) return renderItem(item, idx);
|
|
4894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: itemClasses, children: [
|
|
4895
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { "aria-hidden": "true", children: item.icon }),
|
|
4896
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: item.text })
|
|
4897
|
+
] }, idx);
|
|
4898
|
+
}) });
|
|
4899
|
+
}
|
|
4900
|
+
|
|
4901
|
+
// src/components/paywall/blocks/PaywallStickyFooter.tsx
|
|
4902
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
4903
|
+
var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
|
|
4904
|
+
var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
|
|
4905
|
+
function PaywallStickyFooter({
|
|
4906
|
+
children,
|
|
4907
|
+
className,
|
|
4908
|
+
safeAreaInsets = true
|
|
4909
|
+
}) {
|
|
4910
|
+
const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
|
|
4911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: classes, children });
|
|
4253
4912
|
}
|
|
4254
4913
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4255
4914
|
0 && (module.exports = {
|
|
@@ -4269,10 +4928,26 @@ function anchorForCycle(s, c) {
|
|
|
4269
4928
|
OnboardingFlow,
|
|
4270
4929
|
PaymentReturnHandler,
|
|
4271
4930
|
Paywall,
|
|
4931
|
+
PaywallAnchorPrice,
|
|
4932
|
+
PaywallContext,
|
|
4933
|
+
PaywallCountdown,
|
|
4272
4934
|
PaywallCta,
|
|
4273
4935
|
PaywallCyclePicker,
|
|
4936
|
+
PaywallEyebrow,
|
|
4937
|
+
PaywallFeatures,
|
|
4938
|
+
PaywallFeaturesCard,
|
|
4939
|
+
PaywallFinePrint,
|
|
4940
|
+
PaywallHeadline,
|
|
4941
|
+
PaywallHero,
|
|
4274
4942
|
PaywallMethodContent,
|
|
4275
4943
|
PaywallMethodTabs,
|
|
4944
|
+
PaywallPriceHeadline,
|
|
4945
|
+
PaywallProvider,
|
|
4946
|
+
PaywallStatsRow,
|
|
4947
|
+
PaywallStickyFooter,
|
|
4948
|
+
PaywallTestimonials,
|
|
4949
|
+
PaywallTrophyBadge,
|
|
4950
|
+
PaywallTrustLine,
|
|
4276
4951
|
PersistenceRegistry,
|
|
4277
4952
|
PixWaitingPageDefault,
|
|
4278
4953
|
PreAuthShell,
|
|
@@ -4303,6 +4978,7 @@ function anchorForCycle(s, c) {
|
|
|
4303
4978
|
useInstallPrompt,
|
|
4304
4979
|
useLoginForm,
|
|
4305
4980
|
useOnboardingStep,
|
|
4981
|
+
usePaywallContext,
|
|
4306
4982
|
usePaywallState,
|
|
4307
4983
|
usePlan,
|
|
4308
4984
|
usePush,
|