@hook-sdk/template 0.18.1 → 0.19.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 +317 -207
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +70 -3
- package/dist/index.d.ts +70 -3
- package/dist/index.js +191 -93
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -26,8 +36,10 @@ __export(index_exports, {
|
|
|
26
36
|
DeepLinkHandler: () => DeepLinkHandler,
|
|
27
37
|
EmptyState: () => EmptyState,
|
|
28
38
|
ErrorBoundary: () => ErrorBoundary,
|
|
39
|
+
I18nProvider: () => I18nProvider,
|
|
29
40
|
InstallGate: () => InstallGate,
|
|
30
41
|
InstallSplash: () => InstallSplash,
|
|
42
|
+
LanguageSwitcher: () => LanguageSwitcher,
|
|
31
43
|
LoadingState: () => LoadingState,
|
|
32
44
|
OnboardingFlow: () => OnboardingFlow,
|
|
33
45
|
PaymentReturnHandler: () => PaymentReturnHandler,
|
|
@@ -65,14 +77,14 @@ __export(index_exports, {
|
|
|
65
77
|
useSignupForm: () => useSignupForm,
|
|
66
78
|
useSubscription: () => useSubscription,
|
|
67
79
|
useToast: () => useToast,
|
|
68
|
-
useTrackOnboardingStep: () =>
|
|
80
|
+
useTrackOnboardingStep: () => import_sdk21.useTrackOnboardingStep
|
|
69
81
|
});
|
|
70
82
|
module.exports = __toCommonJS(index_exports);
|
|
71
83
|
|
|
72
84
|
// src/AppRoot.tsx
|
|
73
|
-
var
|
|
85
|
+
var import_react14 = require("react");
|
|
74
86
|
var import_react_router_dom2 = require("react-router-dom");
|
|
75
|
-
var
|
|
87
|
+
var import_sdk7 = require("@hook-sdk/sdk");
|
|
76
88
|
|
|
77
89
|
// src/config/AppConfigContext.tsx
|
|
78
90
|
var import_react = require("react");
|
|
@@ -145,6 +157,17 @@ var DeepLinksSchema = import_zod.z.object({
|
|
|
145
157
|
passwordReset: import_zod.z.string().startsWith("/").optional(),
|
|
146
158
|
emailVerify: import_zod.z.string().startsWith("/").optional()
|
|
147
159
|
}).strict();
|
|
160
|
+
var I18nConfigSchema = import_zod.z.object({
|
|
161
|
+
defaultLocale: import_zod.z.string().min(2),
|
|
162
|
+
supportedLocales: import_zod.z.array(import_zod.z.string().min(2)).min(1),
|
|
163
|
+
resources: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.string(), import_zod.z.string()))
|
|
164
|
+
}).strict().refine((v) => v.supportedLocales.includes(v.defaultLocale), {
|
|
165
|
+
message: "i18n.defaultLocale must be a member of i18n.supportedLocales",
|
|
166
|
+
path: ["defaultLocale"]
|
|
167
|
+
});
|
|
168
|
+
var InstallPromptSchema = import_zod.z.object({
|
|
169
|
+
position: import_zod.z.enum(["pre-auth", "post-paywall"]).optional()
|
|
170
|
+
}).strict();
|
|
148
171
|
var AppConfigSchema = import_zod.z.object({
|
|
149
172
|
slug: import_zod.z.string().regex(/^[a-z0-9-]+$/),
|
|
150
173
|
name: import_zod.z.string().min(1),
|
|
@@ -158,12 +181,18 @@ var AppConfigSchema = import_zod.z.object({
|
|
|
158
181
|
persistedKeys: import_zod.z.array(PersistedKeySchema),
|
|
159
182
|
onboarding: OnboardingSchema.optional(),
|
|
160
183
|
deepLinks: DeepLinksSchema.optional(),
|
|
184
|
+
i18n: I18nConfigSchema.optional(),
|
|
161
185
|
features_enabled: import_zod.z.array(import_zod.z.string()).optional(),
|
|
186
|
+
install_prompt: InstallPromptSchema.optional(),
|
|
162
187
|
// Build-time injected theme metadata (e.g. icon_url for InstallSplash).
|
|
163
188
|
// Apps don't author this directly; deploy workflows fill it from
|
|
164
189
|
// env-resolved bundle host. Permissive shape so apps/workflows can
|
|
165
190
|
// extend without re-bumping the template schema.
|
|
166
|
-
theme: import_zod.z.object({}).passthrough().optional()
|
|
191
|
+
theme: import_zod.z.object({}).passthrough().optional(),
|
|
192
|
+
// G133 — per-tenant public app-data keys allowlist. Optional; default
|
|
193
|
+
// backfill em migration 0044 = canonical 6. Apps com keys próprias
|
|
194
|
+
// declaram aqui pra evitar 402 spam pós-signup no SubscriptionGate.
|
|
195
|
+
publicKeys: import_zod.z.array(import_zod.z.string().regex(SnakeKeyRE)).optional()
|
|
167
196
|
}).strict();
|
|
168
197
|
function parseAppConfig(input) {
|
|
169
198
|
const r = AppConfigSchema.safeParse(input);
|
|
@@ -1882,9 +1911,9 @@ var bannerStyle = {
|
|
|
1882
1911
|
|
|
1883
1912
|
// src/components/InstallGate/InstallGate.tsx
|
|
1884
1913
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1885
|
-
function InstallGate({ children }) {
|
|
1914
|
+
function InstallGate({ children, position }) {
|
|
1886
1915
|
const { slug, features_enabled } = useTemplateConfig();
|
|
1887
|
-
const enabled = features_enabled.includes("
|
|
1916
|
+
const enabled = features_enabled.includes("pwa-install");
|
|
1888
1917
|
const installState = useInstallPrompt(slug);
|
|
1889
1918
|
const shouldBlock = enabled && shouldBlockInstall(installState);
|
|
1890
1919
|
const trackedRef = (0, import_react9.useRef)(null);
|
|
@@ -1899,9 +1928,10 @@ function InstallGate({ children }) {
|
|
|
1899
1928
|
platform: installState.platform,
|
|
1900
1929
|
browser: installState.iosBrowser ?? installState.androidBrowser ?? null,
|
|
1901
1930
|
in_app_app: installState.inAppApp,
|
|
1902
|
-
variant: installState.variant
|
|
1931
|
+
variant: installState.variant,
|
|
1932
|
+
...position !== void 0 ? { position } : {}
|
|
1903
1933
|
});
|
|
1904
|
-
}, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);
|
|
1934
|
+
}, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp, position]);
|
|
1905
1935
|
if (!enabled) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children });
|
|
1906
1936
|
if (installState.isInstalled) return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children });
|
|
1907
1937
|
if (installState.variant === "desktop") {
|
|
@@ -2024,21 +2054,58 @@ var ErrorBoundary = class extends import_react11.Component {
|
|
|
2024
2054
|
}
|
|
2025
2055
|
};
|
|
2026
2056
|
|
|
2027
|
-
// src/
|
|
2057
|
+
// src/i18n/I18nProvider.tsx
|
|
2028
2058
|
var import_react12 = require("react");
|
|
2059
|
+
var import_i18next = __toESM(require("i18next"), 1);
|
|
2060
|
+
var import_react_i18next = require("react-i18next");
|
|
2029
2061
|
var import_sdk5 = require("@hook-sdk/sdk");
|
|
2030
2062
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2063
|
+
function ensureInitialized(defaultLocale, supportedLocales, resources, initialLocale) {
|
|
2064
|
+
if (import_i18next.default.isInitialized) return;
|
|
2065
|
+
import_i18next.default.use(import_react_i18next.initReactI18next).init({
|
|
2066
|
+
resources: Object.fromEntries(
|
|
2067
|
+
supportedLocales.map((l) => [l, { translation: resources[l] ?? {} }])
|
|
2068
|
+
),
|
|
2069
|
+
lng: initialLocale,
|
|
2070
|
+
fallbackLng: defaultLocale,
|
|
2071
|
+
interpolation: { escapeValue: false },
|
|
2072
|
+
// useTranslation suspends by default until i18next is "ready". Inline
|
|
2073
|
+
// resources are sync, so suspending creates a guaranteed empty render
|
|
2074
|
+
// tick — confusing in apps and breaks tests that don't use Suspense.
|
|
2075
|
+
react: { useSuspense: false }
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
function I18nProvider({
|
|
2079
|
+
defaultLocale,
|
|
2080
|
+
supportedLocales,
|
|
2081
|
+
resources,
|
|
2082
|
+
children
|
|
2083
|
+
}) {
|
|
2084
|
+
const [userLocale] = (0, import_sdk5.usePersistedState)("user-locale", defaultLocale);
|
|
2085
|
+
ensureInitialized(defaultLocale, supportedLocales, resources, userLocale);
|
|
2086
|
+
(0, import_react12.useEffect)(() => {
|
|
2087
|
+
if (import_i18next.default.isInitialized && import_i18next.default.language !== userLocale) {
|
|
2088
|
+
import_i18next.default.changeLanguage(userLocale);
|
|
2089
|
+
}
|
|
2090
|
+
}, [userLocale]);
|
|
2091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_i18next.I18nextProvider, { i18n: import_i18next.default, children });
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
// src/internal/PaymentReturnHandler.tsx
|
|
2095
|
+
var import_react13 = require("react");
|
|
2096
|
+
var import_sdk6 = require("@hook-sdk/sdk");
|
|
2097
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2031
2098
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
2032
2099
|
var MAX_CYCLES = 3;
|
|
2033
2100
|
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
2034
2101
|
function PaymentReturnHandler({ children }) {
|
|
2035
|
-
const { subscription } = (0,
|
|
2036
|
-
const subRef = (0,
|
|
2102
|
+
const { subscription } = (0, import_sdk6.useHook)();
|
|
2103
|
+
const subRef = (0, import_react13.useRef)(subscription);
|
|
2037
2104
|
subRef.current = subscription;
|
|
2038
|
-
const runIdRef = (0,
|
|
2039
|
-
const cyclesRef = (0,
|
|
2040
|
-
const [state, setState] = (0,
|
|
2041
|
-
const runPoll = (0,
|
|
2105
|
+
const runIdRef = (0, import_react13.useRef)(0);
|
|
2106
|
+
const cyclesRef = (0, import_react13.useRef)(0);
|
|
2107
|
+
const [state, setState] = (0, import_react13.useState)("idle");
|
|
2108
|
+
const runPoll = (0, import_react13.useCallback)(() => {
|
|
2042
2109
|
const runId = ++runIdRef.current;
|
|
2043
2110
|
cyclesRef.current += 1;
|
|
2044
2111
|
setState("confirming");
|
|
@@ -2073,7 +2140,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2073
2140
|
};
|
|
2074
2141
|
void tick();
|
|
2075
2142
|
}, []);
|
|
2076
|
-
(0,
|
|
2143
|
+
(0, import_react13.useEffect)(() => {
|
|
2077
2144
|
if (typeof window === "undefined") return;
|
|
2078
2145
|
const url = new URL(window.location.href);
|
|
2079
2146
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -2083,26 +2150,26 @@ function PaymentReturnHandler({ children }) {
|
|
|
2083
2150
|
runIdRef.current++;
|
|
2084
2151
|
};
|
|
2085
2152
|
}, [runPoll]);
|
|
2086
|
-
const goHome = (0,
|
|
2153
|
+
const goHome = (0, import_react13.useCallback)(() => {
|
|
2087
2154
|
const cleanUrl = new URL(window.location.href);
|
|
2088
2155
|
cleanUrl.searchParams.delete("paymentReturn");
|
|
2089
2156
|
cleanUrl.pathname = "/app/home";
|
|
2090
2157
|
window.location.href = cleanUrl.toString();
|
|
2091
2158
|
}, []);
|
|
2092
2159
|
if (state === "confirming") {
|
|
2093
|
-
return /* @__PURE__ */ (0,
|
|
2160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
|
|
2094
2161
|
}
|
|
2095
2162
|
if (state === "waiting") {
|
|
2096
|
-
return /* @__PURE__ */ (0,
|
|
2097
|
-
/* @__PURE__ */ (0,
|
|
2098
|
-
/* @__PURE__ */ (0,
|
|
2163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
|
|
2099
2166
|
] }) });
|
|
2100
2167
|
}
|
|
2101
2168
|
if (state === "timeout") {
|
|
2102
|
-
return /* @__PURE__ */ (0,
|
|
2103
|
-
/* @__PURE__ */ (0,
|
|
2104
|
-
/* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.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." }),
|
|
2171
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2106
2173
|
"button",
|
|
2107
2174
|
{
|
|
2108
2175
|
type: "button",
|
|
@@ -2115,7 +2182,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2115
2182
|
children: "Tentar de novo"
|
|
2116
2183
|
}
|
|
2117
2184
|
),
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2119
2186
|
"button",
|
|
2120
2187
|
{
|
|
2121
2188
|
type: "button",
|
|
@@ -2125,7 +2192,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2125
2192
|
children: "Voltar pro app"
|
|
2126
2193
|
}
|
|
2127
2194
|
),
|
|
2128
|
-
/* @__PURE__ */ (0,
|
|
2195
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2129
2196
|
"a",
|
|
2130
2197
|
{
|
|
2131
2198
|
href: SUPPORT_MAILTO,
|
|
@@ -2137,7 +2204,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2137
2204
|
] })
|
|
2138
2205
|
] }) });
|
|
2139
2206
|
}
|
|
2140
|
-
return /* @__PURE__ */ (0,
|
|
2207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_jsx_runtime20.Fragment, { children });
|
|
2141
2208
|
}
|
|
2142
2209
|
var overlayStyle2 = {
|
|
2143
2210
|
position: "fixed",
|
|
@@ -2176,7 +2243,7 @@ var linkStyle = {
|
|
|
2176
2243
|
};
|
|
2177
2244
|
|
|
2178
2245
|
// src/AppRoot.tsx
|
|
2179
|
-
var
|
|
2246
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2180
2247
|
function buildLegacyConfigShim(config) {
|
|
2181
2248
|
const paywall = config.paywall;
|
|
2182
2249
|
const isFree = paywall.mode === "free";
|
|
@@ -2249,32 +2316,47 @@ function AppRoot(props) {
|
|
|
2249
2316
|
"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
|
|
2250
2317
|
);
|
|
2251
2318
|
}
|
|
2252
|
-
const legacyShim = (0,
|
|
2319
|
+
const legacyShim = (0, import_react14.useMemo)(() => buildLegacyConfigShim(config), [config]);
|
|
2253
2320
|
const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
|
|
2254
2321
|
const basename = `/app/${config.slug}`;
|
|
2255
2322
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
/* @__PURE__ */ (0,
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2323
|
+
const position = config.install_prompt?.position ?? "post-paywall";
|
|
2324
|
+
const subscriptionGated = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: position === "post-paywall" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(InstallGate, { position: "post-paywall", children: [
|
|
2325
|
+
children,
|
|
2326
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PushPrompt, {})
|
|
2327
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
2328
|
+
children,
|
|
2329
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PushPrompt, {})
|
|
2330
|
+
] }) });
|
|
2331
|
+
const authGated = /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2332
|
+
AuthGated,
|
|
2333
|
+
{
|
|
2334
|
+
config,
|
|
2335
|
+
Login,
|
|
2336
|
+
Signup,
|
|
2337
|
+
Forgot,
|
|
2338
|
+
Reset,
|
|
2339
|
+
EmailVerify,
|
|
2340
|
+
Paywall,
|
|
2341
|
+
Onboarding,
|
|
2342
|
+
PreAuthFlow,
|
|
2343
|
+
children: subscriptionGated
|
|
2344
|
+
}
|
|
2345
|
+
);
|
|
2346
|
+
const routedTree = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Router, { ...routerProps, children: [
|
|
2347
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
|
|
2348
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SessionExpiredBanner, {}),
|
|
2349
|
+
position === "pre-auth" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(InstallGate, { position: "pre-auth", children: authGated }) : authGated
|
|
2350
|
+
] });
|
|
2351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: config.i18n ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2352
|
+
I18nProvider,
|
|
2353
|
+
{
|
|
2354
|
+
defaultLocale: config.i18n.defaultLocale,
|
|
2355
|
+
supportedLocales: config.i18n.supportedLocales,
|
|
2356
|
+
resources: config.i18n.resources,
|
|
2357
|
+
children: routedTree
|
|
2358
|
+
}
|
|
2359
|
+
) : routedTree }) }) }) }) });
|
|
2278
2360
|
}
|
|
2279
2361
|
function AuthGated({
|
|
2280
2362
|
children,
|
|
@@ -2286,37 +2368,37 @@ function AuthGated({
|
|
|
2286
2368
|
EmailVerify,
|
|
2287
2369
|
PreAuthFlow
|
|
2288
2370
|
}) {
|
|
2289
|
-
const { authStatus } = (0,
|
|
2371
|
+
const { authStatus } = (0, import_sdk7.useHook)();
|
|
2290
2372
|
if (authStatus === "loading") return null;
|
|
2291
2373
|
if (authStatus !== "authenticated") {
|
|
2292
2374
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
2293
|
-
return /* @__PURE__ */ (0,
|
|
2294
|
-
/* @__PURE__ */ (0,
|
|
2295
|
-
/* @__PURE__ */ (0,
|
|
2296
|
-
/* @__PURE__ */ (0,
|
|
2297
|
-
/* @__PURE__ */ (0,
|
|
2298
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2299
|
-
/* @__PURE__ */ (0,
|
|
2375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2376
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Login, {}) }),
|
|
2377
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Signup, {}) }),
|
|
2378
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Forgot, {}) }),
|
|
2379
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Reset, {}) }),
|
|
2380
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmailVerify, {}) }) : null,
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PreAuthFlow, {}) })
|
|
2300
2382
|
] });
|
|
2301
2383
|
}
|
|
2302
|
-
return /* @__PURE__ */ (0,
|
|
2303
|
-
/* @__PURE__ */ (0,
|
|
2304
|
-
/* @__PURE__ */ (0,
|
|
2305
|
-
/* @__PURE__ */ (0,
|
|
2306
|
-
/* @__PURE__ */ (0,
|
|
2307
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2308
|
-
/* @__PURE__ */ (0,
|
|
2384
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Login, {}) }),
|
|
2386
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Signup, {}) }),
|
|
2387
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Forgot, {}) }),
|
|
2388
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Reset, {}) }),
|
|
2389
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(EmailVerify, {}) }) : null,
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
|
|
2309
2391
|
] });
|
|
2310
2392
|
}
|
|
2311
|
-
return /* @__PURE__ */ (0,
|
|
2393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children });
|
|
2312
2394
|
}
|
|
2313
2395
|
function FallbackPaywall() {
|
|
2314
2396
|
return null;
|
|
2315
2397
|
}
|
|
2316
2398
|
|
|
2317
2399
|
// src/hooks/usePush.ts
|
|
2318
|
-
var
|
|
2319
|
-
var
|
|
2400
|
+
var import_react15 = require("react");
|
|
2401
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
2320
2402
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2321
2403
|
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2322
2404
|
function detectIosNeedsInstall() {
|
|
@@ -2360,12 +2442,12 @@ function deriveState(push) {
|
|
|
2360
2442
|
return { kind: "prompt" };
|
|
2361
2443
|
}
|
|
2362
2444
|
function usePush() {
|
|
2363
|
-
const { push } = (0,
|
|
2364
|
-
const [state, setState] = (0,
|
|
2365
|
-
(0,
|
|
2445
|
+
const { push } = (0, import_sdk8.useHook)();
|
|
2446
|
+
const [state, setState] = (0, import_react15.useState)(() => deriveState(push));
|
|
2447
|
+
(0, import_react15.useEffect)(() => {
|
|
2366
2448
|
setState(deriveState(push));
|
|
2367
2449
|
}, [push]);
|
|
2368
|
-
const subscribe = (0,
|
|
2450
|
+
const subscribe = (0, import_react15.useCallback)(async () => {
|
|
2369
2451
|
try {
|
|
2370
2452
|
await push.subscribe();
|
|
2371
2453
|
setState({ kind: "subscribed" });
|
|
@@ -2377,7 +2459,7 @@ function usePush() {
|
|
|
2377
2459
|
throw e;
|
|
2378
2460
|
}
|
|
2379
2461
|
}, [push]);
|
|
2380
|
-
const unsubscribe = (0,
|
|
2462
|
+
const unsubscribe = (0, import_react15.useCallback)(async () => {
|
|
2381
2463
|
try {
|
|
2382
2464
|
await push.unsubscribe();
|
|
2383
2465
|
setState({ kind: "prompt" });
|
|
@@ -2386,7 +2468,7 @@ function usePush() {
|
|
|
2386
2468
|
throw e;
|
|
2387
2469
|
}
|
|
2388
2470
|
}, [push]);
|
|
2389
|
-
const dismiss = (0,
|
|
2471
|
+
const dismiss = (0, import_react15.useCallback)(() => {
|
|
2390
2472
|
if (typeof localStorage !== "undefined") {
|
|
2391
2473
|
try {
|
|
2392
2474
|
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
|
|
@@ -2399,7 +2481,7 @@ function usePush() {
|
|
|
2399
2481
|
}
|
|
2400
2482
|
|
|
2401
2483
|
// src/components/PushPrompt.tsx
|
|
2402
|
-
var
|
|
2484
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2403
2485
|
function platformRecoveryCopy(texts) {
|
|
2404
2486
|
if (typeof navigator === "undefined") return null;
|
|
2405
2487
|
const ua = navigator.userAgent || "";
|
|
@@ -2422,28 +2504,28 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2422
2504
|
const { state, subscribe } = usePush();
|
|
2423
2505
|
if (state.kind === "subscribed" || state.kind === "dismissed") return null;
|
|
2424
2506
|
if (state.kind === "ios_needs_install") {
|
|
2425
|
-
return /* @__PURE__ */ (0,
|
|
2426
|
-
/* @__PURE__ */ (0,
|
|
2427
|
-
/* @__PURE__ */ (0,
|
|
2428
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0,
|
|
2507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2508
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { children: texts.iosInstallTitle }),
|
|
2509
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: texts.iosInstallBody }),
|
|
2510
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
2429
2511
|
] });
|
|
2430
2512
|
}
|
|
2431
2513
|
if (state.kind === "denied") {
|
|
2432
2514
|
const recovery = platformRecoveryCopy(texts);
|
|
2433
|
-
return /* @__PURE__ */ (0,
|
|
2434
|
-
/* @__PURE__ */ (0,
|
|
2435
|
-
/* @__PURE__ */ (0,
|
|
2436
|
-
recovery && /* @__PURE__ */ (0,
|
|
2515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
|
|
2516
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { children: texts.deniedTitle }),
|
|
2517
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: texts.deniedBody }),
|
|
2518
|
+
recovery && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { "data-testid": "denied-recovery", children: recovery })
|
|
2437
2519
|
] });
|
|
2438
2520
|
}
|
|
2439
2521
|
if (state.kind === "unsupported") {
|
|
2440
|
-
return /* @__PURE__ */ (0,
|
|
2522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: texts.unsupportedBody }) });
|
|
2441
2523
|
}
|
|
2442
2524
|
if (state.kind === "error") {
|
|
2443
|
-
return /* @__PURE__ */ (0,
|
|
2525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: state.message }) });
|
|
2444
2526
|
}
|
|
2445
|
-
return /* @__PURE__ */ (0,
|
|
2446
|
-
/* @__PURE__ */ (0,
|
|
2527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, role: "region", children: [
|
|
2528
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2447
2529
|
"button",
|
|
2448
2530
|
{
|
|
2449
2531
|
type: "button",
|
|
@@ -2457,41 +2539,67 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2457
2539
|
children: texts.cta
|
|
2458
2540
|
}
|
|
2459
2541
|
),
|
|
2460
|
-
onDeclined && /* @__PURE__ */ (0,
|
|
2542
|
+
onDeclined && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
2543
|
+
] });
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
// src/components/LanguageSwitcher.tsx
|
|
2547
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
2548
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2549
|
+
function LanguageSwitcher({ id, className, label = "Language" }) {
|
|
2550
|
+
const config = useAppConfig();
|
|
2551
|
+
const i18nConfig = config.i18n;
|
|
2552
|
+
const [userLocale, setUserLocale] = (0, import_sdk9.usePersistedState)(
|
|
2553
|
+
"user-locale",
|
|
2554
|
+
i18nConfig?.defaultLocale ?? "en-US"
|
|
2555
|
+
);
|
|
2556
|
+
if (!i18nConfig) return null;
|
|
2557
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className, children: [
|
|
2558
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: label }) : null,
|
|
2559
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2560
|
+
"select",
|
|
2561
|
+
{
|
|
2562
|
+
id,
|
|
2563
|
+
value: userLocale,
|
|
2564
|
+
onChange: (e) => setUserLocale(e.target.value),
|
|
2565
|
+
"data-testid": "language-switcher",
|
|
2566
|
+
children: i18nConfig.supportedLocales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: loc, children: loc }, loc))
|
|
2567
|
+
}
|
|
2568
|
+
)
|
|
2461
2569
|
] });
|
|
2462
2570
|
}
|
|
2463
2571
|
|
|
2464
2572
|
// src/defaults/LoadingState.tsx
|
|
2465
|
-
var
|
|
2573
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2466
2574
|
function LoadingState({ message }) {
|
|
2467
|
-
return /* @__PURE__ */ (0,
|
|
2575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: message ?? "Carregando..." }) });
|
|
2468
2576
|
}
|
|
2469
2577
|
|
|
2470
2578
|
// src/defaults/EmptyState.tsx
|
|
2471
|
-
var
|
|
2579
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2472
2580
|
function EmptyState({ title, description, action }) {
|
|
2473
|
-
return /* @__PURE__ */ (0,
|
|
2474
|
-
/* @__PURE__ */ (0,
|
|
2475
|
-
description && /* @__PURE__ */ (0,
|
|
2476
|
-
action && /* @__PURE__ */ (0,
|
|
2581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2583
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { style: { opacity: 0.7 }, children: description }),
|
|
2584
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { style: { marginTop: 16 }, children: action })
|
|
2477
2585
|
] });
|
|
2478
2586
|
}
|
|
2479
2587
|
|
|
2480
2588
|
// src/hooks/useLoginForm.ts
|
|
2481
|
-
var
|
|
2482
|
-
var
|
|
2589
|
+
var import_react16 = require("react");
|
|
2590
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
2483
2591
|
|
|
2484
2592
|
// src/errors.ts
|
|
2485
|
-
var
|
|
2593
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
2486
2594
|
function mapSdkError(err) {
|
|
2487
|
-
if (err instanceof
|
|
2595
|
+
if (err instanceof import_sdk10.SdkRateLimitError) {
|
|
2488
2596
|
return {
|
|
2489
2597
|
code: "rate_limited",
|
|
2490
2598
|
message: `Aguarde ${err.retryAfter}s e tente novamente.`,
|
|
2491
2599
|
retryAfter: err.retryAfter
|
|
2492
2600
|
};
|
|
2493
2601
|
}
|
|
2494
|
-
if (err instanceof
|
|
2602
|
+
if (err instanceof import_sdk10.SdkAuthError) {
|
|
2495
2603
|
const detail = err.detail;
|
|
2496
2604
|
if (detail === "email_unverified") {
|
|
2497
2605
|
return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
|
|
@@ -2501,7 +2609,7 @@ function mapSdkError(err) {
|
|
|
2501
2609
|
}
|
|
2502
2610
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2503
2611
|
}
|
|
2504
|
-
if (err instanceof
|
|
2612
|
+
if (err instanceof import_sdk10.SdkError && err.httpStatus === 0) {
|
|
2505
2613
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2506
2614
|
}
|
|
2507
2615
|
if (err instanceof TypeError) {
|
|
@@ -2514,20 +2622,20 @@ function mapSdkError(err) {
|
|
|
2514
2622
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2515
2623
|
var MIN_PASSWORD = 8;
|
|
2516
2624
|
function useLoginForm() {
|
|
2517
|
-
const { auth } = (0,
|
|
2518
|
-
const [email, setEmail] = (0,
|
|
2519
|
-
const [password, setPassword] = (0,
|
|
2520
|
-
const [submitting, setSubmitting] = (0,
|
|
2521
|
-
const [error, setError] = (0,
|
|
2522
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2523
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2524
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2525
|
-
const validateEmail = (0,
|
|
2625
|
+
const { auth } = (0, import_sdk11.useHook)();
|
|
2626
|
+
const [email, setEmail] = (0, import_react16.useState)("");
|
|
2627
|
+
const [password, setPassword] = (0, import_react16.useState)("");
|
|
2628
|
+
const [submitting, setSubmitting] = (0, import_react16.useState)(false);
|
|
2629
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
2630
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react16.useState)(false);
|
|
2631
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react16.useState)(false);
|
|
2632
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react16.useState)(false);
|
|
2633
|
+
const validateEmail = (0, import_react16.useMemo)(() => {
|
|
2526
2634
|
if (email.length === 0) return null;
|
|
2527
2635
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2528
2636
|
return null;
|
|
2529
2637
|
}, [email]);
|
|
2530
|
-
const validatePassword = (0,
|
|
2638
|
+
const validatePassword = (0, import_react16.useMemo)(() => {
|
|
2531
2639
|
if (password.length === 0) return null;
|
|
2532
2640
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
2533
2641
|
return null;
|
|
@@ -2535,7 +2643,7 @@ function useLoginForm() {
|
|
|
2535
2643
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2536
2644
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2537
2645
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
|
|
2538
|
-
const submit = (0,
|
|
2646
|
+
const submit = (0, import_react16.useCallback)(async () => {
|
|
2539
2647
|
setFormSubmitAttempted(true);
|
|
2540
2648
|
if (!canSubmit) return false;
|
|
2541
2649
|
setSubmitting(true);
|
|
@@ -2569,32 +2677,32 @@ function useLoginForm() {
|
|
|
2569
2677
|
}
|
|
2570
2678
|
|
|
2571
2679
|
// src/hooks/useSignupForm.ts
|
|
2572
|
-
var
|
|
2573
|
-
var
|
|
2680
|
+
var import_react17 = require("react");
|
|
2681
|
+
var import_sdk12 = require("@hook-sdk/sdk");
|
|
2574
2682
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2575
2683
|
var MIN_PASSWORD2 = 8;
|
|
2576
2684
|
function useSignupForm() {
|
|
2577
|
-
const { auth } = (0,
|
|
2578
|
-
const [name, setName] = (0,
|
|
2579
|
-
const [email, setEmail] = (0,
|
|
2580
|
-
const [password, setPassword] = (0,
|
|
2581
|
-
const [submitting, setSubmitting] = (0,
|
|
2582
|
-
const [error, setError] = (0,
|
|
2583
|
-
const [touchedName, setTouchedName] = (0,
|
|
2584
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2585
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2586
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2587
|
-
const validateName = (0,
|
|
2685
|
+
const { auth } = (0, import_sdk12.useHook)();
|
|
2686
|
+
const [name, setName] = (0, import_react17.useState)("");
|
|
2687
|
+
const [email, setEmail] = (0, import_react17.useState)("");
|
|
2688
|
+
const [password, setPassword] = (0, import_react17.useState)("");
|
|
2689
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2690
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2691
|
+
const [touchedName, setTouchedName] = (0, import_react17.useState)(false);
|
|
2692
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react17.useState)(false);
|
|
2693
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react17.useState)(false);
|
|
2694
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react17.useState)(false);
|
|
2695
|
+
const validateName = (0, import_react17.useMemo)(() => {
|
|
2588
2696
|
if (name.length === 0) return null;
|
|
2589
2697
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2590
2698
|
return null;
|
|
2591
2699
|
}, [name]);
|
|
2592
|
-
const validateEmail = (0,
|
|
2700
|
+
const validateEmail = (0, import_react17.useMemo)(() => {
|
|
2593
2701
|
if (email.length === 0) return null;
|
|
2594
2702
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2595
2703
|
return null;
|
|
2596
2704
|
}, [email]);
|
|
2597
|
-
const validatePassword = (0,
|
|
2705
|
+
const validatePassword = (0, import_react17.useMemo)(() => {
|
|
2598
2706
|
if (password.length === 0) return null;
|
|
2599
2707
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
2600
2708
|
return null;
|
|
@@ -2603,7 +2711,7 @@ function useSignupForm() {
|
|
|
2603
2711
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2604
2712
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2605
2713
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
|
|
2606
|
-
const submit = (0,
|
|
2714
|
+
const submit = (0, import_react17.useCallback)(async () => {
|
|
2607
2715
|
setFormSubmitAttempted(true);
|
|
2608
2716
|
if (!canSubmit) return false;
|
|
2609
2717
|
setSubmitting(true);
|
|
@@ -2641,25 +2749,25 @@ function useSignupForm() {
|
|
|
2641
2749
|
}
|
|
2642
2750
|
|
|
2643
2751
|
// src/hooks/useForgotForm.ts
|
|
2644
|
-
var
|
|
2645
|
-
var
|
|
2752
|
+
var import_react18 = require("react");
|
|
2753
|
+
var import_sdk13 = require("@hook-sdk/sdk");
|
|
2646
2754
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2647
2755
|
function useForgotForm() {
|
|
2648
|
-
const { auth } = (0,
|
|
2649
|
-
const [email, setEmail] = (0,
|
|
2650
|
-
const [submitting, setSubmitting] = (0,
|
|
2651
|
-
const [sent, setSent] = (0,
|
|
2652
|
-
const [error, setError] = (0,
|
|
2653
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2654
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2655
|
-
const validateEmail = (0,
|
|
2756
|
+
const { auth } = (0, import_sdk13.useHook)();
|
|
2757
|
+
const [email, setEmail] = (0, import_react18.useState)("");
|
|
2758
|
+
const [submitting, setSubmitting] = (0, import_react18.useState)(false);
|
|
2759
|
+
const [sent, setSent] = (0, import_react18.useState)(false);
|
|
2760
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
2761
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react18.useState)(false);
|
|
2762
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react18.useState)(false);
|
|
2763
|
+
const validateEmail = (0, import_react18.useMemo)(() => {
|
|
2656
2764
|
if (email.length === 0) return null;
|
|
2657
2765
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2658
2766
|
return null;
|
|
2659
2767
|
}, [email]);
|
|
2660
2768
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2661
2769
|
const canSubmit = email.length > 0 && validateEmail === null && !submitting;
|
|
2662
|
-
const submit = (0,
|
|
2770
|
+
const submit = (0, import_react18.useCallback)(async () => {
|
|
2663
2771
|
setFormSubmitAttempted(true);
|
|
2664
2772
|
if (!canSubmit) return false;
|
|
2665
2773
|
setSubmitting(true);
|
|
@@ -2690,32 +2798,32 @@ function useForgotForm() {
|
|
|
2690
2798
|
}
|
|
2691
2799
|
|
|
2692
2800
|
// src/hooks/useResetForm.ts
|
|
2693
|
-
var
|
|
2694
|
-
var
|
|
2801
|
+
var import_react19 = require("react");
|
|
2802
|
+
var import_sdk14 = require("@hook-sdk/sdk");
|
|
2695
2803
|
var MIN_PASSWORD3 = 12;
|
|
2696
2804
|
function useResetForm() {
|
|
2697
|
-
const { auth } = (0,
|
|
2698
|
-
const [token, setToken] = (0,
|
|
2699
|
-
const [password, setPassword] = (0,
|
|
2700
|
-
const [confirm, setConfirm] = (0,
|
|
2701
|
-
const [submitting, setSubmitting] = (0,
|
|
2702
|
-
const [done, setDone] = (0,
|
|
2703
|
-
const [error, setError] = (0,
|
|
2704
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2705
|
-
const [touchedConfirm, setTouchedConfirm] = (0,
|
|
2706
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2707
|
-
(0,
|
|
2805
|
+
const { auth } = (0, import_sdk14.useHook)();
|
|
2806
|
+
const [token, setToken] = (0, import_react19.useState)(null);
|
|
2807
|
+
const [password, setPassword] = (0, import_react19.useState)("");
|
|
2808
|
+
const [confirm, setConfirm] = (0, import_react19.useState)("");
|
|
2809
|
+
const [submitting, setSubmitting] = (0, import_react19.useState)(false);
|
|
2810
|
+
const [done, setDone] = (0, import_react19.useState)(false);
|
|
2811
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
2812
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react19.useState)(false);
|
|
2813
|
+
const [touchedConfirm, setTouchedConfirm] = (0, import_react19.useState)(false);
|
|
2814
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react19.useState)(false);
|
|
2815
|
+
(0, import_react19.useEffect)(() => {
|
|
2708
2816
|
if (typeof window === "undefined") return;
|
|
2709
2817
|
const params = new URLSearchParams(window.location.search);
|
|
2710
2818
|
const t = params.get("token");
|
|
2711
2819
|
setToken(t && t.length > 0 ? t : null);
|
|
2712
2820
|
}, []);
|
|
2713
|
-
const validatePassword = (0,
|
|
2821
|
+
const validatePassword = (0, import_react19.useMemo)(() => {
|
|
2714
2822
|
if (password.length === 0) return null;
|
|
2715
2823
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
2716
2824
|
return null;
|
|
2717
2825
|
}, [password]);
|
|
2718
|
-
const validateConfirm = (0,
|
|
2826
|
+
const validateConfirm = (0, import_react19.useMemo)(() => {
|
|
2719
2827
|
if (confirm.length === 0) return null;
|
|
2720
2828
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
2721
2829
|
return null;
|
|
@@ -2723,7 +2831,7 @@ function useResetForm() {
|
|
|
2723
2831
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2724
2832
|
const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
|
|
2725
2833
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
|
|
2726
|
-
const submit = (0,
|
|
2834
|
+
const submit = (0, import_react19.useCallback)(async () => {
|
|
2727
2835
|
setFormSubmitAttempted(true);
|
|
2728
2836
|
if (!canSubmit || token === null) return;
|
|
2729
2837
|
setSubmitting(true);
|
|
@@ -2763,9 +2871,9 @@ function useResetForm() {
|
|
|
2763
2871
|
}
|
|
2764
2872
|
|
|
2765
2873
|
// src/hooks/usePlan.ts
|
|
2766
|
-
var
|
|
2874
|
+
var import_sdk15 = require("@hook-sdk/sdk");
|
|
2767
2875
|
function usePlan() {
|
|
2768
|
-
const { plan } = (0,
|
|
2876
|
+
const { plan } = (0, import_sdk15.useHook)();
|
|
2769
2877
|
return plan;
|
|
2770
2878
|
}
|
|
2771
2879
|
|
|
@@ -2798,12 +2906,12 @@ function discountPercent(anchorCents, realCents) {
|
|
|
2798
2906
|
}
|
|
2799
2907
|
|
|
2800
2908
|
// src/hooks/useAuthPrimitives.ts
|
|
2801
|
-
var
|
|
2802
|
-
var
|
|
2909
|
+
var import_react20 = require("react");
|
|
2910
|
+
var import_sdk16 = require("@hook-sdk/sdk");
|
|
2803
2911
|
var warned = false;
|
|
2804
2912
|
function useAuthPrimitives() {
|
|
2805
|
-
const { auth } = (0,
|
|
2806
|
-
(0,
|
|
2913
|
+
const { auth } = (0, import_sdk16.useHook)();
|
|
2914
|
+
(0, import_react20.useEffect)(() => {
|
|
2807
2915
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
2808
2916
|
warned = true;
|
|
2809
2917
|
console.warn(
|
|
@@ -2825,9 +2933,9 @@ function useAuthPrimitives() {
|
|
|
2825
2933
|
}
|
|
2826
2934
|
|
|
2827
2935
|
// src/hooks/useAuth.ts
|
|
2828
|
-
var
|
|
2936
|
+
var import_sdk17 = require("@hook-sdk/sdk");
|
|
2829
2937
|
function useAuth() {
|
|
2830
|
-
const { user, authStatus, auth } = (0,
|
|
2938
|
+
const { user, authStatus, auth } = (0, import_sdk17.useHook)();
|
|
2831
2939
|
return {
|
|
2832
2940
|
user,
|
|
2833
2941
|
authStatus,
|
|
@@ -2836,26 +2944,26 @@ function useAuth() {
|
|
|
2836
2944
|
}
|
|
2837
2945
|
|
|
2838
2946
|
// src/index.ts
|
|
2839
|
-
var
|
|
2947
|
+
var import_sdk21 = require("@hook-sdk/sdk");
|
|
2840
2948
|
|
|
2841
2949
|
// src/hooks/useSubscription.ts
|
|
2842
|
-
var
|
|
2950
|
+
var import_sdk18 = require("@hook-sdk/sdk");
|
|
2843
2951
|
function useSubscription() {
|
|
2844
|
-
const { subscription } = (0,
|
|
2952
|
+
const { subscription } = (0, import_sdk18.useHook)();
|
|
2845
2953
|
return {
|
|
2846
2954
|
status: subscription.status()
|
|
2847
2955
|
};
|
|
2848
2956
|
}
|
|
2849
2957
|
|
|
2850
2958
|
// src/hooks/useReminders.ts
|
|
2851
|
-
var
|
|
2852
|
-
var
|
|
2959
|
+
var import_react21 = require("react");
|
|
2960
|
+
var import_sdk19 = require("@hook-sdk/sdk");
|
|
2853
2961
|
function useReminders() {
|
|
2854
|
-
const { push } = (0,
|
|
2962
|
+
const { push } = (0, import_sdk19.useHook)();
|
|
2855
2963
|
const r = push.reminders;
|
|
2856
|
-
const [reminders, setReminders] = (0,
|
|
2857
|
-
const [loading, setLoading] = (0,
|
|
2858
|
-
const reload = (0,
|
|
2964
|
+
const [reminders, setReminders] = (0, import_react21.useState)([]);
|
|
2965
|
+
const [loading, setLoading] = (0, import_react21.useState)(true);
|
|
2966
|
+
const reload = (0, import_react21.useCallback)(async () => {
|
|
2859
2967
|
setLoading(true);
|
|
2860
2968
|
try {
|
|
2861
2969
|
const next = await r.list();
|
|
@@ -2864,38 +2972,38 @@ function useReminders() {
|
|
|
2864
2972
|
setLoading(false);
|
|
2865
2973
|
}
|
|
2866
2974
|
}, [r]);
|
|
2867
|
-
(0,
|
|
2975
|
+
(0, import_react21.useEffect)(() => {
|
|
2868
2976
|
void reload();
|
|
2869
2977
|
}, [reload]);
|
|
2870
|
-
const setReminder = (0,
|
|
2978
|
+
const setReminder = (0, import_react21.useCallback)(async (input) => {
|
|
2871
2979
|
await r.set(input);
|
|
2872
2980
|
await reload();
|
|
2873
2981
|
}, [r, reload]);
|
|
2874
|
-
const deleteReminder = (0,
|
|
2982
|
+
const deleteReminder = (0, import_react21.useCallback)(async (slot) => {
|
|
2875
2983
|
await r.delete(slot);
|
|
2876
2984
|
await reload();
|
|
2877
2985
|
}, [r, reload]);
|
|
2878
|
-
const schedule = (0,
|
|
2986
|
+
const schedule = (0, import_react21.useCallback)(async (items) => {
|
|
2879
2987
|
return r.schedule(items);
|
|
2880
2988
|
}, [r]);
|
|
2881
|
-
const setFallbacks = (0,
|
|
2989
|
+
const setFallbacks = (0, import_react21.useCallback)(async (items) => {
|
|
2882
2990
|
return r.setFallbacks(items);
|
|
2883
2991
|
}, [r]);
|
|
2884
2992
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
2885
2993
|
}
|
|
2886
2994
|
|
|
2887
2995
|
// src/hooks/useToast.ts
|
|
2888
|
-
var
|
|
2996
|
+
var import_react22 = require("react");
|
|
2889
2997
|
function useToast() {
|
|
2890
|
-
const [items, setItems] = (0,
|
|
2891
|
-
const show = (0,
|
|
2998
|
+
const [items, setItems] = (0, import_react22.useState)([]);
|
|
2999
|
+
const show = (0, import_react22.useCallback)((message, kind = "info") => {
|
|
2892
3000
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2893
3001
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
2894
3002
|
setTimeout(() => {
|
|
2895
3003
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2896
3004
|
}, 4e3);
|
|
2897
3005
|
}, []);
|
|
2898
|
-
const dismiss = (0,
|
|
3006
|
+
const dismiss = (0, import_react22.useCallback)((id) => {
|
|
2899
3007
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2900
3008
|
}, []);
|
|
2901
3009
|
return { items, show, dismiss };
|
|
@@ -2903,20 +3011,20 @@ function useToast() {
|
|
|
2903
3011
|
|
|
2904
3012
|
// src/RouteBoundary.tsx
|
|
2905
3013
|
var import_react_router_dom3 = require("react-router-dom");
|
|
2906
|
-
var
|
|
3014
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2907
3015
|
function RouteBoundary({ children }) {
|
|
2908
|
-
return /* @__PURE__ */ (0,
|
|
3016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react_router_dom3.Routes, { children: [
|
|
2909
3017
|
children,
|
|
2910
|
-
/* @__PURE__ */ (0,
|
|
3018
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_router_dom3.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DefaultNotFound, {}) })
|
|
2911
3019
|
] });
|
|
2912
3020
|
}
|
|
2913
3021
|
function DefaultNotFound() {
|
|
2914
|
-
return /* @__PURE__ */ (0,
|
|
3022
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
|
|
2915
3023
|
}
|
|
2916
3024
|
|
|
2917
3025
|
// src/PreAuthShell.tsx
|
|
2918
3026
|
var import_react_router_dom4 = require("react-router-dom");
|
|
2919
|
-
var
|
|
3027
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2920
3028
|
function PreAuthShell({
|
|
2921
3029
|
basename,
|
|
2922
3030
|
testRouter,
|
|
@@ -2924,20 +3032,20 @@ function PreAuthShell({
|
|
|
2924
3032
|
children
|
|
2925
3033
|
}) {
|
|
2926
3034
|
if (testRouter === "memory") {
|
|
2927
|
-
return /* @__PURE__ */ (0,
|
|
3035
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_router_dom4.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
2928
3036
|
}
|
|
2929
|
-
return /* @__PURE__ */ (0,
|
|
3037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_router_dom4.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
2930
3038
|
}
|
|
2931
3039
|
|
|
2932
3040
|
// src/OnboardingFlow.tsx
|
|
2933
|
-
var
|
|
2934
|
-
var
|
|
3041
|
+
var import_react24 = require("react");
|
|
3042
|
+
var import_sdk20 = require("@hook-sdk/sdk");
|
|
2935
3043
|
|
|
2936
3044
|
// src/hooks/useOnboardingStep.ts
|
|
2937
|
-
var
|
|
2938
|
-
var OnboardingStepContext = (0,
|
|
3045
|
+
var import_react23 = require("react");
|
|
3046
|
+
var OnboardingStepContext = (0, import_react23.createContext)(null);
|
|
2939
3047
|
function useOnboardingStep() {
|
|
2940
|
-
const ctx = (0,
|
|
3048
|
+
const ctx = (0, import_react23.useContext)(OnboardingStepContext);
|
|
2941
3049
|
if (!ctx) {
|
|
2942
3050
|
throw new Error(
|
|
2943
3051
|
"[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
|
|
@@ -2947,7 +3055,7 @@ function useOnboardingStep() {
|
|
|
2947
3055
|
}
|
|
2948
3056
|
|
|
2949
3057
|
// src/OnboardingFlow.tsx
|
|
2950
|
-
var
|
|
3058
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2951
3059
|
var isFilled = (v) => v != null && v !== "";
|
|
2952
3060
|
var CURRENT_STEP_FIELD = "currentStep";
|
|
2953
3061
|
function readPersistedStepIdx(draft) {
|
|
@@ -2960,12 +3068,12 @@ function OnboardingFlow({
|
|
|
2960
3068
|
onComplete,
|
|
2961
3069
|
persistKey
|
|
2962
3070
|
}) {
|
|
2963
|
-
const [draft, setDraft, status] = (0,
|
|
2964
|
-
const draftRef = (0,
|
|
3071
|
+
const [draft, setDraft, status] = (0, import_sdk20.usePersistedState)(persistKey, {});
|
|
3072
|
+
const draftRef = (0, import_react24.useRef)(draft);
|
|
2965
3073
|
draftRef.current = draft;
|
|
2966
3074
|
const idx = readPersistedStepIdx(draft);
|
|
2967
3075
|
const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
|
|
2968
|
-
const setIdx = (0,
|
|
3076
|
+
const setIdx = (0, import_react24.useCallback)(
|
|
2969
3077
|
(n) => {
|
|
2970
3078
|
setDraft((prev) => {
|
|
2971
3079
|
const prevIdx = readPersistedStepIdx(prev);
|
|
@@ -2975,7 +3083,7 @@ function OnboardingFlow({
|
|
|
2975
3083
|
},
|
|
2976
3084
|
[setDraft]
|
|
2977
3085
|
);
|
|
2978
|
-
const setValue = (0,
|
|
3086
|
+
const setValue = (0, import_react24.useCallback)(
|
|
2979
3087
|
(patch) => {
|
|
2980
3088
|
draftRef.current = { ...draftRef.current, ...patch };
|
|
2981
3089
|
setDraft((prev) => ({ ...prev, ...patch }));
|
|
@@ -2983,9 +3091,9 @@ function OnboardingFlow({
|
|
|
2983
3091
|
[setDraft]
|
|
2984
3092
|
);
|
|
2985
3093
|
const step = steps[clampedIdx];
|
|
2986
|
-
const hookCtx = (0,
|
|
3094
|
+
const hookCtx = (0, import_sdk20.useHook)();
|
|
2987
3095
|
const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
|
|
2988
|
-
(0,
|
|
3096
|
+
(0, import_react24.useEffect)(() => {
|
|
2989
3097
|
if (status.loading) return;
|
|
2990
3098
|
if (!step) return;
|
|
2991
3099
|
if (!track2) return;
|
|
@@ -2995,11 +3103,11 @@ function OnboardingFlow({
|
|
|
2995
3103
|
total_steps: steps.length
|
|
2996
3104
|
});
|
|
2997
3105
|
}, [step?.id, clampedIdx, steps.length, status.loading, track2]);
|
|
2998
|
-
const valid = (0,
|
|
3106
|
+
const valid = (0, import_react24.useMemo)(
|
|
2999
3107
|
() => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
|
|
3000
3108
|
[draft, step]
|
|
3001
3109
|
);
|
|
3002
|
-
const next = (0,
|
|
3110
|
+
const next = (0, import_react24.useCallback)(() => {
|
|
3003
3111
|
if (!step) return;
|
|
3004
3112
|
const current = draftRef.current;
|
|
3005
3113
|
const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
|
|
@@ -3010,8 +3118,8 @@ function OnboardingFlow({
|
|
|
3010
3118
|
setIdx(clampedIdx + 1);
|
|
3011
3119
|
}
|
|
3012
3120
|
}, [clampedIdx, onComplete, step, steps.length, setIdx]);
|
|
3013
|
-
const prevStep = (0,
|
|
3014
|
-
const ctx = (0,
|
|
3121
|
+
const prevStep = (0, import_react24.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
|
|
3122
|
+
const ctx = (0, import_react24.useMemo)(
|
|
3015
3123
|
() => ({
|
|
3016
3124
|
stepIndex: clampedIdx,
|
|
3017
3125
|
totalSteps: steps.length,
|
|
@@ -3037,7 +3145,7 @@ function OnboardingFlow({
|
|
|
3037
3145
|
`[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
|
|
3038
3146
|
);
|
|
3039
3147
|
}
|
|
3040
|
-
return /* @__PURE__ */ (0,
|
|
3148
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Screen, {}) });
|
|
3041
3149
|
}
|
|
3042
3150
|
|
|
3043
3151
|
// src/hooks/useFeature.ts
|
|
@@ -3053,8 +3161,10 @@ function useFeature(name) {
|
|
|
3053
3161
|
DeepLinkHandler,
|
|
3054
3162
|
EmptyState,
|
|
3055
3163
|
ErrorBoundary,
|
|
3164
|
+
I18nProvider,
|
|
3056
3165
|
InstallGate,
|
|
3057
3166
|
InstallSplash,
|
|
3167
|
+
LanguageSwitcher,
|
|
3058
3168
|
LoadingState,
|
|
3059
3169
|
OnboardingFlow,
|
|
3060
3170
|
PaymentReturnHandler,
|