@hook-sdk/template 0.23.3 → 0.25.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 +868 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +330 -24
- package/dist/index.d.ts +330 -24
- package/dist/index.js +782 -284
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/AppRoot.tsx
|
|
2
2
|
import { useMemo as useMemo3 } from "react";
|
|
3
3
|
import { BrowserRouter, MemoryRouter, Navigate, Route, Routes } from "react-router-dom";
|
|
4
|
-
import { useHook as
|
|
4
|
+
import { useHook as useHook8 } from "@hook-sdk/sdk";
|
|
5
5
|
|
|
6
6
|
// src/config/AppConfigContext.tsx
|
|
7
7
|
import { createContext, useContext } from "react";
|
|
@@ -630,8 +630,8 @@ function usePaywallState() {
|
|
|
630
630
|
opening: submitting,
|
|
631
631
|
availableMethods: methods,
|
|
632
632
|
monthlyEquivalent,
|
|
633
|
-
|
|
634
|
-
|
|
633
|
+
// G154 fix (template 0.24.0 + SDK 0.26.0): wired to SDK action.
|
|
634
|
+
dismissPix: subscription.clearPixPending,
|
|
635
635
|
refreshPlan: () => {
|
|
636
636
|
}
|
|
637
637
|
};
|
|
@@ -2031,9 +2031,53 @@ function SessionExpiredBanner() {
|
|
|
2031
2031
|
] });
|
|
2032
2032
|
}
|
|
2033
2033
|
|
|
2034
|
+
// src/internal/EmailVerifyBanner.tsx
|
|
2035
|
+
import { useState as useState5 } from "react";
|
|
2036
|
+
import { useHook as useHook5 } from "@hook-sdk/sdk";
|
|
2037
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2038
|
+
function EmailVerifyBanner() {
|
|
2039
|
+
const { user, auth } = useHook5();
|
|
2040
|
+
const [sending, setSending] = useState5(false);
|
|
2041
|
+
const [sent, setSent] = useState5(false);
|
|
2042
|
+
if (!user || user.emailVerified) return null;
|
|
2043
|
+
async function handleResend() {
|
|
2044
|
+
if (sending || sent) return;
|
|
2045
|
+
setSending(true);
|
|
2046
|
+
try {
|
|
2047
|
+
await auth.resendVerify();
|
|
2048
|
+
setSent(true);
|
|
2049
|
+
} catch {
|
|
2050
|
+
} finally {
|
|
2051
|
+
setSending(false);
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
const label = sent ? "Enviado!" : sending ? "Enviando..." : "Reenviar link";
|
|
2055
|
+
return /* @__PURE__ */ jsxs12(
|
|
2056
|
+
"div",
|
|
2057
|
+
{
|
|
2058
|
+
role: "status",
|
|
2059
|
+
"data-testid": "email-verify-banner",
|
|
2060
|
+
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",
|
|
2061
|
+
children: [
|
|
2062
|
+
/* @__PURE__ */ jsx18("span", { children: "Confirma teu e-mail pra liberar tudo." }),
|
|
2063
|
+
/* @__PURE__ */ jsx18(
|
|
2064
|
+
"button",
|
|
2065
|
+
{
|
|
2066
|
+
type: "button",
|
|
2067
|
+
onClick: handleResend,
|
|
2068
|
+
disabled: sending || sent,
|
|
2069
|
+
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",
|
|
2070
|
+
children: label
|
|
2071
|
+
}
|
|
2072
|
+
)
|
|
2073
|
+
]
|
|
2074
|
+
}
|
|
2075
|
+
);
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2034
2078
|
// src/defaults/ErrorBoundary.tsx
|
|
2035
2079
|
import { Component } from "react";
|
|
2036
|
-
import { Fragment as Fragment4, jsx as
|
|
2080
|
+
import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2037
2081
|
var ErrorBoundary = class extends Component {
|
|
2038
2082
|
state = { error: null };
|
|
2039
2083
|
static getDerivedStateFromError(error) {
|
|
@@ -2051,12 +2095,12 @@ var ErrorBoundary = class extends Component {
|
|
|
2051
2095
|
}
|
|
2052
2096
|
render() {
|
|
2053
2097
|
if (this.state.error) {
|
|
2054
|
-
return this.props.fallback ?? /* @__PURE__ */
|
|
2055
|
-
/* @__PURE__ */
|
|
2056
|
-
/* @__PURE__ */
|
|
2098
|
+
return this.props.fallback ?? /* @__PURE__ */ jsxs13("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
2099
|
+
/* @__PURE__ */ jsx19("h2", { children: "Algo deu errado" }),
|
|
2100
|
+
/* @__PURE__ */ jsx19("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
2057
2101
|
] });
|
|
2058
2102
|
}
|
|
2059
|
-
return /* @__PURE__ */
|
|
2103
|
+
return /* @__PURE__ */ jsx19(Fragment4, { children: this.props.children });
|
|
2060
2104
|
}
|
|
2061
2105
|
};
|
|
2062
2106
|
|
|
@@ -2065,7 +2109,7 @@ import { useEffect as useEffect7 } from "react";
|
|
|
2065
2109
|
import i18n from "i18next";
|
|
2066
2110
|
import { I18nextProvider, initReactI18next } from "react-i18next";
|
|
2067
2111
|
import { usePersistedState } from "@hook-sdk/sdk";
|
|
2068
|
-
import { jsx as
|
|
2112
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2069
2113
|
function ensureInitialized(defaultLocale, supportedLocales, resources, initialLocale) {
|
|
2070
2114
|
if (i18n.isInitialized) return;
|
|
2071
2115
|
i18n.use(initReactI18next).init({
|
|
@@ -2094,7 +2138,7 @@ function I18nProvider({
|
|
|
2094
2138
|
i18n.changeLanguage(userLocale);
|
|
2095
2139
|
}
|
|
2096
2140
|
}, [userLocale]);
|
|
2097
|
-
return /* @__PURE__ */
|
|
2141
|
+
return /* @__PURE__ */ jsx20(I18nextProvider, { i18n, children });
|
|
2098
2142
|
}
|
|
2099
2143
|
|
|
2100
2144
|
// src/dev/env.ts
|
|
@@ -2105,9 +2149,9 @@ function isDevToolsEnabled() {
|
|
|
2105
2149
|
}
|
|
2106
2150
|
|
|
2107
2151
|
// src/dev/DevSkipOnboardingFab.tsx
|
|
2108
|
-
import { useCallback as useCallback3, useRef as useRef4, useState as
|
|
2109
|
-
import { useHook as
|
|
2110
|
-
import { jsx as
|
|
2152
|
+
import { useCallback as useCallback3, useRef as useRef4, useState as useState6 } from "react";
|
|
2153
|
+
import { useHook as useHook6 } from "@hook-sdk/sdk";
|
|
2154
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2111
2155
|
var STORAGE_KEY = "hook_dev_skip_email";
|
|
2112
2156
|
var TEST_EMAIL_DOMAIN = "@hook.test";
|
|
2113
2157
|
var TEST_PASSWORD = "SkipTest!2026";
|
|
@@ -2174,10 +2218,10 @@ var STYLES = {
|
|
|
2174
2218
|
};
|
|
2175
2219
|
var CONFIRM_TIMEOUT_MS = 3e3;
|
|
2176
2220
|
function DevSkipOnboardingFab({ defaults }) {
|
|
2177
|
-
const hook =
|
|
2221
|
+
const hook = useHook6();
|
|
2178
2222
|
const { slug } = useAppConfig();
|
|
2179
|
-
const [state, setState] =
|
|
2180
|
-
const [errorMsg, setErrorMsg] =
|
|
2223
|
+
const [state, setState] = useState6("idle");
|
|
2224
|
+
const [errorMsg, setErrorMsg] = useState6(null);
|
|
2181
2225
|
const timerRef = useRef4(null);
|
|
2182
2226
|
const clearTimer = useCallback3(() => {
|
|
2183
2227
|
if (timerRef.current) {
|
|
@@ -2214,7 +2258,7 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2214
2258
|
...state === "confirm" || state === "error" ? STYLES.confirm : {},
|
|
2215
2259
|
...state === "busy" ? STYLES.busy : {}
|
|
2216
2260
|
};
|
|
2217
|
-
return /* @__PURE__ */
|
|
2261
|
+
return /* @__PURE__ */ jsx21(
|
|
2218
2262
|
"button",
|
|
2219
2263
|
{
|
|
2220
2264
|
type: "button",
|
|
@@ -2229,20 +2273,20 @@ function DevSkipOnboardingFab({ defaults }) {
|
|
|
2229
2273
|
}
|
|
2230
2274
|
|
|
2231
2275
|
// src/internal/PaymentReturnHandler.tsx
|
|
2232
|
-
import { useCallback as useCallback4, useEffect as useEffect8, useRef as useRef5, useState as
|
|
2233
|
-
import { useHook as
|
|
2234
|
-
import { Fragment as Fragment5, jsx as
|
|
2276
|
+
import { useCallback as useCallback4, useEffect as useEffect8, useRef as useRef5, useState as useState7 } from "react";
|
|
2277
|
+
import { useHook as useHook7 } from "@hook-sdk/sdk";
|
|
2278
|
+
import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2235
2279
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
2236
2280
|
var MAX_CYCLES = 3;
|
|
2237
2281
|
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
2238
2282
|
function PaymentReturnHandler({ children }) {
|
|
2239
|
-
const { subscription, track: track2 } =
|
|
2283
|
+
const { subscription, track: track2 } = useHook7();
|
|
2240
2284
|
const subRef = useRef5(subscription);
|
|
2241
2285
|
subRef.current = subscription;
|
|
2242
2286
|
const runIdRef = useRef5(0);
|
|
2243
2287
|
const cyclesRef = useRef5(0);
|
|
2244
2288
|
const startMsRef = useRef5(0);
|
|
2245
|
-
const [state, setState] =
|
|
2289
|
+
const [state, setState] = useState7("idle");
|
|
2246
2290
|
const runPoll = useCallback4(() => {
|
|
2247
2291
|
const runId = ++runIdRef.current;
|
|
2248
2292
|
const isFirstRun = cyclesRef.current === 0;
|
|
@@ -2308,19 +2352,19 @@ function PaymentReturnHandler({ children }) {
|
|
|
2308
2352
|
window.location.href = cleanUrl.toString();
|
|
2309
2353
|
}, []);
|
|
2310
2354
|
if (state === "confirming") {
|
|
2311
|
-
return /* @__PURE__ */
|
|
2355
|
+
return /* @__PURE__ */ jsx22("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
|
|
2312
2356
|
}
|
|
2313
2357
|
if (state === "waiting") {
|
|
2314
|
-
return /* @__PURE__ */
|
|
2315
|
-
/* @__PURE__ */
|
|
2316
|
-
/* @__PURE__ */
|
|
2358
|
+
return /* @__PURE__ */ jsx22("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs14("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2359
|
+
/* @__PURE__ */ jsx22("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2360
|
+
/* @__PURE__ */ jsx22("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
|
|
2317
2361
|
] }) });
|
|
2318
2362
|
}
|
|
2319
2363
|
if (state === "timeout") {
|
|
2320
|
-
return /* @__PURE__ */
|
|
2321
|
-
/* @__PURE__ */
|
|
2322
|
-
/* @__PURE__ */
|
|
2323
|
-
/* @__PURE__ */
|
|
2364
|
+
return /* @__PURE__ */ jsx22("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ jsxs14("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2365
|
+
/* @__PURE__ */ jsx22("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." }),
|
|
2366
|
+
/* @__PURE__ */ jsxs14("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
2367
|
+
/* @__PURE__ */ jsx22(
|
|
2324
2368
|
"button",
|
|
2325
2369
|
{
|
|
2326
2370
|
type: "button",
|
|
@@ -2333,7 +2377,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2333
2377
|
children: "Tentar de novo"
|
|
2334
2378
|
}
|
|
2335
2379
|
),
|
|
2336
|
-
/* @__PURE__ */
|
|
2380
|
+
/* @__PURE__ */ jsx22(
|
|
2337
2381
|
"button",
|
|
2338
2382
|
{
|
|
2339
2383
|
type: "button",
|
|
@@ -2343,7 +2387,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2343
2387
|
children: "Voltar pro app"
|
|
2344
2388
|
}
|
|
2345
2389
|
),
|
|
2346
|
-
/* @__PURE__ */
|
|
2390
|
+
/* @__PURE__ */ jsx22(
|
|
2347
2391
|
"a",
|
|
2348
2392
|
{
|
|
2349
2393
|
href: SUPPORT_MAILTO,
|
|
@@ -2355,7 +2399,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2355
2399
|
] })
|
|
2356
2400
|
] }) });
|
|
2357
2401
|
}
|
|
2358
|
-
return /* @__PURE__ */
|
|
2402
|
+
return /* @__PURE__ */ jsx22(Fragment5, { children });
|
|
2359
2403
|
}
|
|
2360
2404
|
var overlayStyle2 = {
|
|
2361
2405
|
position: "fixed",
|
|
@@ -2394,7 +2438,7 @@ var linkStyle = {
|
|
|
2394
2438
|
};
|
|
2395
2439
|
|
|
2396
2440
|
// src/AppRoot.tsx
|
|
2397
|
-
import { Fragment as Fragment6, jsx as
|
|
2441
|
+
import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2398
2442
|
function buildLegacyConfigShim(config) {
|
|
2399
2443
|
const paywall = config.paywall;
|
|
2400
2444
|
const isFree = paywall.mode === "free";
|
|
@@ -2473,14 +2517,17 @@ function AppRoot(props) {
|
|
|
2473
2517
|
const basename = `/app/${config.slug}`;
|
|
2474
2518
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
2475
2519
|
const position = config.install_prompt?.position ?? "post-paywall";
|
|
2476
|
-
const subscriptionGated = /* @__PURE__ */
|
|
2477
|
-
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
|
|
2483
|
-
|
|
2520
|
+
const subscriptionGated = /* @__PURE__ */ jsxs15(SubscriptionGate, { Paywall: Paywall2 ?? FallbackPaywall, children: [
|
|
2521
|
+
/* @__PURE__ */ jsx23(EmailVerifyBanner, {}),
|
|
2522
|
+
position === "post-paywall" ? /* @__PURE__ */ jsxs15(InstallGate, { position: "post-paywall", children: [
|
|
2523
|
+
children,
|
|
2524
|
+
/* @__PURE__ */ jsx23(PushPrompt, {})
|
|
2525
|
+
] }) : /* @__PURE__ */ jsxs15(Fragment6, { children: [
|
|
2526
|
+
children,
|
|
2527
|
+
/* @__PURE__ */ jsx23(PushPrompt, {})
|
|
2528
|
+
] })
|
|
2529
|
+
] });
|
|
2530
|
+
const authGated = /* @__PURE__ */ jsx23(
|
|
2484
2531
|
AuthGated,
|
|
2485
2532
|
{
|
|
2486
2533
|
config,
|
|
@@ -2495,13 +2542,13 @@ function AppRoot(props) {
|
|
|
2495
2542
|
children: subscriptionGated
|
|
2496
2543
|
}
|
|
2497
2544
|
);
|
|
2498
|
-
const routedTree = /* @__PURE__ */
|
|
2499
|
-
/* @__PURE__ */
|
|
2500
|
-
/* @__PURE__ */
|
|
2501
|
-
position === "pre-auth" ? /* @__PURE__ */
|
|
2502
|
-
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */
|
|
2545
|
+
const routedTree = /* @__PURE__ */ jsxs15(Router, { ...routerProps, children: [
|
|
2546
|
+
/* @__PURE__ */ jsx23(DeepLinkHandler, { deepLinks: config.deepLinks }),
|
|
2547
|
+
/* @__PURE__ */ jsx23(SessionExpiredBanner, {}),
|
|
2548
|
+
position === "pre-auth" ? /* @__PURE__ */ jsx23(InstallGate, { position: "pre-auth", children: authGated }) : authGated,
|
|
2549
|
+
isDevToolsEnabled() && devSkipOnboarding ? /* @__PURE__ */ jsx23(DevSkipOnboardingFab, { defaults: devSkipOnboarding.defaults }) : null
|
|
2503
2550
|
] });
|
|
2504
|
-
return /* @__PURE__ */
|
|
2551
|
+
return /* @__PURE__ */ jsx23(ErrorBoundary, { children: /* @__PURE__ */ jsx23(AppConfigProvider, { config, children: /* @__PURE__ */ jsx23(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ jsx23(ThemeProvider, { children: /* @__PURE__ */ jsx23(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ jsx23(
|
|
2505
2552
|
I18nProvider,
|
|
2506
2553
|
{
|
|
2507
2554
|
defaultLocale: config.i18n.defaultLocale,
|
|
@@ -2521,37 +2568,37 @@ function AuthGated({
|
|
|
2521
2568
|
EmailVerify,
|
|
2522
2569
|
PreAuthFlow
|
|
2523
2570
|
}) {
|
|
2524
|
-
const { authStatus } =
|
|
2571
|
+
const { authStatus } = useHook8();
|
|
2525
2572
|
if (authStatus === "loading") return null;
|
|
2526
2573
|
if (authStatus !== "authenticated") {
|
|
2527
2574
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
2528
|
-
return /* @__PURE__ */
|
|
2529
|
-
/* @__PURE__ */
|
|
2530
|
-
/* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2532
|
-
/* @__PURE__ */
|
|
2533
|
-
EmailVerify ? /* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2575
|
+
return /* @__PURE__ */ jsxs15(Routes, { children: [
|
|
2576
|
+
/* @__PURE__ */ jsx23(Route, { path: "/signin", element: /* @__PURE__ */ jsx23(Login, {}) }),
|
|
2577
|
+
/* @__PURE__ */ jsx23(Route, { path: "/signup", element: /* @__PURE__ */ jsx23(Signup, {}) }),
|
|
2578
|
+
/* @__PURE__ */ jsx23(Route, { path: "/forgot", element: /* @__PURE__ */ jsx23(Forgot, {}) }),
|
|
2579
|
+
/* @__PURE__ */ jsx23(Route, { path: "/reset", element: /* @__PURE__ */ jsx23(Reset, {}) }),
|
|
2580
|
+
EmailVerify ? /* @__PURE__ */ jsx23(Route, { path: "/verify", element: /* @__PURE__ */ jsx23(EmailVerify, {}) }) : null,
|
|
2581
|
+
/* @__PURE__ */ jsx23(Route, { path: "/*", element: /* @__PURE__ */ jsx23(PreAuthFlow, {}) })
|
|
2535
2582
|
] });
|
|
2536
2583
|
}
|
|
2537
|
-
return /* @__PURE__ */
|
|
2538
|
-
/* @__PURE__ */
|
|
2539
|
-
/* @__PURE__ */
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
/* @__PURE__ */
|
|
2542
|
-
EmailVerify ? /* @__PURE__ */
|
|
2543
|
-
/* @__PURE__ */
|
|
2584
|
+
return /* @__PURE__ */ jsxs15(Routes, { children: [
|
|
2585
|
+
/* @__PURE__ */ jsx23(Route, { path: "/", element: /* @__PURE__ */ jsx23(Login, {}) }),
|
|
2586
|
+
/* @__PURE__ */ jsx23(Route, { path: "/signup", element: /* @__PURE__ */ jsx23(Signup, {}) }),
|
|
2587
|
+
/* @__PURE__ */ jsx23(Route, { path: "/forgot", element: /* @__PURE__ */ jsx23(Forgot, {}) }),
|
|
2588
|
+
/* @__PURE__ */ jsx23(Route, { path: "/reset", element: /* @__PURE__ */ jsx23(Reset, {}) }),
|
|
2589
|
+
EmailVerify ? /* @__PURE__ */ jsx23(Route, { path: "/verify", element: /* @__PURE__ */ jsx23(EmailVerify, {}) }) : null,
|
|
2590
|
+
/* @__PURE__ */ jsx23(Route, { path: "*", element: /* @__PURE__ */ jsx23(Navigate, { to: "/", replace: true }) })
|
|
2544
2591
|
] });
|
|
2545
2592
|
}
|
|
2546
|
-
return /* @__PURE__ */
|
|
2593
|
+
return /* @__PURE__ */ jsx23(Fragment6, { children });
|
|
2547
2594
|
}
|
|
2548
2595
|
function FallbackPaywall() {
|
|
2549
2596
|
return null;
|
|
2550
2597
|
}
|
|
2551
2598
|
|
|
2552
2599
|
// src/hooks/usePush.ts
|
|
2553
|
-
import { useCallback as useCallback5, useEffect as useEffect9, useState as
|
|
2554
|
-
import { useHook as
|
|
2600
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useState as useState8 } from "react";
|
|
2601
|
+
import { useHook as useHook9 } from "@hook-sdk/sdk";
|
|
2555
2602
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2556
2603
|
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2557
2604
|
function detectIosNeedsInstall() {
|
|
@@ -2595,8 +2642,8 @@ function deriveState(push) {
|
|
|
2595
2642
|
return { kind: "prompt" };
|
|
2596
2643
|
}
|
|
2597
2644
|
function usePush() {
|
|
2598
|
-
const { push } =
|
|
2599
|
-
const [state, setState] =
|
|
2645
|
+
const { push } = useHook9();
|
|
2646
|
+
const [state, setState] = useState8(() => deriveState(push));
|
|
2600
2647
|
useEffect9(() => {
|
|
2601
2648
|
setState(deriveState(push));
|
|
2602
2649
|
}, [push]);
|
|
@@ -2634,27 +2681,27 @@ function usePush() {
|
|
|
2634
2681
|
}
|
|
2635
2682
|
|
|
2636
2683
|
// src/components/PushPrompt.tsx
|
|
2637
|
-
import { jsx as
|
|
2684
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2638
2685
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
2639
2686
|
const { state, subscribe } = usePush();
|
|
2640
2687
|
if (state.kind === "denied" || state.kind === "dismissed" || state.kind === "subscribed") {
|
|
2641
2688
|
return null;
|
|
2642
2689
|
}
|
|
2643
2690
|
if (state.kind === "ios_needs_install") {
|
|
2644
|
-
return /* @__PURE__ */
|
|
2645
|
-
/* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */
|
|
2691
|
+
return /* @__PURE__ */ jsxs16("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2692
|
+
/* @__PURE__ */ jsx24("h3", { children: texts.iosInstallTitle }),
|
|
2693
|
+
/* @__PURE__ */ jsx24("p", { children: texts.iosInstallBody }),
|
|
2694
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx24("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
2648
2695
|
] });
|
|
2649
2696
|
}
|
|
2650
2697
|
if (state.kind === "unsupported") {
|
|
2651
|
-
return /* @__PURE__ */
|
|
2698
|
+
return /* @__PURE__ */ jsx24("div", { className, role: "region", children: /* @__PURE__ */ jsx24("p", { children: texts.unsupportedBody }) });
|
|
2652
2699
|
}
|
|
2653
2700
|
if (state.kind === "error") {
|
|
2654
|
-
return /* @__PURE__ */
|
|
2701
|
+
return /* @__PURE__ */ jsx24("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx24("p", { children: state.message }) });
|
|
2655
2702
|
}
|
|
2656
|
-
return /* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2703
|
+
return /* @__PURE__ */ jsxs16("div", { className, role: "region", children: [
|
|
2704
|
+
/* @__PURE__ */ jsx24(
|
|
2658
2705
|
"button",
|
|
2659
2706
|
{
|
|
2660
2707
|
type: "button",
|
|
@@ -2668,13 +2715,13 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2668
2715
|
children: texts.cta
|
|
2669
2716
|
}
|
|
2670
2717
|
),
|
|
2671
|
-
onDeclined && /* @__PURE__ */
|
|
2718
|
+
onDeclined && /* @__PURE__ */ jsx24("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
2672
2719
|
] });
|
|
2673
2720
|
}
|
|
2674
2721
|
|
|
2675
2722
|
// src/components/LanguageSwitcher.tsx
|
|
2676
2723
|
import { usePersistedState as usePersistedState2 } from "@hook-sdk/sdk";
|
|
2677
|
-
import { jsx as
|
|
2724
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2678
2725
|
function LanguageSwitcher({ id, className, label = "Language" }) {
|
|
2679
2726
|
const config = useAppConfig();
|
|
2680
2727
|
const i18nConfig = config.i18n;
|
|
@@ -2683,43 +2730,43 @@ function LanguageSwitcher({ id, className, label = "Language" }) {
|
|
|
2683
2730
|
i18nConfig?.defaultLocale ?? "en-US"
|
|
2684
2731
|
);
|
|
2685
2732
|
if (!i18nConfig) return null;
|
|
2686
|
-
return /* @__PURE__ */
|
|
2687
|
-
label ? /* @__PURE__ */
|
|
2688
|
-
/* @__PURE__ */
|
|
2733
|
+
return /* @__PURE__ */ jsxs17("label", { className, children: [
|
|
2734
|
+
label ? /* @__PURE__ */ jsx25("span", { children: label }) : null,
|
|
2735
|
+
/* @__PURE__ */ jsx25(
|
|
2689
2736
|
"select",
|
|
2690
2737
|
{
|
|
2691
2738
|
id,
|
|
2692
2739
|
value: userLocale,
|
|
2693
2740
|
onChange: (e) => setUserLocale(e.target.value),
|
|
2694
2741
|
"data-testid": "language-switcher",
|
|
2695
|
-
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */
|
|
2742
|
+
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ jsx25("option", { value: loc, children: loc }, loc))
|
|
2696
2743
|
}
|
|
2697
2744
|
)
|
|
2698
2745
|
] });
|
|
2699
2746
|
}
|
|
2700
2747
|
|
|
2701
2748
|
// src/defaults/LoadingState.tsx
|
|
2702
|
-
import { jsx as
|
|
2749
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
2703
2750
|
function LoadingState({ message }) {
|
|
2704
|
-
return /* @__PURE__ */
|
|
2751
|
+
return /* @__PURE__ */ jsx26("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ jsx26("span", { children: message ?? "Carregando..." }) });
|
|
2705
2752
|
}
|
|
2706
2753
|
|
|
2707
2754
|
// src/defaults/EmptyState.tsx
|
|
2708
|
-
import { jsx as
|
|
2755
|
+
import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2709
2756
|
function EmptyState({ title, description, action }) {
|
|
2710
|
-
return /* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2712
|
-
description && /* @__PURE__ */
|
|
2713
|
-
action && /* @__PURE__ */
|
|
2757
|
+
return /* @__PURE__ */ jsxs18("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2758
|
+
/* @__PURE__ */ jsx27("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2759
|
+
description && /* @__PURE__ */ jsx27("p", { style: { opacity: 0.7 }, children: description }),
|
|
2760
|
+
action && /* @__PURE__ */ jsx27("div", { style: { marginTop: 16 }, children: action })
|
|
2714
2761
|
] });
|
|
2715
2762
|
}
|
|
2716
2763
|
|
|
2717
2764
|
// src/hooks/useLoginForm.ts
|
|
2718
|
-
import { useCallback as useCallback6, useMemo as useMemo4, useState as
|
|
2719
|
-
import { useHook as
|
|
2765
|
+
import { useCallback as useCallback6, useMemo as useMemo4, useState as useState9 } from "react";
|
|
2766
|
+
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
2720
2767
|
|
|
2721
2768
|
// src/errors.ts
|
|
2722
|
-
import { SdkError, SdkAuthError, SdkRateLimitError } from "@hook-sdk/sdk";
|
|
2769
|
+
import { SdkError, SdkAuthError, SdkRateLimitError, SdkValidationError } from "@hook-sdk/sdk";
|
|
2723
2770
|
function mapSdkError(err) {
|
|
2724
2771
|
if (err instanceof SdkRateLimitError) {
|
|
2725
2772
|
return {
|
|
@@ -2738,6 +2785,9 @@ function mapSdkError(err) {
|
|
|
2738
2785
|
}
|
|
2739
2786
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2740
2787
|
}
|
|
2788
|
+
if (err instanceof SdkValidationError && err.code === "auth.email_taken") {
|
|
2789
|
+
return { code: "email_taken", message: "Esse e-mail j\xE1 tem conta." };
|
|
2790
|
+
}
|
|
2741
2791
|
if (err instanceof SdkError && err.httpStatus === 0) {
|
|
2742
2792
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2743
2793
|
}
|
|
@@ -2751,14 +2801,14 @@ function mapSdkError(err) {
|
|
|
2751
2801
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2752
2802
|
var MIN_PASSWORD = 8;
|
|
2753
2803
|
function useLoginForm() {
|
|
2754
|
-
const { auth } =
|
|
2755
|
-
const [email, setEmail] =
|
|
2756
|
-
const [password, setPassword] =
|
|
2757
|
-
const [submitting, setSubmitting] =
|
|
2758
|
-
const [error, setError] =
|
|
2759
|
-
const [touchedEmail, setTouchedEmail] =
|
|
2760
|
-
const [touchedPassword, setTouchedPassword] =
|
|
2761
|
-
const [formSubmitAttempted, setFormSubmitAttempted] =
|
|
2804
|
+
const { auth } = useHook10();
|
|
2805
|
+
const [email, setEmail] = useState9("");
|
|
2806
|
+
const [password, setPassword] = useState9("");
|
|
2807
|
+
const [submitting, setSubmitting] = useState9(false);
|
|
2808
|
+
const [error, setError] = useState9(null);
|
|
2809
|
+
const [touchedEmail, setTouchedEmail] = useState9(false);
|
|
2810
|
+
const [touchedPassword, setTouchedPassword] = useState9(false);
|
|
2811
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = useState9(false);
|
|
2762
2812
|
const validateEmail = useMemo4(() => {
|
|
2763
2813
|
if (email.length === 0) return null;
|
|
2764
2814
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
@@ -2806,21 +2856,21 @@ function useLoginForm() {
|
|
|
2806
2856
|
}
|
|
2807
2857
|
|
|
2808
2858
|
// src/hooks/useSignupForm.ts
|
|
2809
|
-
import { useCallback as useCallback7, useMemo as useMemo5, useState as
|
|
2810
|
-
import { useHook as
|
|
2859
|
+
import { useCallback as useCallback7, useMemo as useMemo5, useState as useState10 } from "react";
|
|
2860
|
+
import { useHook as useHook11 } from "@hook-sdk/sdk";
|
|
2811
2861
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2812
2862
|
var MIN_PASSWORD2 = 8;
|
|
2813
2863
|
function useSignupForm() {
|
|
2814
|
-
const { auth } =
|
|
2815
|
-
const [name, setName] =
|
|
2816
|
-
const [email, setEmail] =
|
|
2817
|
-
const [password, setPassword] =
|
|
2818
|
-
const [submitting, setSubmitting] =
|
|
2819
|
-
const [error, setError] =
|
|
2820
|
-
const [touchedName, setTouchedName] =
|
|
2821
|
-
const [touchedEmail, setTouchedEmail] =
|
|
2822
|
-
const [touchedPassword, setTouchedPassword] =
|
|
2823
|
-
const [formSubmitAttempted, setFormSubmitAttempted] =
|
|
2864
|
+
const { auth } = useHook11();
|
|
2865
|
+
const [name, setName] = useState10("");
|
|
2866
|
+
const [email, setEmail] = useState10("");
|
|
2867
|
+
const [password, setPassword] = useState10("");
|
|
2868
|
+
const [submitting, setSubmitting] = useState10(false);
|
|
2869
|
+
const [error, setError] = useState10(null);
|
|
2870
|
+
const [touchedName, setTouchedName] = useState10(false);
|
|
2871
|
+
const [touchedEmail, setTouchedEmail] = useState10(false);
|
|
2872
|
+
const [touchedPassword, setTouchedPassword] = useState10(false);
|
|
2873
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = useState10(false);
|
|
2824
2874
|
const validateName = useMemo5(() => {
|
|
2825
2875
|
if (name.length === 0) return null;
|
|
2826
2876
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
@@ -2878,17 +2928,17 @@ function useSignupForm() {
|
|
|
2878
2928
|
}
|
|
2879
2929
|
|
|
2880
2930
|
// src/hooks/useForgotForm.ts
|
|
2881
|
-
import { useCallback as useCallback8, useMemo as useMemo6, useState as
|
|
2882
|
-
import { useHook as
|
|
2931
|
+
import { useCallback as useCallback8, useMemo as useMemo6, useState as useState11 } from "react";
|
|
2932
|
+
import { useHook as useHook12 } from "@hook-sdk/sdk";
|
|
2883
2933
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2884
2934
|
function useForgotForm() {
|
|
2885
|
-
const { auth } =
|
|
2886
|
-
const [email, setEmail] =
|
|
2887
|
-
const [submitting, setSubmitting] =
|
|
2888
|
-
const [sent, setSent] =
|
|
2889
|
-
const [error, setError] =
|
|
2890
|
-
const [touchedEmail, setTouchedEmail] =
|
|
2891
|
-
const [formSubmitAttempted, setFormSubmitAttempted] =
|
|
2935
|
+
const { auth } = useHook12();
|
|
2936
|
+
const [email, setEmail] = useState11("");
|
|
2937
|
+
const [submitting, setSubmitting] = useState11(false);
|
|
2938
|
+
const [sent, setSent] = useState11(false);
|
|
2939
|
+
const [error, setError] = useState11(null);
|
|
2940
|
+
const [touchedEmail, setTouchedEmail] = useState11(false);
|
|
2941
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = useState11(false);
|
|
2892
2942
|
const validateEmail = useMemo6(() => {
|
|
2893
2943
|
if (email.length === 0) return null;
|
|
2894
2944
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
@@ -2927,20 +2977,20 @@ function useForgotForm() {
|
|
|
2927
2977
|
}
|
|
2928
2978
|
|
|
2929
2979
|
// src/hooks/useResetForm.ts
|
|
2930
|
-
import { useCallback as useCallback9, useEffect as useEffect10, useMemo as useMemo7, useState as
|
|
2931
|
-
import { useHook as
|
|
2980
|
+
import { useCallback as useCallback9, useEffect as useEffect10, useMemo as useMemo7, useState as useState12 } from "react";
|
|
2981
|
+
import { useHook as useHook13 } from "@hook-sdk/sdk";
|
|
2932
2982
|
var MIN_PASSWORD3 = 12;
|
|
2933
2983
|
function useResetForm() {
|
|
2934
|
-
const { auth } =
|
|
2935
|
-
const [token, setToken] =
|
|
2936
|
-
const [password, setPassword] =
|
|
2937
|
-
const [confirm, setConfirm] =
|
|
2938
|
-
const [submitting, setSubmitting] =
|
|
2939
|
-
const [done, setDone] =
|
|
2940
|
-
const [error, setError] =
|
|
2941
|
-
const [touchedPassword, setTouchedPassword] =
|
|
2942
|
-
const [touchedConfirm, setTouchedConfirm] =
|
|
2943
|
-
const [formSubmitAttempted, setFormSubmitAttempted] =
|
|
2984
|
+
const { auth } = useHook13();
|
|
2985
|
+
const [token, setToken] = useState12(null);
|
|
2986
|
+
const [password, setPassword] = useState12("");
|
|
2987
|
+
const [confirm, setConfirm] = useState12("");
|
|
2988
|
+
const [submitting, setSubmitting] = useState12(false);
|
|
2989
|
+
const [done, setDone] = useState12(false);
|
|
2990
|
+
const [error, setError] = useState12(null);
|
|
2991
|
+
const [touchedPassword, setTouchedPassword] = useState12(false);
|
|
2992
|
+
const [touchedConfirm, setTouchedConfirm] = useState12(false);
|
|
2993
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = useState12(false);
|
|
2944
2994
|
useEffect10(() => {
|
|
2945
2995
|
if (typeof window === "undefined") return;
|
|
2946
2996
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -3000,9 +3050,9 @@ function useResetForm() {
|
|
|
3000
3050
|
}
|
|
3001
3051
|
|
|
3002
3052
|
// src/hooks/usePlan.ts
|
|
3003
|
-
import { useHook as
|
|
3053
|
+
import { useHook as useHook14 } from "@hook-sdk/sdk";
|
|
3004
3054
|
function usePlan() {
|
|
3005
|
-
const { plan } =
|
|
3055
|
+
const { plan } = useHook14();
|
|
3006
3056
|
return plan;
|
|
3007
3057
|
}
|
|
3008
3058
|
|
|
@@ -3036,10 +3086,10 @@ function discountPercent(anchorCents, realCents) {
|
|
|
3036
3086
|
|
|
3037
3087
|
// src/hooks/useAuthPrimitives.ts
|
|
3038
3088
|
import { useEffect as useEffect11 } from "react";
|
|
3039
|
-
import { useHook as
|
|
3089
|
+
import { useHook as useHook15 } from "@hook-sdk/sdk";
|
|
3040
3090
|
var warned = false;
|
|
3041
3091
|
function useAuthPrimitives() {
|
|
3042
|
-
const { auth } =
|
|
3092
|
+
const { auth } = useHook15();
|
|
3043
3093
|
useEffect11(() => {
|
|
3044
3094
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
3045
3095
|
warned = true;
|
|
@@ -3062,9 +3112,9 @@ function useAuthPrimitives() {
|
|
|
3062
3112
|
}
|
|
3063
3113
|
|
|
3064
3114
|
// src/hooks/useAuth.ts
|
|
3065
|
-
import { useHook as
|
|
3115
|
+
import { useHook as useHook16 } from "@hook-sdk/sdk";
|
|
3066
3116
|
function useAuth() {
|
|
3067
|
-
const { user, authStatus, auth } =
|
|
3117
|
+
const { user, authStatus, auth } = useHook16();
|
|
3068
3118
|
return {
|
|
3069
3119
|
user,
|
|
3070
3120
|
authStatus,
|
|
@@ -3076,22 +3126,22 @@ function useAuth() {
|
|
|
3076
3126
|
import { useTrackOnboardingStep } from "@hook-sdk/sdk";
|
|
3077
3127
|
|
|
3078
3128
|
// src/hooks/useSubscription.ts
|
|
3079
|
-
import { useHook as
|
|
3129
|
+
import { useHook as useHook17 } from "@hook-sdk/sdk";
|
|
3080
3130
|
function useSubscription() {
|
|
3081
|
-
const { subscription } =
|
|
3131
|
+
const { subscription } = useHook17();
|
|
3082
3132
|
return {
|
|
3083
3133
|
status: subscription.status()
|
|
3084
3134
|
};
|
|
3085
3135
|
}
|
|
3086
3136
|
|
|
3087
3137
|
// src/hooks/useReminders.ts
|
|
3088
|
-
import { useCallback as useCallback10, useEffect as useEffect12, useState as
|
|
3089
|
-
import { useHook as
|
|
3138
|
+
import { useCallback as useCallback10, useEffect as useEffect12, useState as useState13 } from "react";
|
|
3139
|
+
import { useHook as useHook18 } from "@hook-sdk/sdk";
|
|
3090
3140
|
function useReminders() {
|
|
3091
|
-
const { push } =
|
|
3141
|
+
const { push } = useHook18();
|
|
3092
3142
|
const r = push.reminders;
|
|
3093
|
-
const [reminders, setReminders] =
|
|
3094
|
-
const [loading, setLoading] =
|
|
3143
|
+
const [reminders, setReminders] = useState13([]);
|
|
3144
|
+
const [loading, setLoading] = useState13(true);
|
|
3095
3145
|
const reload = useCallback10(async () => {
|
|
3096
3146
|
setLoading(true);
|
|
3097
3147
|
try {
|
|
@@ -3122,9 +3172,9 @@ function useReminders() {
|
|
|
3122
3172
|
}
|
|
3123
3173
|
|
|
3124
3174
|
// src/hooks/useToast.ts
|
|
3125
|
-
import { useCallback as useCallback11, useState as
|
|
3175
|
+
import { useCallback as useCallback11, useState as useState14 } from "react";
|
|
3126
3176
|
function useToast() {
|
|
3127
|
-
const [items, setItems] =
|
|
3177
|
+
const [items, setItems] = useState14([]);
|
|
3128
3178
|
const show = useCallback11((message, kind = "info") => {
|
|
3129
3179
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
3130
3180
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
@@ -3140,20 +3190,20 @@ function useToast() {
|
|
|
3140
3190
|
|
|
3141
3191
|
// src/RouteBoundary.tsx
|
|
3142
3192
|
import { Routes as Routes2, Route as Route2 } from "react-router-dom";
|
|
3143
|
-
import { jsx as
|
|
3193
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3144
3194
|
function RouteBoundary({ children }) {
|
|
3145
|
-
return /* @__PURE__ */
|
|
3195
|
+
return /* @__PURE__ */ jsxs19(Routes2, { children: [
|
|
3146
3196
|
children,
|
|
3147
|
-
/* @__PURE__ */
|
|
3197
|
+
/* @__PURE__ */ jsx28(Route2, { path: "*", element: /* @__PURE__ */ jsx28(DefaultNotFound, {}) })
|
|
3148
3198
|
] });
|
|
3149
3199
|
}
|
|
3150
3200
|
function DefaultNotFound() {
|
|
3151
|
-
return /* @__PURE__ */
|
|
3201
|
+
return /* @__PURE__ */ jsx28("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
|
|
3152
3202
|
}
|
|
3153
3203
|
|
|
3154
3204
|
// src/PreAuthShell.tsx
|
|
3155
3205
|
import { BrowserRouter as BrowserRouter2, MemoryRouter as MemoryRouter2, Routes as Routes3 } from "react-router-dom";
|
|
3156
|
-
import { jsx as
|
|
3206
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
3157
3207
|
function PreAuthShell({
|
|
3158
3208
|
basename,
|
|
3159
3209
|
testRouter,
|
|
@@ -3161,14 +3211,14 @@ function PreAuthShell({
|
|
|
3161
3211
|
children
|
|
3162
3212
|
}) {
|
|
3163
3213
|
if (testRouter === "memory") {
|
|
3164
|
-
return /* @__PURE__ */
|
|
3214
|
+
return /* @__PURE__ */ jsx29(MemoryRouter2, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ jsx29(Routes3, { children }) });
|
|
3165
3215
|
}
|
|
3166
|
-
return /* @__PURE__ */
|
|
3216
|
+
return /* @__PURE__ */ jsx29(BrowserRouter2, { basename, children: /* @__PURE__ */ jsx29(Routes3, { children }) });
|
|
3167
3217
|
}
|
|
3168
3218
|
|
|
3169
3219
|
// src/OnboardingFlow.tsx
|
|
3170
3220
|
import { useCallback as useCallback12, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef6 } from "react";
|
|
3171
|
-
import { usePersistedState as usePersistedState3, useHook as
|
|
3221
|
+
import { usePersistedState as usePersistedState3, useHook as useHook19 } from "@hook-sdk/sdk";
|
|
3172
3222
|
|
|
3173
3223
|
// src/hooks/useOnboardingStep.ts
|
|
3174
3224
|
import { createContext as createContext3, useContext as useContext4 } from "react";
|
|
@@ -3184,7 +3234,7 @@ function useOnboardingStep() {
|
|
|
3184
3234
|
}
|
|
3185
3235
|
|
|
3186
3236
|
// src/OnboardingFlow.tsx
|
|
3187
|
-
import { jsx as
|
|
3237
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
3188
3238
|
var isFilled = (v) => v != null && v !== "";
|
|
3189
3239
|
var CURRENT_STEP_FIELD = "currentStep";
|
|
3190
3240
|
function readPersistedStepIdx(draft) {
|
|
@@ -3220,7 +3270,7 @@ function OnboardingFlow({
|
|
|
3220
3270
|
[setDraft]
|
|
3221
3271
|
);
|
|
3222
3272
|
const step = steps[clampedIdx];
|
|
3223
|
-
const hookCtx =
|
|
3273
|
+
const hookCtx = useHook19();
|
|
3224
3274
|
const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
|
|
3225
3275
|
useEffect13(() => {
|
|
3226
3276
|
if (status.loading) return;
|
|
@@ -3274,7 +3324,7 @@ function OnboardingFlow({
|
|
|
3274
3324
|
`[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
|
|
3275
3325
|
);
|
|
3276
3326
|
}
|
|
3277
|
-
return /* @__PURE__ */
|
|
3327
|
+
return /* @__PURE__ */ jsx30(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx30(Screen, {}) });
|
|
3278
3328
|
}
|
|
3279
3329
|
|
|
3280
3330
|
// src/hooks/useFeature.ts
|
|
@@ -3285,24 +3335,41 @@ function useFeature(name) {
|
|
|
3285
3335
|
|
|
3286
3336
|
// src/components/paywall/Paywall.tsx
|
|
3287
3337
|
import { useEffect as useEffect14, useMemo as useMemo9 } from "react";
|
|
3288
|
-
import { useHook as
|
|
3338
|
+
import { useHook as useHook20 } from "@hook-sdk/sdk";
|
|
3339
|
+
|
|
3340
|
+
// src/components/paywall/PaywallProvider.tsx
|
|
3341
|
+
import { createContext as createContext4 } from "react";
|
|
3342
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
3343
|
+
var PaywallContext = createContext4(null);
|
|
3344
|
+
function PaywallProvider({ children }) {
|
|
3345
|
+
const state = usePaywallState();
|
|
3346
|
+
return /* @__PURE__ */ jsx31(PaywallContext.Provider, { value: state, children });
|
|
3347
|
+
}
|
|
3348
|
+
|
|
3349
|
+
// src/components/paywall/usePaywallContext.ts
|
|
3350
|
+
import { useContext as useContext5 } from "react";
|
|
3351
|
+
function usePaywallContext() {
|
|
3352
|
+
const ctx = useContext5(PaywallContext);
|
|
3353
|
+
if (!ctx) {
|
|
3354
|
+
throw new Error("usePaywallContext must be used within <PaywallProvider>");
|
|
3355
|
+
}
|
|
3356
|
+
return ctx;
|
|
3357
|
+
}
|
|
3289
3358
|
|
|
3290
3359
|
// src/components/paywall/PaywallMethodTabs.tsx
|
|
3291
|
-
import { jsx as
|
|
3360
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
3292
3361
|
function PaywallMethodTabs({
|
|
3293
|
-
methods,
|
|
3294
|
-
selected,
|
|
3295
|
-
onSelect,
|
|
3296
3362
|
labels,
|
|
3297
3363
|
className,
|
|
3298
3364
|
tabClassName,
|
|
3299
3365
|
tabActiveClassName
|
|
3300
3366
|
}) {
|
|
3367
|
+
const { methods, selectedMethod, selectMethod } = usePaywallContext();
|
|
3301
3368
|
if (methods.length < 2) return null;
|
|
3302
|
-
return /* @__PURE__ */
|
|
3303
|
-
const active = m ===
|
|
3369
|
+
return /* @__PURE__ */ jsx32("div", { role: "tablist", "aria-label": "M\xE9todo de pagamento", className, children: methods.map((m) => {
|
|
3370
|
+
const active = m === selectedMethod;
|
|
3304
3371
|
const label = labels[m] ?? m;
|
|
3305
|
-
return /* @__PURE__ */
|
|
3372
|
+
return /* @__PURE__ */ jsx32(
|
|
3306
3373
|
"button",
|
|
3307
3374
|
{
|
|
3308
3375
|
type: "button",
|
|
@@ -3310,7 +3377,7 @@ function PaywallMethodTabs({
|
|
|
3310
3377
|
"aria-selected": active,
|
|
3311
3378
|
"aria-controls": `paywall-tab-${m}`,
|
|
3312
3379
|
tabIndex: active ? 0 : -1,
|
|
3313
|
-
onClick: () =>
|
|
3380
|
+
onClick: () => selectMethod(m),
|
|
3314
3381
|
className: [tabClassName, active ? tabActiveClassName : ""].filter(Boolean).join(" "),
|
|
3315
3382
|
children: label
|
|
3316
3383
|
},
|
|
@@ -3320,36 +3387,51 @@ function PaywallMethodTabs({
|
|
|
3320
3387
|
}
|
|
3321
3388
|
|
|
3322
3389
|
// src/components/paywall/PaywallMethodContent.tsx
|
|
3323
|
-
import { jsx as
|
|
3324
|
-
function PaywallMethodContent({
|
|
3325
|
-
|
|
3326
|
-
copy
|
|
3327
|
-
|
|
3328
|
-
className,
|
|
3329
|
-
rowClassName
|
|
3330
|
-
}) {
|
|
3331
|
-
const useCardConsumed = method === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
3332
|
-
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : method === "pix-auto" || method === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
3333
|
-
return /* @__PURE__ */ jsx31("div", { role: "tabpanel", id: `paywall-tab-${method}`, className, children: rows.map((row, i) => /* @__PURE__ */ jsx31("div", { className: rowClassName, children: row }, i)) });
|
|
3390
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
3391
|
+
function PaywallMethodContent({ copy, className, rowClassName }) {
|
|
3392
|
+
const { selectedMethod, hasConsumedTrial } = usePaywallContext();
|
|
3393
|
+
const useCardConsumed = selectedMethod === "card" && hasConsumedTrial && copy.cardConsumedTrial;
|
|
3394
|
+
const rows = useCardConsumed ? copy.cardConsumedTrial.bodyRows : selectedMethod === "pix-auto" || selectedMethod === "pix-once" ? copy.pix.bodyRows : copy.card.bodyRows;
|
|
3395
|
+
return /* @__PURE__ */ jsx33("div", { role: "tabpanel", id: `paywall-tab-${selectedMethod}`, className, children: rows.map((row, i) => /* @__PURE__ */ jsx33("div", { className: rowClassName, children: row }, i)) });
|
|
3334
3396
|
}
|
|
3335
3397
|
|
|
3336
3398
|
// src/components/paywall/PaywallCyclePicker.tsx
|
|
3337
|
-
import { jsx as
|
|
3399
|
+
import { jsx as jsx34, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3400
|
+
var VARIANT_CLASSES = {
|
|
3401
|
+
default: { card: "", cardSelected: "" },
|
|
3402
|
+
"premium-gold": {
|
|
3403
|
+
card: "",
|
|
3404
|
+
cardSelected: "border-2 border-yellow-400/80 ring-2 ring-yellow-400/20"
|
|
3405
|
+
},
|
|
3406
|
+
"pink-pill": {
|
|
3407
|
+
card: "rounded-2xl",
|
|
3408
|
+
cardSelected: "border-2 border-pink-500"
|
|
3409
|
+
}
|
|
3410
|
+
};
|
|
3338
3411
|
function PaywallCyclePicker({
|
|
3339
|
-
cycles,
|
|
3340
|
-
selected,
|
|
3341
|
-
onSelect,
|
|
3342
|
-
priceCentsByCycle,
|
|
3343
|
-
anchorCentsByCycle,
|
|
3344
|
-
monthlyEquivByCycle,
|
|
3345
3412
|
labels,
|
|
3346
3413
|
className,
|
|
3347
3414
|
cardClassName,
|
|
3348
3415
|
cardSelectedClassName,
|
|
3349
|
-
anchorClassName
|
|
3416
|
+
anchorClassName,
|
|
3417
|
+
variant = "default",
|
|
3418
|
+
render
|
|
3350
3419
|
}) {
|
|
3420
|
+
const ctx = usePaywallContext();
|
|
3421
|
+
const { cycle: selected, setCycle, plan, anchorPriceCents } = ctx;
|
|
3422
|
+
const cycles = ["MONTHLY", "YEARLY"];
|
|
3423
|
+
if (render) {
|
|
3424
|
+
return /* @__PURE__ */ jsx34("div", { className, children: render({ cycles, selected, setCycle, plan, anchorPriceCents }) });
|
|
3425
|
+
}
|
|
3351
3426
|
if (cycles.length < 2) return null;
|
|
3352
|
-
|
|
3427
|
+
const v = VARIANT_CLASSES[variant];
|
|
3428
|
+
const composedCardClassName = [v.card, cardClassName].filter(Boolean).join(" ");
|
|
3429
|
+
const composedCardSelectedClassName = [v.cardSelected, cardSelectedClassName].filter(Boolean).join(" ");
|
|
3430
|
+
const monthlyCents = plan?.monthlyCents ?? 0;
|
|
3431
|
+
const yearlyCents = plan?.yearlyCents ?? 0;
|
|
3432
|
+
const anchorMonthly = plan?.anchorMonthlyCents ?? null;
|
|
3433
|
+
const anchorYearly = plan?.anchorYearlyCents ?? null;
|
|
3434
|
+
return /* @__PURE__ */ jsx34(
|
|
3353
3435
|
"div",
|
|
3354
3436
|
{
|
|
3355
3437
|
role: "radiogroup",
|
|
@@ -3359,21 +3441,25 @@ function PaywallCyclePicker({
|
|
|
3359
3441
|
const active = c === selected;
|
|
3360
3442
|
const label = c === "YEARLY" ? labels.annualLabel : labels.monthlyLabel;
|
|
3361
3443
|
const suffix = c === "YEARLY" ? labels.annualSuffix : labels.monthlySuffix;
|
|
3362
|
-
const mainCents = c === "YEARLY" ?
|
|
3363
|
-
const anchorCents =
|
|
3364
|
-
return /* @__PURE__ */
|
|
3444
|
+
const mainCents = c === "YEARLY" ? Math.round(yearlyCents / 12) : monthlyCents;
|
|
3445
|
+
const anchorCents = c === "YEARLY" ? anchorYearly : anchorMonthly;
|
|
3446
|
+
return /* @__PURE__ */ jsxs20(
|
|
3365
3447
|
"button",
|
|
3366
3448
|
{
|
|
3367
3449
|
type: "button",
|
|
3368
3450
|
role: "radio",
|
|
3369
3451
|
"aria-checked": active,
|
|
3370
|
-
onClick: () =>
|
|
3371
|
-
className: [
|
|
3452
|
+
onClick: () => setCycle(c),
|
|
3453
|
+
className: [
|
|
3454
|
+
"flex flex-col items-center gap-0.5",
|
|
3455
|
+
composedCardClassName,
|
|
3456
|
+
active ? composedCardSelectedClassName : ""
|
|
3457
|
+
].filter(Boolean).join(" "),
|
|
3372
3458
|
children: [
|
|
3373
|
-
/* @__PURE__ */
|
|
3374
|
-
/* @__PURE__ */
|
|
3375
|
-
/* @__PURE__ */
|
|
3376
|
-
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */
|
|
3459
|
+
/* @__PURE__ */ jsx34("span", { className: "font-bold text-base leading-tight", children: formatBRL(mainCents) }),
|
|
3460
|
+
/* @__PURE__ */ jsx34("span", { className: "text-xs opacity-70 leading-tight", children: suffix }),
|
|
3461
|
+
/* @__PURE__ */ jsx34("span", { className: "text-xs opacity-60 leading-tight", children: label }),
|
|
3462
|
+
anchorCents != null && anchorCents > mainCents ? /* @__PURE__ */ jsx34("span", { className: anchorClassName ?? "text-xs opacity-50", children: /* @__PURE__ */ jsx34("s", { children: formatBRL(anchorCents) }) }) : null
|
|
3377
3463
|
]
|
|
3378
3464
|
},
|
|
3379
3465
|
c
|
|
@@ -3383,40 +3469,8 @@ function PaywallCyclePicker({
|
|
|
3383
3469
|
);
|
|
3384
3470
|
}
|
|
3385
3471
|
|
|
3386
|
-
// src/components/paywall/PaywallCta.tsx
|
|
3387
|
-
import { jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3388
|
-
function PaywallCta({
|
|
3389
|
-
ctaLabel,
|
|
3390
|
-
loadingLabel,
|
|
3391
|
-
switchHint,
|
|
3392
|
-
trustLine,
|
|
3393
|
-
onClick,
|
|
3394
|
-
disabled = false,
|
|
3395
|
-
loading = false,
|
|
3396
|
-
className,
|
|
3397
|
-
buttonClassName,
|
|
3398
|
-
switchHintClassName,
|
|
3399
|
-
trustClassName
|
|
3400
|
-
}) {
|
|
3401
|
-
const label = loading && loadingLabel ? loadingLabel : ctaLabel;
|
|
3402
|
-
return /* @__PURE__ */ jsxs20("div", { className, children: [
|
|
3403
|
-
/* @__PURE__ */ jsx33(
|
|
3404
|
-
"button",
|
|
3405
|
-
{
|
|
3406
|
-
type: "button",
|
|
3407
|
-
onClick,
|
|
3408
|
-
disabled: disabled || loading,
|
|
3409
|
-
className: buttonClassName,
|
|
3410
|
-
children: label
|
|
3411
|
-
}
|
|
3412
|
-
),
|
|
3413
|
-
switchHint ? /* @__PURE__ */ jsx33("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
3414
|
-
/* @__PURE__ */ jsx33("p", { className: trustClassName, children: trustLine })
|
|
3415
|
-
] });
|
|
3416
|
-
}
|
|
3417
|
-
|
|
3418
3472
|
// src/components/paywall/Paywall.tsx
|
|
3419
|
-
import { jsx as
|
|
3473
|
+
import { jsx as jsx35, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3420
3474
|
var NBSP = "\xA0";
|
|
3421
3475
|
function Paywall({
|
|
3422
3476
|
copy,
|
|
@@ -3424,21 +3478,42 @@ function Paywall({
|
|
|
3424
3478
|
slots = {},
|
|
3425
3479
|
onBeforeCheckout
|
|
3426
3480
|
}) {
|
|
3427
|
-
|
|
3428
|
-
|
|
3481
|
+
return /* @__PURE__ */ jsx35(PaywallProvider, { children: /* @__PURE__ */ jsx35(
|
|
3482
|
+
PaywallInner,
|
|
3483
|
+
{
|
|
3484
|
+
copy,
|
|
3485
|
+
themeClasses,
|
|
3486
|
+
slots,
|
|
3487
|
+
onBeforeCheckout
|
|
3488
|
+
}
|
|
3489
|
+
) });
|
|
3490
|
+
}
|
|
3491
|
+
function PaywallInner({
|
|
3492
|
+
copy,
|
|
3493
|
+
themeClasses = {},
|
|
3494
|
+
slots = {},
|
|
3495
|
+
onBeforeCheckout
|
|
3496
|
+
}) {
|
|
3497
|
+
const { track: track2 } = useHook20();
|
|
3498
|
+
const s = usePaywallContext();
|
|
3429
3499
|
const priceLabel = formatBRL(s.currentPriceCents).replace(new RegExp(NBSP, "g"), " ");
|
|
3430
|
-
const monthlyEquivLabel = formatBRL(s.currentMonthlyEquivCents).replace(new RegExp(NBSP, "g"), " ");
|
|
3431
3500
|
const trialDaysCardLabel = String(s.trialDaysCard);
|
|
3432
3501
|
const ctaLabel = useMemo9(() => {
|
|
3433
3502
|
if (s.isFree) return copy.freeCta ?? "Come\xE7ar agora";
|
|
3434
3503
|
if (s.selectedMethod === "card") {
|
|
3435
3504
|
if (s.hasConsumedTrial && copy.cardConsumedTrial) {
|
|
3436
|
-
return interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
3505
|
+
return interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
3506
|
+
price: priceLabel,
|
|
3507
|
+
days: trialDaysCardLabel
|
|
3508
|
+
});
|
|
3437
3509
|
}
|
|
3438
3510
|
if (s.trialDaysCard > 0) {
|
|
3439
3511
|
return interp(copy.card.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
|
|
3440
3512
|
}
|
|
3441
|
-
return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
3513
|
+
return copy.cardConsumedTrial ? interp(copy.cardConsumedTrial.ctaTemplate, {
|
|
3514
|
+
price: priceLabel,
|
|
3515
|
+
days: trialDaysCardLabel
|
|
3516
|
+
}) : `Assinar por ${priceLabel}`;
|
|
3442
3517
|
}
|
|
3443
3518
|
return interp(copy.pix.ctaTemplate, { price: priceLabel, days: trialDaysCardLabel });
|
|
3444
3519
|
}, [
|
|
@@ -3478,52 +3553,33 @@ function Paywall({
|
|
|
3478
3553
|
const ctaTheme = s.selectedMethod === "card" ? themeClasses.ctaCard : themeClasses.ctaPix;
|
|
3479
3554
|
return /* @__PURE__ */ jsxs21("div", { className: themeClasses.container, children: [
|
|
3480
3555
|
slots.heroSlot,
|
|
3481
|
-
/* @__PURE__ */
|
|
3482
|
-
/* @__PURE__ */
|
|
3556
|
+
/* @__PURE__ */ jsx35("h1", { className: themeClasses.headline, children: copy.headline }),
|
|
3557
|
+
/* @__PURE__ */ jsx35("ul", { children: copy.features.map((f) => /* @__PURE__ */ jsxs21("li", { className: themeClasses.feature, children: [
|
|
3483
3558
|
"\u2713 ",
|
|
3484
|
-
/* @__PURE__ */
|
|
3559
|
+
/* @__PURE__ */ jsx35("span", { children: f })
|
|
3485
3560
|
] }, f)) }),
|
|
3486
|
-
copy.socialProof ? /* @__PURE__ */
|
|
3487
|
-
slots.cyclePickerSlot ?? /* @__PURE__ */
|
|
3561
|
+
copy.socialProof ? /* @__PURE__ */ jsx35("p", { className: themeClasses.socialProof, children: copy.socialProof }) : null,
|
|
3562
|
+
slots.cyclePickerSlot ?? /* @__PURE__ */ jsx35(
|
|
3488
3563
|
PaywallCyclePicker,
|
|
3489
3564
|
{
|
|
3490
|
-
cycles: ["MONTHLY", "YEARLY"],
|
|
3491
|
-
selected: s.cycle,
|
|
3492
|
-
onSelect: s.selectCycle,
|
|
3493
|
-
priceCentsByCycle: {
|
|
3494
|
-
MONTHLY: priceCentsForCycle(s, "MONTHLY"),
|
|
3495
|
-
YEARLY: priceCentsForCycle(s, "YEARLY")
|
|
3496
|
-
},
|
|
3497
|
-
anchorCentsByCycle: {
|
|
3498
|
-
MONTHLY: anchorForCycle(s, "MONTHLY"),
|
|
3499
|
-
YEARLY: anchorForCycle(s, "YEARLY")
|
|
3500
|
-
},
|
|
3501
|
-
monthlyEquivByCycle: {
|
|
3502
|
-
MONTHLY: priceCentsForCycle(s, "MONTHLY"),
|
|
3503
|
-
YEARLY: Math.round(priceCentsForCycle(s, "YEARLY") / 12)
|
|
3504
|
-
},
|
|
3505
3565
|
labels: copy.cycle,
|
|
3506
3566
|
cardClassName: themeClasses.cycleCard,
|
|
3507
3567
|
cardSelectedClassName: themeClasses.cycleCardSelected,
|
|
3508
3568
|
anchorClassName: themeClasses.anchorPrice
|
|
3509
3569
|
}
|
|
3510
3570
|
),
|
|
3511
|
-
/* @__PURE__ */
|
|
3571
|
+
/* @__PURE__ */ jsx35(
|
|
3512
3572
|
PaywallMethodTabs,
|
|
3513
3573
|
{
|
|
3514
|
-
methods: s.methods,
|
|
3515
|
-
selected: s.selectedMethod,
|
|
3516
|
-
onSelect: s.selectMethod,
|
|
3517
3574
|
labels: { "pix-auto": copy.pix.tabLabel, card: copy.card.tabLabel },
|
|
3518
3575
|
className: themeClasses.tabs,
|
|
3519
3576
|
tabClassName: themeClasses.tab,
|
|
3520
3577
|
tabActiveClassName: themeClasses.tabActive
|
|
3521
3578
|
}
|
|
3522
3579
|
),
|
|
3523
|
-
/* @__PURE__ */
|
|
3580
|
+
/* @__PURE__ */ jsx35(
|
|
3524
3581
|
PaywallMethodContent,
|
|
3525
3582
|
{
|
|
3526
|
-
method: s.selectedMethod,
|
|
3527
3583
|
copy: {
|
|
3528
3584
|
pix: interpolateCopy(copy.pix, priceLabel, trialDaysCardLabel),
|
|
3529
3585
|
card: interpolateCopy(copy.card, priceLabel, trialDaysCardLabel),
|
|
@@ -3534,27 +3590,27 @@ function Paywall({
|
|
|
3534
3590
|
ctaTemplate: copy.cardConsumedTrial.ctaTemplate
|
|
3535
3591
|
} : void 0
|
|
3536
3592
|
},
|
|
3537
|
-
hasConsumedTrial: s.hasConsumedTrial,
|
|
3538
3593
|
className: themeClasses.tabContent,
|
|
3539
3594
|
rowClassName: themeClasses.tabContentRow
|
|
3540
3595
|
}
|
|
3541
3596
|
),
|
|
3542
3597
|
slots.beforeCtaSlot,
|
|
3543
|
-
/* @__PURE__ */
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
}
|
|
3557
|
-
|
|
3598
|
+
/* @__PURE__ */ jsxs21("div", { children: [
|
|
3599
|
+
/* @__PURE__ */ jsx35(
|
|
3600
|
+
"button",
|
|
3601
|
+
{
|
|
3602
|
+
type: "button",
|
|
3603
|
+
onClick: () => {
|
|
3604
|
+
void handleCta();
|
|
3605
|
+
},
|
|
3606
|
+
disabled: s.submitting,
|
|
3607
|
+
className: ctaTheme,
|
|
3608
|
+
children: s.submitting ? "Abrindo checkout\u2026" : ctaLabel
|
|
3609
|
+
}
|
|
3610
|
+
),
|
|
3611
|
+
switchHint ? /* @__PURE__ */ jsx35("p", { className: themeClasses.switchHint, children: switchHint }) : null,
|
|
3612
|
+
/* @__PURE__ */ jsx35("p", { className: themeClasses.trustLine, children: copy.trustLine })
|
|
3613
|
+
] })
|
|
3558
3614
|
] });
|
|
3559
3615
|
}
|
|
3560
3616
|
function interp(tpl, vars) {
|
|
@@ -3568,13 +3624,438 @@ function interpolateCopy(m, price, days) {
|
|
|
3568
3624
|
switchHint: m.switchHint
|
|
3569
3625
|
};
|
|
3570
3626
|
}
|
|
3571
|
-
|
|
3572
|
-
|
|
3627
|
+
|
|
3628
|
+
// src/components/paywall/PaywallCta.tsx
|
|
3629
|
+
import { jsx as jsx36, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3630
|
+
function PaywallCta({
|
|
3631
|
+
ctaLabel,
|
|
3632
|
+
loadingLabel,
|
|
3633
|
+
switchHint,
|
|
3634
|
+
trustLine,
|
|
3635
|
+
className,
|
|
3636
|
+
buttonClassName,
|
|
3637
|
+
switchHintClassName,
|
|
3638
|
+
trustClassName
|
|
3639
|
+
}) {
|
|
3640
|
+
const { submit, submitting } = usePaywallContext();
|
|
3641
|
+
const label = submitting && loadingLabel ? loadingLabel : ctaLabel;
|
|
3642
|
+
return /* @__PURE__ */ jsxs22("div", { className, children: [
|
|
3643
|
+
/* @__PURE__ */ jsx36(
|
|
3644
|
+
"button",
|
|
3645
|
+
{
|
|
3646
|
+
type: "button",
|
|
3647
|
+
onClick: () => {
|
|
3648
|
+
void submit();
|
|
3649
|
+
},
|
|
3650
|
+
disabled: submitting,
|
|
3651
|
+
className: buttonClassName,
|
|
3652
|
+
children: label
|
|
3653
|
+
}
|
|
3654
|
+
),
|
|
3655
|
+
switchHint ? /* @__PURE__ */ jsx36("p", { className: switchHintClassName, children: switchHint }) : null,
|
|
3656
|
+
/* @__PURE__ */ jsx36("p", { className: trustClassName, children: trustLine })
|
|
3657
|
+
] });
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
// src/components/paywall/blocks/PaywallEyebrow.tsx
|
|
3661
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
3662
|
+
var DEFAULT_EYEBROW_CLASSES = "text-xs uppercase tracking-widest font-semibold opacity-70";
|
|
3663
|
+
function PaywallEyebrow({ text, className }) {
|
|
3664
|
+
return /* @__PURE__ */ jsx37("div", { className: [DEFAULT_EYEBROW_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3665
|
+
}
|
|
3666
|
+
|
|
3667
|
+
// src/components/paywall/blocks/PaywallHero.tsx
|
|
3668
|
+
import { jsx as jsx38, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3669
|
+
var DEFAULT_GRADIENT = "absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent";
|
|
3670
|
+
function PaywallHero({
|
|
3671
|
+
src,
|
|
3672
|
+
alt = "",
|
|
3673
|
+
headline,
|
|
3674
|
+
aspectRatio = "16/9",
|
|
3675
|
+
gradientClassName,
|
|
3676
|
+
className,
|
|
3677
|
+
headlineClassName,
|
|
3678
|
+
imgClassName,
|
|
3679
|
+
render
|
|
3680
|
+
}) {
|
|
3681
|
+
if (render) {
|
|
3682
|
+
return /* @__PURE__ */ jsx38("div", { className, children: render({ src, headline }) });
|
|
3683
|
+
}
|
|
3684
|
+
return /* @__PURE__ */ jsxs23(
|
|
3685
|
+
"div",
|
|
3686
|
+
{
|
|
3687
|
+
className: ["relative overflow-hidden", className].filter(Boolean).join(" "),
|
|
3688
|
+
style: { aspectRatio },
|
|
3689
|
+
children: [
|
|
3690
|
+
/* @__PURE__ */ jsx38(
|
|
3691
|
+
"img",
|
|
3692
|
+
{
|
|
3693
|
+
src,
|
|
3694
|
+
alt,
|
|
3695
|
+
className: ["absolute inset-0 w-full h-full object-cover", imgClassName].filter(Boolean).join(" ")
|
|
3696
|
+
}
|
|
3697
|
+
),
|
|
3698
|
+
/* @__PURE__ */ jsx38("div", { className: gradientClassName ?? DEFAULT_GRADIENT, "aria-hidden": "true" }),
|
|
3699
|
+
headline ? /* @__PURE__ */ jsx38(
|
|
3700
|
+
"h1",
|
|
3701
|
+
{
|
|
3702
|
+
className: ["absolute bottom-0 left-0 right-0 p-4 text-white font-bold text-2xl", headlineClassName].filter(Boolean).join(" "),
|
|
3703
|
+
children: headline
|
|
3704
|
+
}
|
|
3705
|
+
) : null
|
|
3706
|
+
]
|
|
3707
|
+
}
|
|
3708
|
+
);
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
// src/components/paywall/blocks/PaywallHeadline.tsx
|
|
3712
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
3713
|
+
var DEFAULT_HEADLINE_CLASSES = "text-2xl font-bold leading-tight";
|
|
3714
|
+
function PaywallHeadline({ text, className, as = "h1" }) {
|
|
3715
|
+
const Tag = as;
|
|
3716
|
+
return /* @__PURE__ */ jsx39(Tag, { className: [DEFAULT_HEADLINE_CLASSES, className].filter(Boolean).join(" "), children: text });
|
|
3717
|
+
}
|
|
3718
|
+
|
|
3719
|
+
// src/components/paywall/blocks/PaywallPriceHeadline.tsx
|
|
3720
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
3721
|
+
var DEFAULT_CLASS = "text-2xl font-bold leading-tight";
|
|
3722
|
+
var CYCLE_LABEL = {
|
|
3723
|
+
MONTHLY: "mensal",
|
|
3724
|
+
YEARLY: "anual"
|
|
3725
|
+
};
|
|
3726
|
+
function PaywallPriceHeadline({
|
|
3727
|
+
template,
|
|
3728
|
+
className,
|
|
3729
|
+
as = "h1",
|
|
3730
|
+
render
|
|
3731
|
+
}) {
|
|
3732
|
+
const { cycle, currentMonthlyEquivCents, plan } = usePaywallContext();
|
|
3733
|
+
const yearlyCents = plan?.yearlyCents ?? null;
|
|
3734
|
+
const pricePerDay = formatBRL(dailyFromYearly(yearlyCents));
|
|
3735
|
+
const monthlyEquiv = currentMonthlyEquivCents ?? 0;
|
|
3736
|
+
const cycleLabel = CYCLE_LABEL[cycle] ?? cycle.toLowerCase();
|
|
3737
|
+
const rootClasses = [DEFAULT_CLASS, className].filter(Boolean).join(" ");
|
|
3738
|
+
if (render) {
|
|
3739
|
+
const RootTag2 = as;
|
|
3740
|
+
return /* @__PURE__ */ jsx40(RootTag2, { className: [className].filter(Boolean).join(" ") || void 0, children: render({ pricePerDay, currentMonthlyEquivCents: monthlyEquiv, cycle }) });
|
|
3741
|
+
}
|
|
3742
|
+
const text = template.replaceAll("{pricePerDay}", pricePerDay).replaceAll("{currentMonthlyEquiv}", formatBRL(monthlyEquiv)).replaceAll("{cycle}", cycleLabel);
|
|
3743
|
+
const RootTag = as;
|
|
3744
|
+
return /* @__PURE__ */ jsx40(RootTag, { className: rootClasses, children: text });
|
|
3573
3745
|
}
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3746
|
+
|
|
3747
|
+
// src/components/paywall/blocks/PaywallCountdown.tsx
|
|
3748
|
+
import { useEffect as useEffect15, useRef as useRef7, useState as useState15 } from "react";
|
|
3749
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
3750
|
+
var DEFAULT_COUNTDOWN_CLASSES = "font-mono tabular-nums";
|
|
3751
|
+
function resolveDeadlineMs(deadline) {
|
|
3752
|
+
if (deadline instanceof Date) return deadline.getTime();
|
|
3753
|
+
if (typeof deadline === "string") return new Date(deadline).getTime();
|
|
3754
|
+
const { sessionStorageKey, durationMs } = deadline;
|
|
3755
|
+
if (typeof window === "undefined" || typeof window.sessionStorage === "undefined") {
|
|
3756
|
+
return Date.now() + durationMs;
|
|
3757
|
+
}
|
|
3758
|
+
const stored = window.sessionStorage.getItem(sessionStorageKey);
|
|
3759
|
+
const parsed = stored ? Number.parseInt(stored, 10) : NaN;
|
|
3760
|
+
const now = Date.now();
|
|
3761
|
+
if (!Number.isFinite(parsed) || parsed < now) {
|
|
3762
|
+
const target = now + durationMs;
|
|
3763
|
+
window.sessionStorage.setItem(sessionStorageKey, String(target));
|
|
3764
|
+
return target;
|
|
3765
|
+
}
|
|
3766
|
+
return parsed;
|
|
3767
|
+
}
|
|
3768
|
+
function computeRemaining(deadlineMs) {
|
|
3769
|
+
const diff = Math.max(0, deadlineMs - Date.now());
|
|
3770
|
+
const totalSeconds = Math.floor(diff / 1e3);
|
|
3771
|
+
const h = Math.floor(totalSeconds / 3600);
|
|
3772
|
+
const m = Math.floor(totalSeconds % 3600 / 60);
|
|
3773
|
+
const s = totalSeconds % 60;
|
|
3774
|
+
return { h, m, s, expired: diff === 0 };
|
|
3775
|
+
}
|
|
3776
|
+
function pad(n) {
|
|
3777
|
+
return String(n).padStart(2, "0");
|
|
3778
|
+
}
|
|
3779
|
+
function PaywallCountdown({
|
|
3780
|
+
deadline,
|
|
3781
|
+
format = "h:m:s",
|
|
3782
|
+
onExpire,
|
|
3783
|
+
className,
|
|
3784
|
+
render
|
|
3785
|
+
}) {
|
|
3786
|
+
const deadlineMsRef = useRef7(null);
|
|
3787
|
+
if (deadlineMsRef.current === null) {
|
|
3788
|
+
deadlineMsRef.current = resolveDeadlineMs(deadline);
|
|
3789
|
+
}
|
|
3790
|
+
const [state, setState] = useState15(() => computeRemaining(deadlineMsRef.current));
|
|
3791
|
+
const expiredCalledRef = useRef7(false);
|
|
3792
|
+
useEffect15(() => {
|
|
3793
|
+
if (state.expired) {
|
|
3794
|
+
if (!expiredCalledRef.current) {
|
|
3795
|
+
expiredCalledRef.current = true;
|
|
3796
|
+
onExpire?.();
|
|
3797
|
+
}
|
|
3798
|
+
return;
|
|
3799
|
+
}
|
|
3800
|
+
const tick = () => {
|
|
3801
|
+
const next = computeRemaining(deadlineMsRef.current);
|
|
3802
|
+
setState(next);
|
|
3803
|
+
if (next.expired && !expiredCalledRef.current) {
|
|
3804
|
+
expiredCalledRef.current = true;
|
|
3805
|
+
onExpire?.();
|
|
3806
|
+
}
|
|
3807
|
+
};
|
|
3808
|
+
const id = setInterval(tick, 1e3);
|
|
3809
|
+
return () => clearInterval(id);
|
|
3810
|
+
}, [state.expired]);
|
|
3811
|
+
if (render) {
|
|
3812
|
+
return /* @__PURE__ */ jsx41("div", { className, children: render(state) });
|
|
3813
|
+
}
|
|
3814
|
+
const formatted = format === "h:m:s" ? `${pad(state.h)}:${pad(state.m)}:${pad(state.s)}` : `${pad(state.h * 60 + state.m)}:${pad(state.s)}`;
|
|
3815
|
+
return /* @__PURE__ */ jsx41("div", { className: [DEFAULT_COUNTDOWN_CLASSES, className].filter(Boolean).join(" "), children: formatted });
|
|
3816
|
+
}
|
|
3817
|
+
|
|
3818
|
+
// src/components/paywall/blocks/PaywallFeatures.tsx
|
|
3819
|
+
import { jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3820
|
+
function PaywallFeatures({
|
|
3821
|
+
items,
|
|
3822
|
+
IconComponent,
|
|
3823
|
+
className,
|
|
3824
|
+
itemClassName,
|
|
3825
|
+
iconClassName,
|
|
3826
|
+
render,
|
|
3827
|
+
renderItem
|
|
3828
|
+
}) {
|
|
3829
|
+
if (render) {
|
|
3830
|
+
return /* @__PURE__ */ jsx42("div", { className, children: render({ items }) });
|
|
3831
|
+
}
|
|
3832
|
+
if (renderItem) {
|
|
3833
|
+
return /* @__PURE__ */ jsx42("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ jsx42("li", { children: renderItem(item, idx) }, idx)) });
|
|
3834
|
+
}
|
|
3835
|
+
return /* @__PURE__ */ jsx42("ul", { className, children: items.map((item, idx) => /* @__PURE__ */ jsxs24("li", { className: itemClassName, children: [
|
|
3836
|
+
IconComponent ? /* @__PURE__ */ jsx42(IconComponent, { className: iconClassName }) : /* @__PURE__ */ jsx42("span", { className: iconClassName, "aria-hidden": "true", children: "\u2713" }),
|
|
3837
|
+
/* @__PURE__ */ jsx42("span", { children: item })
|
|
3838
|
+
] }, idx)) });
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
// src/components/paywall/blocks/PaywallFeaturesCard.tsx
|
|
3842
|
+
import { jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3843
|
+
var DEFAULT_CARD_CLASSES = "rounded-xl border p-4";
|
|
3844
|
+
function PaywallFeaturesCard({
|
|
3845
|
+
title,
|
|
3846
|
+
items,
|
|
3847
|
+
className,
|
|
3848
|
+
cardClassName,
|
|
3849
|
+
titleClassName,
|
|
3850
|
+
itemClassName,
|
|
3851
|
+
renderItem
|
|
3852
|
+
}) {
|
|
3853
|
+
return /* @__PURE__ */ jsx43("div", { className, children: /* @__PURE__ */ jsxs25("div", { className: [DEFAULT_CARD_CLASSES, cardClassName].filter(Boolean).join(" "), children: [
|
|
3854
|
+
title ? /* @__PURE__ */ jsx43("div", { className: ["font-semibold mb-2", titleClassName].filter(Boolean).join(" "), children: title }) : null,
|
|
3855
|
+
/* @__PURE__ */ jsx43("ul", { children: items.map(
|
|
3856
|
+
(item, idx) => renderItem ? /* @__PURE__ */ jsx43("li", { children: renderItem(item, idx) }, idx) : /* @__PURE__ */ jsxs25("li", { className: itemClassName, children: [
|
|
3857
|
+
/* @__PURE__ */ jsx43("span", { "aria-hidden": "true", children: "\u2022" }),
|
|
3858
|
+
" ",
|
|
3859
|
+
/* @__PURE__ */ jsx43("span", { children: item })
|
|
3860
|
+
] }, idx)
|
|
3861
|
+
) })
|
|
3862
|
+
] }) });
|
|
3863
|
+
}
|
|
3864
|
+
|
|
3865
|
+
// src/components/paywall/blocks/PaywallTrophyBadge.tsx
|
|
3866
|
+
import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3867
|
+
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";
|
|
3868
|
+
var FLOATING_CLASSES = "absolute top-2 right-2 z-10 shadow-md";
|
|
3869
|
+
function PaywallTrophyBadge({
|
|
3870
|
+
text,
|
|
3871
|
+
className,
|
|
3872
|
+
iconClassName,
|
|
3873
|
+
floating = false,
|
|
3874
|
+
render
|
|
3875
|
+
}) {
|
|
3876
|
+
if (render) {
|
|
3877
|
+
return /* @__PURE__ */ jsx44("div", { className, children: render({ text }) });
|
|
3878
|
+
}
|
|
3879
|
+
const rootClasses = [
|
|
3880
|
+
DEFAULT_CHIP_CLASSES,
|
|
3881
|
+
floating ? FLOATING_CLASSES : "",
|
|
3882
|
+
className
|
|
3883
|
+
].filter(Boolean).join(" ");
|
|
3884
|
+
return /* @__PURE__ */ jsxs26("div", { className: rootClasses, children: [
|
|
3885
|
+
/* @__PURE__ */ jsx44("span", { className: iconClassName, "aria-hidden": "true", children: "\u{1F3C6}" }),
|
|
3886
|
+
/* @__PURE__ */ jsx44("span", { children: text })
|
|
3887
|
+
] });
|
|
3888
|
+
}
|
|
3889
|
+
|
|
3890
|
+
// src/components/paywall/blocks/PaywallAnchorPrice.tsx
|
|
3891
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
3892
|
+
var DEFAULT_CLASS2 = "text-sm opacity-60 line-through";
|
|
3893
|
+
function PaywallAnchorPrice({
|
|
3894
|
+
className,
|
|
3895
|
+
render
|
|
3896
|
+
}) {
|
|
3897
|
+
const { anchorPriceCents, cycle } = usePaywallContext();
|
|
3898
|
+
if (anchorPriceCents === null || anchorPriceCents === void 0 || anchorPriceCents <= 0) {
|
|
3899
|
+
return null;
|
|
3900
|
+
}
|
|
3901
|
+
void cycle;
|
|
3902
|
+
const formatted = formatBRL(anchorPriceCents);
|
|
3903
|
+
const rootClasses = [DEFAULT_CLASS2, className].filter(Boolean).join(" ");
|
|
3904
|
+
if (render) {
|
|
3905
|
+
return /* @__PURE__ */ jsx45("span", { className: className || void 0, children: render({ anchorCents: anchorPriceCents, formatted }) });
|
|
3906
|
+
}
|
|
3907
|
+
return /* @__PURE__ */ jsx45("span", { className: rootClasses, children: formatted });
|
|
3908
|
+
}
|
|
3909
|
+
|
|
3910
|
+
// src/components/paywall/blocks/PaywallTestimonials.tsx
|
|
3911
|
+
import { jsx as jsx46, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
3912
|
+
var DEFAULT_ROOT = "flex gap-3 overflow-x-auto snap-x snap-mandatory pb-2";
|
|
3913
|
+
var DEFAULT_CARD = "snap-start shrink-0 w-72 rounded-2xl border p-4 flex flex-col gap-2";
|
|
3914
|
+
var DEFAULT_AVATAR = "w-10 h-10 rounded-full object-cover";
|
|
3915
|
+
var DEFAULT_QUOTE = "text-sm leading-snug";
|
|
3916
|
+
var DEFAULT_NAME = "text-xs font-semibold opacity-80";
|
|
3917
|
+
var DEFAULT_STARS = "text-yellow-500 text-sm";
|
|
3918
|
+
function clampStars(n) {
|
|
3919
|
+
return Math.max(0, Math.min(5, Math.round(n)));
|
|
3920
|
+
}
|
|
3921
|
+
function PaywallTestimonials({
|
|
3922
|
+
items,
|
|
3923
|
+
className,
|
|
3924
|
+
cardClassName,
|
|
3925
|
+
avatarClassName,
|
|
3926
|
+
quoteClassName,
|
|
3927
|
+
nameClassName,
|
|
3928
|
+
starsClassName,
|
|
3929
|
+
renderItem
|
|
3930
|
+
}) {
|
|
3931
|
+
const rootClasses = [DEFAULT_ROOT, className].filter(Boolean).join(" ");
|
|
3932
|
+
const cardClasses = [DEFAULT_CARD, cardClassName].filter(Boolean).join(" ");
|
|
3933
|
+
const avatarClasses = [DEFAULT_AVATAR, avatarClassName].filter(Boolean).join(" ");
|
|
3934
|
+
const quoteClasses = [DEFAULT_QUOTE, quoteClassName].filter(Boolean).join(" ");
|
|
3935
|
+
const nameClasses = [DEFAULT_NAME, nameClassName].filter(Boolean).join(" ");
|
|
3936
|
+
const starsClasses = [DEFAULT_STARS, starsClassName].filter(Boolean).join(" ");
|
|
3937
|
+
return /* @__PURE__ */ jsx46("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
3938
|
+
if (renderItem) return renderItem(item, idx);
|
|
3939
|
+
const filled = clampStars(item.stars);
|
|
3940
|
+
const empty = 5 - filled;
|
|
3941
|
+
return /* @__PURE__ */ jsxs27("div", { className: cardClasses, children: [
|
|
3942
|
+
/* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2", children: [
|
|
3943
|
+
item.avatar ? /* @__PURE__ */ jsx46(
|
|
3944
|
+
"img",
|
|
3945
|
+
{
|
|
3946
|
+
src: item.avatar,
|
|
3947
|
+
alt: "",
|
|
3948
|
+
loading: "lazy",
|
|
3949
|
+
className: avatarClasses,
|
|
3950
|
+
"aria-hidden": "true"
|
|
3951
|
+
}
|
|
3952
|
+
) : null,
|
|
3953
|
+
/* @__PURE__ */ jsx46("div", { className: nameClasses, children: item.name })
|
|
3954
|
+
] }),
|
|
3955
|
+
/* @__PURE__ */ jsxs27("div", { className: starsClasses, "aria-label": `${filled} de 5 estrelas`, children: [
|
|
3956
|
+
"\u2605".repeat(filled),
|
|
3957
|
+
"\u2606".repeat(empty)
|
|
3958
|
+
] }),
|
|
3959
|
+
/* @__PURE__ */ jsx46("p", { className: quoteClasses, children: item.quote })
|
|
3960
|
+
] }, idx);
|
|
3961
|
+
}) });
|
|
3962
|
+
}
|
|
3963
|
+
|
|
3964
|
+
// src/components/paywall/blocks/PaywallStatsRow.tsx
|
|
3965
|
+
import { jsx as jsx47, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
3966
|
+
var DEFAULT_ROOT2 = "grid grid-cols-3 gap-4";
|
|
3967
|
+
var DEFAULT_CELL = "flex flex-col items-center text-center";
|
|
3968
|
+
var DEFAULT_VALUE = "text-2xl font-bold";
|
|
3969
|
+
var DEFAULT_LABEL = "text-xs opacity-70";
|
|
3970
|
+
function PaywallStatsRow({
|
|
3971
|
+
stats,
|
|
3972
|
+
className,
|
|
3973
|
+
cellClassName,
|
|
3974
|
+
valueClassName,
|
|
3975
|
+
labelClassName,
|
|
3976
|
+
renderCell
|
|
3977
|
+
}) {
|
|
3978
|
+
const rootClasses = [DEFAULT_ROOT2, className].filter(Boolean).join(" ");
|
|
3979
|
+
const cellClasses = [DEFAULT_CELL, cellClassName].filter(Boolean).join(" ");
|
|
3980
|
+
const valueClasses = [DEFAULT_VALUE, valueClassName].filter(Boolean).join(" ");
|
|
3981
|
+
const labelClasses = [DEFAULT_LABEL, labelClassName].filter(Boolean).join(" ");
|
|
3982
|
+
return /* @__PURE__ */ jsx47("div", { className: rootClasses, children: stats.map((stat, idx) => {
|
|
3983
|
+
if (renderCell) return renderCell(stat, idx);
|
|
3984
|
+
return /* @__PURE__ */ jsxs28("div", { className: cellClasses, children: [
|
|
3985
|
+
stat.icon ? /* @__PURE__ */ jsx47("div", { "aria-hidden": "true", children: stat.icon }) : null,
|
|
3986
|
+
/* @__PURE__ */ jsx47("div", { className: valueClasses, children: stat.value }),
|
|
3987
|
+
/* @__PURE__ */ jsx47("div", { className: labelClasses, children: stat.label })
|
|
3988
|
+
] }, idx);
|
|
3989
|
+
}) });
|
|
3990
|
+
}
|
|
3991
|
+
|
|
3992
|
+
// src/components/paywall/blocks/PaywallFinePrint.tsx
|
|
3993
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
3994
|
+
var DEFAULT_CLASS3 = "text-xs opacity-60 leading-snug";
|
|
3995
|
+
var CYCLE_LABEL2 = {
|
|
3996
|
+
MONTHLY: "mensal",
|
|
3997
|
+
YEARLY: "anual"
|
|
3998
|
+
};
|
|
3999
|
+
function PaywallFinePrint({
|
|
4000
|
+
template,
|
|
4001
|
+
className,
|
|
4002
|
+
render
|
|
4003
|
+
}) {
|
|
4004
|
+
const {
|
|
4005
|
+
currentPriceCents,
|
|
4006
|
+
cycle,
|
|
4007
|
+
trialDaysCard,
|
|
4008
|
+
trialDaysPix,
|
|
4009
|
+
selectedMethod
|
|
4010
|
+
} = usePaywallContext();
|
|
4011
|
+
const trialDays = selectedMethod === "card" ? trialDaysCard : trialDaysPix;
|
|
4012
|
+
const cycleLabel = CYCLE_LABEL2[cycle] ?? cycle.toLowerCase();
|
|
4013
|
+
const priceFormatted = formatBRL(currentPriceCents ?? 0);
|
|
4014
|
+
const rootClasses = [DEFAULT_CLASS3, className].filter(Boolean).join(" ");
|
|
4015
|
+
if (render) {
|
|
4016
|
+
return /* @__PURE__ */ jsx48("p", { className: className || void 0, children: render({
|
|
4017
|
+
currentPriceCents: currentPriceCents ?? 0,
|
|
4018
|
+
cycle,
|
|
4019
|
+
trialDays: trialDays ?? 0,
|
|
4020
|
+
selectedMethod
|
|
4021
|
+
}) });
|
|
4022
|
+
}
|
|
4023
|
+
const text = template.replaceAll("{price}", priceFormatted).replaceAll("{trialDays}", String(trialDays ?? 0)).replaceAll("{cycle}", cycleLabel);
|
|
4024
|
+
return /* @__PURE__ */ jsx48("p", { className: rootClasses, children: text });
|
|
4025
|
+
}
|
|
4026
|
+
|
|
4027
|
+
// src/components/paywall/blocks/PaywallTrustLine.tsx
|
|
4028
|
+
import { jsx as jsx49, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
4029
|
+
var DEFAULT_ROOT3 = "flex items-center gap-3";
|
|
4030
|
+
var DEFAULT_ITEM = "flex items-center gap-1.5 text-xs";
|
|
4031
|
+
function PaywallTrustLine({
|
|
4032
|
+
items,
|
|
4033
|
+
className,
|
|
4034
|
+
itemClassName,
|
|
4035
|
+
renderItem
|
|
4036
|
+
}) {
|
|
4037
|
+
const rootClasses = [DEFAULT_ROOT3, className].filter(Boolean).join(" ");
|
|
4038
|
+
const itemClasses = [DEFAULT_ITEM, itemClassName].filter(Boolean).join(" ");
|
|
4039
|
+
return /* @__PURE__ */ jsx49("div", { className: rootClasses, children: items.map((item, idx) => {
|
|
4040
|
+
if (renderItem) return renderItem(item, idx);
|
|
4041
|
+
return /* @__PURE__ */ jsxs29("span", { className: itemClasses, children: [
|
|
4042
|
+
/* @__PURE__ */ jsx49("span", { "aria-hidden": "true", children: item.icon }),
|
|
4043
|
+
/* @__PURE__ */ jsx49("span", { children: item.text })
|
|
4044
|
+
] }, idx);
|
|
4045
|
+
}) });
|
|
4046
|
+
}
|
|
4047
|
+
|
|
4048
|
+
// src/components/paywall/blocks/PaywallStickyFooter.tsx
|
|
4049
|
+
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
4050
|
+
var DEFAULT_CLASSES = "sticky bottom-0 left-0 right-0 bg-background";
|
|
4051
|
+
var SAFE_AREA_CLASS = "pb-[env(safe-area-inset-bottom)]";
|
|
4052
|
+
function PaywallStickyFooter({
|
|
4053
|
+
children,
|
|
4054
|
+
className,
|
|
4055
|
+
safeAreaInsets = true
|
|
4056
|
+
}) {
|
|
4057
|
+
const classes = [DEFAULT_CLASSES, safeAreaInsets ? SAFE_AREA_CLASS : null, className].filter(Boolean).join(" ");
|
|
4058
|
+
return /* @__PURE__ */ jsx50("div", { className: classes, children });
|
|
3578
4059
|
}
|
|
3579
4060
|
export {
|
|
3580
4061
|
AppConfigProvider,
|
|
@@ -3592,10 +4073,26 @@ export {
|
|
|
3592
4073
|
OnboardingFlow,
|
|
3593
4074
|
PaymentReturnHandler,
|
|
3594
4075
|
Paywall,
|
|
4076
|
+
PaywallAnchorPrice,
|
|
4077
|
+
PaywallContext,
|
|
4078
|
+
PaywallCountdown,
|
|
3595
4079
|
PaywallCta,
|
|
3596
4080
|
PaywallCyclePicker,
|
|
4081
|
+
PaywallEyebrow,
|
|
4082
|
+
PaywallFeatures,
|
|
4083
|
+
PaywallFeaturesCard,
|
|
4084
|
+
PaywallFinePrint,
|
|
4085
|
+
PaywallHeadline,
|
|
4086
|
+
PaywallHero,
|
|
3597
4087
|
PaywallMethodContent,
|
|
3598
4088
|
PaywallMethodTabs,
|
|
4089
|
+
PaywallPriceHeadline,
|
|
4090
|
+
PaywallProvider,
|
|
4091
|
+
PaywallStatsRow,
|
|
4092
|
+
PaywallStickyFooter,
|
|
4093
|
+
PaywallTestimonials,
|
|
4094
|
+
PaywallTrophyBadge,
|
|
4095
|
+
PaywallTrustLine,
|
|
3599
4096
|
PersistenceRegistry,
|
|
3600
4097
|
PreAuthShell,
|
|
3601
4098
|
PushPrompt2 as PushPrompt,
|
|
@@ -3624,6 +4121,7 @@ export {
|
|
|
3624
4121
|
useInstallPrompt,
|
|
3625
4122
|
useLoginForm,
|
|
3626
4123
|
useOnboardingStep,
|
|
4124
|
+
usePaywallContext,
|
|
3627
4125
|
usePaywallState,
|
|
3628
4126
|
usePlan,
|
|
3629
4127
|
usePush,
|