@hook-sdk/template 0.1.1 → 0.1.2
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/README.md +51 -0
- package/dist/index.cjs +100 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -4
- package/dist/index.d.ts +26 -4
- package/dist/index.js +112 -33
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @hook-sdk/template
|
|
2
|
+
|
|
3
|
+
Primitivas do golden-path para apps Hook — `AppRoot`, providers internos, hooks headless de auth (`useLoginForm`, `useSignupForm`, `useForgotForm`), estado de paywall (`usePaywallState`) e escape hatch `useAuthPrimitives`.
|
|
4
|
+
|
|
5
|
+
Os apps consomem esse pacote via `import { AppRoot } from '@hook-sdk/template'` no `source.jsx`. Visual fica livre dentro de `screens/`; a lógica de auth/paywall/push é blindada por esses hooks.
|
|
6
|
+
|
|
7
|
+
## Uso básico
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { AppRoot } from '@hook-sdk/template';
|
|
11
|
+
import LoginScreen from './screens/Login';
|
|
12
|
+
import PaywallScreen from './screens/Paywall';
|
|
13
|
+
|
|
14
|
+
export default function App() {
|
|
15
|
+
return <AppRoot Login={LoginScreen} Paywall={PaywallScreen} />;
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Spec
|
|
20
|
+
|
|
21
|
+
Estrutura técnica detalhada: `docs/19-golden-template.md` + `docs/adr/012-golden-template.md` (e amendment 2026-04-19).
|
|
22
|
+
|
|
23
|
+
## Comandos
|
|
24
|
+
|
|
25
|
+
- `bun run test` — Vitest unit suite
|
|
26
|
+
- `bun run build` — gera `dist/` (CJS + ESM + .d.ts) via tsup
|
|
27
|
+
- `bun run typecheck` — `tsc --noEmit`
|
|
28
|
+
|
|
29
|
+
## Release flow (maintainers)
|
|
30
|
+
|
|
31
|
+
CI publica via `.github/workflows/publish-packages.yml` quando uma release com tag `template-v*` é criada.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# 1. Bump version
|
|
35
|
+
$EDITOR template/package.json # ex: 0.1.1 → 0.1.2
|
|
36
|
+
|
|
37
|
+
# 2. Commit + push
|
|
38
|
+
git commit -am "chore(template): bump to 0.1.2"
|
|
39
|
+
git push origin main
|
|
40
|
+
|
|
41
|
+
# 3. Tag release (workflow detecta tag, valida que template/package.json bate, publica)
|
|
42
|
+
gh release create template-v0.1.2 --generate-notes --title "template v0.1.2"
|
|
43
|
+
|
|
44
|
+
# 4. Confirma
|
|
45
|
+
gh run watch
|
|
46
|
+
npm view @hook-sdk/template@0.1.2
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pré-requisitos: secret `NPM_TOKEN` no repo (granular `@hook-sdk` scope, "Allow bypassing 2FA" ✅). Workflow falha cedo se a versão na tag não bater com `template/package.json`.
|
|
50
|
+
|
|
51
|
+
> **Ordering note:** `template/package.json` declara `"@hook-sdk/sdk": "workspace:*"`. `bun publish` resolve isso para a versão SDK atualmente publicada na npm no momento do publish. Se você quer que um release de template use uma versão SDK específica, publique o SDK primeiro.
|
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,10 @@ __export(index_exports, {
|
|
|
42
42
|
});
|
|
43
43
|
module.exports = __toCommonJS(index_exports);
|
|
44
44
|
|
|
45
|
+
// src/AppRoot.tsx
|
|
46
|
+
var import_react10 = require("react");
|
|
47
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
48
|
+
|
|
45
49
|
// src/internal/TemplateConfigContext.tsx
|
|
46
50
|
var import_react = require("react");
|
|
47
51
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -50,7 +54,11 @@ function TemplateConfigProvider({
|
|
|
50
54
|
config,
|
|
51
55
|
children
|
|
52
56
|
}) {
|
|
53
|
-
|
|
57
|
+
const value = (0, import_react.useMemo)(() => ({
|
|
58
|
+
...config,
|
|
59
|
+
mode: config.subscription?.mode ?? "trial"
|
|
60
|
+
}), [config]);
|
|
61
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TemplateConfigContext.Provider, { value, children });
|
|
54
62
|
}
|
|
55
63
|
function useTemplateConfig() {
|
|
56
64
|
const ctx = (0, import_react.useContext)(TemplateConfigContext);
|
|
@@ -166,11 +174,17 @@ function usePaywallState() {
|
|
|
166
174
|
|
|
167
175
|
// src/internal/SubscriptionGate.tsx
|
|
168
176
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
177
|
+
var BLOCKING = /* @__PURE__ */ new Set([
|
|
178
|
+
"pending",
|
|
179
|
+
"expired",
|
|
180
|
+
"canceled",
|
|
181
|
+
"none"
|
|
182
|
+
]);
|
|
169
183
|
function SubscriptionGate({ Paywall, children }) {
|
|
184
|
+
const { mode } = useTemplateConfig();
|
|
170
185
|
const { status } = usePaywallState();
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
}
|
|
186
|
+
if (mode === "free") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
|
|
187
|
+
if (BLOCKING.has(status)) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Paywall, {});
|
|
174
188
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
|
|
175
189
|
}
|
|
176
190
|
|
|
@@ -255,13 +269,15 @@ function useLoginForm() {
|
|
|
255
269
|
}, [password]);
|
|
256
270
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
|
|
257
271
|
const submit = (0, import_react5.useCallback)(async () => {
|
|
258
|
-
if (!canSubmit) return;
|
|
272
|
+
if (!canSubmit) return false;
|
|
259
273
|
setSubmitting(true);
|
|
260
274
|
setError(null);
|
|
261
275
|
try {
|
|
262
276
|
await auth.login({ email, password });
|
|
277
|
+
return true;
|
|
263
278
|
} catch (err) {
|
|
264
279
|
setError(mapSdkError(err));
|
|
280
|
+
return false;
|
|
265
281
|
} finally {
|
|
266
282
|
setSubmitting(false);
|
|
267
283
|
}
|
|
@@ -376,13 +392,15 @@ function useSignupForm() {
|
|
|
376
392
|
}, [password]);
|
|
377
393
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
|
|
378
394
|
const submit = (0, import_react6.useCallback)(async () => {
|
|
379
|
-
if (!canSubmit) return;
|
|
395
|
+
if (!canSubmit) return false;
|
|
380
396
|
setSubmitting(true);
|
|
381
397
|
setError(null);
|
|
382
398
|
try {
|
|
383
399
|
await auth.signup({ name, email, password });
|
|
400
|
+
return true;
|
|
384
401
|
} catch (err) {
|
|
385
402
|
setError(mapSdkError(err));
|
|
403
|
+
return false;
|
|
386
404
|
} finally {
|
|
387
405
|
setSubmitting(false);
|
|
388
406
|
}
|
|
@@ -455,14 +473,16 @@ function useForgotForm() {
|
|
|
455
473
|
}, [email]);
|
|
456
474
|
const canSubmit = email.length > 0 && emailError === null && !submitting;
|
|
457
475
|
const submit = (0, import_react7.useCallback)(async () => {
|
|
458
|
-
if (!canSubmit) return;
|
|
476
|
+
if (!canSubmit) return false;
|
|
459
477
|
setSubmitting(true);
|
|
460
478
|
setError(null);
|
|
461
479
|
try {
|
|
462
480
|
await auth.forgot({ email });
|
|
463
481
|
setSent(true);
|
|
482
|
+
return true;
|
|
464
483
|
} catch (err) {
|
|
465
484
|
setError(mapSdkError(err));
|
|
485
|
+
return false;
|
|
466
486
|
} finally {
|
|
467
487
|
setSubmitting(false);
|
|
468
488
|
}
|
|
@@ -677,6 +697,65 @@ function DefaultPaywall() {
|
|
|
677
697
|
|
|
678
698
|
// src/AppRoot.tsx
|
|
679
699
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
700
|
+
function PaymentReturnHandler({ children }) {
|
|
701
|
+
const { subscription } = (0, import_sdk8.useHook)();
|
|
702
|
+
const [confirming, setConfirming] = (0, import_react10.useState)(false);
|
|
703
|
+
(0, import_react10.useEffect)(() => {
|
|
704
|
+
if (typeof window === "undefined") return;
|
|
705
|
+
const url = new URL(window.location.href);
|
|
706
|
+
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
707
|
+
let cancelled = false;
|
|
708
|
+
let attempts = 0;
|
|
709
|
+
setConfirming(true);
|
|
710
|
+
const tick = async () => {
|
|
711
|
+
if (cancelled) return;
|
|
712
|
+
if (attempts >= 10) {
|
|
713
|
+
setConfirming(false);
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
attempts++;
|
|
717
|
+
try {
|
|
718
|
+
await subscription.refresh();
|
|
719
|
+
} catch {
|
|
720
|
+
}
|
|
721
|
+
if (cancelled) return;
|
|
722
|
+
if (subscription.status() === "active") {
|
|
723
|
+
const cleanUrl = new URL(window.location.href);
|
|
724
|
+
cleanUrl.searchParams.delete("paymentReturn");
|
|
725
|
+
window.history.replaceState({}, "", cleanUrl.toString());
|
|
726
|
+
setConfirming(false);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
setTimeout(tick, 1e3);
|
|
730
|
+
};
|
|
731
|
+
void tick();
|
|
732
|
+
return () => {
|
|
733
|
+
cancelled = true;
|
|
734
|
+
};
|
|
735
|
+
}, [subscription]);
|
|
736
|
+
if (confirming) {
|
|
737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
738
|
+
"div",
|
|
739
|
+
{
|
|
740
|
+
role: "status",
|
|
741
|
+
"aria-live": "polite",
|
|
742
|
+
style: {
|
|
743
|
+
position: "fixed",
|
|
744
|
+
inset: 0,
|
|
745
|
+
display: "flex",
|
|
746
|
+
alignItems: "center",
|
|
747
|
+
justifyContent: "center",
|
|
748
|
+
background: "rgba(0,0,0,0.4)",
|
|
749
|
+
zIndex: 9999,
|
|
750
|
+
color: "white",
|
|
751
|
+
fontSize: "1rem"
|
|
752
|
+
},
|
|
753
|
+
children: "Confirmando pagamento\u2026"
|
|
754
|
+
}
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children });
|
|
758
|
+
}
|
|
680
759
|
function AppRoot({
|
|
681
760
|
config,
|
|
682
761
|
children,
|
|
@@ -686,10 +765,10 @@ function AppRoot({
|
|
|
686
765
|
Reset = DefaultResetScreen,
|
|
687
766
|
Paywall = DefaultPaywall
|
|
688
767
|
}) {
|
|
689
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TemplateConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(SubscriptionGate, { Paywall, children: [
|
|
768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PaymentReturnHandler, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TemplateConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(SubscriptionGate, { Paywall, children: [
|
|
690
769
|
children,
|
|
691
770
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PushPrompt, {})
|
|
692
|
-
] }) }) }) }) });
|
|
771
|
+
] }) }) }) }) }) });
|
|
693
772
|
}
|
|
694
773
|
|
|
695
774
|
// src/defaults/EmptyState.tsx
|
|
@@ -703,12 +782,12 @@ function EmptyState({ title, description, action }) {
|
|
|
703
782
|
}
|
|
704
783
|
|
|
705
784
|
// src/hooks/useAuthPrimitives.ts
|
|
706
|
-
var
|
|
707
|
-
var
|
|
785
|
+
var import_react11 = require("react");
|
|
786
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
708
787
|
var warned = false;
|
|
709
788
|
function useAuthPrimitives() {
|
|
710
|
-
const { auth } = (0,
|
|
711
|
-
(0,
|
|
789
|
+
const { auth } = (0, import_sdk9.useHook)();
|
|
790
|
+
(0, import_react11.useEffect)(() => {
|
|
712
791
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
713
792
|
warned = true;
|
|
714
793
|
console.warn(
|
|
@@ -730,18 +809,18 @@ function useAuthPrimitives() {
|
|
|
730
809
|
}
|
|
731
810
|
|
|
732
811
|
// src/hooks/useSubscription.ts
|
|
733
|
-
var
|
|
812
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
734
813
|
function useSubscription() {
|
|
735
|
-
const { subscription } = (0,
|
|
814
|
+
const { subscription } = (0, import_sdk10.useHook)();
|
|
736
815
|
return {
|
|
737
816
|
status: subscription.status()
|
|
738
817
|
};
|
|
739
818
|
}
|
|
740
819
|
|
|
741
820
|
// src/hooks/usePush.ts
|
|
742
|
-
var
|
|
821
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
743
822
|
function usePush() {
|
|
744
|
-
const { push } = (0,
|
|
823
|
+
const { push } = (0, import_sdk11.useHook)();
|
|
745
824
|
return {
|
|
746
825
|
status: push.status(),
|
|
747
826
|
subscribe: push.subscribe,
|
|
@@ -750,17 +829,17 @@ function usePush() {
|
|
|
750
829
|
}
|
|
751
830
|
|
|
752
831
|
// src/hooks/useToast.ts
|
|
753
|
-
var
|
|
832
|
+
var import_react12 = require("react");
|
|
754
833
|
function useToast() {
|
|
755
|
-
const [items, setItems] = (0,
|
|
756
|
-
const show = (0,
|
|
834
|
+
const [items, setItems] = (0, import_react12.useState)([]);
|
|
835
|
+
const show = (0, import_react12.useCallback)((message, kind = "info") => {
|
|
757
836
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
758
837
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
759
838
|
setTimeout(() => {
|
|
760
839
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
761
840
|
}, 4e3);
|
|
762
841
|
}, []);
|
|
763
|
-
const dismiss = (0,
|
|
842
|
+
const dismiss = (0, import_react12.useCallback)((id) => {
|
|
764
843
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
765
844
|
}, []);
|
|
766
845
|
return { items, show, dismiss };
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/internal/TemplateConfigContext.tsx","../src/internal/ThemeProvider.tsx","../src/internal/AuthGate.tsx","../src/hooks/useAuth.ts","../src/defaults/LoadingState.tsx","../src/hooks/usePaywallState.ts","../src/internal/SubscriptionGate.tsx","../src/internal/PushPrompt.tsx","../src/defaults/ErrorBoundary.tsx","../src/hooks/useLoginForm.ts","../src/errors.ts","../src/defaults/DefaultLoginScreen.tsx","../src/hooks/useSignupForm.ts","../src/defaults/DefaultSignupScreen.tsx","../src/hooks/useForgotForm.ts","../src/defaults/DefaultForgotScreen.tsx","../src/hooks/useResetForm.ts","../src/defaults/DefaultResetScreen.tsx","../src/defaults/DefaultPaywall.tsx","../src/AppRoot.tsx","../src/defaults/EmptyState.tsx","../src/hooks/useAuthPrimitives.ts","../src/hooks/useSubscription.ts","../src/hooks/usePush.ts","../src/hooks/useToast.ts"],"sourcesContent":["// Entry point\nexport { AppRoot, type AppRootProps } from './AppRoot';\n\n// Defaults\nexport { DefaultLoginScreen, type AuthScreenProps, type AuthScreen } from './defaults/DefaultLoginScreen';\nexport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nexport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nexport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nexport { DefaultPaywall } from './defaults/DefaultPaywall';\nexport { LoadingState } from './defaults/LoadingState';\nexport { EmptyState } from './defaults/EmptyState';\nexport { ErrorBoundary } from './defaults/ErrorBoundary';\n\n// Hooks padrão\nexport { useLoginForm, type UseLoginFormResult } from './hooks/useLoginForm';\nexport { useSignupForm } from './hooks/useSignupForm';\nexport { useForgotForm } from './hooks/useForgotForm';\nexport { useResetForm, type UseResetFormResult } from './hooks/useResetForm';\nexport { usePaywallState, type SubscriptionStatus } from './hooks/usePaywallState';\n\n// Escape hatch\nexport { useAuthPrimitives } from './hooks/useAuthPrimitives';\n\n// Convenience\nexport { useAuth } from './hooks/useAuth';\nexport { useSubscription } from './hooks/useSubscription';\nexport { usePush } from './hooks/usePush';\nexport { useToast, type ToastItem } from './hooks/useToast';\n\n// Types\nexport type { AuthFormError, AuthFormErrorCode } from './errors';\n","import { createContext, useContext, type ReactNode } from 'react';\nimport type { AppConfig } from '../../../scripts/schemas/app-config';\n\nconst TemplateConfigContext = createContext<AppConfig | null>(null);\n\nexport function TemplateConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n return (\n <TemplateConfigContext.Provider value={config}>\n {children}\n </TemplateConfigContext.Provider>\n );\n}\n\nexport function useTemplateConfig(): AppConfig {\n const ctx = useContext(TemplateConfigContext);\n if (ctx === null) {\n throw new Error('useTemplateConfig must be used inside <TemplateConfigProvider>');\n }\n return ctx;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const config = useTemplateConfig();\n const style = {\n '--hook-color-primary': config.theme.primary_color,\n ...(config.theme.background_color && {\n '--hook-color-background': config.theme.background_color,\n }),\n } as CSSProperties;\n\n return <div style={style}>{children}</div>;\n}\n","import { useEffect, useState, type ComponentType, type ReactNode } from 'react';\nimport { useAuth } from '../hooks/useAuth';\nimport { LoadingState } from '../defaults/LoadingState';\nimport type { AuthScreenProps, AuthScreen } from '../defaults/DefaultLoginScreen';\n\ninterface Props {\n Login: ComponentType<AuthScreenProps>;\n Signup: ComponentType<AuthScreenProps>;\n Forgot: ComponentType<AuthScreenProps>;\n Reset: ComponentType<AuthScreenProps>;\n children: ReactNode;\n}\n\n/**\n * Detecta `?token=` + `?screen=reset` na URL — link do email de password_reset.\n * Se presente E user não autenticado, força tela Reset antes do Login default.\n *\n * `useResetForm` limpa `?token=&screen=reset` via `history.replaceState` após\n * reset bem-sucedido — evita re-dispatch do Reset no próximo logout (F22\n * follow-up descoberto no smoke).\n *\n * Query é snapshot no mount + re-avalia em popstate (permite link aberto em\n * tab já montada). Não re-avalia em re-render normal; AuthGate remontar seria\n * indicador de reset state mal-limpado.\n */\nfunction detectResetFromUrl(): boolean {\n if (typeof window === 'undefined') return false;\n const params = new URLSearchParams(window.location.search);\n return params.get('token') !== null && params.get('screen') === 'reset';\n}\n\nexport function AuthGate({ Login, Signup, Forgot, Reset, children }: Props) {\n const { user, authStatus } = useAuth();\n const [screen, setScreen] = useState<AuthScreen>(() =>\n detectResetFromUrl() ? 'reset' : 'login',\n );\n\n // Reset é fluxo exclusivamente pre-auth. Se user autenticou (login OU logout\n // que recicla useAuth state), AuthGate volta pra 'login' default.\n // Isso corrige F22 follow-up: logout pós-reset jogava user de volta no Reset\n // porque ?token= ainda estava na URL (fix principal é clear URL no useResetForm,\n // este é cinto-e-suspensório).\n useEffect(() => {\n if (user && screen !== 'login') {\n setScreen('login');\n }\n }, [user, screen]);\n\n // Se URL mudar em runtime (SPA navigation), re-avalia. Raro mas permite\n // e-mail abrir em tab já montada.\n useEffect(() => {\n const onPop = () => {\n if (detectResetFromUrl()) setScreen('reset');\n };\n window.addEventListener('popstate', onPop);\n return () => window.removeEventListener('popstate', onPop);\n }, []);\n\n if (authStatus === 'loading') return <LoadingState />;\n if (!user) {\n if (screen === 'reset') return <Reset onNavigate={setScreen} />;\n if (screen === 'signup') return <Signup onNavigate={setScreen} />;\n if (screen === 'forgot') return <Forgot onNavigate={setScreen} />;\n return <Login onNavigate={setScreen} />;\n }\n return <>{children}</>;\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`\n * pros consumidores que não precisam das methods completas do auth.\n */\nexport function useAuth() {\n const { user, authStatus, auth } = useHook();\n return {\n user,\n authStatus,\n refresh: auth.refresh,\n };\n}\n","export function LoadingState({ message }: { message?: string }) {\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ padding: 24, textAlign: 'center' }}>\n <span>{message ?? 'Carregando...'}</span>\n </div>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'none';\n\n/**\n * Hook headless pro Paywall. Expõe status atual da subscription + ação\n * `checkout(cpf)` que chama `POST /payments/checkout/card` e redireciona\n * o browser pro `invoiceUrl` hosted do Asaas. Após o checkout, Asaas\n * redireciona de volta com query string indicativa; subscription real\n * é atualizada via webhook (`PAYMENT_RECEIVED` / `SUBSCRIPTION_ACTIVATED`).\n *\n * MVP: checkout só cartão. Pix vem depois (gatilho documentado em P10.7).\n */\nexport function usePaywallState() {\n const { subscription } = useHook();\n const [opening, setOpening] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n\n const checkout = useCallback(\n async (args: { cpf: string; cycle?: 'MONTHLY' | 'YEARLY' }) => {\n setOpening(true);\n setError(null);\n try {\n const result = await subscription.checkoutCard({\n cpf: args.cpf,\n cycle: args.cycle ?? 'MONTHLY',\n });\n // Redireciona pro checkout hosted do Asaas. Após confirmação,\n // Asaas redireciona de volta e webhook atualiza DB.\n window.location.href = result.invoiceUrl;\n } catch (err) {\n setError(err as Error);\n setOpening(false); // só reseta em erro; success navega away\n }\n },\n [subscription],\n );\n\n const cancel = useCallback(async () => {\n try {\n await subscription.cancel();\n await subscription.refresh();\n } catch (err) {\n setError(err as Error);\n }\n }, [subscription]);\n\n return { status, daysLeftInTrial, checkout, cancel, opening, error };\n}\n","import type { ComponentType, ReactNode } from 'react';\nimport { usePaywallState } from '../hooks/usePaywallState';\n\ninterface Props {\n Paywall: ComponentType;\n children: ReactNode;\n}\n\nexport function SubscriptionGate({ Paywall, children }: Props) {\n const { status } = usePaywallState();\n // MVP: stub retorna 'none' — não bloqueia. Quando P10 entregar real,\n // 'expired'|'canceled'|'past_due' bloqueiam com Paywall.\n if (status === 'expired' || status === 'canceled' || status === 'past_due') {\n return <Paywall />;\n }\n return <>{children}</>;\n}\n","// Side-effect-only component: observa estado e dispara push.subscribe() quando\n// apropriado. NUNCA renderiza UI bloqueante — sempre retorna null. No MVP, o SDK\n// stub de push lança 'unsupported_mvp', então este componente não faz nada.\n// Quando P14 entregar VAPID real, adicionar gate por 2ª sessão + dismissed_at.\nexport function PushPrompt() {\n return null;\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error) {\n console.error('[ErrorBoundary] caught', error);\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback ?? (\n <div role=\"alert\" style={{ padding: 24, textAlign: 'center' }}>\n <h2>Algo deu errado</h2>\n <p style={{ opacity: 0.7 }}>Recarregue a página pra tentar de novo.</p>\n </div>\n );\n }\n return <>{this.props.children}</>;\n }\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseLoginFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useLoginForm(): UseLoginFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.login({ email, password });\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, password, canSubmit]);\n\n return {\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { SdkError, SdkAuthError, SdkRateLimitError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\n | 'account_locked'\n | 'network'\n | 'server';\n\nexport interface AuthFormError {\n code: AuthFormErrorCode;\n message: string;\n retryAfter?: number;\n}\n\n/**\n * Mapeia SdkError do @hook-sdk/sdk pra AuthFormError tipado do template.\n * Usado por useLoginForm/useSignupForm/useForgotForm.\n */\nexport function mapSdkError(err: unknown): AuthFormError {\n if (err instanceof SdkRateLimitError) {\n return {\n code: 'rate_limited',\n message: `Aguarde ${err.retryAfter}s e tente novamente.`,\n retryAfter: err.retryAfter,\n };\n }\n if (err instanceof SdkAuthError) {\n const detail = (err as { detail?: string }).detail;\n if (detail === 'email_unverified') {\n return { code: 'email_unverified', message: 'Confirme seu e-mail antes de entrar.' };\n }\n if (detail === 'account_locked') {\n return { code: 'account_locked', message: 'Conta bloqueada. Contate o suporte.' };\n }\n return { code: 'invalid_credentials', message: 'E-mail ou senha inválidos.' };\n }\n if (err instanceof SdkError && err.httpStatus === 0) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n // Falhas de rede em POST/PATCH/DELETE não são envolvidas em SdkError pelo\n // HttpClient (só GET tem retry wrap). fetch() lança TypeError cru — tratamos\n // como 'network' pra manter UX consistente com GETs.\n if (err instanceof TypeError) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n return { code: 'server', message: 'Algo deu errado. Tente novamente em instantes.' };\n}\n","import { useLoginForm } from '../hooks/useLoginForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport type AuthScreen = 'login' | 'signup' | 'forgot' | 'reset';\nexport interface AuthScreenProps {\n onNavigate: (to: AuthScreen) => void;\n}\n\nexport function DefaultLoginScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useLoginForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Entre na sua conta</p>\n\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input\n data-testid=\"login-email\"\n type=\"email\"\n value={f.email}\n onChange={(e) => f.setEmail(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input\n data-testid=\"login-password\"\n type=\"password\"\n value={f.password}\n onChange={(e) => f.setPassword(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n\n {f.error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {f.error.message}\n </div>\n )}\n\n <button\n data-testid=\"login-submit\"\n type=\"submit\"\n disabled={!f.canSubmit}\n style={{\n width: '100%', padding: 12,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: f.canSubmit ? 1 : 0.5,\n }}\n >\n {f.submitting ? 'Entrando...' : 'Entrar'}\n </button>\n </form>\n\n <div style={{ marginTop: 16, display: 'flex', justifyContent: 'space-between' }}>\n <button data-testid=\"login-goto-signup\" type=\"button\" onClick={() => onNavigate('signup')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Criar conta\n </button>\n <button data-testid=\"login-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Esqueci senha\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseSignupFormResult {\n name: string;\n setName: (v: string) => void;\n nameError: string | null;\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useSignupForm(): UseSignupFormResult {\n const { auth } = useHook();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const nameError = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n name.trim().length >= 2 &&\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n nameError === null &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.signup({ name, email, password });\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, name, email, password, canSubmit]);\n\n return {\n name, setName, nameError,\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { useSignupForm } from '../hooks/useSignupForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultSignupScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useSignupForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Criar sua conta</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nome\n <input data-testid=\"signup-name\" value={f.name} onChange={(e) => f.setName(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.nameError && <small style={{ color: '#c00' }}>{f.nameError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"signup-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input data-testid=\"signup-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"signup-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Criando...' : 'Criar conta'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"signup-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Já tem conta? Entre\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface UseForgotFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n sent: boolean;\n error: AuthFormError | null;\n}\n\nexport function useForgotForm(): UseForgotFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [sent, setSent] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const canSubmit = email.length > 0 && emailError === null && !submitting;\n\n const submit = useCallback(async () => {\n if (!canSubmit) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.forgot({ email });\n setSent(true);\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, canSubmit]);\n\n return {\n email, setEmail, emailError,\n submit, submitting, canSubmit, sent, error,\n };\n}\n","import { useForgotForm } from '../hooks/useForgotForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultForgotScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useForgotForm();\n\n if (f.sent) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Verifique seu e-mail</h1>\n <p style={{ opacity: 0.7 }}>Enviamos um link pra redefinir sua senha.</p>\n <button data-testid=\"forgot-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Voltar pro login</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Redefinir senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"forgot-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"forgot-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Enviando...' : 'Enviar link'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"forgot-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Voltar pro login\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst MIN_PASSWORD = 12;\n\nexport interface UseResetFormResult {\n /** Token JWT lido de `?token=` da URL. null se ausente. */\n token: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n confirm: string;\n setConfirm: (v: string) => void;\n confirmError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n /** true após submit 200. UI deve mostrar \"senha alterada, volte pro login\". */\n done: boolean;\n error: AuthFormError | null;\n}\n\n/**\n * Hook headless pro fluxo de reset de senha via link do email.\n *\n * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).\n * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar\n * mensagem \"link inválido\".\n *\n * Após submit 200, todos os refresh tokens do user são revogados pelo\n * backend (forçar re-login). UI deve direcionar pra LoginScreen.\n */\nexport function useResetForm(): UseResetFormResult {\n const { auth } = useHook();\n const [token, setToken] = useState<string | null>(null);\n const [password, setPassword] = useState('');\n const [confirm, setConfirm] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [done, setDone] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n useEffect(() => {\n // Snapshot no mount. URL pode ter sido limpa depois (history.replaceState)\n // mas token deve estar no primeiro render.\n if (typeof window === 'undefined') return;\n const params = new URLSearchParams(window.location.search);\n const t = params.get('token');\n setToken(t && t.length > 0 ? t : null);\n }, []);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const confirmError = useMemo(() => {\n if (confirm.length === 0) return null;\n if (confirm !== password) return 'Senhas não coincidem.';\n return null;\n }, [confirm, password]);\n\n const canSubmit =\n token !== null &&\n password.length >= MIN_PASSWORD &&\n confirm === password &&\n passwordError === null &&\n confirmError === null &&\n !submitting &&\n !done;\n\n const submit = useCallback(async () => {\n if (!canSubmit || token === null) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.reset({ token, newPassword: password });\n setDone(true);\n // Limpa `?token=&screen=reset` da URL pra AuthGate não re-disparar Reset\n // em re-renders futuros (logout depois do reset, popstate, etc.).\n // Mantém mesmo path, só strip dos query params de auth.\n if (typeof window !== 'undefined') {\n const url = new URL(window.location.href);\n url.searchParams.delete('token');\n url.searchParams.delete('screen');\n window.history.replaceState({}, '', url.toString());\n }\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, token, password, canSubmit]);\n\n return {\n token,\n password, setPassword, passwordError,\n confirm, setConfirm, confirmError,\n submit, submitting, canSubmit, done, error,\n };\n}\n","import { useResetForm } from '../hooks/useResetForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\n/**\n * Tela default de reset de senha. Renderizada pelo AuthGate quando\n * `?token=` está presente na URL (link vindo do email de password_reset).\n *\n * AuthScreenProps.onNavigate é usado pra voltar pro login após reset\n * bem-sucedido (usuário precisa re-autenticar — backend revoga todos\n * os refresh tokens na chamada de `auth.reset`).\n */\nexport function DefaultResetScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useResetForm();\n\n if (f.done) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Senha alterada</h1>\n <p style={{ opacity: 0.7 }}>Agora é só fazer login com a nova senha.</p>\n <button data-testid=\"reset-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Ir pro login</button>\n </main>\n );\n }\n\n if (f.token === null) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Link inválido</h1>\n <p style={{ opacity: 0.7 }}>Peça um novo link de reset.</p>\n <button data-testid=\"reset-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')}>Pedir novo link</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Escolha uma nova senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nova senha\n <input data-testid=\"reset-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Confirmar senha\n <input data-testid=\"reset-confirm\" type=\"password\" value={f.confirm} onChange={(e) => f.setConfirm(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.confirmError && <small style={{ color: '#c00' }}>{f.confirmError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"reset-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Alterando...' : 'Alterar senha'}\n </button>\n </form>\n </main>\n );\n}\n","import { useState } from 'react';\nimport { usePaywallState } from '../hooks/usePaywallState';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport function DefaultPaywall() {\n const config = useTemplateConfig();\n const { checkout, opening, error } = usePaywallState();\n const p = config.subscription.paywall_config;\n const [cpf, setCpf] = useState('');\n const cpfDigits = cpf.replace(/\\D/g, '');\n const canCheckout = cpfDigits.length === 11 && !opening;\n\n return (\n <main style={{ padding: 24, maxWidth: 440, margin: '0 auto', textAlign: 'center' }}>\n <h1 style={{ marginBottom: 8 }}>{p.title}</h1>\n {p.subtitle && <p style={{ opacity: 0.7, marginBottom: 24 }}>{p.subtitle}</p>}\n\n <ul style={{ listStyle: 'none', padding: 0, textAlign: 'left', marginBottom: 24 }}>\n {p.benefits.map((b) => (\n <li key={b} style={{ padding: '8px 0', display: 'flex', alignItems: 'center' }}>\n <span aria-hidden style={{ marginRight: 8 }}>✓</span>\n <span>{b}</span>\n </li>\n ))}\n </ul>\n\n <div style={{ textAlign: 'left', marginBottom: 16 }}>\n <label style={{ display: 'block', fontSize: 14, opacity: 0.7, marginBottom: 4 }}>\n Seu CPF (pra emissão de recibo)\n </label>\n <input\n data-testid=\"paywall-cpf\"\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"000.000.000-00\"\n value={cpf}\n onChange={(e) => setCpf(e.target.value)}\n style={{ width: '100%', padding: 10, fontSize: 14, borderRadius: 8, border: '1px solid #ccc' }}\n />\n </div>\n\n {error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {error.message}\n </div>\n )}\n\n <button\n data-testid=\"paywall-cta\"\n type=\"button\"\n onClick={() => void checkout({ cpf: cpfDigits })}\n disabled={!canCheckout}\n style={{\n width: '100%', padding: 14,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: canCheckout ? 1 : 0.5,\n fontSize: 16, fontWeight: 600,\n }}\n >\n {opening ? 'Abrindo...' : p.cta}\n </button>\n\n {p.priceHint && <p style={{ opacity: 0.6, marginTop: 12 }}>{p.priceHint}</p>}\n {p.footerNote && <p style={{ opacity: 0.5, marginTop: 16, fontSize: 12 }}>{p.footerNote}</p>}\n </main>\n );\n}\n","/**\n * @golden-path — único componente público do template.\n * Consumidores (apps) usam via: <AppRoot config={appConfig}>{children}</AppRoot>\n * Pra customizar auth/paywall screens: passe Login/Signup/Forgot/Paywall como props.\n *\n * IMPORTANTE: AppRoot NÃO embrulha em <HookProvider>. O shell (frontend/shell/AppLoader.tsx)\n * já embrulha o bundle com config real ({ appId, apiHost: API_HOST }). Embrulhar de novo\n * criaria duplo HookProvider → dois useAuthState + dois HTTP clients no mesmo bundle, e\n * o interno (com apiHost relativo) sobrescreveria o externo via Context mais próximo —\n * quebra em staging/prod onde shell e API moram em hosts distintos.\n *\n * Testes que precisam de HookProvider montam explicitamente no wrapper de teste.\n */\nimport type { ComponentType, ReactNode } from 'react';\nimport type { AppConfig } from '../../scripts/schemas/app-config';\nimport { TemplateConfigProvider } from './internal/TemplateConfigContext';\nimport { ThemeProvider } from './internal/ThemeProvider';\nimport { AuthGate } from './internal/AuthGate';\nimport { SubscriptionGate } from './internal/SubscriptionGate';\nimport { PushPrompt } from './internal/PushPrompt';\nimport { ErrorBoundary } from './defaults/ErrorBoundary';\nimport { DefaultLoginScreen, type AuthScreenProps } from './defaults/DefaultLoginScreen';\nimport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nimport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nimport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nimport { DefaultPaywall } from './defaults/DefaultPaywall';\n\nexport interface AppRootProps {\n config: AppConfig;\n children: ReactNode;\n Login?: ComponentType<AuthScreenProps>;\n Signup?: ComponentType<AuthScreenProps>;\n Forgot?: ComponentType<AuthScreenProps>;\n /**\n * Tela de reset de senha (form com nova senha via link do email).\n * Renderizada pelo AuthGate quando URL tem `?token=` + user não logado.\n * Default: DefaultResetScreen.\n */\n Reset?: ComponentType<AuthScreenProps>;\n Paywall?: ComponentType;\n}\n\nexport function AppRoot({\n config,\n children,\n Login = DefaultLoginScreen,\n Signup = DefaultSignupScreen,\n Forgot = DefaultForgotScreen,\n Reset = DefaultResetScreen,\n Paywall = DefaultPaywall,\n}: AppRootProps) {\n return (\n <TemplateConfigProvider config={config}>\n <ErrorBoundary>\n <ThemeProvider>\n <AuthGate Login={Login} Signup={Signup} Forgot={Forgot} Reset={Reset}>\n <SubscriptionGate Paywall={Paywall}>\n {children}\n <PushPrompt />\n </SubscriptionGate>\n </AuthGate>\n </ThemeProvider>\n </ErrorBoundary>\n </TemplateConfigProvider>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function EmptyState({ title, description, action }: {\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div role=\"status\" style={{ padding: 32, textAlign: 'center' }}>\n <h2 style={{ marginBottom: 8 }}>{title}</h2>\n {description && <p style={{ opacity: 0.7 }}>{description}</p>}\n {action && <div style={{ marginTop: 16 }}>{action}</div>}\n </div>\n );\n}\n","import { useEffect } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nlet warned = false;\n\n/** Test-only: reseta flag pra permitir validar warn uma única vez em re-mounts de test */\nexport function __resetWarnForTest() { warned = false; }\n\n/**\n * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).\n * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.\n */\nexport function useAuthPrimitives() {\n const { auth } = useHook();\n\n useEffect(() => {\n if (!warned && process.env.NODE_ENV !== 'production') {\n warned = true;\n console.warn(\n '[@hook-sdk/template] useAuthPrimitives() é escape hatch. ' +\n 'Pra login/signup/forgot, use useLoginForm/useSignupForm/useForgotForm. ' +\n 'Docs: docs/19-golden-template.md#escape-hatch',\n );\n }\n }, []);\n\n return {\n login: auth.login,\n signup: auth.signup,\n logout: auth.logout,\n logoutAll: auth.logoutAll,\n forgot: auth.forgot,\n resendVerify: auth.resendVerify,\n changePassword: auth.changePassword,\n changeEmail: auth.changeEmail,\n refresh: auth.refresh,\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').\n */\nexport function useSubscription() {\n const { subscription } = useHook();\n return {\n status: subscription.status(),\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `push` do SDK. MVP: stub retorna 'unsupported' no status\n * e subscribe/unsubscribe lançam SdkError. A shape segue o SDK real.\n */\nexport function usePush() {\n const { push } = useHook();\n return {\n status: push.status(),\n subscribe: push.subscribe,\n unsubscribe: push.unsubscribe,\n };\n}\n","import { useCallback, useState } from 'react';\n\nexport interface ToastItem {\n id: string;\n message: string;\n kind: 'info' | 'error' | 'success';\n}\n\n/**\n * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).\n * Não opina sobre UI; retorna items + actions.\n */\nexport function useToast() {\n const [items, setItems] = useState<ToastItem[]>([]);\n\n const show = useCallback((message: string, kind: ToastItem['kind'] = 'info') => {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n setItems((prev) => [...prev, { id, message, kind }]);\n setTimeout(() => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, 4000);\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return { items, show, dismiss };\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_sdk","import_sdk","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","MIN_PASSWORD","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","import_jsx_runtime","import_react","import_sdk","MIN_PASSWORD","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_sdk","import_sdk","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/AppRoot.tsx","../src/internal/TemplateConfigContext.tsx","../src/internal/ThemeProvider.tsx","../src/internal/AuthGate.tsx","../src/hooks/useAuth.ts","../src/defaults/LoadingState.tsx","../src/hooks/usePaywallState.ts","../src/internal/SubscriptionGate.tsx","../src/internal/PushPrompt.tsx","../src/defaults/ErrorBoundary.tsx","../src/hooks/useLoginForm.ts","../src/errors.ts","../src/defaults/DefaultLoginScreen.tsx","../src/hooks/useSignupForm.ts","../src/defaults/DefaultSignupScreen.tsx","../src/hooks/useForgotForm.ts","../src/defaults/DefaultForgotScreen.tsx","../src/hooks/useResetForm.ts","../src/defaults/DefaultResetScreen.tsx","../src/defaults/DefaultPaywall.tsx","../src/defaults/EmptyState.tsx","../src/hooks/useAuthPrimitives.ts","../src/hooks/useSubscription.ts","../src/hooks/usePush.ts","../src/hooks/useToast.ts"],"sourcesContent":["// Entry point\nexport { AppRoot, type AppRootProps } from './AppRoot';\n\n// Defaults\nexport { DefaultLoginScreen, type AuthScreenProps, type AuthScreen } from './defaults/DefaultLoginScreen';\nexport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nexport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nexport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nexport { DefaultPaywall } from './defaults/DefaultPaywall';\nexport { LoadingState } from './defaults/LoadingState';\nexport { EmptyState } from './defaults/EmptyState';\nexport { ErrorBoundary } from './defaults/ErrorBoundary';\n\n// Hooks padrão\nexport { useLoginForm, type UseLoginFormResult } from './hooks/useLoginForm';\nexport { useSignupForm } from './hooks/useSignupForm';\nexport { useForgotForm } from './hooks/useForgotForm';\nexport { useResetForm, type UseResetFormResult } from './hooks/useResetForm';\nexport { usePaywallState, type SubscriptionStatus } from './hooks/usePaywallState';\n\n// Escape hatch\nexport { useAuthPrimitives } from './hooks/useAuthPrimitives';\n\n// Convenience\nexport { useAuth } from './hooks/useAuth';\nexport { useSubscription } from './hooks/useSubscription';\nexport { usePush } from './hooks/usePush';\nexport { useToast, type ToastItem } from './hooks/useToast';\n\n// Types\nexport type { AuthFormError, AuthFormErrorCode } from './errors';\n","/**\n * @golden-path — único componente público do template.\n * Consumidores (apps) usam via: <AppRoot config={appConfig}>{children}</AppRoot>\n * Pra customizar auth/paywall screens: passe Login/Signup/Forgot/Paywall como props.\n *\n * IMPORTANTE: AppRoot NÃO embrulha em <HookProvider>. O shell (frontend/shell/AppLoader.tsx)\n * já embrulha o bundle com config real ({ appId, apiHost: API_HOST }). Embrulhar de novo\n * criaria duplo HookProvider → dois useAuthState + dois HTTP clients no mesmo bundle, e\n * o interno (com apiHost relativo) sobrescreveria o externo via Context mais próximo —\n * quebra em staging/prod onde shell e API moram em hosts distintos.\n *\n * Testes que precisam de HookProvider montam explicitamente no wrapper de teste.\n */\nimport { useEffect, useState, type ComponentType, type ReactNode } from 'react';\nimport type { AppConfig } from '../../scripts/schemas/app-config';\nimport { useHook } from '@hook-sdk/sdk';\nimport { TemplateConfigProvider } from './internal/TemplateConfigContext';\nimport { ThemeProvider } from './internal/ThemeProvider';\nimport { AuthGate } from './internal/AuthGate';\nimport { SubscriptionGate } from './internal/SubscriptionGate';\nimport { PushPrompt } from './internal/PushPrompt';\nimport { ErrorBoundary } from './defaults/ErrorBoundary';\nimport { DefaultLoginScreen, type AuthScreenProps } from './defaults/DefaultLoginScreen';\nimport { DefaultSignupScreen } from './defaults/DefaultSignupScreen';\nimport { DefaultForgotScreen } from './defaults/DefaultForgotScreen';\nimport { DefaultResetScreen } from './defaults/DefaultResetScreen';\nimport { DefaultPaywall } from './defaults/DefaultPaywall';\n\n/**\n * Detecta `?paymentReturn=1` na URL (usuário voltando do checkout Asaas).\n * Polla `subscription.refresh()` 1×/s até 10× ou status=active.\n * Quando active: limpa a query string via history.replaceState.\n * Enquanto polls: mostra overlay \"Confirmando pagamento…\" (F19).\n * Após 10 tentativas sem sucesso: renderiza normalmente (graceful degradation).\n *\n * Precisa estar dentro de <HookProvider> (fornecido pelo shell).\n * Exportado para teste isolado.\n */\nexport function PaymentReturnHandler({ children }: { children: ReactNode }) {\n const { subscription } = useHook();\n const [confirming, setConfirming] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n if (url.searchParams.get('paymentReturn') !== '1') return;\n\n let cancelled = false;\n let attempts = 0;\n setConfirming(true);\n\n const tick = async () => {\n if (cancelled) return;\n if (attempts >= 10) {\n setConfirming(false);\n return;\n }\n attempts++;\n try {\n await subscription.refresh();\n } catch {\n // swallow — próxima tentativa\n }\n if (cancelled) return;\n if (subscription.status() === 'active') {\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n window.history.replaceState({}, '', cleanUrl.toString());\n setConfirming(false);\n return;\n }\n setTimeout(tick, 1000);\n };\n void tick();\n\n return () => {\n cancelled = true;\n };\n // Deliberately [subscription] only — re-run somente se subscription object trocar.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [subscription]);\n\n if (confirming) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n position: 'fixed',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.4)',\n zIndex: 9999,\n color: 'white',\n fontSize: '1rem',\n }}\n >\n Confirmando pagamento…\n </div>\n );\n }\n\n return <>{children}</>;\n}\n\nexport interface AppRootProps {\n config: AppConfig;\n children: ReactNode;\n Login?: ComponentType<AuthScreenProps>;\n Signup?: ComponentType<AuthScreenProps>;\n Forgot?: ComponentType<AuthScreenProps>;\n /**\n * Tela de reset de senha (form com nova senha via link do email).\n * Renderizada pelo AuthGate quando URL tem `?token=` + user não logado.\n * Default: DefaultResetScreen.\n */\n Reset?: ComponentType<AuthScreenProps>;\n Paywall?: ComponentType;\n}\n\nexport function AppRoot({\n config,\n children,\n Login = DefaultLoginScreen,\n Signup = DefaultSignupScreen,\n Forgot = DefaultForgotScreen,\n Reset = DefaultResetScreen,\n Paywall = DefaultPaywall,\n}: AppRootProps) {\n return (\n <PaymentReturnHandler>\n <TemplateConfigProvider config={config}>\n <ErrorBoundary>\n <ThemeProvider>\n <AuthGate Login={Login} Signup={Signup} Forgot={Forgot} Reset={Reset}>\n <SubscriptionGate Paywall={Paywall}>\n {children}\n <PushPrompt />\n </SubscriptionGate>\n </AuthGate>\n </ThemeProvider>\n </ErrorBoundary>\n </TemplateConfigProvider>\n </PaymentReturnHandler>\n );\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport type { AppConfig } from '../../../scripts/schemas/app-config';\n\nexport type SubscriptionMode = 'trial' | 'pay_first' | 'free';\n\nexport interface TemplateConfig extends AppConfig {\n /** Resolved subscription mode. Defaults to 'trial' when absent in app.config.json. */\n mode: SubscriptionMode;\n}\n\nconst TemplateConfigContext = createContext<TemplateConfig | null>(null);\n\nexport function TemplateConfigProvider({\n config,\n children,\n}: {\n config: AppConfig;\n children: ReactNode;\n}) {\n const value = useMemo<TemplateConfig>(() => ({\n ...config,\n mode: (config.subscription?.mode as SubscriptionMode | undefined) ?? 'trial',\n }), [config]);\n\n return (\n <TemplateConfigContext.Provider value={value}>\n {children}\n </TemplateConfigContext.Provider>\n );\n}\n\nexport function useTemplateConfig(): TemplateConfig {\n const ctx = useContext(TemplateConfigContext);\n if (ctx === null) {\n throw new Error('useTemplateConfig must be used inside <TemplateConfigProvider>');\n }\n return ctx;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n const config = useTemplateConfig();\n const style = {\n '--hook-color-primary': config.theme.primary_color,\n ...(config.theme.background_color && {\n '--hook-color-background': config.theme.background_color,\n }),\n } as CSSProperties;\n\n return <div style={style}>{children}</div>;\n}\n","import { useEffect, useState, type ComponentType, type ReactNode } from 'react';\nimport { useAuth } from '../hooks/useAuth';\nimport { LoadingState } from '../defaults/LoadingState';\nimport type { AuthScreenProps, AuthScreen } from '../defaults/DefaultLoginScreen';\n\ninterface Props {\n Login: ComponentType<AuthScreenProps>;\n Signup: ComponentType<AuthScreenProps>;\n Forgot: ComponentType<AuthScreenProps>;\n Reset: ComponentType<AuthScreenProps>;\n children: ReactNode;\n}\n\n/**\n * Detecta `?token=` + `?screen=reset` na URL — link do email de password_reset.\n * Se presente E user não autenticado, força tela Reset antes do Login default.\n *\n * `useResetForm` limpa `?token=&screen=reset` via `history.replaceState` após\n * reset bem-sucedido — evita re-dispatch do Reset no próximo logout (F22\n * follow-up descoberto no smoke).\n *\n * Query é snapshot no mount + re-avalia em popstate (permite link aberto em\n * tab já montada). Não re-avalia em re-render normal; AuthGate remontar seria\n * indicador de reset state mal-limpado.\n */\nfunction detectResetFromUrl(): boolean {\n if (typeof window === 'undefined') return false;\n const params = new URLSearchParams(window.location.search);\n return params.get('token') !== null && params.get('screen') === 'reset';\n}\n\nexport function AuthGate({ Login, Signup, Forgot, Reset, children }: Props) {\n const { user, authStatus } = useAuth();\n const [screen, setScreen] = useState<AuthScreen>(() =>\n detectResetFromUrl() ? 'reset' : 'login',\n );\n\n // Reset é fluxo exclusivamente pre-auth. Se user autenticou (login OU logout\n // que recicla useAuth state), AuthGate volta pra 'login' default.\n // Isso corrige F22 follow-up: logout pós-reset jogava user de volta no Reset\n // porque ?token= ainda estava na URL (fix principal é clear URL no useResetForm,\n // este é cinto-e-suspensório).\n useEffect(() => {\n if (user && screen !== 'login') {\n setScreen('login');\n }\n }, [user, screen]);\n\n // Se URL mudar em runtime (SPA navigation), re-avalia. Raro mas permite\n // e-mail abrir em tab já montada.\n useEffect(() => {\n const onPop = () => {\n if (detectResetFromUrl()) setScreen('reset');\n };\n window.addEventListener('popstate', onPop);\n return () => window.removeEventListener('popstate', onPop);\n }, []);\n\n if (authStatus === 'loading') return <LoadingState />;\n if (!user) {\n if (screen === 'reset') return <Reset onNavigate={setScreen} />;\n if (screen === 'signup') return <Signup onNavigate={setScreen} />;\n if (screen === 'forgot') return <Forgot onNavigate={setScreen} />;\n return <Login onNavigate={setScreen} />;\n }\n return <>{children}</>;\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre useHook(). Expõe apenas `user`, `authStatus` e `refresh`\n * pros consumidores que não precisam das methods completas do auth.\n */\nexport function useAuth() {\n const { user, authStatus, auth } = useHook();\n return {\n user,\n authStatus,\n refresh: auth.refresh,\n };\n}\n","export function LoadingState({ message }: { message?: string }) {\n return (\n <div role=\"status\" aria-live=\"polite\" style={{ padding: 24, textAlign: 'center' }}>\n <span>{message ?? 'Carregando...'}</span>\n </div>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'pending' | 'none';\n\n/**\n * Hook headless pro Paywall. Expõe status atual da subscription + ação\n * `checkout(cpf)` que chama `POST /payments/checkout/card` e redireciona\n * o browser pro `invoiceUrl` hosted do Asaas. Após o checkout, Asaas\n * redireciona de volta com query string indicativa; subscription real\n * é atualizada via webhook (`PAYMENT_RECEIVED` / `SUBSCRIPTION_ACTIVATED`).\n *\n * MVP: checkout só cartão. Pix vem depois (gatilho documentado em P10.7).\n */\nexport function usePaywallState() {\n const { subscription } = useHook();\n const [opening, setOpening] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n\n const checkout = useCallback(\n async (args: { cpf: string; cycle?: 'MONTHLY' | 'YEARLY' }) => {\n setOpening(true);\n setError(null);\n try {\n const result = await subscription.checkoutCard({\n cpf: args.cpf,\n cycle: args.cycle ?? 'MONTHLY',\n });\n // Redireciona pro checkout hosted do Asaas. Após confirmação,\n // Asaas redireciona de volta e webhook atualiza DB.\n window.location.href = result.invoiceUrl;\n } catch (err) {\n setError(err as Error);\n setOpening(false); // só reseta em erro; success navega away\n }\n },\n [subscription],\n );\n\n const cancel = useCallback(async () => {\n try {\n await subscription.cancel();\n await subscription.refresh();\n } catch (err) {\n setError(err as Error);\n }\n }, [subscription]);\n\n return { status, daysLeftInTrial, checkout, cancel, opening, error };\n}\n","import type { ComponentType, ReactNode } from 'react';\nimport { useTemplateConfig } from './TemplateConfigContext';\nimport { usePaywallState, type SubscriptionStatus } from '../hooks/usePaywallState';\n\ninterface Props {\n Paywall: ComponentType;\n children: ReactNode;\n}\n\nconst BLOCKING: ReadonlySet<SubscriptionStatus> = new Set([\n 'pending',\n 'expired',\n 'canceled',\n 'none',\n]);\n\nexport function SubscriptionGate({ Paywall, children }: Props) {\n const { mode } = useTemplateConfig();\n const { status } = usePaywallState();\n\n // free: nunca bloqueia, independente de status.\n if (mode === 'free') return <>{children}</>;\n // pending/expired/canceled/none → Paywall.\n if (BLOCKING.has(status)) return <Paywall />;\n // trialing/active/past_due → libera (past_due é window de grace).\n return <>{children}</>;\n}\n","// Side-effect-only component: observa estado e dispara push.subscribe() quando\n// apropriado. NUNCA renderiza UI bloqueante — sempre retorna null. No MVP, o SDK\n// stub de push lança 'unsupported_mvp', então este componente não faz nada.\n// Quando P14 entregar VAPID real, adicionar gate por 2ª sessão + dismissed_at.\nexport function PushPrompt() {\n return null;\n}\n","import { Component, type ReactNode } from 'react';\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<Props, State> {\n state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n componentDidCatch(error: Error) {\n console.error('[ErrorBoundary] caught', error);\n }\n\n render() {\n if (this.state.error) {\n return this.props.fallback ?? (\n <div role=\"alert\" style={{ padding: 24, textAlign: 'center' }}>\n <h2>Algo deu errado</h2>\n <p style={{ opacity: 0.7 }}>Recarregue a página pra tentar de novo.</p>\n </div>\n );\n }\n return <>{this.props.children}</>;\n }\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseLoginFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /**\n * Submete o form. Retorna true se o login deu OK (cookies setados), false\n * se validação falhou, credenciais inválidas, rate-limit ou erro de rede.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useLoginForm(): UseLoginFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.login({ email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, password, canSubmit]);\n\n return {\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { SdkError, SdkAuthError, SdkRateLimitError } from '@hook-sdk/sdk';\n\nexport type AuthFormErrorCode =\n | 'invalid_credentials'\n | 'rate_limited'\n | 'email_unverified'\n | 'account_locked'\n | 'network'\n | 'server';\n\nexport interface AuthFormError {\n code: AuthFormErrorCode;\n message: string;\n retryAfter?: number;\n}\n\n/**\n * Mapeia SdkError do @hook-sdk/sdk pra AuthFormError tipado do template.\n * Usado por useLoginForm/useSignupForm/useForgotForm.\n */\nexport function mapSdkError(err: unknown): AuthFormError {\n if (err instanceof SdkRateLimitError) {\n return {\n code: 'rate_limited',\n message: `Aguarde ${err.retryAfter}s e tente novamente.`,\n retryAfter: err.retryAfter,\n };\n }\n if (err instanceof SdkAuthError) {\n const detail = (err as { detail?: string }).detail;\n if (detail === 'email_unverified') {\n return { code: 'email_unverified', message: 'Confirme seu e-mail antes de entrar.' };\n }\n if (detail === 'account_locked') {\n return { code: 'account_locked', message: 'Conta bloqueada. Contate o suporte.' };\n }\n return { code: 'invalid_credentials', message: 'E-mail ou senha inválidos.' };\n }\n if (err instanceof SdkError && err.httpStatus === 0) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n // Falhas de rede em POST/PATCH/DELETE não são envolvidas em SdkError pelo\n // HttpClient (só GET tem retry wrap). fetch() lança TypeError cru — tratamos\n // como 'network' pra manter UX consistente com GETs.\n if (err instanceof TypeError) {\n return { code: 'network', message: 'Sem conexão com o servidor. Verifique sua internet.' };\n }\n return { code: 'server', message: 'Algo deu errado. Tente novamente em instantes.' };\n}\n","import { useLoginForm } from '../hooks/useLoginForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport type AuthScreen = 'login' | 'signup' | 'forgot' | 'reset';\nexport interface AuthScreenProps {\n onNavigate: (to: AuthScreen) => void;\n}\n\nexport function DefaultLoginScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useLoginForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Entre na sua conta</p>\n\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input\n data-testid=\"login-email\"\n type=\"email\"\n value={f.email}\n onChange={(e) => f.setEmail(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input\n data-testid=\"login-password\"\n type=\"password\"\n value={f.password}\n onChange={(e) => f.setPassword(e.target.value)}\n style={{ display: 'block', width: '100%' }}\n />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n\n {f.error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {f.error.message}\n </div>\n )}\n\n <button\n data-testid=\"login-submit\"\n type=\"submit\"\n disabled={!f.canSubmit}\n style={{\n width: '100%', padding: 12,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: f.canSubmit ? 1 : 0.5,\n }}\n >\n {f.submitting ? 'Entrando...' : 'Entrar'}\n </button>\n </form>\n\n <div style={{ marginTop: 16, display: 'flex', justifyContent: 'space-between' }}>\n <button data-testid=\"login-goto-signup\" type=\"button\" onClick={() => onNavigate('signup')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Criar conta\n </button>\n <button data-testid=\"login-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Esqueci senha\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst MIN_PASSWORD = 8;\n\nexport interface UseSignupFormResult {\n name: string;\n setName: (v: string) => void;\n nameError: string | null;\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n /**\n * Submete o form. Retorna true se o signup deu OK (backend respondeu 2xx),\n * false se validação falhou, houve erro de rede/servidor, ou email já em uso.\n * Em caso de false, `error` state é populado com detalhes.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n error: AuthFormError | null;\n}\n\nexport function useSignupForm(): UseSignupFormResult {\n const { auth } = useHook();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const nameError = useMemo(() => {\n if (name.length === 0) return null;\n if (name.trim().length < 2) return 'Nome muito curto.';\n return null;\n }, [name]);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const canSubmit =\n name.trim().length >= 2 &&\n email.length > 0 &&\n password.length >= MIN_PASSWORD &&\n nameError === null &&\n emailError === null &&\n passwordError === null &&\n !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.signup({ name, email, password });\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, name, email, password, canSubmit]);\n\n return {\n name, setName, nameError,\n email, setEmail, emailError,\n password, setPassword, passwordError,\n submit, submitting, canSubmit, error,\n };\n}\n","import { useSignupForm } from '../hooks/useSignupForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultSignupScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useSignupForm();\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Criar sua conta</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nome\n <input data-testid=\"signup-name\" value={f.name} onChange={(e) => f.setName(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.nameError && <small style={{ color: '#c00' }}>{f.nameError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"signup-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Senha\n <input data-testid=\"signup-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"signup-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Criando...' : 'Criar conta'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"signup-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Já tem conta? Entre\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport interface UseForgotFormResult {\n email: string;\n setEmail: (v: string) => void;\n emailError: string | null;\n /**\n * Submete o form. Retorna true se o backend aceitou a requisição (email\n * de reset foi enfileirado — sem leak de \"existe esse email\" por design),\n * false se validação falhou, rate-limit ou erro de rede.\n * Em caso de sucesso, `sent` state também é setado para true.\n */\n submit: () => Promise<boolean>;\n submitting: boolean;\n canSubmit: boolean;\n sent: boolean;\n error: AuthFormError | null;\n}\n\nexport function useForgotForm(): UseForgotFormResult {\n const { auth } = useHook();\n const [email, setEmail] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [sent, setSent] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n const emailError = useMemo(() => {\n if (email.length === 0) return null;\n if (!EMAIL_RE.test(email)) return 'Formato de e-mail inválido.';\n return null;\n }, [email]);\n\n const canSubmit = email.length > 0 && emailError === null && !submitting;\n\n const submit = useCallback(async (): Promise<boolean> => {\n if (!canSubmit) return false;\n setSubmitting(true);\n setError(null);\n try {\n await auth.forgot({ email });\n setSent(true);\n return true;\n } catch (err) {\n setError(mapSdkError(err));\n return false;\n } finally {\n setSubmitting(false);\n }\n }, [auth, email, canSubmit]);\n\n return {\n email, setEmail, emailError,\n submit, submitting, canSubmit, sent, error,\n };\n}\n","import { useForgotForm } from '../hooks/useForgotForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\nexport function DefaultForgotScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useForgotForm();\n\n if (f.sent) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Verifique seu e-mail</h1>\n <p style={{ opacity: 0.7 }}>Enviamos um link pra redefinir sua senha.</p>\n <button data-testid=\"forgot-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Voltar pro login</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Redefinir senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n E-mail\n <input data-testid=\"forgot-email\" type=\"email\" value={f.email} onChange={(e) => f.setEmail(e.target.value)} style={{ display: 'block', width: '100%' }} />\n {f.emailError && <small style={{ color: '#c00' }}>{f.emailError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"forgot-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Enviando...' : 'Enviar link'}\n </button>\n </form>\n <div style={{ marginTop: 16 }}>\n <button data-testid=\"forgot-goto-login\" type=\"button\" onClick={() => onNavigate('login')} style={{ background: 'none', border: 'none', cursor: 'pointer' }}>\n Voltar pro login\n </button>\n </div>\n </main>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { mapSdkError, type AuthFormError } from '../errors';\n\nconst MIN_PASSWORD = 12;\n\nexport interface UseResetFormResult {\n /** Token JWT lido de `?token=` da URL. null se ausente. */\n token: string | null;\n password: string;\n setPassword: (v: string) => void;\n passwordError: string | null;\n confirm: string;\n setConfirm: (v: string) => void;\n confirmError: string | null;\n submit: () => Promise<void>;\n submitting: boolean;\n canSubmit: boolean;\n /** true após submit 200. UI deve mostrar \"senha alterada, volte pro login\". */\n done: boolean;\n error: AuthFormError | null;\n}\n\n/**\n * Hook headless pro fluxo de reset de senha via link do email.\n *\n * Lê `?token=` da URL atual automaticamente (readonly snapshot no mount).\n * Se token ausente, `canSubmit` fica false + `token: null` pra UI mostrar\n * mensagem \"link inválido\".\n *\n * Após submit 200, todos os refresh tokens do user são revogados pelo\n * backend (forçar re-login). UI deve direcionar pra LoginScreen.\n */\nexport function useResetForm(): UseResetFormResult {\n const { auth } = useHook();\n const [token, setToken] = useState<string | null>(null);\n const [password, setPassword] = useState('');\n const [confirm, setConfirm] = useState('');\n const [submitting, setSubmitting] = useState(false);\n const [done, setDone] = useState(false);\n const [error, setError] = useState<AuthFormError | null>(null);\n\n useEffect(() => {\n // Snapshot no mount. URL pode ter sido limpa depois (history.replaceState)\n // mas token deve estar no primeiro render.\n if (typeof window === 'undefined') return;\n const params = new URLSearchParams(window.location.search);\n const t = params.get('token');\n setToken(t && t.length > 0 ? t : null);\n }, []);\n\n const passwordError = useMemo(() => {\n if (password.length === 0) return null;\n if (password.length < MIN_PASSWORD) return `Mínimo de ${MIN_PASSWORD} caracteres.`;\n return null;\n }, [password]);\n\n const confirmError = useMemo(() => {\n if (confirm.length === 0) return null;\n if (confirm !== password) return 'Senhas não coincidem.';\n return null;\n }, [confirm, password]);\n\n const canSubmit =\n token !== null &&\n password.length >= MIN_PASSWORD &&\n confirm === password &&\n passwordError === null &&\n confirmError === null &&\n !submitting &&\n !done;\n\n const submit = useCallback(async () => {\n if (!canSubmit || token === null) return;\n setSubmitting(true);\n setError(null);\n try {\n await auth.reset({ token, newPassword: password });\n setDone(true);\n // Limpa `?token=&screen=reset` da URL pra AuthGate não re-disparar Reset\n // em re-renders futuros (logout depois do reset, popstate, etc.).\n // Mantém mesmo path, só strip dos query params de auth.\n if (typeof window !== 'undefined') {\n const url = new URL(window.location.href);\n url.searchParams.delete('token');\n url.searchParams.delete('screen');\n window.history.replaceState({}, '', url.toString());\n }\n } catch (err) {\n setError(mapSdkError(err));\n } finally {\n setSubmitting(false);\n }\n }, [auth, token, password, canSubmit]);\n\n return {\n token,\n password, setPassword, passwordError,\n confirm, setConfirm, confirmError,\n submit, submitting, canSubmit, done, error,\n };\n}\n","import { useResetForm } from '../hooks/useResetForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport type { AuthScreenProps } from './DefaultLoginScreen';\n\n/**\n * Tela default de reset de senha. Renderizada pelo AuthGate quando\n * `?token=` está presente na URL (link vindo do email de password_reset).\n *\n * AuthScreenProps.onNavigate é usado pra voltar pro login após reset\n * bem-sucedido (usuário precisa re-autenticar — backend revoga todos\n * os refresh tokens na chamada de `auth.reset`).\n */\nexport function DefaultResetScreen({ onNavigate }: AuthScreenProps) {\n const { name } = useTemplateConfig();\n const f = useResetForm();\n\n if (f.done) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Senha alterada</h1>\n <p style={{ opacity: 0.7 }}>Agora é só fazer login com a nova senha.</p>\n <button data-testid=\"reset-back-login\" type=\"button\" onClick={() => onNavigate('login')}>Ir pro login</button>\n </main>\n );\n }\n\n if (f.token === null) {\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto', textAlign: 'center' }}>\n <h1>Link inválido</h1>\n <p style={{ opacity: 0.7 }}>Peça um novo link de reset.</p>\n <button data-testid=\"reset-goto-forgot\" type=\"button\" onClick={() => onNavigate('forgot')}>Pedir novo link</button>\n </main>\n );\n }\n\n return (\n <main style={{ padding: 24, maxWidth: 360, margin: '0 auto' }}>\n <h1 style={{ marginBottom: 8 }}>{name}</h1>\n <p style={{ opacity: 0.7, marginBottom: 24 }}>Escolha uma nova senha</p>\n <form onSubmit={(e) => { e.preventDefault(); void f.submit(); }}>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Nova senha\n <input data-testid=\"reset-password\" type=\"password\" value={f.password} onChange={(e) => f.setPassword(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.passwordError && <small style={{ color: '#c00' }}>{f.passwordError}</small>}\n </label>\n <label style={{ display: 'block', marginBottom: 12 }}>\n Confirmar senha\n <input data-testid=\"reset-confirm\" type=\"password\" value={f.confirm} onChange={(e) => f.setConfirm(e.target.value)} style={{ display: 'block', width: '100%' }} autoComplete=\"new-password\" />\n {f.confirmError && <small style={{ color: '#c00' }}>{f.confirmError}</small>}\n </label>\n {f.error && <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>{f.error.message}</div>}\n <button data-testid=\"reset-submit\" type=\"submit\" disabled={!f.canSubmit} style={{ width: '100%', padding: 12, background: 'var(--hook-color-primary)', color: '#fff', border: 'none', borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }}>\n {f.submitting ? 'Alterando...' : 'Alterar senha'}\n </button>\n </form>\n </main>\n );\n}\n","import { useState } from 'react';\nimport { usePaywallState } from '../hooks/usePaywallState';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\n\nexport function DefaultPaywall() {\n const config = useTemplateConfig();\n const { checkout, opening, error } = usePaywallState();\n const p = config.subscription.paywall_config;\n const [cpf, setCpf] = useState('');\n const cpfDigits = cpf.replace(/\\D/g, '');\n const canCheckout = cpfDigits.length === 11 && !opening;\n\n return (\n <main style={{ padding: 24, maxWidth: 440, margin: '0 auto', textAlign: 'center' }}>\n <h1 style={{ marginBottom: 8 }}>{p.title}</h1>\n {p.subtitle && <p style={{ opacity: 0.7, marginBottom: 24 }}>{p.subtitle}</p>}\n\n <ul style={{ listStyle: 'none', padding: 0, textAlign: 'left', marginBottom: 24 }}>\n {p.benefits.map((b) => (\n <li key={b} style={{ padding: '8px 0', display: 'flex', alignItems: 'center' }}>\n <span aria-hidden style={{ marginRight: 8 }}>✓</span>\n <span>{b}</span>\n </li>\n ))}\n </ul>\n\n <div style={{ textAlign: 'left', marginBottom: 16 }}>\n <label style={{ display: 'block', fontSize: 14, opacity: 0.7, marginBottom: 4 }}>\n Seu CPF (pra emissão de recibo)\n </label>\n <input\n data-testid=\"paywall-cpf\"\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"000.000.000-00\"\n value={cpf}\n onChange={(e) => setCpf(e.target.value)}\n style={{ width: '100%', padding: 10, fontSize: 14, borderRadius: 8, border: '1px solid #ccc' }}\n />\n </div>\n\n {error && (\n <div role=\"alert\" style={{ color: '#c00', marginBottom: 12 }}>\n {error.message}\n </div>\n )}\n\n <button\n data-testid=\"paywall-cta\"\n type=\"button\"\n onClick={() => void checkout({ cpf: cpfDigits })}\n disabled={!canCheckout}\n style={{\n width: '100%', padding: 14,\n background: 'var(--hook-color-primary)', color: '#fff',\n border: 'none', borderRadius: 8,\n opacity: canCheckout ? 1 : 0.5,\n fontSize: 16, fontWeight: 600,\n }}\n >\n {opening ? 'Abrindo...' : p.cta}\n </button>\n\n {p.priceHint && <p style={{ opacity: 0.6, marginTop: 12 }}>{p.priceHint}</p>}\n {p.footerNote && <p style={{ opacity: 0.5, marginTop: 16, fontSize: 12 }}>{p.footerNote}</p>}\n </main>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function EmptyState({ title, description, action }: {\n title: string;\n description?: string;\n action?: ReactNode;\n}) {\n return (\n <div role=\"status\" style={{ padding: 32, textAlign: 'center' }}>\n <h2 style={{ marginBottom: 8 }}>{title}</h2>\n {description && <p style={{ opacity: 0.7 }}>{description}</p>}\n {action && <div style={{ marginTop: 16 }}>{action}</div>}\n </div>\n );\n}\n","import { useEffect } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nlet warned = false;\n\n/** Test-only: reseta flag pra permitir validar warn uma única vez em re-mounts de test */\nexport function __resetWarnForTest() { warned = false; }\n\n/**\n * Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).\n * Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.\n */\nexport function useAuthPrimitives() {\n const { auth } = useHook();\n\n useEffect(() => {\n if (!warned && process.env.NODE_ENV !== 'production') {\n warned = true;\n console.warn(\n '[@hook-sdk/template] useAuthPrimitives() é escape hatch. ' +\n 'Pra login/signup/forgot, use useLoginForm/useSignupForm/useForgotForm. ' +\n 'Docs: docs/19-golden-template.md#escape-hatch',\n );\n }\n }, []);\n\n return {\n login: auth.login,\n signup: auth.signup,\n logout: auth.logout,\n logoutAll: auth.logoutAll,\n forgot: auth.forgot,\n resendVerify: auth.resendVerify,\n changePassword: auth.changePassword,\n changeEmail: auth.changeEmail,\n refresh: auth.refresh,\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `subscription` do SDK. MVP: apenas status (stub retorna 'none').\n */\nexport function useSubscription() {\n const { subscription } = useHook();\n return {\n status: subscription.status(),\n };\n}\n","import { useHook } from '@hook-sdk/sdk';\n\n/**\n * Wrapper fino sobre `push` do SDK. MVP: stub retorna 'unsupported' no status\n * e subscribe/unsubscribe lançam SdkError. A shape segue o SDK real.\n */\nexport function usePush() {\n const { push } = useHook();\n return {\n status: push.status(),\n subscribe: push.subscribe,\n unsubscribe: push.unsubscribe,\n };\n}\n","import { useCallback, useState } from 'react';\n\nexport interface ToastItem {\n id: string;\n message: string;\n kind: 'info' | 'error' | 'success';\n}\n\n/**\n * Toast mínimo in-memory. MVP: IA renderiza a lista onde quiser (ex: no final do <Home>).\n * Não opina sobre UI; retorna items + actions.\n */\nexport function useToast() {\n const [items, setItems] = useState<ToastItem[]>([]);\n\n const show = useCallback((message: string, kind: ToastItem['kind'] = 'info') => {\n const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n setItems((prev) => [...prev, { id, message, kind }]);\n setTimeout(() => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, 4000);\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setItems((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return { items, show, dismiss };\n}\n"],"mappings":"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","names":["import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_sdk","import_sdk","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","MIN_PASSWORD","import_jsx_runtime","import_react","import_sdk","EMAIL_RE","import_jsx_runtime","import_react","import_sdk","MIN_PASSWORD","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_sdk","import_sdk","import_sdk","import_react"]}
|