@hook-sdk/template 0.24.0 → 0.25.1
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 +383 -333
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +308 -258
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -102,14 +102,14 @@ __export(index_exports, {
|
|
|
102
102
|
useSignupForm: () => useSignupForm,
|
|
103
103
|
useSubscription: () => useSubscription,
|
|
104
104
|
useToast: () => useToast,
|
|
105
|
-
useTrackOnboardingStep: () =>
|
|
105
|
+
useTrackOnboardingStep: () => import_sdk24.useTrackOnboardingStep
|
|
106
106
|
});
|
|
107
107
|
module.exports = __toCommonJS(index_exports);
|
|
108
108
|
|
|
109
109
|
// src/AppRoot.tsx
|
|
110
|
-
var
|
|
110
|
+
var import_react16 = require("react");
|
|
111
111
|
var import_react_router_dom2 = require("react-router-dom");
|
|
112
|
-
var
|
|
112
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
113
113
|
|
|
114
114
|
// src/config/AppConfigContext.tsx
|
|
115
115
|
var import_react = require("react");
|
|
@@ -2139,10 +2139,54 @@ function SessionExpiredBanner() {
|
|
|
2139
2139
|
] });
|
|
2140
2140
|
}
|
|
2141
2141
|
|
|
2142
|
-
// src/
|
|
2142
|
+
// src/internal/EmailVerifyBanner.tsx
|
|
2143
2143
|
var import_react11 = require("react");
|
|
2144
|
+
var import_sdk5 = require("@hook-sdk/sdk");
|
|
2144
2145
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2145
|
-
|
|
2146
|
+
function EmailVerifyBanner() {
|
|
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 {
|
|
2146
2190
|
state = { error: null };
|
|
2147
2191
|
static getDerivedStateFromError(error) {
|
|
2148
2192
|
return { error };
|
|
@@ -2159,21 +2203,21 @@ var ErrorBoundary = class extends import_react11.Component {
|
|
|
2159
2203
|
}
|
|
2160
2204
|
render() {
|
|
2161
2205
|
if (this.state.error) {
|
|
2162
|
-
return this.props.fallback ?? /* @__PURE__ */ (0,
|
|
2163
|
-
/* @__PURE__ */ (0,
|
|
2164
|
-
/* @__PURE__ */ (0,
|
|
2206
|
+
return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
2207
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { children: "Algo deu errado" }),
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
2165
2209
|
] });
|
|
2166
2210
|
}
|
|
2167
|
-
return /* @__PURE__ */ (0,
|
|
2211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children: this.props.children });
|
|
2168
2212
|
}
|
|
2169
2213
|
};
|
|
2170
2214
|
|
|
2171
2215
|
// src/i18n/I18nProvider.tsx
|
|
2172
|
-
var
|
|
2216
|
+
var import_react13 = require("react");
|
|
2173
2217
|
var import_i18next = __toESM(require("i18next"), 1);
|
|
2174
2218
|
var import_react_i18next = require("react-i18next");
|
|
2175
|
-
var
|
|
2176
|
-
var
|
|
2219
|
+
var import_sdk6 = require("@hook-sdk/sdk");
|
|
2220
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2177
2221
|
function ensureInitialized(defaultLocale, supportedLocales, resources, initialLocale) {
|
|
2178
2222
|
if (import_i18next.default.isInitialized) return;
|
|
2179
2223
|
import_i18next.default.use(import_react_i18next.initReactI18next).init({
|
|
@@ -2195,14 +2239,14 @@ function I18nProvider({
|
|
|
2195
2239
|
resources,
|
|
2196
2240
|
children
|
|
2197
2241
|
}) {
|
|
2198
|
-
const [userLocale] = (0,
|
|
2242
|
+
const [userLocale] = (0, import_sdk6.usePersistedState)("user-locale", defaultLocale);
|
|
2199
2243
|
ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);
|
|
2200
|
-
(0,
|
|
2244
|
+
(0, import_react13.useEffect)(() => {
|
|
2201
2245
|
if (import_i18next.default.isInitialized && import_i18next.default.language !== userLocale) {
|
|
2202
2246
|
import_i18next.default.changeLanguage(userLocale);
|
|
2203
2247
|
}
|
|
2204
2248
|
}, [userLocale]);
|
|
2205
|
-
return /* @__PURE__ */ (0,
|
|
2249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_i18next.I18nextProvider, { i18n: import_i18next.default, children });
|
|
2206
2250
|
}
|
|
2207
2251
|
|
|
2208
2252
|
// src/dev/env.ts
|
|
@@ -2213,9 +2257,9 @@ function isDevToolsEnabled() {
|
|
|
2213
2257
|
}
|
|
2214
2258
|
|
|
2215
2259
|
// src/dev/DevSkipOnboardingFab.tsx
|
|
2216
|
-
var
|
|
2217
|
-
var
|
|
2218
|
-
var
|
|
2260
|
+
var import_react14 = require("react");
|
|
2261
|
+
var import_sdk7 = require("@hook-sdk/sdk");
|
|
2262
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2219
2263
|
var STORAGE_KEY = "hook_dev_skip_email";
|
|
2220
2264
|
var TEST_EMAIL_DOMAIN = "@hook.test";
|
|
2221
2265
|
var TEST_PASSWORD = "SkipTest!2026";
|
|
@@ -2282,18 +2326,18 @@ var STYLES = {
|
|
|
2282
2326
|
};
|
|
2283
2327
|
var CONFIRM_TIMEOUT_MS = 3e3;
|
|
2284
2328
|
function DevSkipOnboardingFab({ defaults }) {
|
|
2285
|
-
const hook = (0,
|
|
2329
|
+
const hook = (0, import_sdk7.useHook)();
|
|
2286
2330
|
const { slug } = useAppConfig();
|
|
2287
|
-
const [state, setState] = (0,
|
|
2288
|
-
const [errorMsg, setErrorMsg] = (0,
|
|
2289
|
-
const timerRef = (0,
|
|
2290
|
-
const clearTimer = (0,
|
|
2331
|
+
const [state, setState] = (0, import_react14.useState)("idle");
|
|
2332
|
+
const [errorMsg, setErrorMsg] = (0, import_react14.useState)(null);
|
|
2333
|
+
const timerRef = (0, import_react14.useRef)(null);
|
|
2334
|
+
const clearTimer = (0, import_react14.useCallback)(() => {
|
|
2291
2335
|
if (timerRef.current) {
|
|
2292
2336
|
clearTimeout(timerRef.current);
|
|
2293
2337
|
timerRef.current = null;
|
|
2294
2338
|
}
|
|
2295
2339
|
}, []);
|
|
2296
|
-
const onClick = (0,
|
|
2340
|
+
const onClick = (0, import_react14.useCallback)(async () => {
|
|
2297
2341
|
if (state === "busy") return;
|
|
2298
2342
|
if (state === "idle" || state === "error") {
|
|
2299
2343
|
setState("confirm");
|
|
@@ -2322,7 +2366,7 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2322
2366
|
...state === "confirm" || state === "error" ? STYLES.confirm : {},
|
|
2323
2367
|
...state === "busy" ? STYLES.busy : {}
|
|
2324
2368
|
};
|
|
2325
|
-
return /* @__PURE__ */ (0,
|
|
2369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2326
2370
|
"button",
|
|
2327
2371
|
{
|
|
2328
2372
|
type: "button",
|
|
@@ -2337,21 +2381,21 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2337
2381
|
}
|
|
2338
2382
|
|
|
2339
2383
|
// src/internal/PaymentReturnHandler.tsx
|
|
2340
|
-
var
|
|
2341
|
-
var
|
|
2342
|
-
var
|
|
2384
|
+
var import_react15 = require("react");
|
|
2385
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
2386
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2343
2387
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
2344
2388
|
var MAX_CYCLES = 3;
|
|
2345
2389
|
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
2346
2390
|
function PaymentReturnHandler({ children }) {
|
|
2347
|
-
const { subscription, track: track2 } = (0,
|
|
2348
|
-
const subRef = (0,
|
|
2391
|
+
const { subscription, track: track2 } = (0, import_sdk8.useHook)();
|
|
2392
|
+
const subRef = (0, import_react15.useRef)(subscription);
|
|
2349
2393
|
subRef.current = subscription;
|
|
2350
|
-
const runIdRef = (0,
|
|
2351
|
-
const cyclesRef = (0,
|
|
2352
|
-
const startMsRef = (0,
|
|
2353
|
-
const [state, setState] = (0,
|
|
2354
|
-
const runPoll = (0,
|
|
2394
|
+
const runIdRef = (0, import_react15.useRef)(0);
|
|
2395
|
+
const cyclesRef = (0, import_react15.useRef)(0);
|
|
2396
|
+
const startMsRef = (0, import_react15.useRef)(0);
|
|
2397
|
+
const [state, setState] = (0, import_react15.useState)("idle");
|
|
2398
|
+
const runPoll = (0, import_react15.useCallback)(() => {
|
|
2355
2399
|
const runId = ++runIdRef.current;
|
|
2356
2400
|
const isFirstRun = cyclesRef.current === 0;
|
|
2357
2401
|
cyclesRef.current += 1;
|
|
@@ -2399,7 +2443,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2399
2443
|
};
|
|
2400
2444
|
void tick();
|
|
2401
2445
|
}, [track2]);
|
|
2402
|
-
(0,
|
|
2446
|
+
(0, import_react15.useEffect)(() => {
|
|
2403
2447
|
if (typeof window === "undefined") return;
|
|
2404
2448
|
const url = new URL(window.location.href);
|
|
2405
2449
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -2409,26 +2453,26 @@ function PaymentReturnHandler({ children }) {
|
|
|
2409
2453
|
runIdRef.current++;
|
|
2410
2454
|
};
|
|
2411
2455
|
}, [runPoll]);
|
|
2412
|
-
const goHome = (0,
|
|
2456
|
+
const goHome = (0, import_react15.useCallback)(() => {
|
|
2413
2457
|
const cleanUrl = new URL(window.location.href);
|
|
2414
2458
|
cleanUrl.searchParams.delete("paymentReturn");
|
|
2415
2459
|
cleanUrl.pathname = "/app/home";
|
|
2416
2460
|
window.location.href = cleanUrl.toString();
|
|
2417
2461
|
}, []);
|
|
2418
2462
|
if (state === "confirming") {
|
|
2419
|
-
return /* @__PURE__ */ (0,
|
|
2463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
|
|
2420
2464
|
}
|
|
2421
2465
|
if (state === "waiting") {
|
|
2422
|
-
return /* @__PURE__ */ (0,
|
|
2423
|
-
/* @__PURE__ */ (0,
|
|
2424
|
-
/* @__PURE__ */ (0,
|
|
2466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2467
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2468
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
|
|
2425
2469
|
] }) });
|
|
2426
2470
|
}
|
|
2427
2471
|
if (state === "timeout") {
|
|
2428
|
-
return /* @__PURE__ */ (0,
|
|
2429
|
-
/* @__PURE__ */ (0,
|
|
2430
|
-
/* @__PURE__ */ (0,
|
|
2431
|
-
/* @__PURE__ */ (0,
|
|
2472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2473
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.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." }),
|
|
2474
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
2475
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2432
2476
|
"button",
|
|
2433
2477
|
{
|
|
2434
2478
|
type: "button",
|
|
@@ -2441,7 +2485,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2441
2485
|
children: "Tentar de novo"
|
|
2442
2486
|
}
|
|
2443
2487
|
),
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2488
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2445
2489
|
"button",
|
|
2446
2490
|
{
|
|
2447
2491
|
type: "button",
|
|
@@ -2451,7 +2495,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2451
2495
|
children: "Voltar pro app"
|
|
2452
2496
|
}
|
|
2453
2497
|
),
|
|
2454
|
-
/* @__PURE__ */ (0,
|
|
2498
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2455
2499
|
"a",
|
|
2456
2500
|
{
|
|
2457
2501
|
href: SUPPORT_MAILTO,
|
|
@@ -2463,7 +2507,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2463
2507
|
] })
|
|
2464
2508
|
] }) });
|
|
2465
2509
|
}
|
|
2466
|
-
return /* @__PURE__ */ (0,
|
|
2510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children });
|
|
2467
2511
|
}
|
|
2468
2512
|
var overlayStyle2 = {
|
|
2469
2513
|
position: "fixed",
|
|
@@ -2502,7 +2546,7 @@ var linkStyle = {
|
|
|
2502
2546
|
};
|
|
2503
2547
|
|
|
2504
2548
|
// src/AppRoot.tsx
|
|
2505
|
-
var
|
|
2549
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2506
2550
|
function buildLegacyConfigShim(config) {
|
|
2507
2551
|
const paywall = config.paywall;
|
|
2508
2552
|
const isFree = paywall.mode === "free";
|
|
@@ -2576,19 +2620,22 @@ function AppRoot(props) {
|
|
|
2576
2620
|
"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
|
|
2577
2621
|
);
|
|
2578
2622
|
}
|
|
2579
|
-
const legacyShim = (0,
|
|
2623
|
+
const legacyShim = (0, import_react16.useMemo)(() => buildLegacyConfigShim(config), [config]);
|
|
2580
2624
|
const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
|
|
2581
2625
|
const basename = `/app/${config.slug}`;
|
|
2582
2626
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
2583
2627
|
const position = config.install_prompt?.position ?? "post-paywall";
|
|
2584
|
-
const subscriptionGated = /* @__PURE__ */ (0,
|
|
2585
|
-
|
|
2586
|
-
/* @__PURE__ */ (0,
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
/* @__PURE__ */ (0,
|
|
2590
|
-
|
|
2591
|
-
|
|
2628
|
+
const subscriptionGated = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(SubscriptionGate, { Paywall: Paywall2 ?? FallbackPaywall, children: [
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerifyBanner, {}),
|
|
2630
|
+
position === "post-paywall" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(InstallGate, { position: "post-paywall", children: [
|
|
2631
|
+
children,
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PushPrompt, {})
|
|
2633
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
2634
|
+
children,
|
|
2635
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PushPrompt, {})
|
|
2636
|
+
] })
|
|
2637
|
+
] });
|
|
2638
|
+
const authGated = /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2592
2639
|
AuthGated,
|
|
2593
2640
|
{
|
|
2594
2641
|
config,
|
|
@@ -2603,13 +2650,13 @@ function AppRoot(props) {
|
|
|
2603
2650
|
children: subscriptionGated
|
|
2604
2651
|
}
|
|
2605
2652
|
);
|
|
2606
|
-
const routedTree = /* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2608
|
-
/* @__PURE__ */ (0,
|
|
2609
|
-
position === "pre-auth" ? /* @__PURE__ */ (0,
|
|
2610
|
-
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0,
|
|
2653
|
+
const routedTree = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Router, { ...routerProps, children: [
|
|
2654
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SessionExpiredBanner, {}),
|
|
2656
|
+
position === "pre-auth" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InstallGate, { position: "pre-auth", children: authGated }) : authGated,
|
|
2657
|
+
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DevSkipOnboardingFab, { defaults: devSkipOnboarding.defaults }) : null
|
|
2611
2658
|
] });
|
|
2612
|
-
return /* @__PURE__ */ (0,
|
|
2659
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2613
2660
|
I18nProvider,
|
|
2614
2661
|
{
|
|
2615
2662
|
defaultLocale: config.i18n.defaultLocale,
|
|
@@ -2629,37 +2676,37 @@ function AuthGated({
|
|
|
2629
2676
|
EmailVerify,
|
|
2630
2677
|
PreAuthFlow
|
|
2631
2678
|
}) {
|
|
2632
|
-
const { authStatus } = (0,
|
|
2679
|
+
const { authStatus } = (0, import_sdk9.useHook)();
|
|
2633
2680
|
if (authStatus === "loading") return null;
|
|
2634
2681
|
if (authStatus !== "authenticated") {
|
|
2635
2682
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
2636
|
-
return /* @__PURE__ */ (0,
|
|
2637
|
-
/* @__PURE__ */ (0,
|
|
2638
|
-
/* @__PURE__ */ (0,
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2640
|
-
/* @__PURE__ */ (0,
|
|
2641
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2642
|
-
/* @__PURE__ */ (0,
|
|
2683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2684
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Login, {}) }),
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Signup, {}) }),
|
|
2686
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Forgot, {}) }),
|
|
2687
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Reset, {}) }),
|
|
2688
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerify, {}) }) : null,
|
|
2689
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PreAuthFlow, {}) })
|
|
2643
2690
|
] });
|
|
2644
2691
|
}
|
|
2645
|
-
return /* @__PURE__ */ (0,
|
|
2646
|
-
/* @__PURE__ */ (0,
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
2649
|
-
/* @__PURE__ */ (0,
|
|
2650
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2651
|
-
/* @__PURE__ */ (0,
|
|
2692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2693
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Login, {}) }),
|
|
2694
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Signup, {}) }),
|
|
2695
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Forgot, {}) }),
|
|
2696
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Reset, {}) }),
|
|
2697
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EmailVerify, {}) }) : null,
|
|
2698
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
|
|
2652
2699
|
] });
|
|
2653
2700
|
}
|
|
2654
|
-
return /* @__PURE__ */ (0,
|
|
2701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children });
|
|
2655
2702
|
}
|
|
2656
2703
|
function FallbackPaywall() {
|
|
2657
2704
|
return null;
|
|
2658
2705
|
}
|
|
2659
2706
|
|
|
2660
2707
|
// src/hooks/usePush.ts
|
|
2661
|
-
var
|
|
2662
|
-
var
|
|
2708
|
+
var import_react17 = require("react");
|
|
2709
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
2663
2710
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2664
2711
|
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2665
2712
|
function detectIosNeedsInstall() {
|
|
@@ -2703,12 +2750,12 @@ function deriveState(push) {
|
|
|
2703
2750
|
return { kind: "prompt" };
|
|
2704
2751
|
}
|
|
2705
2752
|
function usePush() {
|
|
2706
|
-
const { push } = (0,
|
|
2707
|
-
const [state, setState] = (0,
|
|
2708
|
-
(0,
|
|
2753
|
+
const { push } = (0, import_sdk10.useHook)();
|
|
2754
|
+
const [state, setState] = (0, import_react17.useState)(() => deriveState(push));
|
|
2755
|
+
(0, import_react17.useEffect)(() => {
|
|
2709
2756
|
setState(deriveState(push));
|
|
2710
2757
|
}, [push]);
|
|
2711
|
-
const subscribe = (0,
|
|
2758
|
+
const subscribe = (0, import_react17.useCallback)(async () => {
|
|
2712
2759
|
try {
|
|
2713
2760
|
await push.subscribe();
|
|
2714
2761
|
setState({ kind: "subscribed" });
|
|
@@ -2720,7 +2767,7 @@ function usePush() {
|
|
|
2720
2767
|
throw e;
|
|
2721
2768
|
}
|
|
2722
2769
|
}, [push]);
|
|
2723
|
-
const unsubscribe = (0,
|
|
2770
|
+
const unsubscribe = (0, import_react17.useCallback)(async () => {
|
|
2724
2771
|
try {
|
|
2725
2772
|
await push.unsubscribe();
|
|
2726
2773
|
setState({ kind: "prompt" });
|
|
@@ -2729,7 +2776,7 @@ function usePush() {
|
|
|
2729
2776
|
throw e;
|
|
2730
2777
|
}
|
|
2731
2778
|
}, [push]);
|
|
2732
|
-
const dismiss = (0,
|
|
2779
|
+
const dismiss = (0, import_react17.useCallback)(() => {
|
|
2733
2780
|
if (typeof localStorage !== "undefined") {
|
|
2734
2781
|
try {
|
|
2735
2782
|
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
|
|
@@ -2742,27 +2789,27 @@ function usePush() {
|
|
|
2742
2789
|
}
|
|
2743
2790
|
|
|
2744
2791
|
// src/components/PushPrompt.tsx
|
|
2745
|
-
var
|
|
2792
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2746
2793
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
2747
2794
|
const { state, subscribe } = usePush();
|
|
2748
2795
|
if (state.kind === "denied" || state.kind === "dismissed" || state.kind === "subscribed") {
|
|
2749
2796
|
return null;
|
|
2750
2797
|
}
|
|
2751
2798
|
if (state.kind === "ios_needs_install") {
|
|
2752
|
-
return /* @__PURE__ */ (0,
|
|
2753
|
-
/* @__PURE__ */ (0,
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
2755
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0,
|
|
2799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { children: texts.iosInstallTitle }),
|
|
2801
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: texts.iosInstallBody }),
|
|
2802
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
2756
2803
|
] });
|
|
2757
2804
|
}
|
|
2758
2805
|
if (state.kind === "unsupported") {
|
|
2759
|
-
return /* @__PURE__ */ (0,
|
|
2806
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: texts.unsupportedBody }) });
|
|
2760
2807
|
}
|
|
2761
2808
|
if (state.kind === "error") {
|
|
2762
|
-
return /* @__PURE__ */ (0,
|
|
2809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { children: state.message }) });
|
|
2763
2810
|
}
|
|
2764
|
-
return /* @__PURE__ */ (0,
|
|
2765
|
-
/* @__PURE__ */ (0,
|
|
2811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className, role: "region", children: [
|
|
2812
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2766
2813
|
"button",
|
|
2767
2814
|
{
|
|
2768
2815
|
type: "button",
|
|
@@ -2776,67 +2823,67 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2776
2823
|
children: texts.cta
|
|
2777
2824
|
}
|
|
2778
2825
|
),
|
|
2779
|
-
onDeclined && /* @__PURE__ */ (0,
|
|
2826
|
+
onDeclined && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
2780
2827
|
] });
|
|
2781
2828
|
}
|
|
2782
2829
|
|
|
2783
2830
|
// src/components/LanguageSwitcher.tsx
|
|
2784
|
-
var
|
|
2785
|
-
var
|
|
2831
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
2832
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2786
2833
|
function LanguageSwitcher({ id, className, label = "Language" }) {
|
|
2787
2834
|
const config = useAppConfig();
|
|
2788
2835
|
const i18nConfig = config.i18n;
|
|
2789
|
-
const [userLocale, setUserLocale] = (0,
|
|
2836
|
+
const [userLocale, setUserLocale] = (0, import_sdk11.usePersistedState)(
|
|
2790
2837
|
"user-locale",
|
|
2791
2838
|
i18nConfig?.defaultLocale ?? "en-US"
|
|
2792
2839
|
);
|
|
2793
2840
|
if (!i18nConfig) return null;
|
|
2794
|
-
return /* @__PURE__ */ (0,
|
|
2795
|
-
label ? /* @__PURE__ */ (0,
|
|
2796
|
-
/* @__PURE__ */ (0,
|
|
2841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className, children: [
|
|
2842
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: label }) : null,
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2797
2844
|
"select",
|
|
2798
2845
|
{
|
|
2799
2846
|
id,
|
|
2800
2847
|
value: userLocale,
|
|
2801
2848
|
onChange: (e) => setUserLocale(e.target.value),
|
|
2802
2849
|
"data-testid": "language-switcher",
|
|
2803
|
-
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0,
|
|
2850
|
+
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: loc, children: loc }, loc))
|
|
2804
2851
|
}
|
|
2805
2852
|
)
|
|
2806
2853
|
] });
|
|
2807
2854
|
}
|
|
2808
2855
|
|
|
2809
2856
|
// src/defaults/LoadingState.tsx
|
|
2810
|
-
var
|
|
2857
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2811
2858
|
function LoadingState({ message }) {
|
|
2812
|
-
return /* @__PURE__ */ (0,
|
|
2859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: message ?? "Carregando..." }) });
|
|
2813
2860
|
}
|
|
2814
2861
|
|
|
2815
2862
|
// src/defaults/EmptyState.tsx
|
|
2816
|
-
var
|
|
2863
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2817
2864
|
function EmptyState({ title, description, action }) {
|
|
2818
|
-
return /* @__PURE__ */ (0,
|
|
2819
|
-
/* @__PURE__ */ (0,
|
|
2820
|
-
description && /* @__PURE__ */ (0,
|
|
2821
|
-
action && /* @__PURE__ */ (0,
|
|
2865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2867
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { style: { opacity: 0.7 }, children: description }),
|
|
2868
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { style: { marginTop: 16 }, children: action })
|
|
2822
2869
|
] });
|
|
2823
2870
|
}
|
|
2824
2871
|
|
|
2825
2872
|
// src/hooks/useLoginForm.ts
|
|
2826
|
-
var
|
|
2827
|
-
var
|
|
2873
|
+
var import_react18 = require("react");
|
|
2874
|
+
var import_sdk13 = require("@hook-sdk/sdk");
|
|
2828
2875
|
|
|
2829
2876
|
// src/errors.ts
|
|
2830
|
-
var
|
|
2877
|
+
var import_sdk12 = require("@hook-sdk/sdk");
|
|
2831
2878
|
function mapSdkError(err) {
|
|
2832
|
-
if (err instanceof
|
|
2879
|
+
if (err instanceof import_sdk12.SdkRateLimitError) {
|
|
2833
2880
|
return {
|
|
2834
2881
|
code: "rate_limited",
|
|
2835
2882
|
message: `Aguarde ${err.retryAfter}s e tente novamente.`,
|
|
2836
2883
|
retryAfter: err.retryAfter
|
|
2837
2884
|
};
|
|
2838
2885
|
}
|
|
2839
|
-
if (err instanceof
|
|
2886
|
+
if (err instanceof import_sdk12.SdkAuthError) {
|
|
2840
2887
|
const detail = err.detail;
|
|
2841
2888
|
if (detail === "email_unverified") {
|
|
2842
2889
|
return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
|
|
@@ -2846,7 +2893,10 @@ function mapSdkError(err) {
|
|
|
2846
2893
|
}
|
|
2847
2894
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2848
2895
|
}
|
|
2849
|
-
if (err instanceof
|
|
2896
|
+
if (err instanceof import_sdk12.SdkValidationError && err.code === "auth.email_taken") {
|
|
2897
|
+
return { code: "email_taken", message: "Esse e-mail j\xE1 tem conta." };
|
|
2898
|
+
}
|
|
2899
|
+
if (err instanceof import_sdk12.SdkError && err.httpStatus === 0) {
|
|
2850
2900
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2851
2901
|
}
|
|
2852
2902
|
if (err instanceof TypeError) {
|
|
@@ -2859,20 +2909,20 @@ function mapSdkError(err) {
|
|
|
2859
2909
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2860
2910
|
var MIN_PASSWORD = 8;
|
|
2861
2911
|
function useLoginForm() {
|
|
2862
|
-
const { auth } = (0,
|
|
2863
|
-
const [email, setEmail] = (0,
|
|
2864
|
-
const [password, setPassword] = (0,
|
|
2865
|
-
const [submitting, setSubmitting] = (0,
|
|
2866
|
-
const [error, setError] = (0,
|
|
2867
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2868
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2869
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2870
|
-
const validateEmail = (0,
|
|
2912
|
+
const { auth } = (0, import_sdk13.useHook)();
|
|
2913
|
+
const [email, setEmail] = (0, import_react18.useState)("");
|
|
2914
|
+
const [password, setPassword] = (0, import_react18.useState)("");
|
|
2915
|
+
const [submitting, setSubmitting] = (0, import_react18.useState)(false);
|
|
2916
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
2917
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react18.useState)(false);
|
|
2918
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react18.useState)(false);
|
|
2919
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react18.useState)(false);
|
|
2920
|
+
const validateEmail = (0, import_react18.useMemo)(() => {
|
|
2871
2921
|
if (email.length === 0) return null;
|
|
2872
2922
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2873
2923
|
return null;
|
|
2874
2924
|
}, [email]);
|
|
2875
|
-
const validatePassword = (0,
|
|
2925
|
+
const validatePassword = (0, import_react18.useMemo)(() => {
|
|
2876
2926
|
if (password.length === 0) return null;
|
|
2877
2927
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
2878
2928
|
return null;
|
|
@@ -2880,7 +2930,7 @@ function useLoginForm() {
|
|
|
2880
2930
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2881
2931
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2882
2932
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
|
|
2883
|
-
const submit = (0,
|
|
2933
|
+
const submit = (0, import_react18.useCallback)(async () => {
|
|
2884
2934
|
setFormSubmitAttempted(true);
|
|
2885
2935
|
if (!canSubmit) return false;
|
|
2886
2936
|
setSubmitting(true);
|
|
@@ -2914,32 +2964,32 @@ function useLoginForm() {
|
|
|
2914
2964
|
}
|
|
2915
2965
|
|
|
2916
2966
|
// src/hooks/useSignupForm.ts
|
|
2917
|
-
var
|
|
2918
|
-
var
|
|
2967
|
+
var import_react19 = require("react");
|
|
2968
|
+
var import_sdk14 = require("@hook-sdk/sdk");
|
|
2919
2969
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2920
2970
|
var MIN_PASSWORD2 = 8;
|
|
2921
2971
|
function useSignupForm() {
|
|
2922
|
-
const { auth } = (0,
|
|
2923
|
-
const [name, setName] = (0,
|
|
2924
|
-
const [email, setEmail] = (0,
|
|
2925
|
-
const [password, setPassword] = (0,
|
|
2926
|
-
const [submitting, setSubmitting] = (0,
|
|
2927
|
-
const [error, setError] = (0,
|
|
2928
|
-
const [touchedName, setTouchedName] = (0,
|
|
2929
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2930
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2931
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2932
|
-
const validateName = (0,
|
|
2972
|
+
const { auth } = (0, import_sdk14.useHook)();
|
|
2973
|
+
const [name, setName] = (0, import_react19.useState)("");
|
|
2974
|
+
const [email, setEmail] = (0, import_react19.useState)("");
|
|
2975
|
+
const [password, setPassword] = (0, import_react19.useState)("");
|
|
2976
|
+
const [submitting, setSubmitting] = (0, import_react19.useState)(false);
|
|
2977
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
2978
|
+
const [touchedName, setTouchedName] = (0, import_react19.useState)(false);
|
|
2979
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react19.useState)(false);
|
|
2980
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react19.useState)(false);
|
|
2981
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react19.useState)(false);
|
|
2982
|
+
const validateName = (0, import_react19.useMemo)(() => {
|
|
2933
2983
|
if (name.length === 0) return null;
|
|
2934
2984
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2935
2985
|
return null;
|
|
2936
2986
|
}, [name]);
|
|
2937
|
-
const validateEmail = (0,
|
|
2987
|
+
const validateEmail = (0, import_react19.useMemo)(() => {
|
|
2938
2988
|
if (email.length === 0) return null;
|
|
2939
2989
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2940
2990
|
return null;
|
|
2941
2991
|
}, [email]);
|
|
2942
|
-
const validatePassword = (0,
|
|
2992
|
+
const validatePassword = (0, import_react19.useMemo)(() => {
|
|
2943
2993
|
if (password.length === 0) return null;
|
|
2944
2994
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
2945
2995
|
return null;
|
|
@@ -2948,7 +2998,7 @@ function useSignupForm() {
|
|
|
2948
2998
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2949
2999
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2950
3000
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
|
|
2951
|
-
const submit = (0,
|
|
3001
|
+
const submit = (0, import_react19.useCallback)(async () => {
|
|
2952
3002
|
setFormSubmitAttempted(true);
|
|
2953
3003
|
if (!canSubmit) return false;
|
|
2954
3004
|
setSubmitting(true);
|
|
@@ -2986,25 +3036,25 @@ function useSignupForm() {
|
|
|
2986
3036
|
}
|
|
2987
3037
|
|
|
2988
3038
|
// src/hooks/useForgotForm.ts
|
|
2989
|
-
var
|
|
2990
|
-
var
|
|
3039
|
+
var import_react20 = require("react");
|
|
3040
|
+
var import_sdk15 = require("@hook-sdk/sdk");
|
|
2991
3041
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2992
3042
|
function useForgotForm() {
|
|
2993
|
-
const { auth } = (0,
|
|
2994
|
-
const [email, setEmail] = (0,
|
|
2995
|
-
const [submitting, setSubmitting] = (0,
|
|
2996
|
-
const [sent, setSent] = (0,
|
|
2997
|
-
const [error, setError] = (0,
|
|
2998
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2999
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
3000
|
-
const validateEmail = (0,
|
|
3043
|
+
const { auth } = (0, import_sdk15.useHook)();
|
|
3044
|
+
const [email, setEmail] = (0, import_react20.useState)("");
|
|
3045
|
+
const [submitting, setSubmitting] = (0, import_react20.useState)(false);
|
|
3046
|
+
const [sent, setSent] = (0, import_react20.useState)(false);
|
|
3047
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
3048
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react20.useState)(false);
|
|
3049
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react20.useState)(false);
|
|
3050
|
+
const validateEmail = (0, import_react20.useMemo)(() => {
|
|
3001
3051
|
if (email.length === 0) return null;
|
|
3002
3052
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
3003
3053
|
return null;
|
|
3004
3054
|
}, [email]);
|
|
3005
3055
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
3006
3056
|
const canSubmit = email.length > 0 && validateEmail === null && !submitting;
|
|
3007
|
-
const submit = (0,
|
|
3057
|
+
const submit = (0, import_react20.useCallback)(async () => {
|
|
3008
3058
|
setFormSubmitAttempted(true);
|
|
3009
3059
|
if (!canSubmit) return false;
|
|
3010
3060
|
setSubmitting(true);
|
|
@@ -3035,32 +3085,32 @@ function useForgotForm() {
|
|
|
3035
3085
|
}
|
|
3036
3086
|
|
|
3037
3087
|
// src/hooks/useResetForm.ts
|
|
3038
|
-
var
|
|
3039
|
-
var
|
|
3040
|
-
var MIN_PASSWORD3 =
|
|
3088
|
+
var import_react21 = require("react");
|
|
3089
|
+
var import_sdk16 = require("@hook-sdk/sdk");
|
|
3090
|
+
var MIN_PASSWORD3 = 8;
|
|
3041
3091
|
function useResetForm() {
|
|
3042
|
-
const { auth } = (0,
|
|
3043
|
-
const [token, setToken] = (0,
|
|
3044
|
-
const [password, setPassword] = (0,
|
|
3045
|
-
const [confirm, setConfirm] = (0,
|
|
3046
|
-
const [submitting, setSubmitting] = (0,
|
|
3047
|
-
const [done, setDone] = (0,
|
|
3048
|
-
const [error, setError] = (0,
|
|
3049
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
3050
|
-
const [touchedConfirm, setTouchedConfirm] = (0,
|
|
3051
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
3052
|
-
(0,
|
|
3092
|
+
const { auth } = (0, import_sdk16.useHook)();
|
|
3093
|
+
const [token, setToken] = (0, import_react21.useState)(null);
|
|
3094
|
+
const [password, setPassword] = (0, import_react21.useState)("");
|
|
3095
|
+
const [confirm, setConfirm] = (0, import_react21.useState)("");
|
|
3096
|
+
const [submitting, setSubmitting] = (0, import_react21.useState)(false);
|
|
3097
|
+
const [done, setDone] = (0, import_react21.useState)(false);
|
|
3098
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
3099
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react21.useState)(false);
|
|
3100
|
+
const [touchedConfirm, setTouchedConfirm] = (0, import_react21.useState)(false);
|
|
3101
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react21.useState)(false);
|
|
3102
|
+
(0, import_react21.useEffect)(() => {
|
|
3053
3103
|
if (typeof window === "undefined") return;
|
|
3054
3104
|
const params = new URLSearchParams(window.location.search);
|
|
3055
3105
|
const t = params.get("token");
|
|
3056
3106
|
setToken(t && t.length > 0 ? t : null);
|
|
3057
3107
|
}, []);
|
|
3058
|
-
const validatePassword = (0,
|
|
3108
|
+
const validatePassword = (0, import_react21.useMemo)(() => {
|
|
3059
3109
|
if (password.length === 0) return null;
|
|
3060
3110
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
3061
3111
|
return null;
|
|
3062
3112
|
}, [password]);
|
|
3063
|
-
const validateConfirm = (0,
|
|
3113
|
+
const validateConfirm = (0, import_react21.useMemo)(() => {
|
|
3064
3114
|
if (confirm.length === 0) return null;
|
|
3065
3115
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
3066
3116
|
return null;
|
|
@@ -3068,7 +3118,7 @@ function useResetForm() {
|
|
|
3068
3118
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
3069
3119
|
const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
|
|
3070
3120
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
|
|
3071
|
-
const submit = (0,
|
|
3121
|
+
const submit = (0, import_react21.useCallback)(async () => {
|
|
3072
3122
|
setFormSubmitAttempted(true);
|
|
3073
3123
|
if (!canSubmit || token === null) return;
|
|
3074
3124
|
setSubmitting(true);
|
|
@@ -3108,9 +3158,9 @@ function useResetForm() {
|
|
|
3108
3158
|
}
|
|
3109
3159
|
|
|
3110
3160
|
// src/hooks/usePlan.ts
|
|
3111
|
-
var
|
|
3161
|
+
var import_sdk17 = require("@hook-sdk/sdk");
|
|
3112
3162
|
function usePlan() {
|
|
3113
|
-
const { plan } = (0,
|
|
3163
|
+
const { plan } = (0, import_sdk17.useHook)();
|
|
3114
3164
|
return plan;
|
|
3115
3165
|
}
|
|
3116
3166
|
|
|
@@ -3143,12 +3193,12 @@ function discountPercent(anchorCents, realCents) {
|
|
|
3143
3193
|
}
|
|
3144
3194
|
|
|
3145
3195
|
// src/hooks/useAuthPrimitives.ts
|
|
3146
|
-
var
|
|
3147
|
-
var
|
|
3196
|
+
var import_react22 = require("react");
|
|
3197
|
+
var import_sdk18 = require("@hook-sdk/sdk");
|
|
3148
3198
|
var warned = false;
|
|
3149
3199
|
function useAuthPrimitives() {
|
|
3150
|
-
const { auth } = (0,
|
|
3151
|
-
(0,
|
|
3200
|
+
const { auth } = (0, import_sdk18.useHook)();
|
|
3201
|
+
(0, import_react22.useEffect)(() => {
|
|
3152
3202
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
3153
3203
|
warned = true;
|
|
3154
3204
|
console.warn(
|
|
@@ -3170,9 +3220,9 @@ function useAuthPrimitives() {
|
|
|
3170
3220
|
}
|
|
3171
3221
|
|
|
3172
3222
|
// src/hooks/useAuth.ts
|
|
3173
|
-
var
|
|
3223
|
+
var import_sdk19 = require("@hook-sdk/sdk");
|
|
3174
3224
|
function useAuth() {
|
|
3175
|
-
const { user, authStatus, auth } = (0,
|
|
3225
|
+
const { user, authStatus, auth } = (0, import_sdk19.useHook)();
|
|
3176
3226
|
return {
|
|
3177
3227
|
user,
|
|
3178
3228
|
authStatus,
|
|
@@ -3181,26 +3231,26 @@ function useAuth() {
|
|
|
3181
3231
|
}
|
|
3182
3232
|
|
|
3183
3233
|
// src/index.ts
|
|
3184
|
-
var
|
|
3234
|
+
var import_sdk24 = require("@hook-sdk/sdk");
|
|
3185
3235
|
|
|
3186
3236
|
// src/hooks/useSubscription.ts
|
|
3187
|
-
var
|
|
3237
|
+
var import_sdk20 = require("@hook-sdk/sdk");
|
|
3188
3238
|
function useSubscription() {
|
|
3189
|
-
const { subscription } = (0,
|
|
3239
|
+
const { subscription } = (0, import_sdk20.useHook)();
|
|
3190
3240
|
return {
|
|
3191
3241
|
status: subscription.status()
|
|
3192
3242
|
};
|
|
3193
3243
|
}
|
|
3194
3244
|
|
|
3195
3245
|
// src/hooks/useReminders.ts
|
|
3196
|
-
var
|
|
3197
|
-
var
|
|
3246
|
+
var import_react23 = require("react");
|
|
3247
|
+
var import_sdk21 = require("@hook-sdk/sdk");
|
|
3198
3248
|
function useReminders() {
|
|
3199
|
-
const { push } = (0,
|
|
3249
|
+
const { push } = (0, import_sdk21.useHook)();
|
|
3200
3250
|
const r = push.reminders;
|
|
3201
|
-
const [reminders, setReminders] = (0,
|
|
3202
|
-
const [loading, setLoading] = (0,
|
|
3203
|
-
const reload = (0,
|
|
3251
|
+
const [reminders, setReminders] = (0, import_react23.useState)([]);
|
|
3252
|
+
const [loading, setLoading] = (0, import_react23.useState)(true);
|
|
3253
|
+
const reload = (0, import_react23.useCallback)(async () => {
|
|
3204
3254
|
setLoading(true);
|
|
3205
3255
|
try {
|
|
3206
3256
|
const next = await r.list();
|
|
@@ -3209,38 +3259,38 @@ function useReminders() {
|
|
|
3209
3259
|
setLoading(false);
|
|
3210
3260
|
}
|
|
3211
3261
|
}, [r]);
|
|
3212
|
-
(0,
|
|
3262
|
+
(0, import_react23.useEffect)(() => {
|
|
3213
3263
|
void reload();
|
|
3214
3264
|
}, [reload]);
|
|
3215
|
-
const setReminder = (0,
|
|
3265
|
+
const setReminder = (0, import_react23.useCallback)(async (input) => {
|
|
3216
3266
|
await r.set(input);
|
|
3217
3267
|
await reload();
|
|
3218
3268
|
}, [r, reload]);
|
|
3219
|
-
const deleteReminder = (0,
|
|
3269
|
+
const deleteReminder = (0, import_react23.useCallback)(async (slot) => {
|
|
3220
3270
|
await r.delete(slot);
|
|
3221
3271
|
await reload();
|
|
3222
3272
|
}, [r, reload]);
|
|
3223
|
-
const schedule = (0,
|
|
3273
|
+
const schedule = (0, import_react23.useCallback)(async (items) => {
|
|
3224
3274
|
return r.schedule(items);
|
|
3225
3275
|
}, [r]);
|
|
3226
|
-
const setFallbacks = (0,
|
|
3276
|
+
const setFallbacks = (0, import_react23.useCallback)(async (items) => {
|
|
3227
3277
|
return r.setFallbacks(items);
|
|
3228
3278
|
}, [r]);
|
|
3229
3279
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
3230
3280
|
}
|
|
3231
3281
|
|
|
3232
3282
|
// src/hooks/useToast.ts
|
|
3233
|
-
var
|
|
3283
|
+
var import_react24 = require("react");
|
|
3234
3284
|
function useToast() {
|
|
3235
|
-
const [items, setItems] = (0,
|
|
3236
|
-
const show = (0,
|
|
3285
|
+
const [items, setItems] = (0, import_react24.useState)([]);
|
|
3286
|
+
const show = (0, import_react24.useCallback)((message, kind = "info") => {
|
|
3237
3287
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
3238
3288
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
3239
3289
|
setTimeout(() => {
|
|
3240
3290
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
3241
3291
|
}, 4e3);
|
|
3242
3292
|
}, []);
|
|
3243
|
-
const dismiss = (0,
|
|
3293
|
+
const dismiss = (0, import_react24.useCallback)((id) => {
|
|
3244
3294
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
3245
3295
|
}, []);
|
|
3246
3296
|
return { items, show, dismiss };
|
|
@@ -3248,20 +3298,20 @@ function useToast() {
|
|
|
3248
3298
|
|
|
3249
3299
|
// src/RouteBoundary.tsx
|
|
3250
3300
|
var import_react_router_dom3 = require("react-router-dom");
|
|
3251
|
-
var
|
|
3301
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3252
3302
|
function RouteBoundary({ children }) {
|
|
3253
|
-
return /* @__PURE__ */ (0,
|
|
3303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_react_router_dom3.Routes, { children: [
|
|
3254
3304
|
children,
|
|
3255
|
-
/* @__PURE__ */ (0,
|
|
3305
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_router_dom3.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DefaultNotFound, {}) })
|
|
3256
3306
|
] });
|
|
3257
3307
|
}
|
|
3258
3308
|
function DefaultNotFound() {
|
|
3259
|
-
return /* @__PURE__ */ (0,
|
|
3309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
|
|
3260
3310
|
}
|
|
3261
3311
|
|
|
3262
3312
|
// src/PreAuthShell.tsx
|
|
3263
3313
|
var import_react_router_dom4 = require("react-router-dom");
|
|
3264
|
-
var
|
|
3314
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3265
3315
|
function PreAuthShell({
|
|
3266
3316
|
basename,
|
|
3267
3317
|
testRouter,
|
|
@@ -3269,20 +3319,20 @@ function PreAuthShell({
|
|
|
3269
3319
|
children
|
|
3270
3320
|
}) {
|
|
3271
3321
|
if (testRouter === "memory") {
|
|
3272
|
-
return /* @__PURE__ */ (0,
|
|
3322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
3273
3323
|
}
|
|
3274
|
-
return /* @__PURE__ */ (0,
|
|
3324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
3275
3325
|
}
|
|
3276
3326
|
|
|
3277
3327
|
// src/OnboardingFlow.tsx
|
|
3278
|
-
var
|
|
3279
|
-
var
|
|
3328
|
+
var import_react26 = require("react");
|
|
3329
|
+
var import_sdk22 = require("@hook-sdk/sdk");
|
|
3280
3330
|
|
|
3281
3331
|
// src/hooks/useOnboardingStep.ts
|
|
3282
|
-
var
|
|
3283
|
-
var OnboardingStepContext = (0,
|
|
3332
|
+
var import_react25 = require("react");
|
|
3333
|
+
var OnboardingStepContext = (0, import_react25.createContext)(null);
|
|
3284
3334
|
function useOnboardingStep() {
|
|
3285
|
-
const ctx = (0,
|
|
3335
|
+
const ctx = (0, import_react25.useContext)(OnboardingStepContext);
|
|
3286
3336
|
if (!ctx) {
|
|
3287
3337
|
throw new Error(
|
|
3288
3338
|
"[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
|
|
@@ -3292,7 +3342,7 @@ function useOnboardingStep() {
|
|
|
3292
3342
|
}
|
|
3293
3343
|
|
|
3294
3344
|
// src/OnboardingFlow.tsx
|
|
3295
|
-
var
|
|
3345
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3296
3346
|
var isFilled = (v) => v != null && v !== "";
|
|
3297
3347
|
var CURRENT_STEP_FIELD = "currentStep";
|
|
3298
3348
|
function readPersistedStepIdx(draft) {
|
|
@@ -3305,12 +3355,12 @@ function OnboardingFlow({
|
|
|
3305
3355
|
onComplete,
|
|
3306
3356
|
persistKey
|
|
3307
3357
|
}) {
|
|
3308
|
-
const [draft, setDraft, status] = (0,
|
|
3309
|
-
const draftRef = (0,
|
|
3358
|
+
const [draft, setDraft, status] = (0, import_sdk22.usePersistedState)(persistKey, {});
|
|
3359
|
+
const draftRef = (0, import_react26.useRef)(draft);
|
|
3310
3360
|
draftRef.current = draft;
|
|
3311
3361
|
const idx = readPersistedStepIdx(draft);
|
|
3312
3362
|
const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
|
|
3313
|
-
const setIdx = (0,
|
|
3363
|
+
const setIdx = (0, import_react26.useCallback)(
|
|
3314
3364
|
(n) => {
|
|
3315
3365
|
setDraft((prev) => {
|
|
3316
3366
|
const prevIdx = readPersistedStepIdx(prev);
|
|
@@ -3320,7 +3370,7 @@ function OnboardingFlow({
|
|
|
3320
3370
|
},
|
|
3321
3371
|
[setDraft]
|
|
3322
3372
|
);
|
|
3323
|
-
const setValue = (0,
|
|
3373
|
+
const setValue = (0, import_react26.useCallback)(
|
|
3324
3374
|
(patch) => {
|
|
3325
3375
|
draftRef.current = { ...draftRef.current, ...patch };
|
|
3326
3376
|
setDraft((prev) => ({ ...prev, ...patch }));
|
|
@@ -3328,9 +3378,9 @@ function OnboardingFlow({
|
|
|
3328
3378
|
[setDraft]
|
|
3329
3379
|
);
|
|
3330
3380
|
const step = steps[clampedIdx];
|
|
3331
|
-
const hookCtx = (0,
|
|
3381
|
+
const hookCtx = (0, import_sdk22.useHook)();
|
|
3332
3382
|
const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
|
|
3333
|
-
(0,
|
|
3383
|
+
(0, import_react26.useEffect)(() => {
|
|
3334
3384
|
if (status.loading) return;
|
|
3335
3385
|
if (!step) return;
|
|
3336
3386
|
if (!track2) return;
|
|
@@ -3340,11 +3390,11 @@ function OnboardingFlow({
|
|
|
3340
3390
|
total_steps: steps.length
|
|
3341
3391
|
});
|
|
3342
3392
|
}, [step?.id, clampedIdx, steps.length, status.loading, track2]);
|
|
3343
|
-
const valid = (0,
|
|
3393
|
+
const valid = (0, import_react26.useMemo)(
|
|
3344
3394
|
() => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
|
|
3345
3395
|
[draft, step]
|
|
3346
3396
|
);
|
|
3347
|
-
const next = (0,
|
|
3397
|
+
const next = (0, import_react26.useCallback)(() => {
|
|
3348
3398
|
if (!step) return;
|
|
3349
3399
|
const current = draftRef.current;
|
|
3350
3400
|
const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
|
|
@@ -3355,8 +3405,8 @@ function OnboardingFlow({
|
|
|
3355
3405
|
setIdx(clampedIdx + 1);
|
|
3356
3406
|
}
|
|
3357
3407
|
}, [clampedIdx, onComplete, step, steps.length, setIdx]);
|
|
3358
|
-
const prevStep = (0,
|
|
3359
|
-
const ctx = (0,
|
|
3408
|
+
const prevStep = (0, import_react26.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
|
|
3409
|
+
const ctx = (0, import_react26.useMemo)(
|
|
3360
3410
|
() => ({
|
|
3361
3411
|
stepIndex: clampedIdx,
|
|
3362
3412
|
totalSteps: steps.length,
|
|
@@ -3382,7 +3432,7 @@ function OnboardingFlow({
|
|
|
3382
3432
|
`[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
|
|
3383
3433
|
);
|
|
3384
3434
|
}
|
|
3385
|
-
return /* @__PURE__ */ (0,
|
|
3435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Screen, {}) });
|
|
3386
3436
|
}
|
|
3387
3437
|
|
|
3388
3438
|
// src/hooks/useFeature.ts
|
|
@@ -3392,22 +3442,22 @@ function useFeature(name) {
|
|
|
3392
3442
|
}
|
|
3393
3443
|
|
|
3394
3444
|
// src/components/paywall/Paywall.tsx
|
|
3395
|
-
var
|
|
3396
|
-
var
|
|
3445
|
+
var import_react29 = require("react");
|
|
3446
|
+
var import_sdk23 = require("@hook-sdk/sdk");
|
|
3397
3447
|
|
|
3398
3448
|
// src/components/paywall/PaywallProvider.tsx
|
|
3399
|
-
var
|
|
3400
|
-
var
|
|
3401
|
-
var PaywallContext = (0,
|
|
3449
|
+
var import_react27 = require("react");
|
|
3450
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3451
|
+
var PaywallContext = (0, import_react27.createContext)(null);
|
|
3402
3452
|
function PaywallProvider({ children }) {
|
|
3403
3453
|
const state = usePaywallState();
|
|
3404
|
-
return /* @__PURE__ */ (0,
|
|
3454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PaywallContext.Provider, { value: state, children });
|
|
3405
3455
|
}
|
|
3406
3456
|
|
|
3407
3457
|
// src/components/paywall/usePaywallContext.ts
|
|
3408
|
-
var
|
|
3458
|
+
var import_react28 = require("react");
|
|
3409
3459
|
function usePaywallContext() {
|
|
3410
|
-
const ctx = (0,
|
|
3460
|
+
const ctx = (0, import_react28.useContext)(PaywallContext);
|
|
3411
3461
|
if (!ctx) {
|
|
3412
3462
|
throw new Error("usePaywallContext must be used within <PaywallProvider>");
|
|
3413
3463
|
}
|
|
@@ -3415,7 +3465,7 @@ function usePaywallContext() {
|
|
|
3415
3465
|
}
|
|
3416
3466
|
|
|
3417
3467
|
// src/components/paywall/PaywallMethodTabs.tsx
|
|
3418
|
-
var
|
|
3468
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3419
3469
|
function PaywallMethodTabs({
|
|
3420
3470
|
labels,
|
|
3421
3471
|
className,
|
|
@@ -3424,10 +3474,10 @@ function PaywallMethodTabs({
|
|
|
3424
3474
|
}) {
|
|
3425
3475
|
const { methods, selectedMethod, selectMethod } = usePaywallContext();
|
|
3426
3476
|
if (methods.length < 2) return null;
|
|
3427
|
-
return /* @__PURE__ */ (0,
|
|
3477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
|
|
3428
3478
|
const active = m === selectedMethod;
|
|
3429
3479
|
const label = labels[m] ?? m;
|
|
3430
|
-
return /* @__PURE__ */ (0,
|
|
3480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3431
3481
|
"button",
|
|
3432
3482
|
{
|
|
3433
3483
|
type: "button",
|
|
@@ -3445,16 +3495,16 @@ function PaywallMethodTabs({
|
|
|
3445
3495
|
}
|
|
3446
3496
|
|
|
3447
3497
|
// src/components/paywall/PaywallMethodContent.tsx
|
|
3448
|
-
var
|
|
3498
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3449
3499
|
function PaywallMethodContent({ copy, className, rowClassName }) {
|
|
3450
3500
|
const { selectedMethod, hasConsumedTrial } = usePaywallContext();
|
|
3451
3501
|
const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
3452
3502
|
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
3453
|
-
return /* @__PURE__ */ (0,
|
|
3503
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: rowClassName, children: row }, i)) });
|
|
3454
3504
|
}
|
|
3455
3505
|
|
|
3456
3506
|
// src/components/paywall/PaywallCyclePicker.tsx
|
|
3457
|
-
var
|
|
3507
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3458
3508
|
var VARIANT_CLASSES = {
|
|
3459
3509
|
default: { card: "", cardSelected: "" },
|
|
3460
3510
|
"premium-gold": {
|
|
@@ -3479,7 +3529,7 @@ function PaywallCyclePicker({
|
|
|
3479
3529
|
const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
|
|
3480
3530
|
const cycles = ["MONTHLY", "YEARLY"];
|
|
3481
3531
|
if (render) {
|
|
3482
|
-
return /* @__PURE__ */ (0,
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
|
|
3483
3533
|
}
|
|
3484
3534
|
if (cycles.length < 2) return null;
|
|
3485
3535
|
const v = VARIANT_CLASSES[variant];
|
|
@@ -3489,7 +3539,7 @@ function PaywallCyclePicker({
|
|
|
3489
3539
|
const yearlyCents = plan?.yearlyCents ?? 0;
|
|
3490
3540
|
const anchorMonthly = plan?.anchorMonthlyCents ?? null;
|
|
3491
3541
|
const anchorYearly = plan?.anchorYearlyCents ?? null;
|
|
3492
|
-
return /* @__PURE__ */ (0,
|
|
3542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3493
3543
|
"div",
|
|
3494
3544
|
{
|
|
3495
3545
|
role: "radiogroup",
|
|
@@ -3501,7 +3551,7 @@ function PaywallCyclePicker({
|
|
|
3501
3551
|
const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
|
|
3502
3552
|
const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
|
|
3503
3553
|
const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
|
|
3504
|
-
return /* @__PURE__ */ (0,
|
|
3554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
3505
3555
|
"button",
|
|
3506
3556
|
{
|
|
3507
3557
|
type: "button",
|
|
@@ -3514,10 +3564,10 @@ function PaywallCyclePicker({
|
|
|
3514
3564
|
active ? composedCardSelectedClassName : ""
|
|
3515
3565
|
].filter(Boolean).join(" "),
|
|
3516
3566
|
children: [
|
|
3517
|
-
/* @__PURE__ */ (0,
|
|
3518
|
-
/* @__PURE__ */ (0,
|
|
3519
|
-
/* @__PURE__ */ (0,
|
|
3520
|
-
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0,
|
|
3567
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
|
|
3568
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
|
|
3569
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-xs opacity-60 leading-tight", children: label }),
|
|
3570
|
+
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("s", { children: formatBRL(anchorCents) }) }) : null
|
|
3521
3571
|
]
|
|
3522
3572
|
},
|
|
3523
3573
|
c
|
|
@@ -3528,7 +3578,7 @@ function PaywallCyclePicker({
|
|
|
3528
3578
|
}
|
|
3529
3579
|
|
|
3530
3580
|
// src/components/paywall/Paywall.tsx
|
|
3531
|
-
var
|
|
3581
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3532
3582
|
var NBSP = "\xA0";
|
|
3533
3583
|
function Paywall({
|
|
3534
3584
|
copy,
|
|
@@ -3536,7 +3586,7 @@ function Paywall({
|
|
|
3536
3586
|
slots = {},
|
|
3537
3587
|
onBeforeCheckout
|
|
3538
3588
|
}) {
|
|
3539
|
-
return /* @__PURE__ */ (0,
|
|
3589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(PaywallProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3540
3590
|
PaywallInner,
|
|
3541
3591
|
{
|
|
3542
3592
|
copy,
|
|
@@ -3552,11 +3602,11 @@ function PaywallInner({
|
|
|
3552
3602
|
slots = {},
|
|
3553
3603
|
onBeforeCheckout
|
|
3554
3604
|
}) {
|
|
3555
|
-
const { track: track2 } = (0,
|
|
3605
|
+
const { track: track2 } = (0, import_sdk23.useHook)();
|
|
3556
3606
|
const s = usePaywallContext();
|
|
3557
3607
|
const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
|
|
3558
3608
|
const trialDaysCardLabel = String(s.trialDaysCard);
|
|
3559
|
-
const ctaLabel = (0,
|
|
3609
|
+
const ctaLabel = (0, import_react29.useMemo)(() => {
|
|
3560
3610
|
if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
|
|
3561
3611
|
if (s.selectedMethod === "card") {
|
|
3562
3612
|
if (s.hasConsumedTrial && copy.cardConsumedTrial) {
|
|
@@ -3583,11 +3633,11 @@ function PaywallInner({
|
|
|
3583
3633
|
priceLabel,
|
|
3584
3634
|
trialDaysCardLabel
|
|
3585
3635
|
]);
|
|
3586
|
-
const switchHint = (0,
|
|
3636
|
+
const switchHint = (0, import_react29.useMemo)(() => {
|
|
3587
3637
|
if (s.methods.length < 2) return void 0;
|
|
3588
3638
|
return s.selectedMethod === "card" ? copy.card.switchHint : copy.pix.switchHint;
|
|
3589
3639
|
}, [s.methods.length, s.selectedMethod, copy]);
|
|
3590
|
-
(0,
|
|
3640
|
+
(0, import_react29.useEffect)(() => {
|
|
3591
3641
|
if (!s.initialLoadComplete) return;
|
|
3592
3642
|
track2("paywall_view", {
|
|
3593
3643
|
default_method: s.selectedMethod,
|
|
@@ -3609,15 +3659,15 @@ function PaywallInner({
|
|
|
3609
3659
|
await s.submit();
|
|
3610
3660
|
};
|
|
3611
3661
|
const ctaTheme = s.selectedMethod === "card" ? themeClasses.ctaCard : themeClasses.ctaPix;
|
|
3612
|
-
return /* @__PURE__ */ (0,
|
|
3662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: themeClasses.container, children: [
|
|
3613
3663
|
slots.heroSlot,
|
|
3614
|
-
/* @__PURE__ */ (0,
|
|
3615
|
-
/* @__PURE__ */ (0,
|
|
3664
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", { className: themeClasses.headline, children: copy.headline }),
|
|
3665
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { children: copy.features.map((f) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("li", { className: themeClasses.feature, children: [
|
|
3616
3666
|
"\u2713 ",
|
|
3617
|
-
/* @__PURE__ */ (0,
|
|
3667
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: f })
|
|
3618
3668
|
] }, f)) }),
|
|
3619
|
-
copy.socialProof ? /* @__PURE__ */ (0,
|
|
3620
|
-
slots.cyclePickerSlot ?? /* @__PURE__ */ (0,
|
|
3669
|
+
copy.socialProof ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.socialProof, children: copy.socialProof }) : null,
|
|
3670
|
+
slots.cyclePickerSlot ?? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3621
3671
|
PaywallCyclePicker,
|
|
3622
3672
|
{
|
|
3623
3673
|
labels: copy.cycle,
|
|
@@ -3626,7 +3676,7 @@ function PaywallInner({
|
|
|
3626
3676
|
anchorClassName: themeClasses.anchorPrice
|
|
3627
3677
|
}
|
|
3628
3678
|
),
|
|
3629
|
-
/* @__PURE__ */ (0,
|
|
3679
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3630
3680
|
PaywallMethodTabs,
|
|
3631
3681
|
{
|
|
3632
3682
|
labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
|
|
@@ -3635,7 +3685,7 @@ function PaywallInner({
|
|
|
3635
3685
|
tabActiveClassName: themeClasses.tabActive
|
|
3636
3686
|
}
|
|
3637
3687
|
),
|
|
3638
|
-
/* @__PURE__ */ (0,
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3639
3689
|
PaywallMethodContent,
|
|
3640
3690
|
{
|
|
3641
3691
|
copy: {
|
|
@@ -3653,8 +3703,8 @@ function PaywallInner({
|
|
|
3653
3703
|
}
|
|
3654
3704
|
),
|
|
3655
3705
|
slots.beforeCtaSlot,
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
3657
|
-
/* @__PURE__ */ (0,
|
|
3706
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
|
|
3707
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3658
3708
|
"button",
|
|
3659
3709
|
{
|
|
3660
3710
|
type: "button",
|
|
@@ -3666,8 +3716,8 @@ function PaywallInner({
|
|
|
3666
3716
|
children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
|
|
3667
3717
|
}
|
|
3668
3718
|
),
|
|
3669
|
-
switchHint ? /* @__PURE__ */ (0,
|
|
3670
|
-
/* @__PURE__ */ (0,
|
|
3719
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.switchHint, children: switchHint }) : null,
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: themeClasses.trustLine, children: copy.trustLine })
|
|
3671
3721
|
] })
|
|
3672
3722
|
] });
|
|
3673
3723
|
}
|
|
@@ -3684,7 +3734,7 @@ function interpolateCopy(m, price, days) {
|
|
|
3684
3734
|
}
|
|
3685
3735
|
|
|
3686
3736
|
// src/components/paywall/PaywallCta.tsx
|
|
3687
|
-
var
|
|
3737
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3688
3738
|
function PaywallCta({
|
|
3689
3739
|
ctaLabel,
|
|
3690
3740
|
loadingLabel,
|
|
@@ -3697,8 +3747,8 @@ function PaywallCta({
|
|
|
3697
3747
|
}) {
|
|
3698
3748
|
const { submit, submitting } = usePaywallContext();
|
|
3699
3749
|
const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
|
|
3700
|
-
return /* @__PURE__ */ (0,
|
|
3701
|
-
/* @__PURE__ */ (0,
|
|
3750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className, children: [
|
|
3751
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3702
3752
|
"button",
|
|
3703
3753
|
{
|
|
3704
3754
|
type: "button",
|
|
@@ -3710,20 +3760,20 @@ function PaywallCta({
|
|
|
3710
3760
|
children: label
|
|
3711
3761
|
}
|
|
3712
3762
|
),
|
|
3713
|
-
switchHint ? /* @__PURE__ */ (0,
|
|
3714
|
-
/* @__PURE__ */ (0,
|
|
3763
|
+
switchHint ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
3764
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: trustClassName, children: trustLine })
|
|
3715
3765
|
] });
|
|
3716
3766
|
}
|
|
3717
3767
|
|
|
3718
3768
|
// src/components/paywall/blocks/PaywallEyebrow.tsx
|
|
3719
|
-
var
|
|
3769
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3720
3770
|
var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
|
|
3721
3771
|
function PaywallEyebrow({ text, className }) {
|
|
3722
|
-
return /* @__PURE__ */ (0,
|
|
3772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3723
3773
|
}
|
|
3724
3774
|
|
|
3725
3775
|
// src/components/paywall/blocks/PaywallHero.tsx
|
|
3726
|
-
var
|
|
3776
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3727
3777
|
var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
|
|
3728
3778
|
function PaywallHero({
|
|
3729
3779
|
src,
|
|
@@ -3737,15 +3787,15 @@ function PaywallHero({
|
|
|
3737
3787
|
render
|
|
3738
3788
|
}) {
|
|
3739
3789
|
if (render) {
|
|
3740
|
-
return /* @__PURE__ */ (0,
|
|
3790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className, children: render({ src, headline }) });
|
|
3741
3791
|
}
|
|
3742
|
-
return /* @__PURE__ */ (0,
|
|
3792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3743
3793
|
"div",
|
|
3744
3794
|
{
|
|
3745
3795
|
className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
|
|
3746
3796
|
style: { aspectRatio },
|
|
3747
3797
|
children: [
|
|
3748
|
-
/* @__PURE__ */ (0,
|
|
3798
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3749
3799
|
"img",
|
|
3750
3800
|
{
|
|
3751
3801
|
src,
|
|
@@ -3753,8 +3803,8 @@ function PaywallHero({
|
|
|
3753
3803
|
className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
|
|
3754
3804
|
}
|
|
3755
3805
|
),
|
|
3756
|
-
/* @__PURE__ */ (0,
|
|
3757
|
-
headline ? /* @__PURE__ */ (0,
|
|
3806
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
|
|
3807
|
+
headline ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3758
3808
|
"h1",
|
|
3759
3809
|
{
|
|
3760
3810
|
className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
|
|
@@ -3767,15 +3817,15 @@ function PaywallHero({
|
|
|
3767
3817
|
}
|
|
3768
3818
|
|
|
3769
3819
|
// src/components/paywall/blocks/PaywallHeadline.tsx
|
|
3770
|
-
var
|
|
3820
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3771
3821
|
var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
|
|
3772
3822
|
function PaywallHeadline({ text, className, as = "h1" }) {
|
|
3773
3823
|
const Tag = as;
|
|
3774
|
-
return /* @__PURE__ */ (0,
|
|
3824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3775
3825
|
}
|
|
3776
3826
|
|
|
3777
3827
|
// src/components/paywall/blocks/PaywallPriceHeadline.tsx
|
|
3778
|
-
var
|
|
3828
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3779
3829
|
var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
|
|
3780
3830
|
var CYCLE_LABEL = {
|
|
3781
3831
|
MONTHLY: "mensal",
|
|
@@ -3795,16 +3845,16 @@ function PaywallPriceHeadline({
|
|
|
3795
3845
|
const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
|
|
3796
3846
|
if (render) {
|
|
3797
3847
|
const RootTag2 = as;
|
|
3798
|
-
return /* @__PURE__ */ (0,
|
|
3848
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
|
|
3799
3849
|
}
|
|
3800
3850
|
const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
|
|
3801
3851
|
const RootTag = as;
|
|
3802
|
-
return /* @__PURE__ */ (0,
|
|
3852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(RootTag, { className: rootClasses, children: text });
|
|
3803
3853
|
}
|
|
3804
3854
|
|
|
3805
3855
|
// src/components/paywall/blocks/PaywallCountdown.tsx
|
|
3806
|
-
var
|
|
3807
|
-
var
|
|
3856
|
+
var import_react30 = require("react");
|
|
3857
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3808
3858
|
var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
|
|
3809
3859
|
function resolveDeadlineMs(deadline) {
|
|
3810
3860
|
if (deadline instanceof Date) return deadline.getTime();
|
|
@@ -3841,13 +3891,13 @@ function PaywallCountdown({
|
|
|
3841
3891
|
className,
|
|
3842
3892
|
render
|
|
3843
3893
|
}) {
|
|
3844
|
-
const deadlineMsRef = (0,
|
|
3894
|
+
const deadlineMsRef = (0, import_react30.useRef)(null);
|
|
3845
3895
|
if (deadlineMsRef.current === null) {
|
|
3846
3896
|
deadlineMsRef.current = resolveDeadlineMs(deadline);
|
|
3847
3897
|
}
|
|
3848
|
-
const [state, setState] = (0,
|
|
3849
|
-
const expiredCalledRef = (0,
|
|
3850
|
-
(0,
|
|
3898
|
+
const [state, setState] = (0, import_react30.useState)(() => computeRemaining(deadlineMsRef.current));
|
|
3899
|
+
const expiredCalledRef = (0, import_react30.useRef)(false);
|
|
3900
|
+
(0, import_react30.useEffect)(() => {
|
|
3851
3901
|
if (state.expired) {
|
|
3852
3902
|
if (!expiredCalledRef.current) {
|
|
3853
3903
|
expiredCalledRef.current = true;
|
|
@@ -3867,14 +3917,14 @@ function PaywallCountdown({
|
|
|
3867
3917
|
return () => clearInterval(id);
|
|
3868
3918
|
}, [state.expired]);
|
|
3869
3919
|
if (render) {
|
|
3870
|
-
return /* @__PURE__ */ (0,
|
|
3920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className, children: render(state) });
|
|
3871
3921
|
}
|
|
3872
3922
|
const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
|
|
3873
|
-
return /* @__PURE__ */ (0,
|
|
3923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
|
|
3874
3924
|
}
|
|
3875
3925
|
|
|
3876
3926
|
// src/components/paywall/blocks/PaywallFeatures.tsx
|
|
3877
|
-
var
|
|
3927
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
3878
3928
|
function PaywallFeatures({
|
|
3879
3929
|
items,
|
|
3880
3930
|
IconComponent,
|
|
@@ -3885,19 +3935,19 @@ function PaywallFeatures({
|
|
|
3885
3935
|
renderItem
|
|
3886
3936
|
}) {
|
|
3887
3937
|
if (render) {
|
|
3888
|
-
return /* @__PURE__ */ (0,
|
|
3938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, children: render({ items }) });
|
|
3889
3939
|
}
|
|
3890
3940
|
if (renderItem) {
|
|
3891
|
-
return /* @__PURE__ */ (0,
|
|
3941
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: renderItem(item, idx) }, idx)) });
|
|
3892
3942
|
}
|
|
3893
|
-
return /* @__PURE__ */ (0,
|
|
3894
|
-
IconComponent ? /* @__PURE__ */ (0,
|
|
3895
|
-
/* @__PURE__ */ (0,
|
|
3943
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { className: itemClassName, children: [
|
|
3944
|
+
IconComponent ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(IconComponent, { className: iconClassName }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
|
|
3945
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item })
|
|
3896
3946
|
] }, idx)) });
|
|
3897
3947
|
}
|
|
3898
3948
|
|
|
3899
3949
|
// src/components/paywall/blocks/PaywallFeaturesCard.tsx
|
|
3900
|
-
var
|
|
3950
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
3901
3951
|
var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
|
|
3902
3952
|
function PaywallFeaturesCard({
|
|
3903
3953
|
title,
|
|
@@ -3908,20 +3958,20 @@ function PaywallFeaturesCard({
|
|
|
3908
3958
|
itemClassName,
|
|
3909
3959
|
renderItem
|
|
3910
3960
|
}) {
|
|
3911
|
-
return /* @__PURE__ */ (0,
|
|
3912
|
-
title ? /* @__PURE__ */ (0,
|
|
3913
|
-
/* @__PURE__ */ (0,
|
|
3914
|
-
(item, idx) => renderItem ? /* @__PURE__ */ (0,
|
|
3915
|
-
/* @__PURE__ */ (0,
|
|
3961
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
|
|
3962
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
|
|
3963
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { children: items.map(
|
|
3964
|
+
(item, idx) => renderItem ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("li", { className: itemClassName, children: [
|
|
3965
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { "aria-hidden": "true", children: "\u2022" }),
|
|
3916
3966
|
" ",
|
|
3917
|
-
/* @__PURE__ */ (0,
|
|
3967
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: item })
|
|
3918
3968
|
] }, idx)
|
|
3919
3969
|
) })
|
|
3920
3970
|
] }) });
|
|
3921
3971
|
}
|
|
3922
3972
|
|
|
3923
3973
|
// src/components/paywall/blocks/PaywallTrophyBadge.tsx
|
|
3924
|
-
var
|
|
3974
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
3925
3975
|
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";
|
|
3926
3976
|
var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
|
|
3927
3977
|
function PaywallTrophyBadge({
|
|
@@ -3932,21 +3982,21 @@ function PaywallTrophyBadge({
|
|
|
3932
3982
|
render
|
|
3933
3983
|
}) {
|
|
3934
3984
|
if (render) {
|
|
3935
|
-
return /* @__PURE__ */ (0,
|
|
3985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className, children: render({ text }) });
|
|
3936
3986
|
}
|
|
3937
3987
|
const rootClasses = [
|
|
3938
3988
|
DEFAULT_CHIP_CLASSES,
|
|
3939
3989
|
floating ? FLOATING_CLASSES : "",
|
|
3940
3990
|
className
|
|
3941
3991
|
].filter(Boolean).join(" ");
|
|
3942
|
-
return /* @__PURE__ */ (0,
|
|
3943
|
-
/* @__PURE__ */ (0,
|
|
3944
|
-
/* @__PURE__ */ (0,
|
|
3992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: rootClasses, children: [
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
|
|
3994
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: text })
|
|
3945
3995
|
] });
|
|
3946
3996
|
}
|
|
3947
3997
|
|
|
3948
3998
|
// src/components/paywall/blocks/PaywallAnchorPrice.tsx
|
|
3949
|
-
var
|
|
3999
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
3950
4000
|
var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
|
|
3951
4001
|
function PaywallAnchorPrice({
|
|
3952
4002
|
className,
|
|
@@ -3960,13 +4010,13 @@ function PaywallAnchorPrice({
|
|
|
3960
4010
|
const formatted = formatBRL(anchorPriceCents);
|
|
3961
4011
|
const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
|
|
3962
4012
|
if (render) {
|
|
3963
|
-
return /* @__PURE__ */ (0,
|
|
4013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
|
|
3964
4014
|
}
|
|
3965
|
-
return /* @__PURE__ */ (0,
|
|
4015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: rootClasses, children: formatted });
|
|
3966
4016
|
}
|
|
3967
4017
|
|
|
3968
4018
|
// src/components/paywall/blocks/PaywallTestimonials.tsx
|
|
3969
|
-
var
|
|
4019
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
3970
4020
|
var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
|
|
3971
4021
|
var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
|
|
3972
4022
|
var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
|
|
@@ -3992,13 +4042,13 @@ function PaywallTestimonials({
|
|
|
3992
4042
|
const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
|
|
3993
4043
|
const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
|
|
3994
4044
|
const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
|
|
3995
|
-
return /* @__PURE__ */ (0,
|
|
4045
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
3996
4046
|
if (renderItem) return renderItem(item, idx);
|
|
3997
4047
|
const filled = clampStars(item.stars);
|
|
3998
4048
|
const empty = 5 - filled;
|
|
3999
|
-
return /* @__PURE__ */ (0,
|
|
4000
|
-
/* @__PURE__ */ (0,
|
|
4001
|
-
item.avatar ? /* @__PURE__ */ (0,
|
|
4049
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cardClasses, children: [
|
|
4050
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4051
|
+
item.avatar ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4002
4052
|
"img",
|
|
4003
4053
|
{
|
|
4004
4054
|
src: item.avatar,
|
|
@@ -4008,19 +4058,19 @@ function PaywallTestimonials({
|
|
|
4008
4058
|
"aria-hidden": "true"
|
|
4009
4059
|
}
|
|
4010
4060
|
) : null,
|
|
4011
|
-
/* @__PURE__ */ (0,
|
|
4061
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: nameClasses, children: item.name })
|
|
4012
4062
|
] }),
|
|
4013
|
-
/* @__PURE__ */ (0,
|
|
4063
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
|
|
4014
4064
|
"\u2605".repeat(filled),
|
|
4015
4065
|
"\u2606".repeat(empty)
|
|
4016
4066
|
] }),
|
|
4017
|
-
/* @__PURE__ */ (0,
|
|
4067
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: quoteClasses, children: item.quote })
|
|
4018
4068
|
] }, idx);
|
|
4019
4069
|
}) });
|
|
4020
4070
|
}
|
|
4021
4071
|
|
|
4022
4072
|
// src/components/paywall/blocks/PaywallStatsRow.tsx
|
|
4023
|
-
var
|
|
4073
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
4024
4074
|
var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
|
|
4025
4075
|
var DEFAULT_CELL = "flex flex-col items-center text-center";
|
|
4026
4076
|
var DEFAULT_VALUE = "text-2xl font-bold";
|
|
@@ -4037,18 +4087,18 @@ function PaywallStatsRow({
|
|
|
4037
4087
|
const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
|
|
4038
4088
|
const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
|
|
4039
4089
|
const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
|
|
4040
|
-
return /* @__PURE__ */ (0,
|
|
4090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: rootClasses, children: stats.map((stat, idx) => {
|
|
4041
4091
|
if (renderCell) return renderCell(stat, idx);
|
|
4042
|
-
return /* @__PURE__ */ (0,
|
|
4043
|
-
stat.icon ? /* @__PURE__ */ (0,
|
|
4044
|
-
/* @__PURE__ */ (0,
|
|
4045
|
-
/* @__PURE__ */ (0,
|
|
4092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cellClasses, children: [
|
|
4093
|
+
stat.icon ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { "aria-hidden": "true", children: stat.icon }) : null,
|
|
4094
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: valueClasses, children: stat.value }),
|
|
4095
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: labelClasses, children: stat.label })
|
|
4046
4096
|
] }, idx);
|
|
4047
4097
|
}) });
|
|
4048
4098
|
}
|
|
4049
4099
|
|
|
4050
4100
|
// src/components/paywall/blocks/PaywallFinePrint.tsx
|
|
4051
|
-
var
|
|
4101
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
4052
4102
|
var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
|
|
4053
4103
|
var CYCLE_LABEL2 = {
|
|
4054
4104
|
MONTHLY: "mensal",
|
|
@@ -4071,7 +4121,7 @@ function PaywallFinePrint({
|
|
|
4071
4121
|
const priceFormatted = formatBRL(currentPriceCents ?? 0);
|
|
4072
4122
|
const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
|
|
4073
4123
|
if (render) {
|
|
4074
|
-
return /* @__PURE__ */ (0,
|
|
4124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: className || void 0, children: render({
|
|
4075
4125
|
currentPriceCents: currentPriceCents ?? 0,
|
|
4076
4126
|
cycle,
|
|
4077
4127
|
trialDays: trialDays ?? 0,
|
|
@@ -4079,11 +4129,11 @@ function PaywallFinePrint({
|
|
|
4079
4129
|
}) });
|
|
4080
4130
|
}
|
|
4081
4131
|
const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
|
|
4082
|
-
return /* @__PURE__ */ (0,
|
|
4132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: rootClasses, children: text });
|
|
4083
4133
|
}
|
|
4084
4134
|
|
|
4085
4135
|
// src/components/paywall/blocks/PaywallTrustLine.tsx
|
|
4086
|
-
var
|
|
4136
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
4087
4137
|
var DEFAULT_ROOT3 = "flex items-center gap-3";
|
|
4088
4138
|
var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
|
|
4089
4139
|
function PaywallTrustLine({
|
|
@@ -4094,17 +4144,17 @@ function PaywallTrustLine({
|
|
|
4094
4144
|
}) {
|
|
4095
4145
|
const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
|
|
4096
4146
|
const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
|
|
4097
|
-
return /* @__PURE__ */ (0,
|
|
4147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4098
4148
|
if (renderItem) return renderItem(item, idx);
|
|
4099
|
-
return /* @__PURE__ */ (0,
|
|
4100
|
-
/* @__PURE__ */ (0,
|
|
4101
|
-
/* @__PURE__ */ (0,
|
|
4149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: itemClasses, children: [
|
|
4150
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { "aria-hidden": "true", children: item.icon }),
|
|
4151
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { children: item.text })
|
|
4102
4152
|
] }, idx);
|
|
4103
4153
|
}) });
|
|
4104
4154
|
}
|
|
4105
4155
|
|
|
4106
4156
|
// src/components/paywall/blocks/PaywallStickyFooter.tsx
|
|
4107
|
-
var
|
|
4157
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
4108
4158
|
var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
|
|
4109
4159
|
var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
|
|
4110
4160
|
function PaywallStickyFooter({
|
|
@@ -4113,7 +4163,7 @@ function PaywallStickyFooter({
|
|
|
4113
4163
|
safeAreaInsets = true
|
|
4114
4164
|
}) {
|
|
4115
4165
|
const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
|
|
4116
|
-
return /* @__PURE__ */ (0,
|
|
4166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: classes, children });
|
|
4117
4167
|
}
|
|
4118
4168
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4119
4169
|
0 && (module.exports = {
|