@hook-sdk/template 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../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":["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":["jsx","jsx","jsx","useState","useHook","Fragment","jsx","Fragment","jsx","useCallback","useState","useHook","useHook","useState","useCallback","jsx","jsxs","useCallback","useMemo","useState","useHook","EMAIL_RE","MIN_PASSWORD","useHook","useState","useMemo","useCallback","jsx","jsxs","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","jsx","jsxs","useCallback","useEffect","useMemo","useState","useHook","MIN_PASSWORD","useHook","useState","useEffect","useMemo","useCallback","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs","useEffect","useHook","useHook","useEffect","useHook","useHook","useCallback","useState"]}
1
+ {"version":3,"sources":["../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/PersistedKeysPrefetch.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":["/**\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 { useCallback, useEffect, useRef, useState, type ComponentType, type CSSProperties, 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 { PersistedKeysPrefetch } from './internal/PersistedKeysPrefetch';\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) e\n * polla `subscription.refresh()` com backoff exponencial (2s, 5s, 10s, 20s, 40s\n * — total ~77s) até status ∈ {active, trialing}.\n *\n * Regras de projeto (2026-04-21, pós-incidente QA papomaterno):\n *\n * - **Effect `[]`**: nunca `[subscription]`. O objeto `subscription` é\n * referencialmente memoizado pelo SDK mas re-memoiza a cada mudança de\n * `sub` (quando `/me` resolve). Re-dispara em cada render causava storm\n * exponencial (258→654 req em 20s observados em QA). Lemos a última\n * referência via `subRef.current` e rodamos o polling só 1× por mount.\n *\n * - **Backoff** em vez de 1s constante: evita martelar o backend quando\n * webhook atrasa e respeita o orçamento de ~77s total (cobre p99 observado\n * em staging). `http.ts` já respeita `Retry-After` em 429, mas backoff\n * reduz a chance de bater o rate limit em primeiro lugar.\n *\n * - **Aceita `trialing`** além de `active`: em `mode=pay_first` post-checkout\n * vira ACTIVE; em `mode=trial` o backend pode manter TRIAL com\n * trial_ends_at avançado. Ambos = libera o gate (`SubscriptionGate` trata\n * os dois como non-blocking).\n *\n * - **Timeout → estado `waiting` bloqueante com botão \"Atualizar\"**: se a\n * gente renderizasse children, o `SubscriptionGate` mostraria paywall de\n * novo (status=none sem subscription row) — user cliparia \"Pagar\" em\n * looping. Bloquear é menos ruim.\n *\n * Precisa estar dentro de <HookProvider> (fornecido pelo shell).\n * Exportado para teste isolado.\n */\nconst BACKOFF_MS = [2_000, 5_000, 10_000, 20_000, 40_000] as const; // ~77s total\n\ntype ReturnState = 'idle' | 'confirming' | 'waiting';\n\nexport function PaymentReturnHandler({ children }: { children: ReactNode }) {\n const { subscription } = useHook();\n const subRef = useRef(subscription);\n subRef.current = subscription;\n const runIdRef = useRef(0);\n const [state, setState] = useState<ReturnState>('idle');\n\n const runPoll = useCallback(() => {\n const runId = ++runIdRef.current;\n setState('confirming');\n let attempts = 0;\n\n const tick = async () => {\n if (runIdRef.current !== runId) return;\n attempts++;\n try {\n await subRef.current.refresh();\n } catch {\n // swallow — http.ts já honra Retry-After em 429 e retry em 5xx.\n // Se ainda falhou, cai no próximo passo do backoff.\n }\n if (runIdRef.current !== runId) return;\n const status = subRef.current.status();\n if (status === 'active' || status === 'trialing') {\n const cleanUrl = new URL(window.location.href);\n cleanUrl.searchParams.delete('paymentReturn');\n window.history.replaceState({}, '', cleanUrl.toString());\n setState('idle');\n return;\n }\n const delay = BACKOFF_MS[attempts - 1];\n if (delay === undefined) {\n setState('waiting');\n return;\n }\n setTimeout(tick, delay);\n };\n void tick();\n }, []);\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 runPoll();\n return () => {\n // Invalida o run ativo — qualquer tick() pendente vai ver runId velho\n // e retornar sem tocar state. Cobre unmount e StrictMode double-invoke.\n runIdRef.current++;\n };\n }, [runPoll]);\n\n if (state === 'confirming') {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={overlayStyle}\n >\n Confirmando pagamento…\n </div>\n );\n }\n\n if (state === 'waiting') {\n return (\n <div role=\"status\" aria-live=\"polite\" style={overlayStyle}>\n <div style={{ maxWidth: 320, textAlign: 'center', lineHeight: 1.5 }}>\n <div style={{ marginBottom: 16 }}>\n Pagamento aceito. Estamos confirmando com o banco — pode levar\n alguns minutos.\n </div>\n <button\n type=\"button\"\n onClick={runPoll}\n style={buttonStyle}\n >\n Atualizar\n </button>\n </div>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n\nconst overlayStyle: CSSProperties = {\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 padding: 24,\n};\n\nconst buttonStyle: CSSProperties = {\n background: 'white',\n color: 'black',\n border: 'none',\n borderRadius: 8,\n padding: '10px 24px',\n fontSize: '1rem',\n fontWeight: 600,\n cursor: 'pointer',\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 <PersistedKeysPrefetch>\n <SubscriptionGate Paywall={Paywall}>\n {children}\n <PushPrompt />\n </SubscriptionGate>\n </PersistedKeysPrefetch>\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","import { useEffect, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\n/**\n * Dispara 1 POST `:bulk-read` no mount pra prefetch todas as chaves declaradas\n * em `app.config.json.persistedKeys`, priming o cache do SDK. Depois disso,\n * `usePersistedState` hits na cache ao invés de disparar GET individual por\n * key — corta de N requests pra 1 no cold mount.\n *\n * Montado dentro de `AuthGate` → só dispara pós-login. Se `persistedKeys`\n * estiver ausente/vazio, o efeito é no-op: cache fica `disabled` e o\n * comportamento legacy (N GETs individuais) permanece.\n *\n * Erros do bulkRead não bloqueiam o render — o cache vira `disabled` e\n * callers caem no path normal. Decisão intencional: este é best-effort,\n * não um gate de renderização.\n */\nexport function PersistedKeysPrefetch({ children }: { children: ReactNode }) {\n const { appData } = useHook();\n const config = useTemplateConfig();\n\n useEffect(() => {\n const keys = config.persistedKeys;\n if (!keys || keys.length === 0) return;\n appData.cache.startPrefetch(keys, (ks) => appData.bulkRead(ks));\n }, [appData, config.persistedKeys]);\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 /**\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":["useCallback","useEffect","useState","useHook","jsx","jsx","jsx","useState","useHook","Fragment","jsx","useEffect","useHook","Fragment","jsx","useHook","useEffect","Fragment","jsx","useCallback","useMemo","useState","useHook","useHook","useState","useMemo","useCallback","jsx","jsxs","useCallback","useMemo","useState","useHook","EMAIL_RE","MIN_PASSWORD","useHook","useState","useMemo","useCallback","jsx","jsxs","useCallback","useMemo","useState","useHook","EMAIL_RE","useHook","useState","useMemo","useCallback","jsx","jsxs","useCallback","useEffect","useMemo","useState","useHook","MIN_PASSWORD","useHook","useState","useEffect","useMemo","useCallback","jsx","jsxs","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","useHook","useState","useCallback","useEffect","jsx","jsxs","useEffect","useHook","useHook","useEffect","useHook","useHook","useCallback","useState"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hook-sdk/template",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Golden-path template primitives for Hook apps — AppRoot, auth hooks, paywall state.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "react-dom": "^18.3.1"
41
41
  },
42
42
  "dependencies": {
43
- "@hook-sdk/sdk": "0.1.0",
43
+ "@hook-sdk/sdk": "workspace:*",
44
44
  "zod": "^4.3.6"
45
45
  },
46
46
  "devDependencies": {