@hook-sdk/template 0.8.0 → 0.9.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 +540 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -17
- package/dist/index.d.ts +30 -17
- package/dist/index.js +557 -97
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/AppRoot.tsx
|
|
2
2
|
import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef3, useState as useState12 } from "react";
|
|
3
|
-
import { useHook as
|
|
3
|
+
import { useHook as useHook9 } from "@hook-sdk/sdk";
|
|
4
4
|
|
|
5
5
|
// src/internal/TemplateConfigContext.tsx
|
|
6
6
|
import { createContext, useContext, useMemo } from "react";
|
|
@@ -92,53 +92,69 @@ function AuthGate({ Login, Signup, Forgot, Reset, children }) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// src/hooks/usePaywallState.ts
|
|
95
|
-
import { useCallback, useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
95
|
+
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
96
96
|
import { useHook as useHook2 } from "@hook-sdk/sdk";
|
|
97
97
|
function usePaywallState() {
|
|
98
|
-
const { subscription } = useHook2();
|
|
98
|
+
const { subscription, plan } = useHook2();
|
|
99
99
|
const [opening, setOpening] = useState2(false);
|
|
100
100
|
const [error, setError] = useState2(null);
|
|
101
101
|
const [pixPending, setPixPending] = useState2(null);
|
|
102
102
|
const status = subscription.status();
|
|
103
103
|
const daysLeftInTrial = subscription.daysLeftInTrial();
|
|
104
104
|
const initialLoadComplete = subscription.initialLoadComplete;
|
|
105
|
+
const availableMethods = useMemo2(
|
|
106
|
+
() => ["card", "pix-auto"],
|
|
107
|
+
[]
|
|
108
|
+
);
|
|
109
|
+
const priceCents = plan.data?.priceCents ?? 0;
|
|
110
|
+
const yearlyPriceCents = plan.data?.yearlyPriceCents ?? null;
|
|
111
|
+
const monthlyEquivalent = useCallback(
|
|
112
|
+
(cycle) => {
|
|
113
|
+
if (cycle === "YEARLY" && yearlyPriceCents) {
|
|
114
|
+
return Math.round(yearlyPriceCents / 12);
|
|
115
|
+
}
|
|
116
|
+
return priceCents;
|
|
117
|
+
},
|
|
118
|
+
[priceCents, yearlyPriceCents]
|
|
119
|
+
);
|
|
105
120
|
const checkout = useCallback(
|
|
106
121
|
async (args) => {
|
|
107
122
|
setOpening(true);
|
|
108
123
|
setError(null);
|
|
109
124
|
setPixPending(null);
|
|
110
|
-
const method = args.method ?? "card";
|
|
111
|
-
const cycle = args.cycle ?? "MONTHLY";
|
|
112
125
|
try {
|
|
113
|
-
if (method === "card") {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
expiresAt: null,
|
|
125
|
-
paid: false
|
|
126
|
+
if (args.method === "card") {
|
|
127
|
+
if (!args.card || !args.holderInfo) {
|
|
128
|
+
throw new Error('card and holderInfo are required when method is "card"');
|
|
129
|
+
}
|
|
130
|
+
await subscription.checkout({
|
|
131
|
+
method: "card",
|
|
132
|
+
cycle: args.cycle,
|
|
133
|
+
cpf: args.cpf,
|
|
134
|
+
card: args.card,
|
|
135
|
+
holderInfo: args.holderInfo,
|
|
136
|
+
...args.remoteIp ? { remoteIp: args.remoteIp } : {}
|
|
126
137
|
});
|
|
138
|
+
await subscription.refresh();
|
|
127
139
|
setOpening(false);
|
|
128
140
|
return;
|
|
129
141
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
paid: false
|
|
138
|
-
});
|
|
139
|
-
setOpening(false);
|
|
140
|
-
return;
|
|
142
|
+
const result = await subscription.checkout({
|
|
143
|
+
method: "pix-auto",
|
|
144
|
+
cycle: args.cycle,
|
|
145
|
+
cpf: args.cpf
|
|
146
|
+
});
|
|
147
|
+
if (result.method !== "pix-auto") {
|
|
148
|
+
throw new Error(`unexpected checkout result method: ${result.method}`);
|
|
141
149
|
}
|
|
150
|
+
setPixPending({
|
|
151
|
+
method: "pix-auto",
|
|
152
|
+
qrCodePayload: result.qrCodePayload,
|
|
153
|
+
qrCodeBase64: result.qrCodeBase64,
|
|
154
|
+
expiresAt: null,
|
|
155
|
+
paid: false
|
|
156
|
+
});
|
|
157
|
+
setOpening(false);
|
|
142
158
|
} catch (err) {
|
|
143
159
|
setError(err);
|
|
144
160
|
setOpening(false);
|
|
@@ -191,7 +207,9 @@ function usePaywallState() {
|
|
|
191
207
|
opening,
|
|
192
208
|
error,
|
|
193
209
|
pixPending,
|
|
194
|
-
dismissPix
|
|
210
|
+
dismissPix,
|
|
211
|
+
availableMethods,
|
|
212
|
+
monthlyEquivalent
|
|
195
213
|
};
|
|
196
214
|
}
|
|
197
215
|
|
|
@@ -1487,9 +1505,10 @@ function InstallGate({ children }) {
|
|
|
1487
1505
|
if (!enabled) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1488
1506
|
if (installState.isInstalled) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1489
1507
|
if (installState.variant === "desktop") {
|
|
1508
|
+
const showBanner = !installState.isDismissedSession && !installState.isDismissedPermanent;
|
|
1490
1509
|
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1491
1510
|
children,
|
|
1492
|
-
/* @__PURE__ */ jsx16(DesktopVariant, { state: installState, actions: installState })
|
|
1511
|
+
showBanner && /* @__PURE__ */ jsx16(DesktopVariant, { state: installState, actions: installState })
|
|
1493
1512
|
] });
|
|
1494
1513
|
}
|
|
1495
1514
|
if (!shouldBlock) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
@@ -1533,7 +1552,7 @@ var ErrorBoundary = class extends Component {
|
|
|
1533
1552
|
};
|
|
1534
1553
|
|
|
1535
1554
|
// src/hooks/useLoginForm.ts
|
|
1536
|
-
import { useCallback as useCallback3, useMemo as
|
|
1555
|
+
import { useCallback as useCallback3, useMemo as useMemo3, useState as useState6 } from "react";
|
|
1537
1556
|
import { useHook as useHook4 } from "@hook-sdk/sdk";
|
|
1538
1557
|
|
|
1539
1558
|
// src/errors.ts
|
|
@@ -1574,12 +1593,12 @@ function useLoginForm() {
|
|
|
1574
1593
|
const [password, setPassword] = useState6("");
|
|
1575
1594
|
const [submitting, setSubmitting] = useState6(false);
|
|
1576
1595
|
const [error, setError] = useState6(null);
|
|
1577
|
-
const emailError =
|
|
1596
|
+
const emailError = useMemo3(() => {
|
|
1578
1597
|
if (email.length === 0) return null;
|
|
1579
1598
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
1580
1599
|
return null;
|
|
1581
1600
|
}, [email]);
|
|
1582
|
-
const passwordError =
|
|
1601
|
+
const passwordError = useMemo3(() => {
|
|
1583
1602
|
if (password.length === 0) return null;
|
|
1584
1603
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
1585
1604
|
return null;
|
|
@@ -1839,7 +1858,7 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
1839
1858
|
}
|
|
1840
1859
|
|
|
1841
1860
|
// src/hooks/useSignupForm.ts
|
|
1842
|
-
import { useCallback as useCallback4, useMemo as
|
|
1861
|
+
import { useCallback as useCallback4, useMemo as useMemo4, useState as useState8 } from "react";
|
|
1843
1862
|
import { useHook as useHook5 } from "@hook-sdk/sdk";
|
|
1844
1863
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1845
1864
|
var MIN_PASSWORD2 = 8;
|
|
@@ -1850,17 +1869,17 @@ function useSignupForm() {
|
|
|
1850
1869
|
const [password, setPassword] = useState8("");
|
|
1851
1870
|
const [submitting, setSubmitting] = useState8(false);
|
|
1852
1871
|
const [error, setError] = useState8(null);
|
|
1853
|
-
const nameError =
|
|
1872
|
+
const nameError = useMemo4(() => {
|
|
1854
1873
|
if (name.length === 0) return null;
|
|
1855
1874
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
1856
1875
|
return null;
|
|
1857
1876
|
}, [name]);
|
|
1858
|
-
const emailError =
|
|
1877
|
+
const emailError = useMemo4(() => {
|
|
1859
1878
|
if (email.length === 0) return null;
|
|
1860
1879
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
1861
1880
|
return null;
|
|
1862
1881
|
}, [email]);
|
|
1863
|
-
const passwordError =
|
|
1882
|
+
const passwordError = useMemo4(() => {
|
|
1864
1883
|
if (password.length === 0) return null;
|
|
1865
1884
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
1866
1885
|
return null;
|
|
@@ -1954,7 +1973,7 @@ function DefaultSignupScreen({ onNavigate }) {
|
|
|
1954
1973
|
}
|
|
1955
1974
|
|
|
1956
1975
|
// src/hooks/useForgotForm.ts
|
|
1957
|
-
import { useCallback as useCallback5, useMemo as
|
|
1976
|
+
import { useCallback as useCallback5, useMemo as useMemo5, useState as useState9 } from "react";
|
|
1958
1977
|
import { useHook as useHook6 } from "@hook-sdk/sdk";
|
|
1959
1978
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1960
1979
|
function useForgotForm() {
|
|
@@ -1963,7 +1982,7 @@ function useForgotForm() {
|
|
|
1963
1982
|
const [submitting, setSubmitting] = useState9(false);
|
|
1964
1983
|
const [sent, setSent] = useState9(false);
|
|
1965
1984
|
const [error, setError] = useState9(null);
|
|
1966
|
-
const emailError =
|
|
1985
|
+
const emailError = useMemo5(() => {
|
|
1967
1986
|
if (email.length === 0) return null;
|
|
1968
1987
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
1969
1988
|
return null;
|
|
@@ -2028,7 +2047,7 @@ function DefaultForgotScreen({ onNavigate }) {
|
|
|
2028
2047
|
}
|
|
2029
2048
|
|
|
2030
2049
|
// src/hooks/useResetForm.ts
|
|
2031
|
-
import { useCallback as useCallback6, useEffect as useEffect7, useMemo as
|
|
2050
|
+
import { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo6, useState as useState10 } from "react";
|
|
2032
2051
|
import { useHook as useHook7 } from "@hook-sdk/sdk";
|
|
2033
2052
|
var MIN_PASSWORD3 = 12;
|
|
2034
2053
|
function useResetForm() {
|
|
@@ -2045,12 +2064,12 @@ function useResetForm() {
|
|
|
2045
2064
|
const t = params.get("token");
|
|
2046
2065
|
setToken(t && t.length > 0 ? t : null);
|
|
2047
2066
|
}, []);
|
|
2048
|
-
const passwordError =
|
|
2067
|
+
const passwordError = useMemo6(() => {
|
|
2049
2068
|
if (password.length === 0) return null;
|
|
2050
2069
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
2051
2070
|
return null;
|
|
2052
2071
|
}, [password]);
|
|
2053
|
-
const confirmError =
|
|
2072
|
+
const confirmError = useMemo6(() => {
|
|
2054
2073
|
if (confirm.length === 0) return null;
|
|
2055
2074
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
2056
2075
|
return null;
|
|
@@ -2134,34 +2153,430 @@ function DefaultResetScreen({ onNavigate }) {
|
|
|
2134
2153
|
}
|
|
2135
2154
|
|
|
2136
2155
|
// src/defaults/DefaultPaywall.tsx
|
|
2137
|
-
import { useState as useState11 } from "react";
|
|
2138
|
-
|
|
2156
|
+
import { useMemo as useMemo7, useState as useState11 } from "react";
|
|
2157
|
+
|
|
2158
|
+
// src/hooks/usePlan.ts
|
|
2159
|
+
import { useHook as useHook8 } from "@hook-sdk/sdk";
|
|
2160
|
+
function usePlan() {
|
|
2161
|
+
const { plan } = useHook8();
|
|
2162
|
+
return plan;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
// src/utils/price.ts
|
|
2166
|
+
function formatBRL(cents) {
|
|
2167
|
+
if (cents === null || cents === void 0) return "";
|
|
2168
|
+
const reais = cents / 100;
|
|
2169
|
+
return new Intl.NumberFormat("pt-BR", {
|
|
2170
|
+
style: "currency",
|
|
2171
|
+
currency: "BRL"
|
|
2172
|
+
}).format(reais);
|
|
2173
|
+
}
|
|
2174
|
+
function monthlyFromYearly(yearlyCents) {
|
|
2175
|
+
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2176
|
+
return Math.round(yearlyCents / 12);
|
|
2177
|
+
}
|
|
2178
|
+
function dailyFromYearly(yearlyCents) {
|
|
2179
|
+
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2180
|
+
return Math.round(yearlyCents / 365);
|
|
2181
|
+
}
|
|
2182
|
+
function computeAnchorCents(baseCents, multiplier) {
|
|
2183
|
+
if (multiplier === null || multiplier === void 0) return null;
|
|
2184
|
+
if (!Number.isFinite(multiplier)) return null;
|
|
2185
|
+
if (multiplier <= 1) return null;
|
|
2186
|
+
return Math.round(baseCents * multiplier);
|
|
2187
|
+
}
|
|
2188
|
+
function discountPercent(anchorCents, realCents) {
|
|
2189
|
+
if (anchorCents <= realCents) return 0;
|
|
2190
|
+
return Math.floor((anchorCents - realCents) / anchorCents * 100);
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
// src/defaults/DefaultPaywall.tsx
|
|
2194
|
+
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2139
2195
|
function DefaultPaywall() {
|
|
2140
2196
|
const config = useTemplateConfig();
|
|
2141
|
-
const
|
|
2197
|
+
const plan = usePlan();
|
|
2198
|
+
const {
|
|
2199
|
+
checkout,
|
|
2200
|
+
opening,
|
|
2201
|
+
error,
|
|
2202
|
+
availableMethods,
|
|
2203
|
+
monthlyEquivalent,
|
|
2204
|
+
pixPending,
|
|
2205
|
+
dismissPix
|
|
2206
|
+
} = usePaywallState();
|
|
2142
2207
|
const p = config.subscription.paywall_config;
|
|
2208
|
+
const paywallCfg = plan.data?.paywallConfig ?? {};
|
|
2209
|
+
const anchorMultiplier = paywallCfg.anchorMultiplier ?? p.anchorMultiplier;
|
|
2210
|
+
const anchorPriceCents = paywallCfg.anchorPriceCents ?? p.anchorPriceCents;
|
|
2211
|
+
const [cycle, setCycle] = useState11("MONTHLY");
|
|
2212
|
+
const [method, setMethod] = useState11("card");
|
|
2143
2213
|
const [cpf, setCpf] = useState11("");
|
|
2214
|
+
const [cardNumber, setCardNumber] = useState11("");
|
|
2215
|
+
const [cardHolderName, setCardHolderName] = useState11("");
|
|
2216
|
+
const [cardExpiryMonth, setCardExpiryMonth] = useState11("");
|
|
2217
|
+
const [cardExpiryYear, setCardExpiryYear] = useState11("");
|
|
2218
|
+
const [cardCcv, setCardCcv] = useState11("");
|
|
2219
|
+
const [holderName, setHolderName] = useState11("");
|
|
2220
|
+
const [holderEmail, setHolderEmail] = useState11("");
|
|
2221
|
+
const [holderPostalCode, setHolderPostalCode] = useState11("");
|
|
2222
|
+
const [holderAddressNumber, setHolderAddressNumber] = useState11("");
|
|
2223
|
+
const [holderPhone, setHolderPhone] = useState11("");
|
|
2224
|
+
const trialDays = plan.data?.trialDays ?? 0;
|
|
2225
|
+
const monthlyCents = plan.data?.priceCents ?? 0;
|
|
2226
|
+
const yearlyCents = plan.data?.yearlyPriceCents ?? null;
|
|
2227
|
+
const activeCents = cycle === "YEARLY" && yearlyCents ? monthlyEquivalent("YEARLY") : monthlyCents;
|
|
2228
|
+
const pct = useMemo7(() => {
|
|
2229
|
+
if (!yearlyCents || !monthlyCents) return 0;
|
|
2230
|
+
const derived = Math.round((1 - yearlyCents / 12 / monthlyCents) * 100);
|
|
2231
|
+
return Math.max(0, derived);
|
|
2232
|
+
}, [monthlyCents, yearlyCents]);
|
|
2233
|
+
const anchorBaseCents = cycle === "YEARLY" && yearlyCents ? monthlyFromYearly(yearlyCents) : monthlyCents;
|
|
2234
|
+
const anchorCents = computeAnchorCents(anchorBaseCents, anchorMultiplier) ?? (anchorPriceCents && anchorPriceCents > anchorBaseCents ? anchorPriceCents : null);
|
|
2235
|
+
const anchorDiscount = anchorCents ? discountPercent(anchorCents, activeCents) : 0;
|
|
2144
2236
|
const cpfDigits = cpf.replace(/\D/g, "");
|
|
2145
|
-
const
|
|
2146
|
-
|
|
2237
|
+
const cardFieldsFilled = cardNumber.replace(/\s/g, "").length >= 13 && cardHolderName.trim().length > 0 && cardExpiryMonth.length === 2 && cardExpiryYear.length >= 2 && cardCcv.length >= 3 && holderName.trim().length > 0 && /.+@.+\..+/.test(holderEmail) && holderPostalCode.replace(/\D/g, "").length === 8 && holderAddressNumber.trim().length > 0;
|
|
2238
|
+
const canCheckout = cpfDigits.length === 11 && !opening && (method === "pix-auto" || cardFieldsFilled);
|
|
2239
|
+
const ctaLabel = useMemo7(() => {
|
|
2240
|
+
if (opening) return "Abrindo\u2026";
|
|
2241
|
+
if (trialDays > 0) return `Comece trial de ${trialDays} dias gr\xE1tis`;
|
|
2242
|
+
return p.cta ?? "Assinar agora";
|
|
2243
|
+
}, [opening, trialDays, p.cta]);
|
|
2244
|
+
const footer = useMemo7(() => {
|
|
2245
|
+
if (trialDays > 0) {
|
|
2246
|
+
return `Sem cobran\xE7a agora. Cobran\xE7a autom\xE1tica em ${trialDays} dias. Cancele quando quiser.`;
|
|
2247
|
+
}
|
|
2248
|
+
return "Cobran\xE7a imediata. Cancele quando quiser.";
|
|
2249
|
+
}, [trialDays]);
|
|
2250
|
+
const yearSuffix = cardExpiryYear.length === 2 ? `20${cardExpiryYear}` : cardExpiryYear;
|
|
2251
|
+
const phoneDigits = holderPhone.replace(/\D/g, "");
|
|
2252
|
+
const postalDigits = holderPostalCode.replace(/\D/g, "");
|
|
2253
|
+
const submit = () => {
|
|
2254
|
+
if (method === "card") {
|
|
2255
|
+
void checkout({
|
|
2256
|
+
cpf: cpfDigits,
|
|
2257
|
+
cycle,
|
|
2258
|
+
method: "card",
|
|
2259
|
+
card: {
|
|
2260
|
+
number: cardNumber.replace(/\s/g, ""),
|
|
2261
|
+
holderName: cardHolderName.trim(),
|
|
2262
|
+
expiryMonth: cardExpiryMonth,
|
|
2263
|
+
expiryYear: yearSuffix,
|
|
2264
|
+
ccv: cardCcv
|
|
2265
|
+
},
|
|
2266
|
+
holderInfo: {
|
|
2267
|
+
name: holderName.trim(),
|
|
2268
|
+
email: holderEmail.trim(),
|
|
2269
|
+
cpfCnpj: cpfDigits,
|
|
2270
|
+
postalCode: postalDigits,
|
|
2271
|
+
addressNumber: holderAddressNumber.trim(),
|
|
2272
|
+
...phoneDigits ? { phone: phoneDigits } : {}
|
|
2273
|
+
}
|
|
2274
|
+
});
|
|
2275
|
+
return;
|
|
2276
|
+
}
|
|
2277
|
+
void checkout({ cpf: cpfDigits, cycle, method: "pix-auto" });
|
|
2278
|
+
};
|
|
2279
|
+
const inputStyle = {
|
|
2280
|
+
width: "100%",
|
|
2281
|
+
padding: 10,
|
|
2282
|
+
fontSize: 14,
|
|
2283
|
+
borderRadius: 8,
|
|
2284
|
+
border: "1px solid #ccc",
|
|
2285
|
+
boxSizing: "border-box"
|
|
2286
|
+
};
|
|
2287
|
+
const labelStyle = { display: "block", fontSize: 13, opacity: 0.75, marginBottom: 4 };
|
|
2288
|
+
const fieldGroup = { marginBottom: 10, textAlign: "left" };
|
|
2289
|
+
return /* @__PURE__ */ jsxs18("main", { style: { padding: 24, maxWidth: 480, margin: "0 auto", textAlign: "center" }, children: [
|
|
2147
2290
|
/* @__PURE__ */ jsx24("h1", { style: { marginBottom: 8 }, children: p.title }),
|
|
2148
2291
|
p.subtitle && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
|
|
2149
|
-
/* @__PURE__ */
|
|
2292
|
+
/* @__PURE__ */ jsxs18(
|
|
2293
|
+
"div",
|
|
2294
|
+
{
|
|
2295
|
+
role: "group",
|
|
2296
|
+
"aria-label": "Per\xEDodo de cobran\xE7a",
|
|
2297
|
+
style: { display: "flex", gap: 8, marginBottom: 16 },
|
|
2298
|
+
children: [
|
|
2299
|
+
/* @__PURE__ */ jsx24(
|
|
2300
|
+
"button",
|
|
2301
|
+
{
|
|
2302
|
+
type: "button",
|
|
2303
|
+
"aria-pressed": cycle === "MONTHLY",
|
|
2304
|
+
onClick: () => setCycle("MONTHLY"),
|
|
2305
|
+
style: {
|
|
2306
|
+
flex: 1,
|
|
2307
|
+
padding: 12,
|
|
2308
|
+
borderRadius: 8,
|
|
2309
|
+
border: cycle === "MONTHLY" ? "2px solid var(--hook-color-primary)" : "1px solid #ccc",
|
|
2310
|
+
background: cycle === "MONTHLY" ? "var(--hook-color-primary-soft, #eef)" : "white",
|
|
2311
|
+
cursor: "pointer"
|
|
2312
|
+
},
|
|
2313
|
+
children: "Mensal"
|
|
2314
|
+
}
|
|
2315
|
+
),
|
|
2316
|
+
/* @__PURE__ */ jsxs18(
|
|
2317
|
+
"button",
|
|
2318
|
+
{
|
|
2319
|
+
type: "button",
|
|
2320
|
+
"aria-pressed": cycle === "YEARLY",
|
|
2321
|
+
onClick: () => setCycle("YEARLY"),
|
|
2322
|
+
disabled: !yearlyCents,
|
|
2323
|
+
style: {
|
|
2324
|
+
flex: 1,
|
|
2325
|
+
padding: 12,
|
|
2326
|
+
borderRadius: 8,
|
|
2327
|
+
border: cycle === "YEARLY" ? "2px solid var(--hook-color-primary)" : "1px solid #ccc",
|
|
2328
|
+
background: cycle === "YEARLY" ? "var(--hook-color-primary-soft, #eef)" : "white",
|
|
2329
|
+
cursor: yearlyCents ? "pointer" : "not-allowed",
|
|
2330
|
+
opacity: yearlyCents ? 1 : 0.5
|
|
2331
|
+
},
|
|
2332
|
+
children: [
|
|
2333
|
+
"Anual",
|
|
2334
|
+
pct > 0 ? ` \u2212${pct}%` : ""
|
|
2335
|
+
]
|
|
2336
|
+
}
|
|
2337
|
+
)
|
|
2338
|
+
]
|
|
2339
|
+
}
|
|
2340
|
+
),
|
|
2341
|
+
/* @__PURE__ */ jsxs18("div", { style: { marginBottom: 8 }, children: [
|
|
2342
|
+
/* @__PURE__ */ jsxs18("div", { style: { fontSize: 32, fontWeight: 700, lineHeight: 1 }, children: [
|
|
2343
|
+
formatBRL(activeCents),
|
|
2344
|
+
/* @__PURE__ */ jsx24("span", { style: { fontSize: 16, fontWeight: 400, opacity: 0.7 }, children: "/m\xEAs" })
|
|
2345
|
+
] }),
|
|
2346
|
+
anchorCents && /* @__PURE__ */ jsxs18("div", { style: { fontSize: 14, opacity: 0.6, marginTop: 4 }, children: [
|
|
2347
|
+
/* @__PURE__ */ jsx24("span", { style: { textDecoration: "line-through" }, children: formatBRL(anchorCents) }),
|
|
2348
|
+
anchorDiscount > 0 && /* @__PURE__ */ jsxs18("span", { style: { marginLeft: 6 }, children: [
|
|
2349
|
+
"\u2212",
|
|
2350
|
+
anchorDiscount,
|
|
2351
|
+
"%"
|
|
2352
|
+
] })
|
|
2353
|
+
] }),
|
|
2354
|
+
cycle === "YEARLY" && yearlyCents && /* @__PURE__ */ jsxs18("div", { style: { fontSize: 12, opacity: 0.6, marginTop: 4 }, children: [
|
|
2355
|
+
"Cobrado ",
|
|
2356
|
+
formatBRL(yearlyCents),
|
|
2357
|
+
" por ano"
|
|
2358
|
+
] })
|
|
2359
|
+
] }),
|
|
2360
|
+
/* @__PURE__ */ jsx24("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", margin: "24px 0" }, children: p.benefits.map((b) => /* @__PURE__ */ jsxs18("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
|
|
2150
2361
|
/* @__PURE__ */ jsx24("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
|
|
2151
2362
|
/* @__PURE__ */ jsx24("span", { children: b })
|
|
2152
2363
|
] }, b)) }),
|
|
2153
|
-
/* @__PURE__ */
|
|
2154
|
-
|
|
2364
|
+
/* @__PURE__ */ jsx24("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", style: { display: "flex", gap: 8, marginBottom: 16 }, children: availableMethods.map((m) => /* @__PURE__ */ jsx24(
|
|
2365
|
+
"button",
|
|
2366
|
+
{
|
|
2367
|
+
type: "button",
|
|
2368
|
+
role: "tab",
|
|
2369
|
+
"aria-selected": method === m,
|
|
2370
|
+
onClick: () => setMethod(m),
|
|
2371
|
+
style: {
|
|
2372
|
+
flex: 1,
|
|
2373
|
+
padding: 10,
|
|
2374
|
+
borderRadius: 8,
|
|
2375
|
+
border: method === m ? "2px solid var(--hook-color-primary)" : "1px solid #ccc",
|
|
2376
|
+
background: method === m ? "var(--hook-color-primary-soft, #eef)" : "white",
|
|
2377
|
+
cursor: "pointer"
|
|
2378
|
+
},
|
|
2379
|
+
children: m === "card" ? "\u{1F4B3} Cart\xE3o" : "\u{1F4F1} Pix Autom\xE1tico"
|
|
2380
|
+
},
|
|
2381
|
+
m
|
|
2382
|
+
)) }),
|
|
2383
|
+
method === "card" && /* @__PURE__ */ jsxs18(
|
|
2384
|
+
"fieldset",
|
|
2385
|
+
{
|
|
2386
|
+
"data-testid": "paywall-card-form",
|
|
2387
|
+
style: { border: "none", padding: 0, marginBottom: 16 },
|
|
2388
|
+
children: [
|
|
2389
|
+
/* @__PURE__ */ jsx24("legend", { style: { fontSize: 13, opacity: 0.75, marginBottom: 8 }, children: "Dados do cart\xE3o" }),
|
|
2390
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2391
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-card-number", style: labelStyle, children: "N\xFAmero do cart\xE3o" }),
|
|
2392
|
+
/* @__PURE__ */ jsx24(
|
|
2393
|
+
"input",
|
|
2394
|
+
{
|
|
2395
|
+
id: "pw-card-number",
|
|
2396
|
+
"data-testid": "pw-card-number",
|
|
2397
|
+
type: "text",
|
|
2398
|
+
inputMode: "numeric",
|
|
2399
|
+
autoComplete: "cc-number",
|
|
2400
|
+
placeholder: "0000 0000 0000 0000",
|
|
2401
|
+
value: cardNumber,
|
|
2402
|
+
onChange: (e) => setCardNumber(e.target.value),
|
|
2403
|
+
style: inputStyle
|
|
2404
|
+
}
|
|
2405
|
+
)
|
|
2406
|
+
] }),
|
|
2407
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2408
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-card-holder", style: labelStyle, children: "Nome impresso no cart\xE3o" }),
|
|
2409
|
+
/* @__PURE__ */ jsx24(
|
|
2410
|
+
"input",
|
|
2411
|
+
{
|
|
2412
|
+
id: "pw-card-holder",
|
|
2413
|
+
"data-testid": "pw-card-holder",
|
|
2414
|
+
type: "text",
|
|
2415
|
+
autoComplete: "cc-name",
|
|
2416
|
+
placeholder: "NOME SOBRENOME",
|
|
2417
|
+
value: cardHolderName,
|
|
2418
|
+
onChange: (e) => setCardHolderName(e.target.value),
|
|
2419
|
+
style: inputStyle
|
|
2420
|
+
}
|
|
2421
|
+
)
|
|
2422
|
+
] }),
|
|
2423
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 8, marginBottom: 10 }, children: [
|
|
2424
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, textAlign: "left" }, children: [
|
|
2425
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-card-exp-m", style: labelStyle, children: "M\xEAs" }),
|
|
2426
|
+
/* @__PURE__ */ jsx24(
|
|
2427
|
+
"input",
|
|
2428
|
+
{
|
|
2429
|
+
id: "pw-card-exp-m",
|
|
2430
|
+
"data-testid": "pw-card-exp-m",
|
|
2431
|
+
type: "text",
|
|
2432
|
+
inputMode: "numeric",
|
|
2433
|
+
autoComplete: "cc-exp-month",
|
|
2434
|
+
placeholder: "MM",
|
|
2435
|
+
maxLength: 2,
|
|
2436
|
+
value: cardExpiryMonth,
|
|
2437
|
+
onChange: (e) => setCardExpiryMonth(e.target.value.replace(/\D/g, "")),
|
|
2438
|
+
style: inputStyle
|
|
2439
|
+
}
|
|
2440
|
+
)
|
|
2441
|
+
] }),
|
|
2442
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, textAlign: "left" }, children: [
|
|
2443
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-card-exp-y", style: labelStyle, children: "Ano" }),
|
|
2444
|
+
/* @__PURE__ */ jsx24(
|
|
2445
|
+
"input",
|
|
2446
|
+
{
|
|
2447
|
+
id: "pw-card-exp-y",
|
|
2448
|
+
"data-testid": "pw-card-exp-y",
|
|
2449
|
+
type: "text",
|
|
2450
|
+
inputMode: "numeric",
|
|
2451
|
+
autoComplete: "cc-exp-year",
|
|
2452
|
+
placeholder: "AA",
|
|
2453
|
+
maxLength: 4,
|
|
2454
|
+
value: cardExpiryYear,
|
|
2455
|
+
onChange: (e) => setCardExpiryYear(e.target.value.replace(/\D/g, "")),
|
|
2456
|
+
style: inputStyle
|
|
2457
|
+
}
|
|
2458
|
+
)
|
|
2459
|
+
] }),
|
|
2460
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, textAlign: "left" }, children: [
|
|
2461
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-card-cvv", style: labelStyle, children: "CVV" }),
|
|
2462
|
+
/* @__PURE__ */ jsx24(
|
|
2463
|
+
"input",
|
|
2464
|
+
{
|
|
2465
|
+
id: "pw-card-cvv",
|
|
2466
|
+
"data-testid": "pw-card-cvv",
|
|
2467
|
+
type: "text",
|
|
2468
|
+
inputMode: "numeric",
|
|
2469
|
+
autoComplete: "cc-csc",
|
|
2470
|
+
placeholder: "123",
|
|
2471
|
+
maxLength: 4,
|
|
2472
|
+
value: cardCcv,
|
|
2473
|
+
onChange: (e) => setCardCcv(e.target.value.replace(/\D/g, "")),
|
|
2474
|
+
style: inputStyle
|
|
2475
|
+
}
|
|
2476
|
+
)
|
|
2477
|
+
] })
|
|
2478
|
+
] }),
|
|
2479
|
+
/* @__PURE__ */ jsx24("legend", { style: { fontSize: 13, opacity: 0.75, marginBottom: 8, marginTop: 8 }, children: "Dados do titular" }),
|
|
2480
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2481
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-holder-name", style: labelStyle, children: "Nome completo" }),
|
|
2482
|
+
/* @__PURE__ */ jsx24(
|
|
2483
|
+
"input",
|
|
2484
|
+
{
|
|
2485
|
+
id: "pw-holder-name",
|
|
2486
|
+
"data-testid": "pw-holder-name",
|
|
2487
|
+
type: "text",
|
|
2488
|
+
autoComplete: "name",
|
|
2489
|
+
placeholder: "Nome Sobrenome",
|
|
2490
|
+
value: holderName,
|
|
2491
|
+
onChange: (e) => setHolderName(e.target.value),
|
|
2492
|
+
style: inputStyle
|
|
2493
|
+
}
|
|
2494
|
+
)
|
|
2495
|
+
] }),
|
|
2496
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2497
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-holder-email", style: labelStyle, children: "E-mail" }),
|
|
2498
|
+
/* @__PURE__ */ jsx24(
|
|
2499
|
+
"input",
|
|
2500
|
+
{
|
|
2501
|
+
id: "pw-holder-email",
|
|
2502
|
+
"data-testid": "pw-holder-email",
|
|
2503
|
+
type: "email",
|
|
2504
|
+
autoComplete: "email",
|
|
2505
|
+
placeholder: "voce@email.com",
|
|
2506
|
+
value: holderEmail,
|
|
2507
|
+
onChange: (e) => setHolderEmail(e.target.value),
|
|
2508
|
+
style: inputStyle
|
|
2509
|
+
}
|
|
2510
|
+
)
|
|
2511
|
+
] }),
|
|
2512
|
+
/* @__PURE__ */ jsxs18("div", { style: { display: "flex", gap: 8, marginBottom: 10 }, children: [
|
|
2513
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, textAlign: "left" }, children: [
|
|
2514
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-holder-cep", style: labelStyle, children: "CEP" }),
|
|
2515
|
+
/* @__PURE__ */ jsx24(
|
|
2516
|
+
"input",
|
|
2517
|
+
{
|
|
2518
|
+
id: "pw-holder-cep",
|
|
2519
|
+
"data-testid": "pw-holder-cep",
|
|
2520
|
+
type: "text",
|
|
2521
|
+
inputMode: "numeric",
|
|
2522
|
+
autoComplete: "postal-code",
|
|
2523
|
+
placeholder: "00000-000",
|
|
2524
|
+
value: holderPostalCode,
|
|
2525
|
+
onChange: (e) => setHolderPostalCode(e.target.value),
|
|
2526
|
+
style: inputStyle
|
|
2527
|
+
}
|
|
2528
|
+
)
|
|
2529
|
+
] }),
|
|
2530
|
+
/* @__PURE__ */ jsxs18("div", { style: { flex: 1, textAlign: "left" }, children: [
|
|
2531
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-holder-addr-n", style: labelStyle, children: "N\xFAmero" }),
|
|
2532
|
+
/* @__PURE__ */ jsx24(
|
|
2533
|
+
"input",
|
|
2534
|
+
{
|
|
2535
|
+
id: "pw-holder-addr-n",
|
|
2536
|
+
"data-testid": "pw-holder-addr-n",
|
|
2537
|
+
type: "text",
|
|
2538
|
+
inputMode: "numeric",
|
|
2539
|
+
placeholder: "123",
|
|
2540
|
+
value: holderAddressNumber,
|
|
2541
|
+
onChange: (e) => setHolderAddressNumber(e.target.value),
|
|
2542
|
+
style: inputStyle
|
|
2543
|
+
}
|
|
2544
|
+
)
|
|
2545
|
+
] })
|
|
2546
|
+
] }),
|
|
2547
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2548
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-holder-phone", style: labelStyle, children: "Telefone (opcional)" }),
|
|
2549
|
+
/* @__PURE__ */ jsx24(
|
|
2550
|
+
"input",
|
|
2551
|
+
{
|
|
2552
|
+
id: "pw-holder-phone",
|
|
2553
|
+
"data-testid": "pw-holder-phone",
|
|
2554
|
+
type: "tel",
|
|
2555
|
+
inputMode: "tel",
|
|
2556
|
+
autoComplete: "tel",
|
|
2557
|
+
placeholder: "(11) 99999-9999",
|
|
2558
|
+
value: holderPhone,
|
|
2559
|
+
onChange: (e) => setHolderPhone(e.target.value),
|
|
2560
|
+
style: inputStyle
|
|
2561
|
+
}
|
|
2562
|
+
)
|
|
2563
|
+
] })
|
|
2564
|
+
]
|
|
2565
|
+
}
|
|
2566
|
+
),
|
|
2567
|
+
/* @__PURE__ */ jsxs18("div", { style: fieldGroup, children: [
|
|
2568
|
+
/* @__PURE__ */ jsx24("label", { htmlFor: "pw-cpf", style: labelStyle, children: "Seu CPF" }),
|
|
2155
2569
|
/* @__PURE__ */ jsx24(
|
|
2156
2570
|
"input",
|
|
2157
2571
|
{
|
|
2572
|
+
id: "pw-cpf",
|
|
2158
2573
|
"data-testid": "paywall-cpf",
|
|
2159
2574
|
type: "text",
|
|
2160
2575
|
inputMode: "numeric",
|
|
2161
2576
|
placeholder: "000.000.000-00",
|
|
2162
2577
|
value: cpf,
|
|
2163
2578
|
onChange: (e) => setCpf(e.target.value),
|
|
2164
|
-
style:
|
|
2579
|
+
style: inputStyle
|
|
2165
2580
|
}
|
|
2166
2581
|
)
|
|
2167
2582
|
] }),
|
|
@@ -2171,7 +2586,7 @@ function DefaultPaywall() {
|
|
|
2171
2586
|
{
|
|
2172
2587
|
"data-testid": "paywall-cta",
|
|
2173
2588
|
type: "button",
|
|
2174
|
-
onClick:
|
|
2589
|
+
onClick: submit,
|
|
2175
2590
|
disabled: !canCheckout,
|
|
2176
2591
|
style: {
|
|
2177
2592
|
width: "100%",
|
|
@@ -2182,21 +2597,101 @@ function DefaultPaywall() {
|
|
|
2182
2597
|
borderRadius: 8,
|
|
2183
2598
|
opacity: canCheckout ? 1 : 0.5,
|
|
2184
2599
|
fontSize: 16,
|
|
2185
|
-
fontWeight: 600
|
|
2600
|
+
fontWeight: 600,
|
|
2601
|
+
cursor: canCheckout ? "pointer" : "not-allowed"
|
|
2186
2602
|
},
|
|
2187
|
-
children:
|
|
2603
|
+
children: ctaLabel
|
|
2188
2604
|
}
|
|
2189
2605
|
),
|
|
2190
|
-
|
|
2191
|
-
p.
|
|
2606
|
+
/* @__PURE__ */ jsx24("p", { style: { opacity: 0.55, marginTop: 16, fontSize: 12 }, children: footer }),
|
|
2607
|
+
p.priceHint && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.6, marginTop: 8, fontSize: 12 }, children: p.priceHint }),
|
|
2608
|
+
p.footerNote && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.5, marginTop: 8, fontSize: 12 }, children: p.footerNote }),
|
|
2609
|
+
pixPending && /* @__PURE__ */ jsx24(
|
|
2610
|
+
"div",
|
|
2611
|
+
{
|
|
2612
|
+
"data-testid": "paywall-pix-modal",
|
|
2613
|
+
role: "dialog",
|
|
2614
|
+
"aria-label": "Pagamento Pix pendente",
|
|
2615
|
+
style: {
|
|
2616
|
+
position: "fixed",
|
|
2617
|
+
inset: 0,
|
|
2618
|
+
background: "rgba(0,0,0,0.6)",
|
|
2619
|
+
display: "flex",
|
|
2620
|
+
alignItems: "center",
|
|
2621
|
+
justifyContent: "center",
|
|
2622
|
+
padding: 24,
|
|
2623
|
+
zIndex: 1e3
|
|
2624
|
+
},
|
|
2625
|
+
children: /* @__PURE__ */ jsxs18("div", { style: {
|
|
2626
|
+
background: "#fff",
|
|
2627
|
+
borderRadius: 12,
|
|
2628
|
+
padding: 24,
|
|
2629
|
+
maxWidth: 360,
|
|
2630
|
+
width: "100%",
|
|
2631
|
+
textAlign: "center"
|
|
2632
|
+
}, children: [
|
|
2633
|
+
pixPending.paid ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
2634
|
+
/* @__PURE__ */ jsx24("h2", { style: { marginTop: 0 }, children: "Pagamento confirmado!" }),
|
|
2635
|
+
/* @__PURE__ */ jsx24("p", { style: { opacity: 0.7 }, children: "Liberando acesso\u2026" })
|
|
2636
|
+
] }) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
2637
|
+
/* @__PURE__ */ jsx24("h2", { style: { marginTop: 0, fontSize: 18 }, children: "Pague com Pix Autom\xE1tico" }),
|
|
2638
|
+
/* @__PURE__ */ jsx24("p", { style: { fontSize: 13, opacity: 0.75 }, children: "Escaneie o QR Code no app do seu banco pra autorizar o d\xE9bito recorrente." }),
|
|
2639
|
+
pixPending.qrCodeBase64 && /* @__PURE__ */ jsx24(
|
|
2640
|
+
"img",
|
|
2641
|
+
{
|
|
2642
|
+
"data-testid": "pix-qr-image",
|
|
2643
|
+
alt: "QR Code Pix",
|
|
2644
|
+
src: `data:image/png;base64,${pixPending.qrCodeBase64}`,
|
|
2645
|
+
style: { width: "100%", maxWidth: 240, margin: "12px auto", display: "block" }
|
|
2646
|
+
}
|
|
2647
|
+
),
|
|
2648
|
+
pixPending.qrCodePayload && /* @__PURE__ */ jsx24(
|
|
2649
|
+
"textarea",
|
|
2650
|
+
{
|
|
2651
|
+
"data-testid": "pix-qr-payload",
|
|
2652
|
+
readOnly: true,
|
|
2653
|
+
value: pixPending.qrCodePayload,
|
|
2654
|
+
style: {
|
|
2655
|
+
width: "100%",
|
|
2656
|
+
minHeight: 72,
|
|
2657
|
+
padding: 8,
|
|
2658
|
+
fontSize: 11,
|
|
2659
|
+
fontFamily: "monospace",
|
|
2660
|
+
borderRadius: 6,
|
|
2661
|
+
border: "1px solid #ccc",
|
|
2662
|
+
resize: "none"
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
),
|
|
2666
|
+
/* @__PURE__ */ jsx24("p", { style: { fontSize: 11, opacity: 0.55, marginTop: 12 }, children: "Aguardando confirma\xE7\xE3o do banco\u2026 Pode levar alguns segundos." })
|
|
2667
|
+
] }),
|
|
2668
|
+
/* @__PURE__ */ jsx24(
|
|
2669
|
+
"button",
|
|
2670
|
+
{
|
|
2671
|
+
type: "button",
|
|
2672
|
+
onClick: dismissPix,
|
|
2673
|
+
style: {
|
|
2674
|
+
marginTop: 16,
|
|
2675
|
+
padding: "8px 16px",
|
|
2676
|
+
border: "1px solid #ccc",
|
|
2677
|
+
borderRadius: 6,
|
|
2678
|
+
background: "white",
|
|
2679
|
+
cursor: "pointer"
|
|
2680
|
+
},
|
|
2681
|
+
children: "Fechar"
|
|
2682
|
+
}
|
|
2683
|
+
)
|
|
2684
|
+
] })
|
|
2685
|
+
}
|
|
2686
|
+
)
|
|
2192
2687
|
] });
|
|
2193
2688
|
}
|
|
2194
2689
|
|
|
2195
2690
|
// src/AppRoot.tsx
|
|
2196
|
-
import { Fragment as
|
|
2691
|
+
import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2197
2692
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
2198
2693
|
function PaymentReturnHandler({ children }) {
|
|
2199
|
-
const { subscription } =
|
|
2694
|
+
const { subscription } = useHook9();
|
|
2200
2695
|
const subRef = useRef3(subscription);
|
|
2201
2696
|
subRef.current = subscription;
|
|
2202
2697
|
const runIdRef = useRef3(0);
|
|
@@ -2264,7 +2759,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2264
2759
|
)
|
|
2265
2760
|
] }) });
|
|
2266
2761
|
}
|
|
2267
|
-
return /* @__PURE__ */ jsx25(
|
|
2762
|
+
return /* @__PURE__ */ jsx25(Fragment7, { children });
|
|
2268
2763
|
}
|
|
2269
2764
|
var overlayStyle2 = {
|
|
2270
2765
|
position: "fixed",
|
|
@@ -2305,7 +2800,7 @@ function AppRoot({
|
|
|
2305
2800
|
|
|
2306
2801
|
// src/hooks/usePush.ts
|
|
2307
2802
|
import { useCallback as useCallback8, useEffect as useEffect9, useState as useState13 } from "react";
|
|
2308
|
-
import { useHook as
|
|
2803
|
+
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
2309
2804
|
function detectIosNeedsInstall() {
|
|
2310
2805
|
if (typeof navigator === "undefined" || typeof window === "undefined") return false;
|
|
2311
2806
|
const ua = navigator.userAgent || "";
|
|
@@ -2331,7 +2826,7 @@ function deriveState(push) {
|
|
|
2331
2826
|
return { kind: "prompt" };
|
|
2332
2827
|
}
|
|
2333
2828
|
function usePush() {
|
|
2334
|
-
const { push } =
|
|
2829
|
+
const { push } = useHook10();
|
|
2335
2830
|
const [state, setState] = useState13(() => deriveState(push));
|
|
2336
2831
|
useEffect9(() => {
|
|
2337
2832
|
setState(deriveState(push));
|
|
@@ -2413,41 +2908,6 @@ function EmptyState({ title, description, action }) {
|
|
|
2413
2908
|
] });
|
|
2414
2909
|
}
|
|
2415
2910
|
|
|
2416
|
-
// src/hooks/usePlan.ts
|
|
2417
|
-
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
2418
|
-
function usePlan() {
|
|
2419
|
-
const { plan } = useHook10();
|
|
2420
|
-
return plan;
|
|
2421
|
-
}
|
|
2422
|
-
|
|
2423
|
-
// src/utils/price.ts
|
|
2424
|
-
function formatBRL(cents) {
|
|
2425
|
-
if (cents === null || cents === void 0) return "";
|
|
2426
|
-
const reais = cents / 100;
|
|
2427
|
-
return new Intl.NumberFormat("pt-BR", {
|
|
2428
|
-
style: "currency",
|
|
2429
|
-
currency: "BRL"
|
|
2430
|
-
}).format(reais);
|
|
2431
|
-
}
|
|
2432
|
-
function monthlyFromYearly(yearlyCents) {
|
|
2433
|
-
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2434
|
-
return Math.round(yearlyCents / 12);
|
|
2435
|
-
}
|
|
2436
|
-
function dailyFromYearly(yearlyCents) {
|
|
2437
|
-
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2438
|
-
return Math.round(yearlyCents / 365);
|
|
2439
|
-
}
|
|
2440
|
-
function computeAnchorCents(baseCents, multiplier) {
|
|
2441
|
-
if (multiplier === null || multiplier === void 0) return null;
|
|
2442
|
-
if (!Number.isFinite(multiplier)) return null;
|
|
2443
|
-
if (multiplier <= 1) return null;
|
|
2444
|
-
return Math.round(baseCents * multiplier);
|
|
2445
|
-
}
|
|
2446
|
-
function discountPercent(anchorCents, realCents) {
|
|
2447
|
-
if (anchorCents <= realCents) return 0;
|
|
2448
|
-
return Math.floor((anchorCents - realCents) / anchorCents * 100);
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
2911
|
// src/hooks/useAuthPrimitives.ts
|
|
2452
2912
|
import { useEffect as useEffect10 } from "react";
|
|
2453
2913
|
import { useHook as useHook11 } from "@hook-sdk/sdk";
|