@hook-sdk/template 0.25.1 → 0.27.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 +934 -397
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -4
- package/dist/index.d.ts +84 -4
- package/dist/index.js +897 -360
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
AppConfigProvider: () => AppConfigProvider,
|
|
34
34
|
AppConfigSchema: () => AppConfigSchema,
|
|
35
35
|
AppRoot: () => AppRoot,
|
|
36
|
+
CheckoutPageDefault: () => CheckoutPageDefault,
|
|
36
37
|
DeepLinkHandler: () => DeepLinkHandler,
|
|
37
38
|
DevSkipOnboardingFab: () => DevSkipOnboardingFab,
|
|
38
39
|
EmptyState: () => EmptyState,
|
|
@@ -66,6 +67,7 @@ __export(index_exports, {
|
|
|
66
67
|
PaywallTrophyBadge: () => PaywallTrophyBadge,
|
|
67
68
|
PaywallTrustLine: () => PaywallTrustLine,
|
|
68
69
|
PersistenceRegistry: () => PersistenceRegistry,
|
|
70
|
+
PixWaitingPageDefault: () => PixWaitingPageDefault,
|
|
69
71
|
PreAuthShell: () => PreAuthShell,
|
|
70
72
|
PushPrompt: () => PushPrompt2,
|
|
71
73
|
RouteBoundary: () => RouteBoundary,
|
|
@@ -88,6 +90,7 @@ __export(index_exports, {
|
|
|
88
90
|
useAppConfig: () => useAppConfig,
|
|
89
91
|
useAuth: () => useAuth,
|
|
90
92
|
useAuthPrimitives: () => useAuthPrimitives,
|
|
93
|
+
useCheckoutForm: () => useCheckoutForm,
|
|
91
94
|
useFeature: () => useFeature,
|
|
92
95
|
useForgotForm: () => useForgotForm,
|
|
93
96
|
useInstallPrompt: () => useInstallPrompt,
|
|
@@ -102,14 +105,14 @@ __export(index_exports, {
|
|
|
102
105
|
useSignupForm: () => useSignupForm,
|
|
103
106
|
useSubscription: () => useSubscription,
|
|
104
107
|
useToast: () => useToast,
|
|
105
|
-
useTrackOnboardingStep: () =>
|
|
108
|
+
useTrackOnboardingStep: () => import_sdk25.useTrackOnboardingStep
|
|
106
109
|
});
|
|
107
110
|
module.exports = __toCommonJS(index_exports);
|
|
108
111
|
|
|
109
112
|
// src/AppRoot.tsx
|
|
110
|
-
var
|
|
113
|
+
var import_react15 = require("react");
|
|
111
114
|
var import_react_router_dom2 = require("react-router-dom");
|
|
112
|
-
var
|
|
115
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
113
116
|
|
|
114
117
|
// src/config/AppConfigContext.tsx
|
|
115
118
|
var import_react = require("react");
|
|
@@ -139,7 +142,9 @@ var AuthFlowSchema = import_zod.z.object({
|
|
|
139
142
|
requiresEmailVerify: import_zod.z.boolean(),
|
|
140
143
|
googleOAuth: import_zod.z.boolean(),
|
|
141
144
|
postAuthLanding: import_zod.z.string().startsWith("/"),
|
|
142
|
-
preAuthRoutes: import_zod.z.array(import_zod.z.string().startsWith("/"))
|
|
145
|
+
preAuthRoutes: import_zod.z.array(import_zod.z.string().startsWith("/")),
|
|
146
|
+
// Plan-V — pay-first signup mode. See types/AppConfig.ts AuthFlowConfig.
|
|
147
|
+
signupMode: import_zod.z.enum(["pre_signup", "pay_first"]).optional()
|
|
143
148
|
});
|
|
144
149
|
var PaywallNonFreeSchema = import_zod.z.object({
|
|
145
150
|
mode: import_zod.z.enum(["trial", "pay_first"]),
|
|
@@ -2139,54 +2144,10 @@ function SessionExpiredBanner() {
|
|
|
2139
2144
|
] });
|
|
2140
2145
|
}
|
|
2141
2146
|
|
|
2142
|
-
// src/
|
|
2147
|
+
// src/defaults/ErrorBoundary.tsx
|
|
2143
2148
|
var import_react11 = require("react");
|
|
2144
|
-
var import_sdk5 = require("@hook-sdk/sdk");
|
|
2145
2149
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2146
|
-
|
|
2147
|
-
const { user, auth } = (0, import_sdk5.useHook)();
|
|
2148
|
-
const [sending, setSending] = (0, import_react11.useState)(false);
|
|
2149
|
-
const [sent, setSent] = (0, import_react11.useState)(false);
|
|
2150
|
-
if (!user || user.emailVerified) return null;
|
|
2151
|
-
async function handleResend() {
|
|
2152
|
-
if (sending || sent) return;
|
|
2153
|
-
setSending(true);
|
|
2154
|
-
try {
|
|
2155
|
-
await auth.resendVerify();
|
|
2156
|
-
setSent(true);
|
|
2157
|
-
} catch {
|
|
2158
|
-
} finally {
|
|
2159
|
-
setSending(false);
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
const label = sent ? "Enviado!" : sending ? "Enviando..." : "Reenviar link";
|
|
2163
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2164
|
-
"div",
|
|
2165
|
-
{
|
|
2166
|
-
role: "status",
|
|
2167
|
-
"data-testid": "email-verify-banner",
|
|
2168
|
-
className: "sticky top-0 inset-x-0 z-50 bg-yellow-100 text-yellow-900 border-b border-yellow-200 px-4 py-2 flex items-center justify-between gap-3 text-sm",
|
|
2169
|
-
children: [
|
|
2170
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Confirma teu e-mail pra liberar tudo." }),
|
|
2171
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2172
|
-
"button",
|
|
2173
|
-
{
|
|
2174
|
-
type: "button",
|
|
2175
|
-
onClick: handleResend,
|
|
2176
|
-
disabled: sending || sent,
|
|
2177
|
-
className: "px-3 py-1 rounded text-xs font-medium bg-yellow-900 text-yellow-50 hover:bg-yellow-800 disabled:opacity-60 disabled:cursor-not-allowed",
|
|
2178
|
-
children: label
|
|
2179
|
-
}
|
|
2180
|
-
)
|
|
2181
|
-
]
|
|
2182
|
-
}
|
|
2183
|
-
);
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
// src/defaults/ErrorBoundary.tsx
|
|
2187
|
-
var import_react12 = require("react");
|
|
2188
|
-
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2189
|
-
var ErrorBoundary = class extends import_react12.Component {
|
|
2150
|
+
var ErrorBoundary = class extends import_react11.Component {
|
|
2190
2151
|
state = { error: null };
|
|
2191
2152
|
static getDerivedStateFromError(error) {
|
|
2192
2153
|
return { error };
|
|
@@ -2203,21 +2164,21 @@ var ErrorBoundary = class extends import_react12.Component {
|
|
|
2203
2164
|
}
|
|
2204
2165
|
render() {
|
|
2205
2166
|
if (this.state.error) {
|
|
2206
|
-
return this.props.fallback ?? /* @__PURE__ */ (0,
|
|
2207
|
-
/* @__PURE__ */ (0,
|
|
2208
|
-
/* @__PURE__ */ (0,
|
|
2167
|
+
return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
2168
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { children: "Algo deu errado" }),
|
|
2169
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
2209
2170
|
] });
|
|
2210
2171
|
}
|
|
2211
|
-
return /* @__PURE__ */ (0,
|
|
2172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children: this.props.children });
|
|
2212
2173
|
}
|
|
2213
2174
|
};
|
|
2214
2175
|
|
|
2215
2176
|
// src/i18n/I18nProvider.tsx
|
|
2216
|
-
var
|
|
2177
|
+
var import_react12 = require("react");
|
|
2217
2178
|
var import_i18next = __toESM(require("i18next"), 1);
|
|
2218
2179
|
var import_react_i18next = require("react-i18next");
|
|
2219
|
-
var
|
|
2220
|
-
var
|
|
2180
|
+
var import_sdk5 = require("@hook-sdk/sdk");
|
|
2181
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2221
2182
|
function ensureInitialized(defaultLocale, supportedLocales, resources, initialLocale) {
|
|
2222
2183
|
if (import_i18next.default.isInitialized) return;
|
|
2223
2184
|
import_i18next.default.use(import_react_i18next.initReactI18next).init({
|
|
@@ -2239,14 +2200,14 @@ function I18nProvider({
|
|
|
2239
2200
|
resources,
|
|
2240
2201
|
children
|
|
2241
2202
|
}) {
|
|
2242
|
-
const [userLocale] = (0,
|
|
2203
|
+
const [userLocale] = (0, import_sdk5.usePersistedState)("user-locale", defaultLocale);
|
|
2243
2204
|
ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);
|
|
2244
|
-
(0,
|
|
2205
|
+
(0, import_react12.useEffect)(() => {
|
|
2245
2206
|
if (import_i18next.default.isInitialized && import_i18next.default.language !== userLocale) {
|
|
2246
2207
|
import_i18next.default.changeLanguage(userLocale);
|
|
2247
2208
|
}
|
|
2248
2209
|
}, [userLocale]);
|
|
2249
|
-
return /* @__PURE__ */ (0,
|
|
2210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_i18next.I18nextProvider, { i18n: import_i18next.default, children });
|
|
2250
2211
|
}
|
|
2251
2212
|
|
|
2252
2213
|
// src/dev/env.ts
|
|
@@ -2257,9 +2218,9 @@ function isDevToolsEnabled() {
|
|
|
2257
2218
|
}
|
|
2258
2219
|
|
|
2259
2220
|
// src/dev/DevSkipOnboardingFab.tsx
|
|
2260
|
-
var
|
|
2261
|
-
var
|
|
2262
|
-
var
|
|
2221
|
+
var import_react13 = require("react");
|
|
2222
|
+
var import_sdk6 = require("@hook-sdk/sdk");
|
|
2223
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2263
2224
|
var STORAGE_KEY = "hook_dev_skip_email";
|
|
2264
2225
|
var TEST_EMAIL_DOMAIN = "@hook.test";
|
|
2265
2226
|
var TEST_PASSWORD = "SkipTest!2026";
|
|
@@ -2326,18 +2287,18 @@ var STYLES = {
|
|
|
2326
2287
|
};
|
|
2327
2288
|
var CONFIRM_TIMEOUT_MS = 3e3;
|
|
2328
2289
|
function DevSkipOnboardingFab({ defaults }) {
|
|
2329
|
-
const hook = (0,
|
|
2290
|
+
const hook = (0, import_sdk6.useHook)();
|
|
2330
2291
|
const { slug } = useAppConfig();
|
|
2331
|
-
const [state, setState] = (0,
|
|
2332
|
-
const [errorMsg, setErrorMsg] = (0,
|
|
2333
|
-
const timerRef = (0,
|
|
2334
|
-
const clearTimer = (0,
|
|
2292
|
+
const [state, setState] = (0, import_react13.useState)("idle");
|
|
2293
|
+
const [errorMsg, setErrorMsg] = (0, import_react13.useState)(null);
|
|
2294
|
+
const timerRef = (0, import_react13.useRef)(null);
|
|
2295
|
+
const clearTimer = (0, import_react13.useCallback)(() => {
|
|
2335
2296
|
if (timerRef.current) {
|
|
2336
2297
|
clearTimeout(timerRef.current);
|
|
2337
2298
|
timerRef.current = null;
|
|
2338
2299
|
}
|
|
2339
2300
|
}, []);
|
|
2340
|
-
const onClick = (0,
|
|
2301
|
+
const onClick = (0, import_react13.useCallback)(async () => {
|
|
2341
2302
|
if (state === "busy") return;
|
|
2342
2303
|
if (state === "idle" || state === "error") {
|
|
2343
2304
|
setState("confirm");
|
|
@@ -2366,7 +2327,7 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2366
2327
|
...state === "confirm" || state === "error" ? STYLES.confirm : {},
|
|
2367
2328
|
...state === "busy" ? STYLES.busy : {}
|
|
2368
2329
|
};
|
|
2369
|
-
return /* @__PURE__ */ (0,
|
|
2330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2370
2331
|
"button",
|
|
2371
2332
|
{
|
|
2372
2333
|
type: "button",
|
|
@@ -2381,21 +2342,21 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2381
2342
|
}
|
|
2382
2343
|
|
|
2383
2344
|
// src/internal/PaymentReturnHandler.tsx
|
|
2384
|
-
var
|
|
2385
|
-
var
|
|
2386
|
-
var
|
|
2345
|
+
var import_react14 = require("react");
|
|
2346
|
+
var import_sdk7 = require("@hook-sdk/sdk");
|
|
2347
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2387
2348
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
2388
2349
|
var MAX_CYCLES = 3;
|
|
2389
2350
|
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
2390
2351
|
function PaymentReturnHandler({ children }) {
|
|
2391
|
-
const { subscription, track: track2 } = (0,
|
|
2392
|
-
const subRef = (0,
|
|
2352
|
+
const { subscription, track: track2 } = (0, import_sdk7.useHook)();
|
|
2353
|
+
const subRef = (0, import_react14.useRef)(subscription);
|
|
2393
2354
|
subRef.current = subscription;
|
|
2394
|
-
const runIdRef = (0,
|
|
2395
|
-
const cyclesRef = (0,
|
|
2396
|
-
const startMsRef = (0,
|
|
2397
|
-
const [state, setState] = (0,
|
|
2398
|
-
const runPoll = (0,
|
|
2355
|
+
const runIdRef = (0, import_react14.useRef)(0);
|
|
2356
|
+
const cyclesRef = (0, import_react14.useRef)(0);
|
|
2357
|
+
const startMsRef = (0, import_react14.useRef)(0);
|
|
2358
|
+
const [state, setState] = (0, import_react14.useState)("idle");
|
|
2359
|
+
const runPoll = (0, import_react14.useCallback)(() => {
|
|
2399
2360
|
const runId = ++runIdRef.current;
|
|
2400
2361
|
const isFirstRun = cyclesRef.current === 0;
|
|
2401
2362
|
cyclesRef.current += 1;
|
|
@@ -2443,7 +2404,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2443
2404
|
};
|
|
2444
2405
|
void tick();
|
|
2445
2406
|
}, [track2]);
|
|
2446
|
-
(0,
|
|
2407
|
+
(0, import_react14.useEffect)(() => {
|
|
2447
2408
|
if (typeof window === "undefined") return;
|
|
2448
2409
|
const url = new URL(window.location.href);
|
|
2449
2410
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -2453,26 +2414,26 @@ function PaymentReturnHandler({ children }) {
|
|
|
2453
2414
|
runIdRef.current++;
|
|
2454
2415
|
};
|
|
2455
2416
|
}, [runPoll]);
|
|
2456
|
-
const goHome = (0,
|
|
2417
|
+
const goHome = (0, import_react14.useCallback)(() => {
|
|
2457
2418
|
const cleanUrl = new URL(window.location.href);
|
|
2458
2419
|
cleanUrl.searchParams.delete("paymentReturn");
|
|
2459
2420
|
cleanUrl.pathname = "/app/home";
|
|
2460
2421
|
window.location.href = cleanUrl.toString();
|
|
2461
2422
|
}, []);
|
|
2462
2423
|
if (state === "confirming") {
|
|
2463
|
-
return /* @__PURE__ */ (0,
|
|
2424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
|
|
2464
2425
|
}
|
|
2465
2426
|
if (state === "waiting") {
|
|
2466
|
-
return /* @__PURE__ */ (0,
|
|
2467
|
-
/* @__PURE__ */ (0,
|
|
2468
|
-
/* @__PURE__ */ (0,
|
|
2427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2428
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2429
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
|
|
2469
2430
|
] }) });
|
|
2470
2431
|
}
|
|
2471
2432
|
if (state === "timeout") {
|
|
2472
|
-
return /* @__PURE__ */ (0,
|
|
2473
|
-
/* @__PURE__ */ (0,
|
|
2474
|
-
/* @__PURE__ */ (0,
|
|
2475
|
-
/* @__PURE__ */ (0,
|
|
2433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2434
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 16 }, children: "Ainda n\xE3o conseguimos confirmar seu pagamento com o banco. Voc\xEA pode tentar de novo, voltar pro app, ou falar com a gente." }),
|
|
2435
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2476
2437
|
"button",
|
|
2477
2438
|
{
|
|
2478
2439
|
type: "button",
|
|
@@ -2485,7 +2446,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2485
2446
|
children: "Tentar de novo"
|
|
2486
2447
|
}
|
|
2487
2448
|
),
|
|
2488
|
-
/* @__PURE__ */ (0,
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2489
2450
|
"button",
|
|
2490
2451
|
{
|
|
2491
2452
|
type: "button",
|
|
@@ -2495,7 +2456,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2495
2456
|
children: "Voltar pro app"
|
|
2496
2457
|
}
|
|
2497
2458
|
),
|
|
2498
|
-
/* @__PURE__ */ (0,
|
|
2459
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2499
2460
|
"a",
|
|
2500
2461
|
{
|
|
2501
2462
|
href: SUPPORT_MAILTO,
|
|
@@ -2507,7 +2468,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2507
2468
|
] })
|
|
2508
2469
|
] }) });
|
|
2509
2470
|
}
|
|
2510
|
-
return /* @__PURE__ */ (0,
|
|
2471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children });
|
|
2511
2472
|
}
|
|
2512
2473
|
var overlayStyle2 = {
|
|
2513
2474
|
position: "fixed",
|
|
@@ -2546,7 +2507,7 @@ var linkStyle = {
|
|
|
2546
2507
|
};
|
|
2547
2508
|
|
|
2548
2509
|
// src/AppRoot.tsx
|
|
2549
|
-
var
|
|
2510
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2550
2511
|
function buildLegacyConfigShim(config) {
|
|
2551
2512
|
const paywall = config.paywall;
|
|
2552
2513
|
const isFree = paywall.mode === "free";
|
|
@@ -2620,22 +2581,19 @@ function AppRoot(props) {
|
|
|
2620
2581
|
"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
|
|
2621
2582
|
);
|
|
2622
2583
|
}
|
|
2623
|
-
const legacyShim = (0,
|
|
2584
|
+
const legacyShim = (0, import_react15.useMemo)(() => buildLegacyConfigShim(config), [config]);
|
|
2624
2585
|
const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
|
|
2625
2586
|
const basename = `/app/${config.slug}`;
|
|
2626
2587
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
2627
2588
|
const position = config.install_prompt?.position ?? "post-paywall";
|
|
2628
|
-
const subscriptionGated = /* @__PURE__ */ (0,
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
] })
|
|
2637
|
-
] });
|
|
2638
|
-
const authGated = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2589
|
+
const subscriptionGated = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubscriptionGate, { Paywall: Paywall2 ?? FallbackPaywall, children: position === "post-paywall" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(InstallGate, { position: "post-paywall", children: [
|
|
2590
|
+
children,
|
|
2591
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PushPrompt, {})
|
|
2592
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
2593
|
+
children,
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PushPrompt, {})
|
|
2595
|
+
] }) });
|
|
2596
|
+
const authGated = /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2639
2597
|
AuthGated,
|
|
2640
2598
|
{
|
|
2641
2599
|
config,
|
|
@@ -2650,13 +2608,13 @@ function AppRoot(props) {
|
|
|
2650
2608
|
children: subscriptionGated
|
|
2651
2609
|
}
|
|
2652
2610
|
);
|
|
2653
|
-
const routedTree = /* @__PURE__ */ (0,
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
2656
|
-
position === "pre-auth" ? /* @__PURE__ */ (0,
|
|
2657
|
-
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0,
|
|
2611
|
+
const routedTree = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Router, { ...routerProps, children: [
|
|
2612
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SessionExpiredBanner, {}),
|
|
2614
|
+
position === "pre-auth" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(InstallGate, { position: "pre-auth", children: authGated }) : authGated,
|
|
2615
|
+
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DevSkipOnboardingFab, { defaults: devSkipOnboarding.defaults }) : null
|
|
2658
2616
|
] });
|
|
2659
|
-
return /* @__PURE__ */ (0,
|
|
2617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2660
2618
|
I18nProvider,
|
|
2661
2619
|
{
|
|
2662
2620
|
defaultLocale: config.i18n.defaultLocale,
|
|
@@ -2676,37 +2634,46 @@ function AuthGated({
|
|
|
2676
2634
|
EmailVerify,
|
|
2677
2635
|
PreAuthFlow
|
|
2678
2636
|
}) {
|
|
2679
|
-
const { authStatus } = (0,
|
|
2637
|
+
const { authStatus } = (0, import_sdk8.useHook)();
|
|
2680
2638
|
if (authStatus === "loading") return null;
|
|
2681
2639
|
if (authStatus !== "authenticated") {
|
|
2640
|
+
if (config.authFlow.signupMode === "pay_first" && PreAuthFlow) {
|
|
2641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Login, {}) }),
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Forgot, {}) }),
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Reset, {}) }),
|
|
2645
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmailVerify, {}) }) : null,
|
|
2646
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PreAuthFlow, {}) })
|
|
2647
|
+
] });
|
|
2648
|
+
}
|
|
2682
2649
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
2683
|
-
return /* @__PURE__ */ (0,
|
|
2684
|
-
/* @__PURE__ */ (0,
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2687
|
-
/* @__PURE__ */ (0,
|
|
2688
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2689
|
-
/* @__PURE__ */ (0,
|
|
2650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2651
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Login, {}) }),
|
|
2652
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Signup, {}) }),
|
|
2653
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Forgot, {}) }),
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Reset, {}) }),
|
|
2655
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmailVerify, {}) }) : null,
|
|
2656
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PreAuthFlow, {}) })
|
|
2690
2657
|
] });
|
|
2691
2658
|
}
|
|
2692
|
-
return /* @__PURE__ */ (0,
|
|
2693
|
-
/* @__PURE__ */ (0,
|
|
2694
|
-
/* @__PURE__ */ (0,
|
|
2695
|
-
/* @__PURE__ */ (0,
|
|
2696
|
-
/* @__PURE__ */ (0,
|
|
2697
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2698
|
-
/* @__PURE__ */ (0,
|
|
2659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Login, {}) }),
|
|
2661
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Signup, {}) }),
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Forgot, {}) }),
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Reset, {}) }),
|
|
2664
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EmailVerify, {}) }) : null,
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
|
|
2699
2666
|
] });
|
|
2700
2667
|
}
|
|
2701
|
-
return /* @__PURE__ */ (0,
|
|
2668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });
|
|
2702
2669
|
}
|
|
2703
2670
|
function FallbackPaywall() {
|
|
2704
2671
|
return null;
|
|
2705
2672
|
}
|
|
2706
2673
|
|
|
2707
2674
|
// src/hooks/usePush.ts
|
|
2708
|
-
var
|
|
2709
|
-
var
|
|
2675
|
+
var import_react16 = require("react");
|
|
2676
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
2710
2677
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2711
2678
|
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2712
2679
|
function detectIosNeedsInstall() {
|
|
@@ -2750,12 +2717,12 @@ function deriveState(push) {
|
|
|
2750
2717
|
return { kind: "prompt" };
|
|
2751
2718
|
}
|
|
2752
2719
|
function usePush() {
|
|
2753
|
-
const { push } = (0,
|
|
2754
|
-
const [state, setState] = (0,
|
|
2755
|
-
(0,
|
|
2720
|
+
const { push } = (0, import_sdk9.useHook)();
|
|
2721
|
+
const [state, setState] = (0, import_react16.useState)(() => deriveState(push));
|
|
2722
|
+
(0, import_react16.useEffect)(() => {
|
|
2756
2723
|
setState(deriveState(push));
|
|
2757
2724
|
}, [push]);
|
|
2758
|
-
const subscribe = (0,
|
|
2725
|
+
const subscribe = (0, import_react16.useCallback)(async () => {
|
|
2759
2726
|
try {
|
|
2760
2727
|
await push.subscribe();
|
|
2761
2728
|
setState({ kind: "subscribed" });
|
|
@@ -2767,7 +2734,7 @@ function usePush() {
|
|
|
2767
2734
|
throw e;
|
|
2768
2735
|
}
|
|
2769
2736
|
}, [push]);
|
|
2770
|
-
const unsubscribe = (0,
|
|
2737
|
+
const unsubscribe = (0, import_react16.useCallback)(async () => {
|
|
2771
2738
|
try {
|
|
2772
2739
|
await push.unsubscribe();
|
|
2773
2740
|
setState({ kind: "prompt" });
|
|
@@ -2776,7 +2743,7 @@ function usePush() {
|
|
|
2776
2743
|
throw e;
|
|
2777
2744
|
}
|
|
2778
2745
|
}, [push]);
|
|
2779
|
-
const dismiss = (0,
|
|
2746
|
+
const dismiss = (0, import_react16.useCallback)(() => {
|
|
2780
2747
|
if (typeof localStorage !== "undefined") {
|
|
2781
2748
|
try {
|
|
2782
2749
|
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
|
|
@@ -2789,27 +2756,27 @@ function usePush() {
|
|
|
2789
2756
|
}
|
|
2790
2757
|
|
|
2791
2758
|
// src/components/PushPrompt.tsx
|
|
2792
|
-
var
|
|
2759
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2793
2760
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
2794
2761
|
const { state, subscribe } = usePush();
|
|
2795
2762
|
if (state.kind === "denied" || state.kind === "dismissed" || state.kind === "subscribed") {
|
|
2796
2763
|
return null;
|
|
2797
2764
|
}
|
|
2798
2765
|
if (state.kind === "ios_needs_install") {
|
|
2799
|
-
return /* @__PURE__ */ (0,
|
|
2800
|
-
/* @__PURE__ */ (0,
|
|
2801
|
-
/* @__PURE__ */ (0,
|
|
2802
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0,
|
|
2766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2767
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { children: texts.iosInstallTitle }),
|
|
2768
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: texts.iosInstallBody }),
|
|
2769
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
2803
2770
|
] });
|
|
2804
2771
|
}
|
|
2805
2772
|
if (state.kind === "unsupported") {
|
|
2806
|
-
return /* @__PURE__ */ (0,
|
|
2773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: texts.unsupportedBody }) });
|
|
2807
2774
|
}
|
|
2808
2775
|
if (state.kind === "error") {
|
|
2809
|
-
return /* @__PURE__ */ (0,
|
|
2776
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { children: state.message }) });
|
|
2810
2777
|
}
|
|
2811
|
-
return /* @__PURE__ */ (0,
|
|
2812
|
-
/* @__PURE__ */ (0,
|
|
2778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className, role: "region", children: [
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2813
2780
|
"button",
|
|
2814
2781
|
{
|
|
2815
2782
|
type: "button",
|
|
@@ -2823,67 +2790,71 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2823
2790
|
children: texts.cta
|
|
2824
2791
|
}
|
|
2825
2792
|
),
|
|
2826
|
-
onDeclined && /* @__PURE__ */ (0,
|
|
2793
|
+
onDeclined && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
2827
2794
|
] });
|
|
2828
2795
|
}
|
|
2829
2796
|
|
|
2830
2797
|
// src/components/LanguageSwitcher.tsx
|
|
2831
|
-
var
|
|
2832
|
-
var
|
|
2798
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
2799
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2833
2800
|
function LanguageSwitcher({ id, className, label = "Language" }) {
|
|
2834
2801
|
const config = useAppConfig();
|
|
2835
2802
|
const i18nConfig = config.i18n;
|
|
2836
|
-
const [userLocale, setUserLocale] = (0,
|
|
2803
|
+
const [userLocale, setUserLocale] = (0, import_sdk10.usePersistedState)(
|
|
2837
2804
|
"user-locale",
|
|
2838
2805
|
i18nConfig?.defaultLocale ?? "en-US"
|
|
2839
2806
|
);
|
|
2840
2807
|
if (!i18nConfig) return null;
|
|
2841
|
-
return /* @__PURE__ */ (0,
|
|
2842
|
-
label ? /* @__PURE__ */ (0,
|
|
2843
|
-
/* @__PURE__ */ (0,
|
|
2808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className, children: [
|
|
2809
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: label }) : null,
|
|
2810
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2844
2811
|
"select",
|
|
2845
2812
|
{
|
|
2846
2813
|
id,
|
|
2847
2814
|
value: userLocale,
|
|
2848
2815
|
onChange: (e) => setUserLocale(e.target.value),
|
|
2849
2816
|
"data-testid": "language-switcher",
|
|
2850
|
-
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0,
|
|
2817
|
+
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: loc, children: loc }, loc))
|
|
2851
2818
|
}
|
|
2852
2819
|
)
|
|
2853
2820
|
] });
|
|
2854
2821
|
}
|
|
2855
2822
|
|
|
2856
2823
|
// src/defaults/LoadingState.tsx
|
|
2857
|
-
var
|
|
2824
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2858
2825
|
function LoadingState({ message }) {
|
|
2859
|
-
return /* @__PURE__ */ (0,
|
|
2826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: message ?? "Carregando..." }) });
|
|
2860
2827
|
}
|
|
2861
2828
|
|
|
2862
2829
|
// src/defaults/EmptyState.tsx
|
|
2863
|
-
var
|
|
2830
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2864
2831
|
function EmptyState({ title, description, action }) {
|
|
2865
|
-
return /* @__PURE__ */ (0,
|
|
2866
|
-
/* @__PURE__ */ (0,
|
|
2867
|
-
description && /* @__PURE__ */ (0,
|
|
2868
|
-
action && /* @__PURE__ */ (0,
|
|
2832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2834
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { style: { opacity: 0.7 }, children: description }),
|
|
2835
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { marginTop: 16 }, children: action })
|
|
2869
2836
|
] });
|
|
2870
2837
|
}
|
|
2871
2838
|
|
|
2872
|
-
// src/
|
|
2839
|
+
// src/defaults/CheckoutPageDefault.tsx
|
|
2873
2840
|
var import_react18 = require("react");
|
|
2874
|
-
var
|
|
2841
|
+
var import_react_router_dom3 = require("react-router-dom");
|
|
2875
2842
|
|
|
2876
|
-
// src/
|
|
2843
|
+
// src/hooks/useCheckoutForm.ts
|
|
2844
|
+
var import_react17 = require("react");
|
|
2877
2845
|
var import_sdk12 = require("@hook-sdk/sdk");
|
|
2846
|
+
|
|
2847
|
+
// src/errors.ts
|
|
2848
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
2878
2849
|
function mapSdkError(err) {
|
|
2879
|
-
if (err instanceof
|
|
2850
|
+
if (err instanceof import_sdk11.SdkRateLimitError) {
|
|
2880
2851
|
return {
|
|
2881
2852
|
code: "rate_limited",
|
|
2882
2853
|
message: `Aguarde ${err.retryAfter}s e tente novamente.`,
|
|
2883
2854
|
retryAfter: err.retryAfter
|
|
2884
2855
|
};
|
|
2885
2856
|
}
|
|
2886
|
-
if (err instanceof
|
|
2857
|
+
if (err instanceof import_sdk11.SdkAuthError) {
|
|
2887
2858
|
const detail = err.detail;
|
|
2888
2859
|
if (detail === "email_unverified") {
|
|
2889
2860
|
return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
|
|
@@ -2893,10 +2864,7 @@ function mapSdkError(err) {
|
|
|
2893
2864
|
}
|
|
2894
2865
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2895
2866
|
}
|
|
2896
|
-
if (err instanceof
|
|
2897
|
-
return { code: "email_taken", message: "Esse e-mail j\xE1 tem conta." };
|
|
2898
|
-
}
|
|
2899
|
-
if (err instanceof import_sdk12.SdkError && err.httpStatus === 0) {
|
|
2867
|
+
if (err instanceof import_sdk11.SdkError && err.httpStatus === 0) {
|
|
2900
2868
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2901
2869
|
}
|
|
2902
2870
|
if (err instanceof TypeError) {
|
|
@@ -2905,24 +2873,597 @@ function mapSdkError(err) {
|
|
|
2905
2873
|
return { code: "server", message: "Algo deu errado. Tente novamente em instantes." };
|
|
2906
2874
|
}
|
|
2907
2875
|
|
|
2908
|
-
// src/hooks/
|
|
2876
|
+
// src/hooks/useCheckoutForm.ts
|
|
2909
2877
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2878
|
+
var PHONE_RE = /^[0-9()+\-\s]{8,20}$/;
|
|
2879
|
+
var CHECK_DEBOUNCE_MS = 400;
|
|
2880
|
+
function useCheckoutForm(args) {
|
|
2881
|
+
const { auth } = (0, import_sdk12.useHook)();
|
|
2882
|
+
const [name, setName] = (0, import_react17.useState)("");
|
|
2883
|
+
const [email, setEmail] = (0, import_react17.useState)("");
|
|
2884
|
+
const [emailConfirm, setEmailConfirm] = (0, import_react17.useState)("");
|
|
2885
|
+
const [phone, setPhone] = (0, import_react17.useState)("");
|
|
2886
|
+
const [cpf, setCpf] = (0, import_react17.useState)("");
|
|
2887
|
+
const [method, setMethod] = (0, import_react17.useState)(args.defaultMethod);
|
|
2888
|
+
const [cycle, setCycle] = (0, import_react17.useState)(args.defaultCycle);
|
|
2889
|
+
const [card, setCardState] = (0, import_react17.useState)({
|
|
2890
|
+
number: "",
|
|
2891
|
+
expiryMonth: "",
|
|
2892
|
+
expiryYear: "",
|
|
2893
|
+
ccv: "",
|
|
2894
|
+
holderName: ""
|
|
2895
|
+
});
|
|
2896
|
+
const setCard = (0, import_react17.useCallback)((patch) => {
|
|
2897
|
+
setCardState((prev) => ({ ...prev, ...patch }));
|
|
2898
|
+
}, []);
|
|
2899
|
+
const [touchedName, setTouchedName] = (0, import_react17.useState)(false);
|
|
2900
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react17.useState)(false);
|
|
2901
|
+
const [touchedEmailConfirm, setTouchedEmailConfirm] = (0, import_react17.useState)(false);
|
|
2902
|
+
const [touchedPhone, setTouchedPhone] = (0, import_react17.useState)(false);
|
|
2903
|
+
const [touchedCpf, setTouchedCpf] = (0, import_react17.useState)(false);
|
|
2904
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react17.useState)(false);
|
|
2905
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2906
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2907
|
+
const [emailTaken, setEmailTaken] = (0, import_react17.useState)(false);
|
|
2908
|
+
const [loginUrl, setLoginUrl] = (0, import_react17.useState)(null);
|
|
2909
|
+
const [emailStatus, setEmailStatus] = (0, import_react17.useState)("idle");
|
|
2910
|
+
const lastCheckedEmail = (0, import_react17.useRef)("");
|
|
2911
|
+
(0, import_react17.useEffect)(() => {
|
|
2912
|
+
if (!email || !EMAIL_RE.test(email)) {
|
|
2913
|
+
setEmailStatus("idle");
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
if (email === lastCheckedEmail.current) return;
|
|
2917
|
+
const timer = setTimeout(async () => {
|
|
2918
|
+
setEmailStatus("checking");
|
|
2919
|
+
try {
|
|
2920
|
+
const result = await auth.checkEmailExists({ email });
|
|
2921
|
+
lastCheckedEmail.current = email;
|
|
2922
|
+
setEmailStatus(result.exists ? "exists" : "available");
|
|
2923
|
+
} catch {
|
|
2924
|
+
setEmailStatus("idle");
|
|
2925
|
+
}
|
|
2926
|
+
}, CHECK_DEBOUNCE_MS);
|
|
2927
|
+
return () => clearTimeout(timer);
|
|
2928
|
+
}, [email, auth]);
|
|
2929
|
+
const validateName = (0, import_react17.useMemo)(() => {
|
|
2930
|
+
if (name.length === 0) return null;
|
|
2931
|
+
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2932
|
+
return null;
|
|
2933
|
+
}, [name]);
|
|
2934
|
+
const validateEmail = (0, import_react17.useMemo)(() => {
|
|
2935
|
+
if (email.length === 0) return null;
|
|
2936
|
+
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2937
|
+
return null;
|
|
2938
|
+
}, [email]);
|
|
2939
|
+
const validateEmailConfirm = (0, import_react17.useMemo)(() => {
|
|
2940
|
+
if (emailConfirm.length === 0) return null;
|
|
2941
|
+
if (emailConfirm !== email) return "Os e-mails n\xE3o coincidem.";
|
|
2942
|
+
return null;
|
|
2943
|
+
}, [emailConfirm, email]);
|
|
2944
|
+
const validatePhone = (0, import_react17.useMemo)(() => {
|
|
2945
|
+
if (phone.length === 0) return null;
|
|
2946
|
+
if (!PHONE_RE.test(phone)) return "Telefone inv\xE1lido.";
|
|
2947
|
+
return null;
|
|
2948
|
+
}, [phone]);
|
|
2949
|
+
const validateCpf = (0, import_react17.useMemo)(() => {
|
|
2950
|
+
if (cpf.length === 0) return null;
|
|
2951
|
+
const digits = cpf.replace(/\D/g, "");
|
|
2952
|
+
if (digits.length !== 11) return "CPF deve ter 11 d\xEDgitos.";
|
|
2953
|
+
if (/^(\d)\1+$/.test(digits)) return "CPF inv\xE1lido.";
|
|
2954
|
+
const ok = mod11(digits, 9) === digits[9] && mod11(digits, 10) === digits[10];
|
|
2955
|
+
return ok ? null : "CPF inv\xE1lido.";
|
|
2956
|
+
}, [cpf]);
|
|
2957
|
+
const nameError = touchedName || formSubmitAttempted ? validateName : null;
|
|
2958
|
+
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2959
|
+
const emailConfirmError = touchedEmailConfirm || formSubmitAttempted ? validateEmailConfirm : null;
|
|
2960
|
+
const phoneError = touchedPhone || formSubmitAttempted ? validatePhone : null;
|
|
2961
|
+
const cpfError = touchedCpf || formSubmitAttempted ? validateCpf : null;
|
|
2962
|
+
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);
|
|
2963
|
+
const submit = (0, import_react17.useCallback)(async () => {
|
|
2964
|
+
setFormSubmitAttempted(true);
|
|
2965
|
+
setError(null);
|
|
2966
|
+
setEmailTaken(false);
|
|
2967
|
+
setLoginUrl(null);
|
|
2968
|
+
if (!canSubmit) return null;
|
|
2969
|
+
setSubmitting(true);
|
|
2970
|
+
try {
|
|
2971
|
+
let args2;
|
|
2972
|
+
if (method === "card") {
|
|
2973
|
+
args2 = {
|
|
2974
|
+
method: "card",
|
|
2975
|
+
name: name.trim(),
|
|
2976
|
+
email,
|
|
2977
|
+
emailConfirm,
|
|
2978
|
+
phone,
|
|
2979
|
+
cpf: cpf.replace(/\D/g, ""),
|
|
2980
|
+
cycle,
|
|
2981
|
+
card: {
|
|
2982
|
+
number: card.number.replace(/\s/g, ""),
|
|
2983
|
+
expiryMonth: card.expiryMonth,
|
|
2984
|
+
expiryYear: card.expiryYear,
|
|
2985
|
+
ccv: card.ccv,
|
|
2986
|
+
holderName: card.holderName
|
|
2987
|
+
},
|
|
2988
|
+
cardHolderInfo: {
|
|
2989
|
+
name: card.holderName || name.trim(),
|
|
2990
|
+
email,
|
|
2991
|
+
cpfCnpj: cpf.replace(/\D/g, ""),
|
|
2992
|
+
// Empty postal/address: backend defaults if Asaas requires.
|
|
2993
|
+
// Apps that need full address should override via custom form.
|
|
2994
|
+
postalCode: "00000000",
|
|
2995
|
+
addressNumber: "0",
|
|
2996
|
+
phone
|
|
2997
|
+
}
|
|
2998
|
+
};
|
|
2999
|
+
} else {
|
|
3000
|
+
args2 = {
|
|
3001
|
+
method: "pix-auto",
|
|
3002
|
+
name: name.trim(),
|
|
3003
|
+
email,
|
|
3004
|
+
emailConfirm,
|
|
3005
|
+
phone,
|
|
3006
|
+
cpf: cpf.replace(/\D/g, ""),
|
|
3007
|
+
cycle
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
const result = await auth.subscribeAnonymous(args2);
|
|
3011
|
+
return result;
|
|
3012
|
+
} catch (err) {
|
|
3013
|
+
if (err instanceof import_sdk12.EmailTakenError) {
|
|
3014
|
+
setEmailTaken(true);
|
|
3015
|
+
setLoginUrl(err.loginUrl);
|
|
3016
|
+
setEmailStatus("exists");
|
|
3017
|
+
return null;
|
|
3018
|
+
}
|
|
3019
|
+
setError(mapSdkError(err));
|
|
3020
|
+
return null;
|
|
3021
|
+
} finally {
|
|
3022
|
+
setSubmitting(false);
|
|
3023
|
+
}
|
|
3024
|
+
}, [auth, canSubmit, method, cycle, name, email, emailConfirm, phone, cpf, card]);
|
|
3025
|
+
return {
|
|
3026
|
+
name,
|
|
3027
|
+
setName,
|
|
3028
|
+
email,
|
|
3029
|
+
setEmail,
|
|
3030
|
+
emailConfirm,
|
|
3031
|
+
setEmailConfirm,
|
|
3032
|
+
phone,
|
|
3033
|
+
setPhone,
|
|
3034
|
+
cpf,
|
|
3035
|
+
setCpf,
|
|
3036
|
+
method,
|
|
3037
|
+
setMethod,
|
|
3038
|
+
cycle,
|
|
3039
|
+
setCycle,
|
|
3040
|
+
card,
|
|
3041
|
+
setCard,
|
|
3042
|
+
nameError,
|
|
3043
|
+
emailError,
|
|
3044
|
+
emailConfirmError,
|
|
3045
|
+
phoneError,
|
|
3046
|
+
cpfError,
|
|
3047
|
+
markNameTouched: () => setTouchedName(true),
|
|
3048
|
+
markEmailTouched: () => setTouchedEmail(true),
|
|
3049
|
+
markEmailConfirmTouched: () => setTouchedEmailConfirm(true),
|
|
3050
|
+
markPhoneTouched: () => setTouchedPhone(true),
|
|
3051
|
+
markCpfTouched: () => setTouchedCpf(true),
|
|
3052
|
+
emailStatus,
|
|
3053
|
+
submit,
|
|
3054
|
+
submitting,
|
|
3055
|
+
canSubmit,
|
|
3056
|
+
formSubmitAttempted,
|
|
3057
|
+
error,
|
|
3058
|
+
emailTaken,
|
|
3059
|
+
loginUrl
|
|
3060
|
+
};
|
|
3061
|
+
}
|
|
3062
|
+
function mod11(digits, len) {
|
|
3063
|
+
let sum = 0;
|
|
3064
|
+
for (let i = 0; i < len; i++) sum += parseInt(digits.charAt(i), 10) * (len + 1 - i);
|
|
3065
|
+
const r = sum * 10 % 11;
|
|
3066
|
+
return String(r === 10 ? 0 : r);
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
// src/hooks/usePlan.ts
|
|
3070
|
+
var import_sdk13 = require("@hook-sdk/sdk");
|
|
3071
|
+
function usePlan() {
|
|
3072
|
+
const { plan } = (0, import_sdk13.useHook)();
|
|
3073
|
+
return plan;
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
// src/defaults/CheckoutPageDefault.tsx
|
|
3077
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3078
|
+
var INTENT_KEY = "hook:paywall:intent";
|
|
3079
|
+
var PIX_PAYLOAD_KEY = "hook:paywall:pix-pending";
|
|
3080
|
+
function readIntent() {
|
|
3081
|
+
if (typeof window === "undefined") return {};
|
|
3082
|
+
try {
|
|
3083
|
+
const raw = sessionStorage.getItem(INTENT_KEY);
|
|
3084
|
+
if (!raw) return {};
|
|
3085
|
+
return JSON.parse(raw);
|
|
3086
|
+
} catch {
|
|
3087
|
+
return {};
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
function formatBrl(cents) {
|
|
3091
|
+
return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(cents / 100);
|
|
3092
|
+
}
|
|
3093
|
+
function CheckoutPageDefault() {
|
|
3094
|
+
const navigate = (0, import_react_router_dom3.useNavigate)();
|
|
3095
|
+
const plan = usePlan();
|
|
3096
|
+
const intent = (0, import_react18.useMemo)(readIntent, []);
|
|
3097
|
+
const defaultMethod = intent.method === "pix-auto" ? "pix-auto" : "card";
|
|
3098
|
+
const defaultCycle = intent.cycle === "YEARLY" ? "YEARLY" : "MONTHLY";
|
|
3099
|
+
const form = useCheckoutForm({ defaultMethod, defaultCycle });
|
|
3100
|
+
(0, import_react18.useEffect)(() => {
|
|
3101
|
+
if (form.emailTaken && form.loginUrl) {
|
|
3102
|
+
const t = setTimeout(() => navigate(form.loginUrl), 1200);
|
|
3103
|
+
return () => clearTimeout(t);
|
|
3104
|
+
}
|
|
3105
|
+
}, [form.emailTaken, form.loginUrl, navigate]);
|
|
3106
|
+
const planInfo = plan.data ? {
|
|
3107
|
+
priceCents: plan.data.priceCents,
|
|
3108
|
+
yearlyPriceCents: plan.data.yearlyPriceCents,
|
|
3109
|
+
trialDays: plan.data.trialDays
|
|
3110
|
+
} : null;
|
|
3111
|
+
const cyclePrice = (0, import_react18.useMemo)(() => {
|
|
3112
|
+
if (!planInfo) return null;
|
|
3113
|
+
return form.cycle === "YEARLY" ? planInfo.yearlyPriceCents ?? planInfo.priceCents * 12 : planInfo.priceCents;
|
|
3114
|
+
}, [planInfo, form.cycle]);
|
|
3115
|
+
const submitLabel = (0, import_react18.useMemo)(() => {
|
|
3116
|
+
if (form.submitting) return "Processando\u2026";
|
|
3117
|
+
if (form.method === "card") {
|
|
3118
|
+
const trial = planInfo?.trialDays ?? 0;
|
|
3119
|
+
if (trial > 0 && cyclePrice) {
|
|
3120
|
+
return `Come\xE7ar ${trial} dias gr\xE1tis \xB7 ${formatBrl(cyclePrice)} depois`;
|
|
3121
|
+
}
|
|
3122
|
+
return cyclePrice ? `Pagar ${formatBrl(cyclePrice)}` : "Continuar";
|
|
3123
|
+
}
|
|
3124
|
+
return cyclePrice ? `Pagar ${formatBrl(cyclePrice)} via PIX` : "Continuar via PIX";
|
|
3125
|
+
}, [form.method, form.submitting, planInfo, cyclePrice]);
|
|
3126
|
+
async function onSubmit(e) {
|
|
3127
|
+
e.preventDefault();
|
|
3128
|
+
const result = await form.submit();
|
|
3129
|
+
if (!result) return;
|
|
3130
|
+
if (form.method === "pix-auto" && result.pix_qr_payload) {
|
|
3131
|
+
try {
|
|
3132
|
+
sessionStorage.setItem(
|
|
3133
|
+
PIX_PAYLOAD_KEY,
|
|
3134
|
+
JSON.stringify({
|
|
3135
|
+
payload: result.pix_qr_payload,
|
|
3136
|
+
base64: result.pix_qr_base64 ?? null,
|
|
3137
|
+
subscriptionId: result.subscription_id,
|
|
3138
|
+
pixAuthorizationId: result.pix_authorization_id ?? null
|
|
3139
|
+
})
|
|
3140
|
+
);
|
|
3141
|
+
} catch {
|
|
3142
|
+
}
|
|
3143
|
+
navigate(result.redirect.replace(/^.*\/app\/[^/]+/, ""));
|
|
3144
|
+
return;
|
|
3145
|
+
}
|
|
3146
|
+
navigate(result.redirect.replace(/^.*\/app\/[^/]+/, "") || "/");
|
|
3147
|
+
}
|
|
3148
|
+
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 px-5 py-6 space-y-6", children: [
|
|
3149
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("header", { className: "space-y-2", children: [
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h1", { className: "font-display text-2xl text-foreground", children: "Finalizar assinatura" }),
|
|
3151
|
+
/* @__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." })
|
|
3152
|
+
] }),
|
|
3153
|
+
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: [
|
|
3154
|
+
"Esse e-mail j\xE1 tem conta nesse app.",
|
|
3155
|
+
" ",
|
|
3156
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: form.loginUrl ?? "/signin", className: "underline font-medium", children: "Entrar agora" })
|
|
3157
|
+
] }) : null,
|
|
3158
|
+
form.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { role: "alert", className: "rounded-xl 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,
|
|
3159
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "space-y-3", children: [
|
|
3160
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-sm font-semibold text-foreground uppercase tracking-wide", children: "Voc\xEA" }),
|
|
3161
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3162
|
+
FieldRow,
|
|
3163
|
+
{
|
|
3164
|
+
label: "Nome completo",
|
|
3165
|
+
value: form.name,
|
|
3166
|
+
onChange: form.setName,
|
|
3167
|
+
onBlur: form.markNameTouched,
|
|
3168
|
+
error: form.nameError,
|
|
3169
|
+
autoComplete: "name"
|
|
3170
|
+
}
|
|
3171
|
+
),
|
|
3172
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3173
|
+
FieldRow,
|
|
3174
|
+
{
|
|
3175
|
+
label: "E-mail",
|
|
3176
|
+
type: "email",
|
|
3177
|
+
value: form.email,
|
|
3178
|
+
onChange: form.setEmail,
|
|
3179
|
+
onBlur: form.markEmailTouched,
|
|
3180
|
+
error: form.emailError,
|
|
3181
|
+
autoComplete: "email",
|
|
3182
|
+
autoCapitalize: "none",
|
|
3183
|
+
autoCorrect: "off",
|
|
3184
|
+
spellCheck: false,
|
|
3185
|
+
hint: form.emailStatus === "checking" ? "Verificando\u2026" : form.emailStatus === "available" ? "\u2713 Dispon\xEDvel" : form.emailStatus === "exists" ? null : null
|
|
3186
|
+
}
|
|
3187
|
+
),
|
|
3188
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3189
|
+
FieldRow,
|
|
3190
|
+
{
|
|
3191
|
+
label: "Confirme o e-mail",
|
|
3192
|
+
type: "email",
|
|
3193
|
+
value: form.emailConfirm,
|
|
3194
|
+
onChange: form.setEmailConfirm,
|
|
3195
|
+
onBlur: form.markEmailConfirmTouched,
|
|
3196
|
+
error: form.emailConfirmError,
|
|
3197
|
+
autoComplete: "email",
|
|
3198
|
+
autoCapitalize: "none",
|
|
3199
|
+
autoCorrect: "off",
|
|
3200
|
+
spellCheck: false
|
|
3201
|
+
}
|
|
3202
|
+
),
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3204
|
+
FieldRow,
|
|
3205
|
+
{
|
|
3206
|
+
label: "Telefone",
|
|
3207
|
+
type: "tel",
|
|
3208
|
+
value: form.phone,
|
|
3209
|
+
onChange: form.setPhone,
|
|
3210
|
+
onBlur: form.markPhoneTouched,
|
|
3211
|
+
error: form.phoneError,
|
|
3212
|
+
autoComplete: "tel",
|
|
3213
|
+
placeholder: "(11) 99999-9999"
|
|
3214
|
+
}
|
|
3215
|
+
),
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3217
|
+
FieldRow,
|
|
3218
|
+
{
|
|
3219
|
+
label: "CPF",
|
|
3220
|
+
type: "text",
|
|
3221
|
+
inputMode: "numeric",
|
|
3222
|
+
value: form.cpf,
|
|
3223
|
+
onChange: form.setCpf,
|
|
3224
|
+
onBlur: form.markCpfTouched,
|
|
3225
|
+
error: form.cpfError,
|
|
3226
|
+
autoComplete: "off",
|
|
3227
|
+
placeholder: "000.000.000-00"
|
|
3228
|
+
}
|
|
3229
|
+
)
|
|
3230
|
+
] }),
|
|
3231
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("section", { className: "space-y-3", children: [
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-sm font-semibold text-foreground uppercase tracking-wide", children: "Pagamento" }),
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-2", role: "tablist", children: [
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.method === "card", onClick: () => form.setMethod("card"), children: "Cart\xE3o" }),
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.method === "pix-auto", onClick: () => form.setMethod("pix-auto"), children: "PIX" })
|
|
3236
|
+
] }),
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-2 gap-2", role: "tablist", children: [
|
|
3238
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.cycle === "MONTHLY", onClick: () => form.setCycle("MONTHLY"), children: "Mensal" }),
|
|
3239
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(MethodTab, { active: form.cycle === "YEARLY", onClick: () => form.setCycle("YEARLY"), children: "Anual" })
|
|
3240
|
+
] }),
|
|
3241
|
+
form.method === "card" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "space-y-3 rounded-xl border border-border p-4", children: [
|
|
3242
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3243
|
+
FieldRow,
|
|
3244
|
+
{
|
|
3245
|
+
label: "Nome no cart\xE3o",
|
|
3246
|
+
value: form.card.holderName,
|
|
3247
|
+
onChange: (v) => form.setCard({ holderName: v }),
|
|
3248
|
+
autoComplete: "cc-name"
|
|
3249
|
+
}
|
|
3250
|
+
),
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3252
|
+
FieldRow,
|
|
3253
|
+
{
|
|
3254
|
+
label: "N\xFAmero",
|
|
3255
|
+
value: form.card.number,
|
|
3256
|
+
onChange: (v) => form.setCard({ number: v }),
|
|
3257
|
+
autoComplete: "cc-number",
|
|
3258
|
+
inputMode: "numeric",
|
|
3259
|
+
placeholder: "0000 0000 0000 0000"
|
|
3260
|
+
}
|
|
3261
|
+
),
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3264
|
+
FieldRow,
|
|
3265
|
+
{
|
|
3266
|
+
label: "M\xEAs",
|
|
3267
|
+
value: form.card.expiryMonth,
|
|
3268
|
+
onChange: (v) => form.setCard({ expiryMonth: v }),
|
|
3269
|
+
autoComplete: "cc-exp-month",
|
|
3270
|
+
inputMode: "numeric",
|
|
3271
|
+
placeholder: "MM"
|
|
3272
|
+
}
|
|
3273
|
+
),
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3275
|
+
FieldRow,
|
|
3276
|
+
{
|
|
3277
|
+
label: "Ano",
|
|
3278
|
+
value: form.card.expiryYear,
|
|
3279
|
+
onChange: (v) => form.setCard({ expiryYear: v }),
|
|
3280
|
+
autoComplete: "cc-exp-year",
|
|
3281
|
+
inputMode: "numeric",
|
|
3282
|
+
placeholder: "AA"
|
|
3283
|
+
}
|
|
3284
|
+
),
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3286
|
+
FieldRow,
|
|
3287
|
+
{
|
|
3288
|
+
label: "CVV",
|
|
3289
|
+
value: form.card.ccv,
|
|
3290
|
+
onChange: (v) => form.setCard({ ccv: v }),
|
|
3291
|
+
autoComplete: "cc-csc",
|
|
3292
|
+
inputMode: "numeric",
|
|
3293
|
+
placeholder: "123"
|
|
3294
|
+
}
|
|
3295
|
+
)
|
|
3296
|
+
] })
|
|
3297
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "rounded-xl border border-border p-4 text-sm text-muted-foreground", children: "Ap\xF3s confirmar, mostraremos o QR Code PIX. Pagamento \xE0 vista." })
|
|
3298
|
+
] }),
|
|
3299
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3300
|
+
"button",
|
|
3301
|
+
{
|
|
3302
|
+
type: "submit",
|
|
3303
|
+
disabled: !form.canSubmit,
|
|
3304
|
+
className: "w-full rounded-xl bg-primary py-4 text-base font-semibold text-primary-foreground disabled:opacity-50 disabled:cursor-not-allowed",
|
|
3305
|
+
children: submitLabel
|
|
3306
|
+
}
|
|
3307
|
+
),
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-center text-xs text-muted-foreground", children: "\u{1F512} SSL \xB7 via Asaas \xB7 Garantia 7 dias" })
|
|
3309
|
+
] }) });
|
|
3310
|
+
}
|
|
3311
|
+
function FieldRow(props) {
|
|
3312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "block space-y-1", children: [
|
|
3313
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "block text-sm font-medium text-foreground", children: props.label }),
|
|
3314
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3315
|
+
"input",
|
|
3316
|
+
{
|
|
3317
|
+
type: props.type ?? "text",
|
|
3318
|
+
value: props.value,
|
|
3319
|
+
onChange: (e) => props.onChange(e.target.value),
|
|
3320
|
+
onBlur: props.onBlur,
|
|
3321
|
+
autoComplete: props.autoComplete,
|
|
3322
|
+
autoCapitalize: props.autoCapitalize,
|
|
3323
|
+
autoCorrect: props.autoCorrect,
|
|
3324
|
+
spellCheck: props.spellCheck,
|
|
3325
|
+
inputMode: props.inputMode,
|
|
3326
|
+
placeholder: props.placeholder,
|
|
3327
|
+
className: `w-full rounded-xl border bg-card px-3 py-2 text-base text-foreground outline-none focus:ring-2 focus:ring-primary ${props.error ? "border-destructive" : "border-border"}`
|
|
3328
|
+
}
|
|
3329
|
+
),
|
|
3330
|
+
props.error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "block text-xs text-destructive", children: props.error }) : props.hint ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "block text-xs text-muted-foreground", children: props.hint }) : null
|
|
3331
|
+
] });
|
|
3332
|
+
}
|
|
3333
|
+
function MethodTab({ active, onClick, children }) {
|
|
3334
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3335
|
+
"button",
|
|
3336
|
+
{
|
|
3337
|
+
type: "button",
|
|
3338
|
+
role: "tab",
|
|
3339
|
+
"aria-selected": active,
|
|
3340
|
+
onClick,
|
|
3341
|
+
className: `rounded-xl border px-4 py-2 text-sm font-medium transition ${active ? "border-primary bg-primary text-primary-foreground" : "border-border bg-card text-foreground"}`,
|
|
3342
|
+
children
|
|
3343
|
+
}
|
|
3344
|
+
);
|
|
3345
|
+
}
|
|
3346
|
+
|
|
3347
|
+
// src/defaults/PixWaitingPageDefault.tsx
|
|
3348
|
+
var import_react19 = require("react");
|
|
3349
|
+
var import_react_router_dom4 = require("react-router-dom");
|
|
3350
|
+
var import_sdk14 = require("@hook-sdk/sdk");
|
|
3351
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3352
|
+
var PIX_PAYLOAD_KEY2 = "hook:paywall:pix-pending";
|
|
3353
|
+
var TIMEOUT_MS = 30 * 60 * 1e3;
|
|
3354
|
+
function readPixPayload() {
|
|
3355
|
+
if (typeof window === "undefined") return null;
|
|
3356
|
+
try {
|
|
3357
|
+
const raw = sessionStorage.getItem(PIX_PAYLOAD_KEY2);
|
|
3358
|
+
if (!raw) return null;
|
|
3359
|
+
return JSON.parse(raw);
|
|
3360
|
+
} catch {
|
|
3361
|
+
return null;
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
function clearPixPayload() {
|
|
3365
|
+
if (typeof window === "undefined") return;
|
|
3366
|
+
try {
|
|
3367
|
+
sessionStorage.removeItem(PIX_PAYLOAD_KEY2);
|
|
3368
|
+
} catch {
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
function PixWaitingPageDefault() {
|
|
3372
|
+
const navigate = (0, import_react_router_dom4.useNavigate)();
|
|
3373
|
+
const { subscription } = (0, import_sdk14.useHook)();
|
|
3374
|
+
const payload = (0, import_react19.useMemo)(readPixPayload, []);
|
|
3375
|
+
const [copied, setCopied] = (0, import_react19.useState)(false);
|
|
3376
|
+
const [timedOut, setTimedOut] = (0, import_react19.useState)(false);
|
|
3377
|
+
(0, import_react19.useEffect)(() => {
|
|
3378
|
+
if (!payload) navigate("/paywall/checkout", { replace: true });
|
|
3379
|
+
}, [payload, navigate]);
|
|
3380
|
+
(0, import_react19.useEffect)(() => {
|
|
3381
|
+
const t = setTimeout(() => setTimedOut(true), TIMEOUT_MS);
|
|
3382
|
+
return () => clearTimeout(t);
|
|
3383
|
+
}, []);
|
|
3384
|
+
const hasAccess = subscription.hasAccess;
|
|
3385
|
+
(0, import_react19.useEffect)(() => {
|
|
3386
|
+
if (hasAccess) {
|
|
3387
|
+
clearPixPayload();
|
|
3388
|
+
navigate("/", { replace: true });
|
|
3389
|
+
}
|
|
3390
|
+
}, [hasAccess, navigate]);
|
|
3391
|
+
async function copyPayload() {
|
|
3392
|
+
if (!payload?.payload) return;
|
|
3393
|
+
try {
|
|
3394
|
+
await navigator.clipboard.writeText(payload.payload);
|
|
3395
|
+
setCopied(true);
|
|
3396
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
3397
|
+
} catch {
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
if (!payload) return null;
|
|
3401
|
+
if (timedOut) {
|
|
3402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex-1 flex flex-col items-center justify-center px-6 py-10 text-center bg-background space-y-4", children: [
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h1", { className: "font-display text-2xl text-foreground", children: "PIX expirado" }),
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm text-muted-foreground", children: "O tempo pra pagar acabou. Gere um novo PIX." }),
|
|
3405
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3406
|
+
"button",
|
|
3407
|
+
{
|
|
3408
|
+
onClick: () => {
|
|
3409
|
+
clearPixPayload();
|
|
3410
|
+
navigate("/paywall/checkout", { replace: true });
|
|
3411
|
+
},
|
|
3412
|
+
className: "rounded-xl bg-primary px-6 py-3 text-base font-semibold text-primary-foreground",
|
|
3413
|
+
children: "Tentar novamente"
|
|
3414
|
+
}
|
|
3415
|
+
)
|
|
3416
|
+
] });
|
|
3417
|
+
}
|
|
3418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex-1 flex flex-col items-center px-6 py-8 bg-background space-y-6", children: [
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("header", { className: "text-center space-y-2", children: [
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h1", { className: "font-display text-2xl text-foreground", children: "Pague o PIX" }),
|
|
3421
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm text-muted-foreground", children: "Escaneie o QR Code no app do seu banco. O acesso libera assim que confirmarmos o pagamento." })
|
|
3422
|
+
] }),
|
|
3423
|
+
payload.base64 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3424
|
+
"img",
|
|
3425
|
+
{
|
|
3426
|
+
src: `data:image/png;base64,${payload.base64}`,
|
|
3427
|
+
alt: "QR Code PIX",
|
|
3428
|
+
className: "w-64 h-64 rounded-2xl border border-border bg-card p-2"
|
|
3429
|
+
}
|
|
3430
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "w-64 h-64 rounded-2xl border border-border bg-card flex items-center justify-center text-sm text-muted-foreground", children: "QR indispon\xEDvel" }),
|
|
3431
|
+
payload.payload ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3432
|
+
"button",
|
|
3433
|
+
{
|
|
3434
|
+
onClick: copyPayload,
|
|
3435
|
+
className: "w-full max-w-xs rounded-xl border border-border bg-card px-4 py-3 text-sm font-medium text-foreground",
|
|
3436
|
+
children: copied ? "\u2713 Copiado!" : "Copiar c\xF3digo PIX"
|
|
3437
|
+
}
|
|
3438
|
+
) : null,
|
|
3439
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
3440
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "inline-block w-2 h-2 rounded-full bg-primary animate-pulse" }),
|
|
3441
|
+
"Aguardando pagamento\u2026"
|
|
3442
|
+
] }),
|
|
3443
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-center text-xs text-muted-foreground", children: "Pode fechar essa janela \u2014 tamb\xE9m enviamos um link de acesso pro seu e-mail." })
|
|
3444
|
+
] });
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
// src/hooks/useLoginForm.ts
|
|
3448
|
+
var import_react20 = require("react");
|
|
3449
|
+
var import_sdk15 = require("@hook-sdk/sdk");
|
|
3450
|
+
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2910
3451
|
var MIN_PASSWORD = 8;
|
|
2911
3452
|
function useLoginForm() {
|
|
2912
|
-
const { auth } = (0,
|
|
2913
|
-
const [email, setEmail] = (0,
|
|
2914
|
-
const [password, setPassword] = (0,
|
|
2915
|
-
const [submitting, setSubmitting] = (0,
|
|
2916
|
-
const [error, setError] = (0,
|
|
2917
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2918
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2919
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2920
|
-
const validateEmail = (0,
|
|
3453
|
+
const { auth } = (0, import_sdk15.useHook)();
|
|
3454
|
+
const [email, setEmail] = (0, import_react20.useState)("");
|
|
3455
|
+
const [password, setPassword] = (0, import_react20.useState)("");
|
|
3456
|
+
const [submitting, setSubmitting] = (0, import_react20.useState)(false);
|
|
3457
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
3458
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react20.useState)(false);
|
|
3459
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react20.useState)(false);
|
|
3460
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react20.useState)(false);
|
|
3461
|
+
const validateEmail = (0, import_react20.useMemo)(() => {
|
|
2921
3462
|
if (email.length === 0) return null;
|
|
2922
|
-
if (!
|
|
3463
|
+
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2923
3464
|
return null;
|
|
2924
3465
|
}, [email]);
|
|
2925
|
-
const validatePassword = (0,
|
|
3466
|
+
const validatePassword = (0, import_react20.useMemo)(() => {
|
|
2926
3467
|
if (password.length === 0) return null;
|
|
2927
3468
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
2928
3469
|
return null;
|
|
@@ -2930,7 +3471,7 @@ function useLoginForm() {
|
|
|
2930
3471
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2931
3472
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2932
3473
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
|
|
2933
|
-
const submit = (0,
|
|
3474
|
+
const submit = (0, import_react20.useCallback)(async () => {
|
|
2934
3475
|
setFormSubmitAttempted(true);
|
|
2935
3476
|
if (!canSubmit) return false;
|
|
2936
3477
|
setSubmitting(true);
|
|
@@ -2964,32 +3505,32 @@ function useLoginForm() {
|
|
|
2964
3505
|
}
|
|
2965
3506
|
|
|
2966
3507
|
// src/hooks/useSignupForm.ts
|
|
2967
|
-
var
|
|
2968
|
-
var
|
|
2969
|
-
var
|
|
3508
|
+
var import_react21 = require("react");
|
|
3509
|
+
var import_sdk16 = require("@hook-sdk/sdk");
|
|
3510
|
+
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2970
3511
|
var MIN_PASSWORD2 = 8;
|
|
2971
3512
|
function useSignupForm() {
|
|
2972
|
-
const { auth } = (0,
|
|
2973
|
-
const [name, setName] = (0,
|
|
2974
|
-
const [email, setEmail] = (0,
|
|
2975
|
-
const [password, setPassword] = (0,
|
|
2976
|
-
const [submitting, setSubmitting] = (0,
|
|
2977
|
-
const [error, setError] = (0,
|
|
2978
|
-
const [touchedName, setTouchedName] = (0,
|
|
2979
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2980
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2981
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2982
|
-
const validateName = (0,
|
|
3513
|
+
const { auth } = (0, import_sdk16.useHook)();
|
|
3514
|
+
const [name, setName] = (0, import_react21.useState)("");
|
|
3515
|
+
const [email, setEmail] = (0, import_react21.useState)("");
|
|
3516
|
+
const [password, setPassword] = (0, import_react21.useState)("");
|
|
3517
|
+
const [submitting, setSubmitting] = (0, import_react21.useState)(false);
|
|
3518
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
3519
|
+
const [touchedName, setTouchedName] = (0, import_react21.useState)(false);
|
|
3520
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react21.useState)(false);
|
|
3521
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react21.useState)(false);
|
|
3522
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react21.useState)(false);
|
|
3523
|
+
const validateName = (0, import_react21.useMemo)(() => {
|
|
2983
3524
|
if (name.length === 0) return null;
|
|
2984
3525
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2985
3526
|
return null;
|
|
2986
3527
|
}, [name]);
|
|
2987
|
-
const validateEmail = (0,
|
|
3528
|
+
const validateEmail = (0, import_react21.useMemo)(() => {
|
|
2988
3529
|
if (email.length === 0) return null;
|
|
2989
|
-
if (!
|
|
3530
|
+
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2990
3531
|
return null;
|
|
2991
3532
|
}, [email]);
|
|
2992
|
-
const validatePassword = (0,
|
|
3533
|
+
const validatePassword = (0, import_react21.useMemo)(() => {
|
|
2993
3534
|
if (password.length === 0) return null;
|
|
2994
3535
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
2995
3536
|
return null;
|
|
@@ -2998,7 +3539,7 @@ function useSignupForm() {
|
|
|
2998
3539
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2999
3540
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
3000
3541
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
|
|
3001
|
-
const submit = (0,
|
|
3542
|
+
const submit = (0, import_react21.useCallback)(async () => {
|
|
3002
3543
|
setFormSubmitAttempted(true);
|
|
3003
3544
|
if (!canSubmit) return false;
|
|
3004
3545
|
setSubmitting(true);
|
|
@@ -3036,25 +3577,25 @@ function useSignupForm() {
|
|
|
3036
3577
|
}
|
|
3037
3578
|
|
|
3038
3579
|
// src/hooks/useForgotForm.ts
|
|
3039
|
-
var
|
|
3040
|
-
var
|
|
3041
|
-
var
|
|
3580
|
+
var import_react22 = require("react");
|
|
3581
|
+
var import_sdk17 = require("@hook-sdk/sdk");
|
|
3582
|
+
var EMAIL_RE4 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3042
3583
|
function useForgotForm() {
|
|
3043
|
-
const { auth } = (0,
|
|
3044
|
-
const [email, setEmail] = (0,
|
|
3045
|
-
const [submitting, setSubmitting] = (0,
|
|
3046
|
-
const [sent, setSent] = (0,
|
|
3047
|
-
const [error, setError] = (0,
|
|
3048
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
3049
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
3050
|
-
const validateEmail = (0,
|
|
3584
|
+
const { auth } = (0, import_sdk17.useHook)();
|
|
3585
|
+
const [email, setEmail] = (0, import_react22.useState)("");
|
|
3586
|
+
const [submitting, setSubmitting] = (0, import_react22.useState)(false);
|
|
3587
|
+
const [sent, setSent] = (0, import_react22.useState)(false);
|
|
3588
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
3589
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react22.useState)(false);
|
|
3590
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react22.useState)(false);
|
|
3591
|
+
const validateEmail = (0, import_react22.useMemo)(() => {
|
|
3051
3592
|
if (email.length === 0) return null;
|
|
3052
|
-
if (!
|
|
3593
|
+
if (!EMAIL_RE4.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
3053
3594
|
return null;
|
|
3054
3595
|
}, [email]);
|
|
3055
3596
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
3056
3597
|
const canSubmit = email.length > 0 && validateEmail === null && !submitting;
|
|
3057
|
-
const submit = (0,
|
|
3598
|
+
const submit = (0, import_react22.useCallback)(async () => {
|
|
3058
3599
|
setFormSubmitAttempted(true);
|
|
3059
3600
|
if (!canSubmit) return false;
|
|
3060
3601
|
setSubmitting(true);
|
|
@@ -3085,32 +3626,32 @@ function useForgotForm() {
|
|
|
3085
3626
|
}
|
|
3086
3627
|
|
|
3087
3628
|
// src/hooks/useResetForm.ts
|
|
3088
|
-
var
|
|
3089
|
-
var
|
|
3090
|
-
var MIN_PASSWORD3 =
|
|
3629
|
+
var import_react23 = require("react");
|
|
3630
|
+
var import_sdk18 = require("@hook-sdk/sdk");
|
|
3631
|
+
var MIN_PASSWORD3 = 12;
|
|
3091
3632
|
function useResetForm() {
|
|
3092
|
-
const { auth } = (0,
|
|
3093
|
-
const [token, setToken] = (0,
|
|
3094
|
-
const [password, setPassword] = (0,
|
|
3095
|
-
const [confirm, setConfirm] = (0,
|
|
3096
|
-
const [submitting, setSubmitting] = (0,
|
|
3097
|
-
const [done, setDone] = (0,
|
|
3098
|
-
const [error, setError] = (0,
|
|
3099
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
3100
|
-
const [touchedConfirm, setTouchedConfirm] = (0,
|
|
3101
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
3102
|
-
(0,
|
|
3633
|
+
const { auth } = (0, import_sdk18.useHook)();
|
|
3634
|
+
const [token, setToken] = (0, import_react23.useState)(null);
|
|
3635
|
+
const [password, setPassword] = (0, import_react23.useState)("");
|
|
3636
|
+
const [confirm, setConfirm] = (0, import_react23.useState)("");
|
|
3637
|
+
const [submitting, setSubmitting] = (0, import_react23.useState)(false);
|
|
3638
|
+
const [done, setDone] = (0, import_react23.useState)(false);
|
|
3639
|
+
const [error, setError] = (0, import_react23.useState)(null);
|
|
3640
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react23.useState)(false);
|
|
3641
|
+
const [touchedConfirm, setTouchedConfirm] = (0, import_react23.useState)(false);
|
|
3642
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react23.useState)(false);
|
|
3643
|
+
(0, import_react23.useEffect)(() => {
|
|
3103
3644
|
if (typeof window === "undefined") return;
|
|
3104
3645
|
const params = new URLSearchParams(window.location.search);
|
|
3105
3646
|
const t = params.get("token");
|
|
3106
3647
|
setToken(t && t.length > 0 ? t : null);
|
|
3107
3648
|
}, []);
|
|
3108
|
-
const validatePassword = (0,
|
|
3649
|
+
const validatePassword = (0, import_react23.useMemo)(() => {
|
|
3109
3650
|
if (password.length === 0) return null;
|
|
3110
3651
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
3111
3652
|
return null;
|
|
3112
3653
|
}, [password]);
|
|
3113
|
-
const validateConfirm = (0,
|
|
3654
|
+
const validateConfirm = (0, import_react23.useMemo)(() => {
|
|
3114
3655
|
if (confirm.length === 0) return null;
|
|
3115
3656
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
3116
3657
|
return null;
|
|
@@ -3118,7 +3659,7 @@ function useResetForm() {
|
|
|
3118
3659
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
3119
3660
|
const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
|
|
3120
3661
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
|
|
3121
|
-
const submit = (0,
|
|
3662
|
+
const submit = (0, import_react23.useCallback)(async () => {
|
|
3122
3663
|
setFormSubmitAttempted(true);
|
|
3123
3664
|
if (!canSubmit || token === null) return;
|
|
3124
3665
|
setSubmitting(true);
|
|
@@ -3157,13 +3698,6 @@ function useResetForm() {
|
|
|
3157
3698
|
};
|
|
3158
3699
|
}
|
|
3159
3700
|
|
|
3160
|
-
// src/hooks/usePlan.ts
|
|
3161
|
-
var import_sdk17 = require("@hook-sdk/sdk");
|
|
3162
|
-
function usePlan() {
|
|
3163
|
-
const { plan } = (0, import_sdk17.useHook)();
|
|
3164
|
-
return plan;
|
|
3165
|
-
}
|
|
3166
|
-
|
|
3167
3701
|
// src/utils/price.ts
|
|
3168
3702
|
function formatBRL(cents) {
|
|
3169
3703
|
if (cents === null || cents === void 0) return "";
|
|
@@ -3193,12 +3727,12 @@ function discountPercent(anchorCents, realCents) {
|
|
|
3193
3727
|
}
|
|
3194
3728
|
|
|
3195
3729
|
// src/hooks/useAuthPrimitives.ts
|
|
3196
|
-
var
|
|
3197
|
-
var
|
|
3730
|
+
var import_react24 = require("react");
|
|
3731
|
+
var import_sdk19 = require("@hook-sdk/sdk");
|
|
3198
3732
|
var warned = false;
|
|
3199
3733
|
function useAuthPrimitives() {
|
|
3200
|
-
const { auth } = (0,
|
|
3201
|
-
(0,
|
|
3734
|
+
const { auth } = (0, import_sdk19.useHook)();
|
|
3735
|
+
(0, import_react24.useEffect)(() => {
|
|
3202
3736
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
3203
3737
|
warned = true;
|
|
3204
3738
|
console.warn(
|
|
@@ -3220,9 +3754,9 @@ function useAuthPrimitives() {
|
|
|
3220
3754
|
}
|
|
3221
3755
|
|
|
3222
3756
|
// src/hooks/useAuth.ts
|
|
3223
|
-
var
|
|
3757
|
+
var import_sdk20 = require("@hook-sdk/sdk");
|
|
3224
3758
|
function useAuth() {
|
|
3225
|
-
const { user, authStatus, auth } = (0,
|
|
3759
|
+
const { user, authStatus, auth } = (0, import_sdk20.useHook)();
|
|
3226
3760
|
return {
|
|
3227
3761
|
user,
|
|
3228
3762
|
authStatus,
|
|
@@ -3231,26 +3765,26 @@ function useAuth() {
|
|
|
3231
3765
|
}
|
|
3232
3766
|
|
|
3233
3767
|
// src/index.ts
|
|
3234
|
-
var
|
|
3768
|
+
var import_sdk25 = require("@hook-sdk/sdk");
|
|
3235
3769
|
|
|
3236
3770
|
// src/hooks/useSubscription.ts
|
|
3237
|
-
var
|
|
3771
|
+
var import_sdk21 = require("@hook-sdk/sdk");
|
|
3238
3772
|
function useSubscription() {
|
|
3239
|
-
const { subscription } = (0,
|
|
3773
|
+
const { subscription } = (0, import_sdk21.useHook)();
|
|
3240
3774
|
return {
|
|
3241
3775
|
status: subscription.status()
|
|
3242
3776
|
};
|
|
3243
3777
|
}
|
|
3244
3778
|
|
|
3245
3779
|
// src/hooks/useReminders.ts
|
|
3246
|
-
var
|
|
3247
|
-
var
|
|
3780
|
+
var import_react25 = require("react");
|
|
3781
|
+
var import_sdk22 = require("@hook-sdk/sdk");
|
|
3248
3782
|
function useReminders() {
|
|
3249
|
-
const { push } = (0,
|
|
3783
|
+
const { push } = (0, import_sdk22.useHook)();
|
|
3250
3784
|
const r = push.reminders;
|
|
3251
|
-
const [reminders, setReminders] = (0,
|
|
3252
|
-
const [loading, setLoading] = (0,
|
|
3253
|
-
const reload = (0,
|
|
3785
|
+
const [reminders, setReminders] = (0, import_react25.useState)([]);
|
|
3786
|
+
const [loading, setLoading] = (0, import_react25.useState)(true);
|
|
3787
|
+
const reload = (0, import_react25.useCallback)(async () => {
|
|
3254
3788
|
setLoading(true);
|
|
3255
3789
|
try {
|
|
3256
3790
|
const next = await r.list();
|
|
@@ -3259,59 +3793,59 @@ function useReminders() {
|
|
|
3259
3793
|
setLoading(false);
|
|
3260
3794
|
}
|
|
3261
3795
|
}, [r]);
|
|
3262
|
-
(0,
|
|
3796
|
+
(0, import_react25.useEffect)(() => {
|
|
3263
3797
|
void reload();
|
|
3264
3798
|
}, [reload]);
|
|
3265
|
-
const setReminder = (0,
|
|
3799
|
+
const setReminder = (0, import_react25.useCallback)(async (input) => {
|
|
3266
3800
|
await r.set(input);
|
|
3267
3801
|
await reload();
|
|
3268
3802
|
}, [r, reload]);
|
|
3269
|
-
const deleteReminder = (0,
|
|
3803
|
+
const deleteReminder = (0, import_react25.useCallback)(async (slot) => {
|
|
3270
3804
|
await r.delete(slot);
|
|
3271
3805
|
await reload();
|
|
3272
3806
|
}, [r, reload]);
|
|
3273
|
-
const schedule = (0,
|
|
3807
|
+
const schedule = (0, import_react25.useCallback)(async (items) => {
|
|
3274
3808
|
return r.schedule(items);
|
|
3275
3809
|
}, [r]);
|
|
3276
|
-
const setFallbacks = (0,
|
|
3810
|
+
const setFallbacks = (0, import_react25.useCallback)(async (items) => {
|
|
3277
3811
|
return r.setFallbacks(items);
|
|
3278
3812
|
}, [r]);
|
|
3279
3813
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
3280
3814
|
}
|
|
3281
3815
|
|
|
3282
3816
|
// src/hooks/useToast.ts
|
|
3283
|
-
var
|
|
3817
|
+
var import_react26 = require("react");
|
|
3284
3818
|
function useToast() {
|
|
3285
|
-
const [items, setItems] = (0,
|
|
3286
|
-
const show = (0,
|
|
3819
|
+
const [items, setItems] = (0, import_react26.useState)([]);
|
|
3820
|
+
const show = (0, import_react26.useCallback)((message, kind = "info") => {
|
|
3287
3821
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
3288
3822
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
3289
3823
|
setTimeout(() => {
|
|
3290
3824
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
3291
3825
|
}, 4e3);
|
|
3292
3826
|
}, []);
|
|
3293
|
-
const dismiss = (0,
|
|
3827
|
+
const dismiss = (0, import_react26.useCallback)((id) => {
|
|
3294
3828
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
3295
3829
|
}, []);
|
|
3296
3830
|
return { items, show, dismiss };
|
|
3297
3831
|
}
|
|
3298
3832
|
|
|
3299
3833
|
// src/RouteBoundary.tsx
|
|
3300
|
-
var
|
|
3301
|
-
var
|
|
3834
|
+
var import_react_router_dom5 = require("react-router-dom");
|
|
3835
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3302
3836
|
function RouteBoundary({ children }) {
|
|
3303
|
-
return /* @__PURE__ */ (0,
|
|
3837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_router_dom5.Routes, { children: [
|
|
3304
3838
|
children,
|
|
3305
|
-
/* @__PURE__ */ (0,
|
|
3839
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom5.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DefaultNotFound, {}) })
|
|
3306
3840
|
] });
|
|
3307
3841
|
}
|
|
3308
3842
|
function DefaultNotFound() {
|
|
3309
|
-
return /* @__PURE__ */ (0,
|
|
3843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
|
|
3310
3844
|
}
|
|
3311
3845
|
|
|
3312
3846
|
// src/PreAuthShell.tsx
|
|
3313
|
-
var
|
|
3314
|
-
var
|
|
3847
|
+
var import_react_router_dom6 = require("react-router-dom");
|
|
3848
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3315
3849
|
function PreAuthShell({
|
|
3316
3850
|
basename,
|
|
3317
3851
|
testRouter,
|
|
@@ -3319,20 +3853,20 @@ function PreAuthShell({
|
|
|
3319
3853
|
children
|
|
3320
3854
|
}) {
|
|
3321
3855
|
if (testRouter === "memory") {
|
|
3322
|
-
return /* @__PURE__ */ (0,
|
|
3856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_router_dom6.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_router_dom6.Routes, { children }) });
|
|
3323
3857
|
}
|
|
3324
|
-
return /* @__PURE__ */ (0,
|
|
3858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_router_dom6.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_router_dom6.Routes, { children }) });
|
|
3325
3859
|
}
|
|
3326
3860
|
|
|
3327
3861
|
// src/OnboardingFlow.tsx
|
|
3328
|
-
var
|
|
3329
|
-
var
|
|
3862
|
+
var import_react28 = require("react");
|
|
3863
|
+
var import_sdk23 = require("@hook-sdk/sdk");
|
|
3330
3864
|
|
|
3331
3865
|
// src/hooks/useOnboardingStep.ts
|
|
3332
|
-
var
|
|
3333
|
-
var OnboardingStepContext = (0,
|
|
3866
|
+
var import_react27 = require("react");
|
|
3867
|
+
var OnboardingStepContext = (0, import_react27.createContext)(null);
|
|
3334
3868
|
function useOnboardingStep() {
|
|
3335
|
-
const ctx = (0,
|
|
3869
|
+
const ctx = (0, import_react27.useContext)(OnboardingStepContext);
|
|
3336
3870
|
if (!ctx) {
|
|
3337
3871
|
throw new Error(
|
|
3338
3872
|
"[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
|
|
@@ -3342,7 +3876,7 @@ function useOnboardingStep() {
|
|
|
3342
3876
|
}
|
|
3343
3877
|
|
|
3344
3878
|
// src/OnboardingFlow.tsx
|
|
3345
|
-
var
|
|
3879
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3346
3880
|
var isFilled = (v) => v != null && v !== "";
|
|
3347
3881
|
var CURRENT_STEP_FIELD = "currentStep";
|
|
3348
3882
|
function readPersistedStepIdx(draft) {
|
|
@@ -3355,12 +3889,12 @@ function OnboardingFlow({
|
|
|
3355
3889
|
onComplete,
|
|
3356
3890
|
persistKey
|
|
3357
3891
|
}) {
|
|
3358
|
-
const [draft, setDraft, status] = (0,
|
|
3359
|
-
const draftRef = (0,
|
|
3892
|
+
const [draft, setDraft, status] = (0, import_sdk23.usePersistedState)(persistKey, {});
|
|
3893
|
+
const draftRef = (0, import_react28.useRef)(draft);
|
|
3360
3894
|
draftRef.current = draft;
|
|
3361
3895
|
const idx = readPersistedStepIdx(draft);
|
|
3362
3896
|
const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
|
|
3363
|
-
const setIdx = (0,
|
|
3897
|
+
const setIdx = (0, import_react28.useCallback)(
|
|
3364
3898
|
(n) => {
|
|
3365
3899
|
setDraft((prev) => {
|
|
3366
3900
|
const prevIdx = readPersistedStepIdx(prev);
|
|
@@ -3370,7 +3904,7 @@ function OnboardingFlow({
|
|
|
3370
3904
|
},
|
|
3371
3905
|
[setDraft]
|
|
3372
3906
|
);
|
|
3373
|
-
const setValue = (0,
|
|
3907
|
+
const setValue = (0, import_react28.useCallback)(
|
|
3374
3908
|
(patch) => {
|
|
3375
3909
|
draftRef.current = { ...draftRef.current, ...patch };
|
|
3376
3910
|
setDraft((prev) => ({ ...prev, ...patch }));
|
|
@@ -3378,9 +3912,9 @@ function OnboardingFlow({
|
|
|
3378
3912
|
[setDraft]
|
|
3379
3913
|
);
|
|
3380
3914
|
const step = steps[clampedIdx];
|
|
3381
|
-
const hookCtx = (0,
|
|
3915
|
+
const hookCtx = (0, import_sdk23.useHook)();
|
|
3382
3916
|
const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
|
|
3383
|
-
(0,
|
|
3917
|
+
(0, import_react28.useEffect)(() => {
|
|
3384
3918
|
if (status.loading) return;
|
|
3385
3919
|
if (!step) return;
|
|
3386
3920
|
if (!track2) return;
|
|
@@ -3390,11 +3924,11 @@ function OnboardingFlow({
|
|
|
3390
3924
|
total_steps: steps.length
|
|
3391
3925
|
});
|
|
3392
3926
|
}, [step?.id, clampedIdx, steps.length, status.loading, track2]);
|
|
3393
|
-
const valid = (0,
|
|
3927
|
+
const valid = (0, import_react28.useMemo)(
|
|
3394
3928
|
() => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
|
|
3395
3929
|
[draft, step]
|
|
3396
3930
|
);
|
|
3397
|
-
const next = (0,
|
|
3931
|
+
const next = (0, import_react28.useCallback)(() => {
|
|
3398
3932
|
if (!step) return;
|
|
3399
3933
|
const current = draftRef.current;
|
|
3400
3934
|
const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
|
|
@@ -3405,8 +3939,8 @@ function OnboardingFlow({
|
|
|
3405
3939
|
setIdx(clampedIdx + 1);
|
|
3406
3940
|
}
|
|
3407
3941
|
}, [clampedIdx, onComplete, step, steps.length, setIdx]);
|
|
3408
|
-
const prevStep = (0,
|
|
3409
|
-
const ctx = (0,
|
|
3942
|
+
const prevStep = (0, import_react28.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
|
|
3943
|
+
const ctx = (0, import_react28.useMemo)(
|
|
3410
3944
|
() => ({
|
|
3411
3945
|
stepIndex: clampedIdx,
|
|
3412
3946
|
totalSteps: steps.length,
|
|
@@ -3432,7 +3966,7 @@ function OnboardingFlow({
|
|
|
3432
3966
|
`[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
|
|
3433
3967
|
);
|
|
3434
3968
|
}
|
|
3435
|
-
return /* @__PURE__ */ (0,
|
|
3969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Screen, {}) });
|
|
3436
3970
|
}
|
|
3437
3971
|
|
|
3438
3972
|
// src/hooks/useFeature.ts
|
|
@@ -3442,22 +3976,22 @@ function useFeature(name) {
|
|
|
3442
3976
|
}
|
|
3443
3977
|
|
|
3444
3978
|
// src/components/paywall/Paywall.tsx
|
|
3445
|
-
var
|
|
3446
|
-
var
|
|
3979
|
+
var import_react31 = require("react");
|
|
3980
|
+
var import_sdk24 = require("@hook-sdk/sdk");
|
|
3447
3981
|
|
|
3448
3982
|
// src/components/paywall/PaywallProvider.tsx
|
|
3449
|
-
var
|
|
3450
|
-
var
|
|
3451
|
-
var PaywallContext = (0,
|
|
3983
|
+
var import_react29 = require("react");
|
|
3984
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3985
|
+
var PaywallContext = (0, import_react29.createContext)(null);
|
|
3452
3986
|
function PaywallProvider({ children }) {
|
|
3453
3987
|
const state = usePaywallState();
|
|
3454
|
-
return /* @__PURE__ */ (0,
|
|
3988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PaywallContext.Provider, { value: state, children });
|
|
3455
3989
|
}
|
|
3456
3990
|
|
|
3457
3991
|
// src/components/paywall/usePaywallContext.ts
|
|
3458
|
-
var
|
|
3992
|
+
var import_react30 = require("react");
|
|
3459
3993
|
function usePaywallContext() {
|
|
3460
|
-
const ctx = (0,
|
|
3994
|
+
const ctx = (0, import_react30.useContext)(PaywallContext);
|
|
3461
3995
|
if (!ctx) {
|
|
3462
3996
|
throw new Error("usePaywallContext must be used within <PaywallProvider>");
|
|
3463
3997
|
}
|
|
@@ -3465,7 +3999,7 @@ function usePaywallContext() {
|
|
|
3465
3999
|
}
|
|
3466
4000
|
|
|
3467
4001
|
// src/components/paywall/PaywallMethodTabs.tsx
|
|
3468
|
-
var
|
|
4002
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3469
4003
|
function PaywallMethodTabs({
|
|
3470
4004
|
labels,
|
|
3471
4005
|
className,
|
|
@@ -3474,10 +4008,10 @@ function PaywallMethodTabs({
|
|
|
3474
4008
|
}) {
|
|
3475
4009
|
const { methods, selectedMethod, selectMethod } = usePaywallContext();
|
|
3476
4010
|
if (methods.length < 2) return null;
|
|
3477
|
-
return /* @__PURE__ */ (0,
|
|
4011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
|
|
3478
4012
|
const active = m === selectedMethod;
|
|
3479
4013
|
const label = labels[m] ?? m;
|
|
3480
|
-
return /* @__PURE__ */ (0,
|
|
4014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3481
4015
|
"button",
|
|
3482
4016
|
{
|
|
3483
4017
|
type: "button",
|
|
@@ -3495,16 +4029,16 @@ function PaywallMethodTabs({
|
|
|
3495
4029
|
}
|
|
3496
4030
|
|
|
3497
4031
|
// src/components/paywall/PaywallMethodContent.tsx
|
|
3498
|
-
var
|
|
4032
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3499
4033
|
function PaywallMethodContent({ copy, className, rowClassName }) {
|
|
3500
4034
|
const { selectedMethod, hasConsumedTrial } = usePaywallContext();
|
|
3501
4035
|
const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
3502
4036
|
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
3503
|
-
return /* @__PURE__ */ (0,
|
|
4037
|
+
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)) });
|
|
3504
4038
|
}
|
|
3505
4039
|
|
|
3506
4040
|
// src/components/paywall/PaywallCyclePicker.tsx
|
|
3507
|
-
var
|
|
4041
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3508
4042
|
var VARIANT_CLASSES = {
|
|
3509
4043
|
default: { card: "", cardSelected: "" },
|
|
3510
4044
|
"premium-gold": {
|
|
@@ -3529,7 +4063,7 @@ function PaywallCyclePicker({
|
|
|
3529
4063
|
const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
|
|
3530
4064
|
const cycles = ["MONTHLY", "YEARLY"];
|
|
3531
4065
|
if (render) {
|
|
3532
|
-
return /* @__PURE__ */ (0,
|
|
4066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
|
|
3533
4067
|
}
|
|
3534
4068
|
if (cycles.length < 2) return null;
|
|
3535
4069
|
const v = VARIANT_CLASSES[variant];
|
|
@@ -3539,7 +4073,7 @@ function PaywallCyclePicker({
|
|
|
3539
4073
|
const yearlyCents = plan?.yearlyCents ?? 0;
|
|
3540
4074
|
const anchorMonthly = plan?.anchorMonthlyCents ?? null;
|
|
3541
4075
|
const anchorYearly = plan?.anchorYearlyCents ?? null;
|
|
3542
|
-
return /* @__PURE__ */ (0,
|
|
4076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3543
4077
|
"div",
|
|
3544
4078
|
{
|
|
3545
4079
|
role: "radiogroup",
|
|
@@ -3551,7 +4085,7 @@ function PaywallCyclePicker({
|
|
|
3551
4085
|
const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
|
|
3552
4086
|
const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
|
|
3553
4087
|
const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
|
|
3554
|
-
return /* @__PURE__ */ (0,
|
|
4088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3555
4089
|
"button",
|
|
3556
4090
|
{
|
|
3557
4091
|
type: "button",
|
|
@@ -3564,10 +4098,10 @@ function PaywallCyclePicker({
|
|
|
3564
4098
|
active ? composedCardSelectedClassName : ""
|
|
3565
4099
|
].filter(Boolean).join(" "),
|
|
3566
4100
|
children: [
|
|
3567
|
-
/* @__PURE__ */ (0,
|
|
3568
|
-
/* @__PURE__ */ (0,
|
|
3569
|
-
/* @__PURE__ */ (0,
|
|
3570
|
-
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0,
|
|
4101
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
|
|
4102
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
|
|
4103
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
|
|
4104
|
+
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
|
|
3571
4105
|
]
|
|
3572
4106
|
},
|
|
3573
4107
|
c
|
|
@@ -3578,7 +4112,7 @@ function PaywallCyclePicker({
|
|
|
3578
4112
|
}
|
|
3579
4113
|
|
|
3580
4114
|
// src/components/paywall/Paywall.tsx
|
|
3581
|
-
var
|
|
4115
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3582
4116
|
var NBSP = "\xA0";
|
|
3583
4117
|
function Paywall({
|
|
3584
4118
|
copy,
|
|
@@ -3586,7 +4120,7 @@ function Paywall({
|
|
|
3586
4120
|
slots = {},
|
|
3587
4121
|
onBeforeCheckout
|
|
3588
4122
|
}) {
|
|
3589
|
-
return /* @__PURE__ */ (0,
|
|
4123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3590
4124
|
PaywallInner,
|
|
3591
4125
|
{
|
|
3592
4126
|
copy,
|
|
@@ -3602,11 +4136,11 @@ function PaywallInner({
|
|
|
3602
4136
|
slots = {},
|
|
3603
4137
|
onBeforeCheckout
|
|
3604
4138
|
}) {
|
|
3605
|
-
const { track: track2 } = (0,
|
|
4139
|
+
const { track: track2 } = (0, import_sdk24.useHook)();
|
|
3606
4140
|
const s = usePaywallContext();
|
|
3607
4141
|
const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
|
|
3608
4142
|
const trialDaysCardLabel = String(s.trialDaysCard);
|
|
3609
|
-
const ctaLabel = (0,
|
|
4143
|
+
const ctaLabel = (0, import_react31.useMemo)(() => {
|
|
3610
4144
|
if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
|
|
3611
4145
|
if (s.selectedMethod === "card") {
|
|
3612
4146
|
if (s.hasConsumedTrial && copy.cardConsumedTrial) {
|
|
@@ -3633,11 +4167,11 @@ function PaywallInner({
|
|
|
3633
4167
|
priceLabel,
|
|
3634
4168
|
trialDaysCardLabel
|
|
3635
4169
|
]);
|
|
3636
|
-
const switchHint = (0,
|
|
4170
|
+
const switchHint = (0, import_react31.useMemo)(() => {
|
|
3637
4171
|
if (s.methods.length < 2) return void 0;
|
|
3638
4172
|
return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
|
|
3639
4173
|
}, [s.methods.length, s.selectedMethod, copy]);
|
|
3640
|
-
(0,
|
|
4174
|
+
(0, import_react31.useEffect)(() => {
|
|
3641
4175
|
if (!s.initialLoadComplete) return;
|
|
3642
4176
|
track2("paywall_view", {
|
|
3643
4177
|
default_method: s.selectedMethod,
|
|
@@ -3659,15 +4193,15 @@ function PaywallInner({
|
|
|
3659
4193
|
await s.submit();
|
|
3660
4194
|
};
|
|
3661
4195
|
const ctaTheme = s.selectedMethod === "card" ? themeClasses.ctaCard : themeClasses.ctaPix;
|
|
3662
|
-
return /* @__PURE__ */ (0,
|
|
4196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: themeClasses.container, children: [
|
|
3663
4197
|
slots.heroSlot,
|
|
3664
|
-
/* @__PURE__ */ (0,
|
|
3665
|
-
/* @__PURE__ */ (0,
|
|
4198
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h1", { className: themeClasses.headline, children: copy.headline }),
|
|
4199
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { children: copy.features.map((f) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("li", { className: themeClasses.feature, children: [
|
|
3666
4200
|
"\u2713 ",
|
|
3667
|
-
/* @__PURE__ */ (0,
|
|
4201
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: f })
|
|
3668
4202
|
] }, f)) }),
|
|
3669
|
-
copy.socialProof ? /* @__PURE__ */ (0,
|
|
3670
|
-
slots.cyclePickerSlot ?? /* @__PURE__ */ (0,
|
|
4203
|
+
copy.socialProof ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.socialProof, children: copy.socialProof }) : null,
|
|
4204
|
+
slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3671
4205
|
PaywallCyclePicker,
|
|
3672
4206
|
{
|
|
3673
4207
|
labels: copy.cycle,
|
|
@@ -3676,7 +4210,7 @@ function PaywallInner({
|
|
|
3676
4210
|
anchorClassName: themeClasses.anchorPrice
|
|
3677
4211
|
}
|
|
3678
4212
|
),
|
|
3679
|
-
/* @__PURE__ */ (0,
|
|
4213
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3680
4214
|
PaywallMethodTabs,
|
|
3681
4215
|
{
|
|
3682
4216
|
labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
|
|
@@ -3685,7 +4219,7 @@ function PaywallInner({
|
|
|
3685
4219
|
tabActiveClassName: themeClasses.tabActive
|
|
3686
4220
|
}
|
|
3687
4221
|
),
|
|
3688
|
-
/* @__PURE__ */ (0,
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3689
4223
|
PaywallMethodContent,
|
|
3690
4224
|
{
|
|
3691
4225
|
copy: {
|
|
@@ -3703,8 +4237,8 @@ function PaywallInner({
|
|
|
3703
4237
|
}
|
|
3704
4238
|
),
|
|
3705
4239
|
slots.beforeCtaSlot,
|
|
3706
|
-
/* @__PURE__ */ (0,
|
|
3707
|
-
/* @__PURE__ */ (0,
|
|
4240
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
|
|
4241
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3708
4242
|
"button",
|
|
3709
4243
|
{
|
|
3710
4244
|
type: "button",
|
|
@@ -3716,8 +4250,8 @@ function PaywallInner({
|
|
|
3716
4250
|
children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
|
|
3717
4251
|
}
|
|
3718
4252
|
),
|
|
3719
|
-
switchHint ? /* @__PURE__ */ (0,
|
|
3720
|
-
/* @__PURE__ */ (0,
|
|
4253
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
|
|
4254
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
|
|
3721
4255
|
] })
|
|
3722
4256
|
] });
|
|
3723
4257
|
}
|
|
@@ -3734,7 +4268,7 @@ function interpolateCopy(m, price, days) {
|
|
|
3734
4268
|
}
|
|
3735
4269
|
|
|
3736
4270
|
// src/components/paywall/PaywallCta.tsx
|
|
3737
|
-
var
|
|
4271
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3738
4272
|
function PaywallCta({
|
|
3739
4273
|
ctaLabel,
|
|
3740
4274
|
loadingLabel,
|
|
@@ -3747,8 +4281,8 @@ function PaywallCta({
|
|
|
3747
4281
|
}) {
|
|
3748
4282
|
const { submit, submitting } = usePaywallContext();
|
|
3749
4283
|
const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
|
|
3750
|
-
return /* @__PURE__ */ (0,
|
|
3751
|
-
/* @__PURE__ */ (0,
|
|
4284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className, children: [
|
|
4285
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
3752
4286
|
"button",
|
|
3753
4287
|
{
|
|
3754
4288
|
type: "button",
|
|
@@ -3760,20 +4294,20 @@ function PaywallCta({
|
|
|
3760
4294
|
children: label
|
|
3761
4295
|
}
|
|
3762
4296
|
),
|
|
3763
|
-
switchHint ? /* @__PURE__ */ (0,
|
|
3764
|
-
/* @__PURE__ */ (0,
|
|
4297
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
4298
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: trustClassName, children: trustLine })
|
|
3765
4299
|
] });
|
|
3766
4300
|
}
|
|
3767
4301
|
|
|
3768
4302
|
// src/components/paywall/blocks/PaywallEyebrow.tsx
|
|
3769
|
-
var
|
|
4303
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3770
4304
|
var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
|
|
3771
4305
|
function PaywallEyebrow({ text, className }) {
|
|
3772
|
-
return /* @__PURE__ */ (0,
|
|
4306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3773
4307
|
}
|
|
3774
4308
|
|
|
3775
4309
|
// src/components/paywall/blocks/PaywallHero.tsx
|
|
3776
|
-
var
|
|
4310
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3777
4311
|
var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
|
|
3778
4312
|
function PaywallHero({
|
|
3779
4313
|
src,
|
|
@@ -3787,15 +4321,15 @@ function PaywallHero({
|
|
|
3787
4321
|
render
|
|
3788
4322
|
}) {
|
|
3789
4323
|
if (render) {
|
|
3790
|
-
return /* @__PURE__ */ (0,
|
|
4324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className, children: render({ src, headline }) });
|
|
3791
4325
|
}
|
|
3792
|
-
return /* @__PURE__ */ (0,
|
|
4326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
3793
4327
|
"div",
|
|
3794
4328
|
{
|
|
3795
4329
|
className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
|
|
3796
4330
|
style: { aspectRatio },
|
|
3797
4331
|
children: [
|
|
3798
|
-
/* @__PURE__ */ (0,
|
|
4332
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
3799
4333
|
"img",
|
|
3800
4334
|
{
|
|
3801
4335
|
src,
|
|
@@ -3803,8 +4337,8 @@ function PaywallHero({
|
|
|
3803
4337
|
className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
|
|
3804
4338
|
}
|
|
3805
4339
|
),
|
|
3806
|
-
/* @__PURE__ */ (0,
|
|
3807
|
-
headline ? /* @__PURE__ */ (0,
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
|
|
4341
|
+
headline ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
3808
4342
|
"h1",
|
|
3809
4343
|
{
|
|
3810
4344
|
className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
|
|
@@ -3817,15 +4351,15 @@ function PaywallHero({
|
|
|
3817
4351
|
}
|
|
3818
4352
|
|
|
3819
4353
|
// src/components/paywall/blocks/PaywallHeadline.tsx
|
|
3820
|
-
var
|
|
4354
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3821
4355
|
var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
|
|
3822
4356
|
function PaywallHeadline({ text, className, as = "h1" }) {
|
|
3823
4357
|
const Tag = as;
|
|
3824
|
-
return /* @__PURE__ */ (0,
|
|
4358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3825
4359
|
}
|
|
3826
4360
|
|
|
3827
4361
|
// src/components/paywall/blocks/PaywallPriceHeadline.tsx
|
|
3828
|
-
var
|
|
4362
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3829
4363
|
var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
|
|
3830
4364
|
var CYCLE_LABEL = {
|
|
3831
4365
|
MONTHLY: "mensal",
|
|
@@ -3845,16 +4379,16 @@ function PaywallPriceHeadline({
|
|
|
3845
4379
|
const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
|
|
3846
4380
|
if (render) {
|
|
3847
4381
|
const RootTag2 = as;
|
|
3848
|
-
return /* @__PURE__ */ (0,
|
|
4382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
|
|
3849
4383
|
}
|
|
3850
4384
|
const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
|
|
3851
4385
|
const RootTag = as;
|
|
3852
|
-
return /* @__PURE__ */ (0,
|
|
4386
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(RootTag, { className: rootClasses, children: text });
|
|
3853
4387
|
}
|
|
3854
4388
|
|
|
3855
4389
|
// src/components/paywall/blocks/PaywallCountdown.tsx
|
|
3856
|
-
var
|
|
3857
|
-
var
|
|
4390
|
+
var import_react32 = require("react");
|
|
4391
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
3858
4392
|
var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
|
|
3859
4393
|
function resolveDeadlineMs(deadline) {
|
|
3860
4394
|
if (deadline instanceof Date) return deadline.getTime();
|
|
@@ -3891,13 +4425,13 @@ function PaywallCountdown({
|
|
|
3891
4425
|
className,
|
|
3892
4426
|
render
|
|
3893
4427
|
}) {
|
|
3894
|
-
const deadlineMsRef = (0,
|
|
4428
|
+
const deadlineMsRef = (0, import_react32.useRef)(null);
|
|
3895
4429
|
if (deadlineMsRef.current === null) {
|
|
3896
4430
|
deadlineMsRef.current = resolveDeadlineMs(deadline);
|
|
3897
4431
|
}
|
|
3898
|
-
const [state, setState] = (0,
|
|
3899
|
-
const expiredCalledRef = (0,
|
|
3900
|
-
(0,
|
|
4432
|
+
const [state, setState] = (0, import_react32.useState)(() => computeRemaining(deadlineMsRef.current));
|
|
4433
|
+
const expiredCalledRef = (0, import_react32.useRef)(false);
|
|
4434
|
+
(0, import_react32.useEffect)(() => {
|
|
3901
4435
|
if (state.expired) {
|
|
3902
4436
|
if (!expiredCalledRef.current) {
|
|
3903
4437
|
expiredCalledRef.current = true;
|
|
@@ -3917,14 +4451,14 @@ function PaywallCountdown({
|
|
|
3917
4451
|
return () => clearInterval(id);
|
|
3918
4452
|
}, [state.expired]);
|
|
3919
4453
|
if (render) {
|
|
3920
|
-
return /* @__PURE__ */ (0,
|
|
4454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: render(state) });
|
|
3921
4455
|
}
|
|
3922
4456
|
const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
|
|
3923
|
-
return /* @__PURE__ */ (0,
|
|
4457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
|
|
3924
4458
|
}
|
|
3925
4459
|
|
|
3926
4460
|
// src/components/paywall/blocks/PaywallFeatures.tsx
|
|
3927
|
-
var
|
|
4461
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
3928
4462
|
function PaywallFeatures({
|
|
3929
4463
|
items,
|
|
3930
4464
|
IconComponent,
|
|
@@ -3935,19 +4469,19 @@ function PaywallFeatures({
|
|
|
3935
4469
|
renderItem
|
|
3936
4470
|
}) {
|
|
3937
4471
|
if (render) {
|
|
3938
|
-
return /* @__PURE__ */ (0,
|
|
4472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: render({ items }) });
|
|
3939
4473
|
}
|
|
3940
4474
|
if (renderItem) {
|
|
3941
|
-
return /* @__PURE__ */ (0,
|
|
4475
|
+
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)) });
|
|
3942
4476
|
}
|
|
3943
|
-
return /* @__PURE__ */ (0,
|
|
3944
|
-
IconComponent ? /* @__PURE__ */ (0,
|
|
3945
|
-
/* @__PURE__ */ (0,
|
|
4477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: itemClassName, children: [
|
|
4478
|
+
IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
|
|
4479
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: item })
|
|
3946
4480
|
] }, idx)) });
|
|
3947
4481
|
}
|
|
3948
4482
|
|
|
3949
4483
|
// src/components/paywall/blocks/PaywallFeaturesCard.tsx
|
|
3950
|
-
var
|
|
4484
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
3951
4485
|
var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
|
|
3952
4486
|
function PaywallFeaturesCard({
|
|
3953
4487
|
title,
|
|
@@ -3958,20 +4492,20 @@ function PaywallFeaturesCard({
|
|
|
3958
4492
|
itemClassName,
|
|
3959
4493
|
renderItem
|
|
3960
4494
|
}) {
|
|
3961
|
-
return /* @__PURE__ */ (0,
|
|
3962
|
-
title ? /* @__PURE__ */ (0,
|
|
3963
|
-
/* @__PURE__ */ (0,
|
|
3964
|
-
(item, idx) => renderItem ? /* @__PURE__ */ (0,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
4495
|
+
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: [
|
|
4496
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
|
|
4497
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("ul", { children: items.map(
|
|
4498
|
+
(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: [
|
|
4499
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
|
|
3966
4500
|
" ",
|
|
3967
|
-
/* @__PURE__ */ (0,
|
|
4501
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: item })
|
|
3968
4502
|
] }, idx)
|
|
3969
4503
|
) })
|
|
3970
4504
|
] }) });
|
|
3971
4505
|
}
|
|
3972
4506
|
|
|
3973
4507
|
// src/components/paywall/blocks/PaywallTrophyBadge.tsx
|
|
3974
|
-
var
|
|
4508
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
3975
4509
|
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";
|
|
3976
4510
|
var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
|
|
3977
4511
|
function PaywallTrophyBadge({
|
|
@@ -3982,21 +4516,21 @@ function PaywallTrophyBadge({
|
|
|
3982
4516
|
render
|
|
3983
4517
|
}) {
|
|
3984
4518
|
if (render) {
|
|
3985
|
-
return /* @__PURE__ */ (0,
|
|
4519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className, children: render({ text }) });
|
|
3986
4520
|
}
|
|
3987
4521
|
const rootClasses = [
|
|
3988
4522
|
DEFAULT_CHIP_CLASSES,
|
|
3989
4523
|
floating ? FLOATING_CLASSES : "",
|
|
3990
4524
|
className
|
|
3991
4525
|
].filter(Boolean).join(" ");
|
|
3992
|
-
return /* @__PURE__ */ (0,
|
|
3993
|
-
/* @__PURE__ */ (0,
|
|
3994
|
-
/* @__PURE__ */ (0,
|
|
4526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: rootClasses, children: [
|
|
4527
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
|
|
4528
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: text })
|
|
3995
4529
|
] });
|
|
3996
4530
|
}
|
|
3997
4531
|
|
|
3998
4532
|
// src/components/paywall/blocks/PaywallAnchorPrice.tsx
|
|
3999
|
-
var
|
|
4533
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
4000
4534
|
var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
|
|
4001
4535
|
function PaywallAnchorPrice({
|
|
4002
4536
|
className,
|
|
@@ -4010,13 +4544,13 @@ function PaywallAnchorPrice({
|
|
|
4010
4544
|
const formatted = formatBRL(anchorPriceCents);
|
|
4011
4545
|
const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
|
|
4012
4546
|
if (render) {
|
|
4013
|
-
return /* @__PURE__ */ (0,
|
|
4547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
|
|
4014
4548
|
}
|
|
4015
|
-
return /* @__PURE__ */ (0,
|
|
4549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: rootClasses, children: formatted });
|
|
4016
4550
|
}
|
|
4017
4551
|
|
|
4018
4552
|
// src/components/paywall/blocks/PaywallTestimonials.tsx
|
|
4019
|
-
var
|
|
4553
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
4020
4554
|
var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
|
|
4021
4555
|
var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
|
|
4022
4556
|
var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
|
|
@@ -4042,13 +4576,13 @@ function PaywallTestimonials({
|
|
|
4042
4576
|
const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
|
|
4043
4577
|
const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
|
|
4044
4578
|
const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
|
|
4045
|
-
return /* @__PURE__ */ (0,
|
|
4579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4046
4580
|
if (renderItem) return renderItem(item, idx);
|
|
4047
4581
|
const filled = clampStars(item.stars);
|
|
4048
4582
|
const empty = 5 - filled;
|
|
4049
|
-
return /* @__PURE__ */ (0,
|
|
4050
|
-
/* @__PURE__ */ (0,
|
|
4051
|
-
item.avatar ? /* @__PURE__ */ (0,
|
|
4583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cardClasses, children: [
|
|
4584
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4585
|
+
item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
4052
4586
|
"img",
|
|
4053
4587
|
{
|
|
4054
4588
|
src: item.avatar,
|
|
@@ -4058,19 +4592,19 @@ function PaywallTestimonials({
|
|
|
4058
4592
|
"aria-hidden": "true"
|
|
4059
4593
|
}
|
|
4060
4594
|
) : null,
|
|
4061
|
-
/* @__PURE__ */ (0,
|
|
4595
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: nameClasses, children: item.name })
|
|
4062
4596
|
] }),
|
|
4063
|
-
/* @__PURE__ */ (0,
|
|
4597
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
|
|
4064
4598
|
"\u2605".repeat(filled),
|
|
4065
4599
|
"\u2606".repeat(empty)
|
|
4066
4600
|
] }),
|
|
4067
|
-
/* @__PURE__ */ (0,
|
|
4601
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: quoteClasses, children: item.quote })
|
|
4068
4602
|
] }, idx);
|
|
4069
4603
|
}) });
|
|
4070
4604
|
}
|
|
4071
4605
|
|
|
4072
4606
|
// src/components/paywall/blocks/PaywallStatsRow.tsx
|
|
4073
|
-
var
|
|
4607
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
4074
4608
|
var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
|
|
4075
4609
|
var DEFAULT_CELL = "flex flex-col items-center text-center";
|
|
4076
4610
|
var DEFAULT_VALUE = "text-2xl font-bold";
|
|
@@ -4087,18 +4621,18 @@ function PaywallStatsRow({
|
|
|
4087
4621
|
const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
|
|
4088
4622
|
const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
|
|
4089
4623
|
const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
|
|
4090
|
-
return /* @__PURE__ */ (0,
|
|
4624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
|
|
4091
4625
|
if (renderCell) return renderCell(stat, idx);
|
|
4092
|
-
return /* @__PURE__ */ (0,
|
|
4093
|
-
stat.icon ? /* @__PURE__ */ (0,
|
|
4094
|
-
/* @__PURE__ */ (0,
|
|
4095
|
-
/* @__PURE__ */ (0,
|
|
4626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cellClasses, children: [
|
|
4627
|
+
stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
|
|
4628
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: valueClasses, children: stat.value }),
|
|
4629
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: labelClasses, children: stat.label })
|
|
4096
4630
|
] }, idx);
|
|
4097
4631
|
}) });
|
|
4098
4632
|
}
|
|
4099
4633
|
|
|
4100
4634
|
// src/components/paywall/blocks/PaywallFinePrint.tsx
|
|
4101
|
-
var
|
|
4635
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
4102
4636
|
var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
|
|
4103
4637
|
var CYCLE_LABEL2 = {
|
|
4104
4638
|
MONTHLY: "mensal",
|
|
@@ -4121,7 +4655,7 @@ function PaywallFinePrint({
|
|
|
4121
4655
|
const priceFormatted = formatBRL(currentPriceCents ?? 0);
|
|
4122
4656
|
const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
|
|
4123
4657
|
if (render) {
|
|
4124
|
-
return /* @__PURE__ */ (0,
|
|
4658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: className || void 0, children: render({
|
|
4125
4659
|
currentPriceCents: currentPriceCents ?? 0,
|
|
4126
4660
|
cycle,
|
|
4127
4661
|
trialDays: trialDays ?? 0,
|
|
@@ -4129,11 +4663,11 @@ function PaywallFinePrint({
|
|
|
4129
4663
|
}) });
|
|
4130
4664
|
}
|
|
4131
4665
|
const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
|
|
4132
|
-
return /* @__PURE__ */ (0,
|
|
4666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: rootClasses, children: text });
|
|
4133
4667
|
}
|
|
4134
4668
|
|
|
4135
4669
|
// src/components/paywall/blocks/PaywallTrustLine.tsx
|
|
4136
|
-
var
|
|
4670
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
4137
4671
|
var DEFAULT_ROOT3 = "flex items-center gap-3";
|
|
4138
4672
|
var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
|
|
4139
4673
|
function PaywallTrustLine({
|
|
@@ -4144,17 +4678,17 @@ function PaywallTrustLine({
|
|
|
4144
4678
|
}) {
|
|
4145
4679
|
const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
|
|
4146
4680
|
const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
|
|
4147
|
-
return /* @__PURE__ */ (0,
|
|
4681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4148
4682
|
if (renderItem) return renderItem(item, idx);
|
|
4149
|
-
return /* @__PURE__ */ (0,
|
|
4150
|
-
/* @__PURE__ */ (0,
|
|
4151
|
-
/* @__PURE__ */ (0,
|
|
4683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: itemClasses, children: [
|
|
4684
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { "aria-hidden": "true", children: item.icon }),
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: item.text })
|
|
4152
4686
|
] }, idx);
|
|
4153
4687
|
}) });
|
|
4154
4688
|
}
|
|
4155
4689
|
|
|
4156
4690
|
// src/components/paywall/blocks/PaywallStickyFooter.tsx
|
|
4157
|
-
var
|
|
4691
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
4158
4692
|
var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
|
|
4159
4693
|
var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
|
|
4160
4694
|
function PaywallStickyFooter({
|
|
@@ -4163,13 +4697,14 @@ function PaywallStickyFooter({
|
|
|
4163
4697
|
safeAreaInsets = true
|
|
4164
4698
|
}) {
|
|
4165
4699
|
const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
|
|
4166
|
-
return /* @__PURE__ */ (0,
|
|
4700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: classes, children });
|
|
4167
4701
|
}
|
|
4168
4702
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4169
4703
|
0 && (module.exports = {
|
|
4170
4704
|
AppConfigProvider,
|
|
4171
4705
|
AppConfigSchema,
|
|
4172
4706
|
AppRoot,
|
|
4707
|
+
CheckoutPageDefault,
|
|
4173
4708
|
DeepLinkHandler,
|
|
4174
4709
|
DevSkipOnboardingFab,
|
|
4175
4710
|
EmptyState,
|
|
@@ -4203,6 +4738,7 @@ function PaywallStickyFooter({
|
|
|
4203
4738
|
PaywallTrophyBadge,
|
|
4204
4739
|
PaywallTrustLine,
|
|
4205
4740
|
PersistenceRegistry,
|
|
4741
|
+
PixWaitingPageDefault,
|
|
4206
4742
|
PreAuthShell,
|
|
4207
4743
|
PushPrompt,
|
|
4208
4744
|
RouteBoundary,
|
|
@@ -4225,6 +4761,7 @@ function PaywallStickyFooter({
|
|
|
4225
4761
|
useAppConfig,
|
|
4226
4762
|
useAuth,
|
|
4227
4763
|
useAuthPrimitives,
|
|
4764
|
+
useCheckoutForm,
|
|
4228
4765
|
useFeature,
|
|
4229
4766
|
useForgotForm,
|
|
4230
4767
|
useInstallPrompt,
|