@hook-sdk/template 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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/components/InstallGate/InstallGate.tsx","../src/hooks/useInstallPrompt.ts","../src/components/InstallGate/copy.ts","../src/components/InstallGate/InstallSplash.tsx","../src/components/InstallGate/icons.tsx","../src/components/InstallGate/variants/AndroidNativeVariant.tsx","../src/components/InstallGate/variants/AndroidManualVariant.tsx","../src/components/InstallGate/Step.tsx","../src/components/InstallGate/variants/IOSafariVariant.tsx","../src/components/InstallGate/variants/IOSOtherVariant.tsx","../src/components/InstallGate/variants/InAppBrowserVariant.tsx","../src/components/InstallGate/variants/DesktopVariant.tsx","../src/defaults/ErrorBoundary.tsx","../src/hooks/useLoginForm.ts","../src/errors.ts","../src/internal/GoogleSignInButton.tsx","../src/internal/OAuthErrorBanner.tsx","../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/hooks/usePush.ts","../src/components/PushPrompt.tsx","../src/defaults/EmptyState.tsx","../src/hooks/usePlan.ts","../src/utils/price.ts","../src/hooks/useAuthPrimitives.ts","../src/hooks/useSubscription.ts","../src/hooks/useReminders.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 { InstallGate } from './components/InstallGate';\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 <InstallGate>\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 </InstallGate>\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, useEffect, useRef, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'pending' | 'none';\nexport type PaymentMethod = 'card' | 'pix-auto' | 'pix-once';\n\nexport interface PixPending {\n method: 'pix-auto' | 'pix-once';\n qrCodePayload: string | null;\n qrCodeBase64: string | null;\n expiresAt: string | null;\n /**\n * Flipa `true` quando o polling detecta subscription ACTIVE/TRIAL (webhook\n * PAYMENT_RECEIVED ou AUTHORIZATION_ACTIVATED chegou). UI deve renderizar\n * confirmação visual nesse momento; após 2-3s chama `dismissPix` pra\n * limpar o modal e deixar SubscriptionGate liberar o app.\n */\n paid: boolean;\n}\n\n/**\n * Hook headless pro Paywall. Expõe status atual da subscription + ação\n * `checkout({cpf, cycle, method})` com 3 métodos:\n *\n * - **card** (default): cria subscription Asaas recorrente, redireciona pro\n * invoiceUrl hosted. Após pagar, Asaas redireciona de volta e webhook\n * atualiza DB.\n * - **pix-auto**: Pix Automático Jornada 3 BACEN. User escaneia QR 1x no app\n * do banco, autoriza débito recorrente. Retorna QR via `pixPending`\n * (hook fica populado até user confirmar no banco).\n * - **pix-once**: Pix avulso. User paga QR único, ganha 1 ciclo. Sem\n * recorrência automática — renova voltando no app. Retorna QR via\n * `pixPending`.\n *\n * Subscription real é atualizada via webhook (`PAYMENT_RECEIVED` ou\n * `PIX_AUTOMATIC_RECURRING_AUTHORIZATION_ACTIVATED`).\n */\nexport function usePaywallState() {\n const { subscription } = useHook();\n const [opening, setOpening] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [pixPending, setPixPending] = useState<PixPending | null>(null);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n // G68: expõe pra SubscriptionGate evitar piscar paywall enquanto o primeiro\n // /me não voltou. Flipa 1× por (appId, userId) no SDK, safe as render dep.\n const initialLoadComplete = subscription.initialLoadComplete;\n\n const checkout = useCallback(\n async (args: {\n cpf: string;\n cycle?: 'MONTHLY' | 'YEARLY';\n method?: PaymentMethod;\n }) => {\n setOpening(true);\n setError(null);\n setPixPending(null);\n const method = args.method ?? 'card';\n const cycle = args.cycle ?? 'MONTHLY';\n try {\n if (method === 'card') {\n const result = await subscription.checkoutCard({ cpf: args.cpf, cycle });\n // Redireciona pro checkout hosted do Asaas.\n window.location.href = result.invoiceUrl;\n return;\n }\n if (method === 'pix-auto') {\n const result = await subscription.checkoutPixAuto({ cpf: args.cpf, cycle });\n setPixPending({\n method: 'pix-auto',\n qrCodePayload: result.qrCodePayload,\n qrCodeBase64: result.qrCodeBase64,\n expiresAt: null,\n paid: false,\n });\n setOpening(false);\n return;\n }\n if (method === 'pix-once') {\n const result = await subscription.checkoutPixOnce({ cpf: args.cpf, cycle });\n setPixPending({\n method: 'pix-once',\n qrCodePayload: result.qrCodePayload,\n qrCodeBase64: result.qrCodeBase64,\n expiresAt: result.expiresAt,\n paid: false,\n });\n setOpening(false);\n return;\n }\n } catch (err) {\n setError(err as Error);\n setOpening(false); // só reseta em erro; card 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 const dismissPix = useCallback(() => setPixPending(null), []);\n\n // Pix polling: enquanto pixPending && !paid, poll subscription.refresh() a\n // cada 3s. Quando status virar ACTIVE/TRIAL, marca `paid: true` (não limpa\n // pixPending) — UI mostra \"Pagamento confirmado!\". Após ~3min sem detectar,\n // para de pollar (user fecha o modal manualmente ou volta depois e recarrega).\n const subRef = useRef(subscription);\n subRef.current = subscription;\n useEffect(() => {\n if (!pixPending || pixPending.paid) return;\n let attempts = 0;\n const MAX_ATTEMPTS = 60; // 3min @ 3s\n let cancelled = false;\n const tick = async () => {\n if (cancelled || attempts >= MAX_ATTEMPTS) return;\n attempts++;\n try {\n await subRef.current.refresh();\n if (cancelled) return;\n const s = subRef.current.status() as SubscriptionStatus;\n if (s === 'active' || s === 'trialing') {\n setPixPending((prev) => (prev ? { ...prev, paid: true } : prev));\n return;\n }\n } catch {\n // swallow — http.ts já tem retry/backoff pra transient errors\n }\n if (!cancelled) setTimeout(tick, 3000);\n };\n setTimeout(tick, 3000);\n return () => {\n cancelled = true;\n };\n }, [pixPending]);\n\n return {\n status,\n daysLeftInTrial,\n initialLoadComplete,\n checkout,\n cancel,\n opening,\n error,\n pixPending,\n dismissPix,\n };\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, initialLoadComplete } = usePaywallState();\n\n // free: nunca bloqueia, independente de status.\n if (mode === 'free') return <>{children}</>;\n // G68: evita flash de paywall no cold start antes do 1º /me resolver.\n // Quando não há cache local (primeiro login, novo device), sub === null e\n // status='none' — BLOCKING dispararia o paywall por ~1-2s até o fetch\n // voltar. Com cache (user já pago), sub já vem populado do localStorage\n // e status reflete o último valor conhecido → sem flash.\n // Render nulo (em vez de paywall/spinner) porque AuthGate/AppShell já\n // cobrem o skeleton visual. Flash rápido de nada > flash de paywall.\n if (!initialLoadComplete && status === 'none') return null;\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, useState, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nconst SAFETY_TIMEOUT_MS = 3000;\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 * Comporta-se como gate: enquanto o bulkRead está em voo, renderiza `null`.\n * Libera children quando o cache vira `primed` (hit) ou `disabled` (falha).\n *\n * **G77**: essa semântica de gate é o que impede o flicker \"receita aparece\n * → some → pede onboarding\" pós-pagamento. Antes (≤ 0.7.3) o componente era\n * fire-and-forget: children montavam com cache `unknown`, `usePersistedState`\n * retornava `defaultValue`, e guards app-side que checavam \"tem filho?\"\n * disparavam redirect com dado fake. Agora o gate garante que `bulkRead`\n * resolveu antes de qualquer render dependente ocorrer.\n *\n * Safety timeout (3s): se `bulkRead` travar em rede adversa, libera render\n * mesmo assim e loga via `console.warn`. Degradação graceful sobre tela\n * branca eterna.\n *\n * Montado dentro de `AuthGate` → só dispara pós-login. Se `persistedKeys`\n * estiver ausente/vazio, é no-op: cache fica `disabled`, gate libera\n * imediatamente e o comportamento legacy (N GETs individuais) permanece.\n */\nexport function PersistedKeysPrefetch({ children }: { children: ReactNode }) {\n const { appData } = useHook();\n const config = useTemplateConfig();\n const hasKeys = !!config.persistedKeys && config.persistedKeys.length > 0;\n const [ready, setReady] = useState<boolean>(!hasKeys);\n\n useEffect(() => {\n const keys = config.persistedKeys;\n if (!keys || keys.length === 0) {\n setReady(true);\n return;\n }\n let cancelled = false;\n appData.cache.startPrefetch(keys, (ks) => appData.bulkRead(ks));\n void appData.cache.waitForPrimed(SAFETY_TIMEOUT_MS).then((result) => {\n if (cancelled) return;\n if (result === 'timeout') {\n console.warn(\n `[@hook-sdk/template] PersistedKeysPrefetch: bulk-read não completou em ${SAFETY_TIMEOUT_MS}ms. Liberando render mesmo assim — usePersistedState pode expor defaultValue até o fetch terminar (G77).`,\n );\n }\n setReady(true);\n });\n return () => {\n cancelled = true;\n };\n }, [appData, config.persistedKeys]);\n\n if (!ready) return null;\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","/**\n * InstallGate — wrapper que decide entre splash bloqueante e pass-through.\n *\n * Colocado em AppRoot entre ThemeProvider e AuthGate. Ver ADR-017 + doc 16.\n *\n * Comportamento:\n * - feature `install_prompt` desabilitado em app.config.json → renderiza children\n * - Standalone detectado → renderiza children\n * - Platform == desktop + !installable → renderiza children (sem banner)\n * - Platform == desktop + installable → renderiza children + banner soft lateral\n * - Mobile/in-app + não-installed + não-dismissed → splash bloqueante (substitui children)\n * - Mobile dismissido → renderiza children\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\nimport { shouldBlockInstall, useInstallPrompt } from '../../hooks/useInstallPrompt';\nimport { AndroidNativeVariant } from './variants/AndroidNativeVariant';\nimport { AndroidManualVariant } from './variants/AndroidManualVariant';\nimport { IOSafariVariant } from './variants/IOSafariVariant';\nimport { IOSOtherVariant } from './variants/IOSOtherVariant';\nimport { InAppBrowserVariant } from './variants/InAppBrowserVariant';\nimport { DesktopVariant } from './variants/DesktopVariant';\n\ninterface InstallGateProps {\n children: ReactNode;\n}\n\nexport function InstallGate({ children }: InstallGateProps) {\n const { slug, features_enabled } = useTemplateConfig();\n const enabled = features_enabled.includes('install_prompt' as never);\n\n const installState = useInstallPrompt(slug);\n const shouldBlock = enabled && shouldBlockInstall(installState);\n\n // Analytics: dispara `pwa_install_splash_shown` 1× por sessão+variant\n const trackedRef = useRef<string | null>(null);\n useEffect(() => {\n if (!shouldBlock) return;\n if (typeof window === 'undefined') return;\n const variantKey = `${slug}:${installState.variant}`;\n if (trackedRef.current === variantKey) return;\n trackedRef.current = variantKey;\n window.posthog?.capture?.('pwa_install_splash_shown', {\n slug,\n platform: installState.platform,\n browser: installState.iosBrowser ?? installState.androidBrowser ?? null,\n in_app_app: installState.inAppApp,\n variant: installState.variant,\n });\n }, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);\n\n if (!enabled) return <>{children}</>;\n if (installState.isInstalled) return <>{children}</>;\n\n // Desktop: banner soft, children renderiza normal em paralelo\n if (installState.variant === 'desktop') {\n return (\n <>\n {children}\n <DesktopVariant state={installState} actions={installState} />\n </>\n );\n }\n\n if (!shouldBlock) return <>{children}</>;\n\n // Mobile / in-app: splash bloqueante substitui children\n switch (installState.variant) {\n case 'android-native':\n return <AndroidNativeVariant state={installState} actions={installState} />;\n case 'android-manual':\n return <AndroidManualVariant state={installState} actions={installState} />;\n case 'ios-safari':\n return <IOSafariVariant state={installState} actions={installState} />;\n case 'ios-other':\n return <IOSOtherVariant state={installState} actions={installState} />;\n case 'in-app':\n return <InAppBrowserVariant state={installState} actions={installState} />;\n case 'none':\n default:\n return <>{children}</>;\n }\n}\n","/**\n * useInstallPrompt — headless hook pra PWA install prompt.\n *\n * Responsabilidades:\n * - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)\n * - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)\n * - Detectar standalone mode (PWA já instalado)\n * - Gerenciar dismissal graduada (session → permanente 14d)\n * - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`\n *\n * Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.\n *\n * Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com\n * divergências deliberadas (ver docs/adr/017 + P20 plan):\n * - enum InAppApp granular pra copy por rede social (G60 amendment)\n * - dismissal graduada em vez de permanente direto\n * - TTL de 14d no permanent dismiss\n * - tracking `skipCount` separado\n *\n * Gotchas de referência:\n * - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)\n * - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)\n * - G63: in-app browsers checados ANTES de Android/iOS\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n// --- Types ---------------------------------------------------------------\n\nexport type Platform =\n | 'android'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'unknown';\n\nexport type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';\n\nexport type AndroidBrowser =\n | 'chrome'\n | 'firefox'\n | 'opera'\n | 'samsung'\n | 'edge'\n | 'other';\n\nexport type InAppApp =\n | 'instagram'\n | 'facebook'\n | 'tiktok'\n | 'whatsapp'\n | 'twitter'\n | 'linkedin'\n | 'telegram'\n | 'line'\n | 'snapchat'\n | 'pinterest'\n | 'wechat'\n | 'other';\n\nexport type InstallVariant =\n | 'android-native'\n | 'android-manual'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'none';\n\ninterface BeforeInstallPromptEvent extends Event {\n prompt: () => Promise<void>;\n userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;\n}\n\ndeclare global {\n interface Window {\n __pwaInstallPrompt?: BeforeInstallPromptEvent | null;\n posthog?: { capture?: (event: string, props?: Record<string, unknown>) => void };\n }\n}\n\nexport interface InstallState {\n platform: Platform;\n iosBrowser: IOSBrowser | null;\n androidBrowser: AndroidBrowser | null;\n inAppApp: InAppApp | null;\n isInstallable: boolean;\n isInstalled: boolean;\n isDismissedSession: boolean;\n isDismissedPermanent: boolean;\n skipCount: number;\n variant: InstallVariant;\n}\n\nexport interface InstallActions {\n promptInstall: () => Promise<boolean>;\n dismissSession: () => void;\n dismissPermanent: () => void;\n copyLink: () => Promise<void>;\n reset: () => void;\n}\n\n// --- Regex canônicas (portadas verbatim de hook-old) ---------------------\n\nconst IOS_RE = /iPad|iPhone|iPod/;\nconst IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;\nconst ANDROID_RE = /Android/;\nconst IN_APP_RE =\n /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;\n\n// --- Constants ----------------------------------------------------------\n\nconst PERMANENT_DISMISS_REPROMPT_DAYS = 14;\nconst SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;\n\n// --- Storage keys -------------------------------------------------------\n\nconst storageKey = {\n sessionSkip: (slug: string) => `install:${slug}:session-skip`,\n dismissedAt: (slug: string) => `install:${slug}:dismissed-at`,\n installedAt: (slug: string) => `install:${slug}:installed-at`,\n skipCount: (slug: string) => `install:${slug}:skip-count`,\n};\n\n// --- Detection (pure functions) -----------------------------------------\n\nexport function detectPlatform(ua: string): Platform {\n if (IN_APP_RE.test(ua)) return 'in-app'; // MUST check first (G63)\n const isIOS = IOS_RE.test(ua);\n if (isIOS) {\n const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);\n return isSafari ? 'ios-safari' : 'ios-other';\n }\n if (ANDROID_RE.test(ua)) return 'android';\n return 'desktop';\n}\n\nexport function detectIOSBrowser(ua: string): IOSBrowser | null {\n if (!IOS_RE.test(ua)) return null;\n if (/CriOS/.test(ua)) return 'chrome';\n if (/FxiOS/.test(ua)) return 'firefox';\n if (/EdgiOS/.test(ua)) return 'edge';\n if (/Safari/.test(ua)) return 'safari';\n return 'other';\n}\n\nexport function detectAndroidBrowser(ua: string): AndroidBrowser | null {\n if (!ANDROID_RE.test(ua)) return null;\n if (/EdgA/.test(ua)) return 'edge';\n if (/OPR|OPT/.test(ua)) return 'opera';\n if (/SamsungBrowser/.test(ua)) return 'samsung';\n if (/Firefox/.test(ua)) return 'firefox';\n if (/Chrome/.test(ua)) return 'chrome';\n return 'other';\n}\n\nexport function detectInAppApp(ua: string): InAppApp | null {\n if (!IN_APP_RE.test(ua)) return null;\n if (/Instagram/i.test(ua)) return 'instagram';\n if (/FBAN|FBAV/.test(ua)) return 'facebook';\n if (/BytedanceWebview|TikTok/i.test(ua)) return 'tiktok';\n if (/WhatsApp/i.test(ua)) return 'whatsapp';\n if (/Twitter/i.test(ua)) return 'twitter';\n if (/LinkedIn/i.test(ua)) return 'linkedin';\n if (/Telegram/i.test(ua)) return 'telegram';\n if (/Line\\//i.test(ua)) return 'line';\n if (/Snapchat/i.test(ua)) return 'snapchat';\n if (/Pinterest/i.test(ua)) return 'pinterest';\n if (/MicroMessenger/i.test(ua)) return 'wechat';\n return 'other';\n}\n\nexport function detectStandalone(): { installed: boolean; source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null } {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return { installed: false, source: null };\n }\n const mm = window.matchMedia?.('(display-mode: standalone)');\n if (mm?.matches) return { installed: true, source: 'match_media' };\n const fs = window.matchMedia?.('(display-mode: fullscreen)');\n if (fs?.matches) return { installed: true, source: 'match_media' };\n // @ts-expect-error — legacy iOS Safari property\n if (navigator.standalone === true) return { installed: true, source: 'navigator_standalone' };\n return { installed: false, source: null };\n}\n\n// --- Analytics helper ----------------------------------------------------\n\nfunction track(event: string, props: Record<string, unknown>): void {\n if (typeof window === 'undefined') return;\n window.posthog?.capture?.(event, props);\n}\n\n// --- Variant picker ------------------------------------------------------\n\nfunction pickVariant(state: Omit<InstallState, 'variant'>): InstallVariant {\n if (state.isInstalled) return 'none';\n switch (state.platform) {\n case 'android':\n return state.isInstallable ? 'android-native' : 'android-manual';\n case 'ios-safari':\n return 'ios-safari';\n case 'ios-other':\n return 'ios-other';\n case 'in-app':\n return 'in-app';\n case 'desktop':\n return state.isInstallable ? 'desktop' : 'none';\n default:\n return 'none';\n }\n}\n\n// --- Hook ---------------------------------------------------------------\n\nfunction safeStorage(): { getItem(k: string): string | null; setItem(k: string, v: string): void; removeItem(k: string): void } | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n localStorage.setItem('__install_probe', '1');\n localStorage.removeItem('__install_probe');\n return localStorage;\n } catch {\n return null;\n }\n}\n\nfunction readPermanentDismiss(slug: string): { dismissed: boolean; dismissedAt: string | null } {\n const storage = safeStorage();\n if (!storage) return { dismissed: false, dismissedAt: null };\n const raw = storage.getItem(storageKey.dismissedAt(slug));\n if (!raw) return { dismissed: false, dismissedAt: null };\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };\n const daysAgo = (Date.now() - parsed) / (1000 * 60 * 60 * 24);\n return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };\n}\n\nfunction readInstalledMarker(slug: string): boolean {\n const storage = safeStorage();\n if (!storage) return false;\n return storage.getItem(storageKey.installedAt(slug)) !== null;\n}\n\nfunction readSkipCount(slug: string): number {\n const storage = safeStorage();\n if (!storage) return 0;\n const raw = storage.getItem(storageKey.skipCount(slug));\n const n = raw ? Number.parseInt(raw, 10) : 0;\n return Number.isFinite(n) && n >= 0 ? n : 0;\n}\n\nfunction readSessionSkip(slug: string): boolean {\n if (typeof sessionStorage === 'undefined') return false;\n try {\n return sessionStorage.getItem(storageKey.sessionSkip(slug)) === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * Hook principal. Passar o slug do app (usado pra namespacing de storage +\n * analytics). Componentes do template pegam via useTemplateConfig().slug.\n */\nexport function useInstallPrompt(slug: string): InstallState & InstallActions {\n const ua =\n typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string'\n ? navigator.userAgent\n : '';\n\n const platform = detectPlatform(ua);\n const iosBrowser = detectIOSBrowser(ua);\n const androidBrowser = detectAndroidBrowser(ua);\n const inAppApp = detectInAppApp(ua);\n\n const [isInstallable, setIsInstallable] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false;\n return window.__pwaInstallPrompt != null;\n });\n\n const [isInstalled, setIsInstalled] = useState<boolean>(() => {\n const { installed } = detectStandalone();\n return installed || readInstalledMarker(slug);\n });\n\n const [isDismissedSession, setIsDismissedSession] = useState<boolean>(() => readSessionSkip(slug));\n const [isDismissedPermanent, setIsDismissedPermanent] = useState<boolean>(() => readPermanentDismiss(slug).dismissed);\n const [skipCount, setSkipCount] = useState<number>(() => readSkipCount(slug));\n\n // beforeinstallprompt listener (fallback — shell main.tsx já captura antes,\n // mas se evento vier pós-React em algum edge case, pegamos aqui também)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (window.__pwaInstallPrompt) {\n setIsInstallable(true);\n }\n const onPrompt = (e: Event) => {\n e.preventDefault();\n window.__pwaInstallPrompt = e as BeforeInstallPromptEvent;\n setIsInstallable(true);\n };\n const onInstalled = () => {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n };\n window.addEventListener('beforeinstallprompt', onPrompt);\n window.addEventListener('appinstalled', onInstalled);\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt);\n window.removeEventListener('appinstalled', onInstalled);\n };\n }, [slug]);\n\n // Standalone changes (user instala durante sessão) → update gate\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia?.('(display-mode: standalone)');\n if (!mq) return;\n const handler = (e: MediaQueryListEvent) => {\n if (e.matches) {\n setIsInstalled(true);\n track('pwa_install_standalone_detected', { slug, source: 'match_media' });\n }\n };\n mq.addEventListener?.('change', handler);\n return () => mq.removeEventListener?.('change', handler);\n }, [slug]);\n\n const variant = pickVariant({\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n });\n\n const promptInstall = useCallback(async (): Promise<boolean> => {\n if (typeof window === 'undefined') return false;\n const prompt = window.__pwaInstallPrompt;\n if (!prompt) return false;\n\n track('pwa_install_prompt_clicked', { slug });\n\n try {\n await prompt.prompt();\n const { outcome } = await prompt.userChoice;\n track('pwa_install_prompt_outcome', { slug, outcome });\n if (outcome === 'accepted') {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }, [slug]);\n\n const dismissSession = useCallback(() => {\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(storageKey.sessionSkip(slug), 'true');\n } catch {\n /* ignore */\n }\n }\n const storage = safeStorage();\n const newCount = skipCount + 1;\n if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));\n setSkipCount(newCount);\n setIsDismissedSession(true);\n track('pwa_install_session_skip', { slug, platform, skip_count: newCount });\n }, [slug, skipCount, platform]);\n\n const dismissPermanent = useCallback(() => {\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.dismissedAt(slug), new Date().toISOString());\n setIsDismissedPermanent(true);\n track('pwa_install_permanent_dismiss', { slug, platform, prior_skip_count: skipCount });\n }, [slug, platform, skipCount]);\n\n const copyLink = useCallback(async (): Promise<void> => {\n if (typeof navigator === 'undefined' || typeof location === 'undefined') return;\n try {\n await navigator.clipboard?.writeText?.(location.href);\n } catch {\n /* ignore — caller surfaces via toast */\n }\n }, []);\n\n const reset = useCallback(() => {\n const storage = safeStorage();\n if (storage) {\n storage.removeItem(storageKey.dismissedAt(slug));\n storage.removeItem(storageKey.installedAt(slug));\n storage.removeItem(storageKey.skipCount(slug));\n }\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.removeItem(storageKey.sessionSkip(slug));\n } catch {\n /* ignore */\n }\n }\n setIsDismissedSession(false);\n setIsDismissedPermanent(false);\n setSkipCount(0);\n }, [slug]);\n\n return {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n variant,\n promptInstall,\n dismissSession,\n dismissPermanent,\n copyLink,\n reset,\n };\n}\n\n/**\n * Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook\n * retornado pra manter surface pequena — componente usa).\n */\nexport function shouldBlockInstall(state: InstallState, now: number = Date.now()): boolean {\n if (state.isInstalled) return false;\n if (state.variant === 'none') return false;\n if (state.isDismissedSession) return false;\n if (state.isDismissedPermanent) {\n // readPermanentDismiss já checou TTL; redundante, mas explicit pra tests\n void now;\n return false;\n }\n // Desktop só bloqueia se não-installable (banner soft vem por fora)\n if (state.platform === 'desktop' && !state.isInstallable) return false;\n if (state.platform === 'unknown') return false;\n return true;\n}\n\n/**\n * Exposto pra decidir se mostra \"Não me pergunte mais\".\n */\nexport function shouldShowPermanentOption(state: InstallState): boolean {\n return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;\n}\n","/**\n * Copy pt-BR do PWA install prompt. Hardcoded (template não tem i18n).\n * Design doc: docs/superpowers/specs/2026-04-22-p20-pwa-install-prompt-design.md\n */\n\nexport const INSTALL_COPY = {\n android: {\n native: {\n title: 'Instale no seu celular',\n subtitle: 'Acesso rápido, sem precisar do navegador',\n cta: 'Baixar',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n manual: {\n title: 'Instale em 2 toques',\n subtitle: 'Toque no menu do navegador e escolha \"Instalar aplicativo\"',\n step1: 'Toque no menu do navegador',\n step2: 'Escolha \"Instalar aplicativo\"',\n cta: 'Entendi',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n },\n iosSafari: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Na barra inferior do Safari',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no Safari',\n skipPermanent: 'Não me pergunte mais',\n },\n iosOther: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Geralmente no topo ou no menu do navegador',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n inApp: {\n instagram: {\n title: 'Pra instalar, abra fora do Instagram',\n step1: 'Toque em ⋯ (canto superior direito)',\n step2: 'Escolha \"Abrir no navegador externo\"',\n },\n facebook: {\n title: 'Pra instalar, abra fora do Facebook',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n tiktok: {\n title: 'Pra instalar, abra fora do TikTok',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no Safari\" (iOS) ou \"Abrir no Chrome\" (Android)',\n },\n whatsapp: {\n title: 'Pra instalar, abra fora do WhatsApp',\n step1: 'Toque longo no link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n twitter: {\n title: 'Pra instalar, abra fora do Twitter',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n linkedin: {\n title: 'Pra instalar, abra fora do LinkedIn',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n telegram: {\n title: 'Pra instalar, abra fora do Telegram',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n line: {\n title: 'Pra instalar, abra fora do LINE',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n snapchat: {\n title: 'Pra instalar, abra fora do Snapchat',\n step1: 'Mantenha pressionado o link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n pinterest: {\n title: 'Pra instalar, abra fora do Pinterest',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n wechat: {\n title: 'Pra instalar, abra fora do WeChat',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n other: {\n title: 'Abra no navegador do celular',\n step1: 'Toque no menu do app atual',\n step2: 'Escolha \"Abrir no Chrome\" ou \"Abrir no Safari\"',\n },\n copy: 'Copiar link',\n copiedToast: 'Link copiado. Cole no Chrome/Safari.',\n skip: 'Continuar aqui mesmo',\n skipPermanent: 'Não me pergunte mais',\n },\n desktop: {\n title: 'Instale no computador',\n subtitle: 'Acesso rápido',\n cta: 'Baixar',\n close: 'Fechar',\n },\n} as const;\n","/**\n * InstallSplash — layout full-screen compartilhado pras variants.\n * Variant renderiza seu próprio conteúdo via children.\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\n\ninterface InstallSplashProps {\n children: ReactNode;\n title: string;\n subtitle?: string;\n}\n\nexport function InstallSplash({ children, title, subtitle }: InstallSplashProps) {\n const { name, theme } = useTemplateConfig();\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"install-splash-title\"\n aria-describedby={subtitle ? 'install-splash-subtitle' : undefined}\n style={overlayStyle}\n >\n <div style={cardStyle}>\n <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>\n {iconUrl ? (\n <img\n src={iconUrl}\n alt={`Ícone de ${name}`}\n style={{ width: 80, height: 80, borderRadius: 20, objectFit: 'cover' }}\n />\n ) : (\n <div\n style={{\n width: 80,\n height: 80,\n borderRadius: 20,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 36,\n fontWeight: 700,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n\n <h1 id=\"install-splash-title\" style={titleStyle}>\n {title}\n </h1>\n\n {subtitle && (\n <p id=\"install-splash-subtitle\" style={subtitleStyle}>\n {subtitle}\n </p>\n )}\n\n <div style={{ marginTop: 24 }}>{children}</div>\n\n <p style={footerStyle}>por Hook</p>\n </div>\n </div>\n );\n}\n\n// --- Shared styles (exported pra reuso nas variants) -------------------\n\nexport const primaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '14px 20px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 17,\n fontWeight: 600,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const secondaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '12px 20px',\n background: 'transparent',\n color: 'var(--hook-color-primary)',\n border: '1px solid var(--hook-color-primary)',\n borderRadius: 999,\n fontSize: 15,\n fontWeight: 500,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const skipLinkStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n padding: '10px',\n marginTop: 8,\n background: 'transparent',\n color: '#555',\n border: 'none',\n fontSize: 14,\n textDecoration: 'underline',\n cursor: 'pointer',\n textAlign: 'center',\n};\n\nexport const skipPermanentLinkStyle: CSSProperties = {\n ...skipLinkStyle,\n color: '#999',\n fontSize: 13,\n marginTop: 4,\n};\n\n// --- Internal layout styles --------------------------------------------\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--hook-color-background, #fafafa)',\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 20,\n overflow: 'auto',\n};\n\nconst cardStyle: CSSProperties = {\n width: '100%',\n maxWidth: 420,\n padding: 24,\n textAlign: 'center',\n};\n\nconst titleStyle: CSSProperties = {\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 1.2,\n margin: '0 0 8px 0',\n color: '#111',\n};\n\nconst subtitleStyle: CSSProperties = {\n fontSize: 15,\n lineHeight: 1.4,\n color: '#555',\n margin: 0,\n};\n\nconst footerStyle: CSSProperties = {\n fontSize: 11,\n color: '#aaa',\n marginTop: 32,\n letterSpacing: 0.5,\n};\n","/**\n * SVG icons inline pro InstallGate. Template não depende de lucide-react;\n * copiamos só os 6 necessários (~1.8 KB total minified).\n *\n * Base: ícones de `lucide-react` com ajustes pra iOS share button (precisa\n * estética específica vs o genérico). Paths conferidos com as versões em\n * hook-old.\n */\n\nimport type { CSSProperties } from 'react';\n\ninterface IconProps {\n size?: number;\n style?: CSSProperties;\n 'aria-hidden'?: boolean | 'true' | 'false';\n className?: string;\n}\n\nconst defaultSvgProps = (size: number) => ({\n width: size,\n height: size,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n});\n\n/** iOS Safari share button — square com seta pra cima */\nexport function ShareIconIOS({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M12 2L12 15\" />\n <path d=\"M8 6L12 2L16 6\" />\n <path d=\"M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9\" />\n </svg>\n );\n}\n\n/** Share genérico — 3 círculos conectados */\nexport function ShareIconGeneric({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <path d=\"M8.59 13.51l6.83 3.98\" />\n <path d=\"M15.41 6.51l-6.82 3.98\" />\n </svg>\n );\n}\n\n/** Menu ⋮ (Android Chrome, Facebook) */\nexport function MenuDotsVerticalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"5\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Menu ⋯ (Instagram, TikTok — horizontal) */\nexport function MenuDotsHorizontalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Square + (iOS \"Adicionar à Tela de Início\") */\nexport function SquarePlusIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M12 8v8\" />\n <path d=\"M8 12h8\" />\n </svg>\n );\n}\n\n/** Download (Android Chrome \"Instalar aplicativo\") */\nexport function DownloadIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\n/** External link (pra in-app \"Abrir no navegador\") */\nexport function ExternalLinkIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n\n/** X (close) */\nexport function XIcon({ size = 20, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { DownloadIcon } from '../icons';\n\nexport function AndroidNativeVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.native;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <button\n data-testid=\"install-prompt-cta-android-native\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{ ...primaryButtonStyle, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}\n >\n <DownloadIcon size={18} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsVerticalIcon, DownloadIcon } from '../icons';\n\nexport function AndroidManualVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.manual;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title}>\n <Step n={1} icon={<MenuDotsVerticalIcon size={20} />}>\n {copy.step1}\n </Step>\n <Step n={2} icon={<DownloadIcon size={18} />}>\n {copy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-android-manual\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={primaryButtonStyle}\n >\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({ n, icon, children }: { n: number; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 15, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function Step({\n n,\n title,\n subtitle,\n visual,\n}: {\n n: number;\n title: string;\n subtitle?: string;\n visual?: ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 12,\n marginBottom: 16,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 15,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1 }}>\n <p style={{ margin: 0, fontSize: 15, fontWeight: 500, color: '#111', lineHeight: 1.3 }}>\n {title}\n </p>\n {subtitle && (\n <p style={{ margin: '4px 0 0 0', fontSize: 13, color: '#777' }}>{subtitle}</p>\n )}\n {visual}\n </div>\n </div>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSafariVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosSafari;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSOtherVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosOther;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import { useState } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsHorizontalIcon, MenuDotsVerticalIcon, ExternalLinkIcon } from '../icons';\n\nexport function InAppBrowserVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const app = state.inAppApp ?? 'other';\n const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;\n const copy = INSTALL_COPY.inApp;\n const showPermanent = shouldShowPermanentOption(state);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await actions.copyLink();\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Ícone varia: FB/Telegram usam ⋮; Instagram/TikTok/Twitter/LinkedIn/Pinterest usam ⋯\n const DotsIcon =\n app === 'facebook' || app === 'telegram' ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;\n\n return (\n <InstallSplash title={appCopy.title}>\n <Step n={1} icon={<DotsIcon size={20} />}>\n {appCopy.step1}\n </Step>\n <Step n={2} icon={<ExternalLinkIcon size={18} />}>\n {appCopy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-inapp-copy\"\n type=\"button\"\n onClick={() => void handleCopy()}\n style={{ ...primaryButtonStyle, marginTop: 8 }}\n >\n {copied ? copy.copiedToast : copy.copy}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({\n n,\n icon,\n children,\n}: {\n n: number;\n icon: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 14, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { useTemplateConfig } from '../../../internal/TemplateConfigContext';\nimport { INSTALL_COPY } from '../copy';\nimport { DownloadIcon, XIcon } from '../icons';\n\n/**\n * Desktop variant — NÃO-bloqueante. Banner soft no canto inferior direito.\n * Só aparece se `beforeinstallprompt` disparou (Chrome/Edge desktop).\n */\nexport function DesktopVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const { name, theme } = useTemplateConfig();\n const copy = INSTALL_COPY.desktop;\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n // Guard defensivo: só renderiza se installable\n if (!state.isInstallable) return null;\n\n return (\n <div\n role=\"complementary\"\n aria-label={copy.title}\n style={bannerStyle}\n >\n {iconUrl ? (\n <img\n src={iconUrl}\n alt=\"\"\n style={{ width: 40, height: 40, borderRadius: 10, objectFit: 'cover', flexShrink: 0 }}\n />\n ) : (\n <div\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 18,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: '#111' }}>{copy.title}</div>\n <div style={{ fontSize: 12, color: '#666' }}>{copy.subtitle}</div>\n </div>\n\n <button\n data-testid=\"install-prompt-cta-desktop\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{\n padding: '8px 14px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 13,\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n flexShrink: 0,\n }}\n >\n <DownloadIcon size={14} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-desktop-close\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n aria-label={copy.close}\n style={{\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: '#888',\n padding: 4,\n flexShrink: 0,\n }}\n >\n <XIcon size={16} />\n </button>\n </div>\n );\n}\n\nconst bannerStyle: CSSProperties = {\n position: 'fixed',\n bottom: 24,\n right: 24,\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 16px',\n background: '#fff',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 16,\n boxShadow: '0 10px 30px rgba(0,0,0,0.12)',\n maxWidth: 400,\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 * Dispara OAuth Google: redireciona pro backend `/api/auth/oauth/google/start`.\n * Fire-and-forget — a página é descarregada antes de qualquer retorno.\n * Volta pro app logado (ou com `?oauth_error=...` em falha).\n */\n loginWithGoogle: () => void;\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 loginWithGoogle: () => auth.loginWithGoogle(),\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","/**\n * Google Sign-In button seguindo as brand guidelines:\n * https://developers.google.com/identity/branding-guidelines\n *\n * Fundo branco, \"G\" logo oficial (SVG 4-color), label \"Continuar com Google\".\n * Usado por DefaultLoginScreen e DefaultSignupScreen. Apps podem substituir\n * os screens via props do <AppRoot> se quiserem branding próprio.\n */\n\ninterface GoogleSignInButtonProps {\n onClick: () => void;\n testId?: string;\n label?: string;\n}\n\nexport function GoogleSignInButton({\n onClick,\n testId = 'oauth-google',\n label = 'Continuar com Google',\n}: GoogleSignInButtonProps) {\n return (\n <button\n data-testid={testId}\n type=\"button\"\n onClick={onClick}\n style={{\n width: '100%',\n padding: '10px 12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 10,\n background: '#fff',\n color: '#1f1f1f',\n border: '1px solid #dadce0',\n borderRadius: 8,\n cursor: 'pointer',\n fontSize: 14,\n fontWeight: 500,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n >\n <GoogleGlyph />\n {label}\n </button>\n );\n}\n\nfunction GoogleGlyph() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z\"\n fill=\"#EA4335\"\n />\n </svg>\n );\n}\n","import { useEffect, useState } from 'react';\n\n/**\n * Lê `?oauth_error=<code>` na URL (setado pelo backend em falhas de callback)\n * e renderiza banner pt-BR. Remove o query param via `history.replaceState`\n * pra não aparecer de novo em refresh.\n *\n * Códigos vêm de `backend/src/auth/oauth/handler.ts` (ex: invalid_state,\n * access_denied, provider_error). Mapeamento explícito; fallback genérico.\n */\n\nconst ERROR_MESSAGES: Record<string, string> = {\n invalid_state: 'Sessão expirou, tente de novo.',\n access_denied: 'Você cancelou o login com Google.',\n provider_error: 'O Google recusou a autenticação. Tente de novo em alguns segundos.',\n invalid_return_to: 'Link inválido. Tente entrar novamente.',\n};\n\nfunction readErrorCode(): string | null {\n if (typeof window === 'undefined') return null;\n const code = new URLSearchParams(window.location.search).get('oauth_error');\n if (!code) return null;\n return code;\n}\n\nfunction stripErrorFromUrl() {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n url.searchParams.delete('oauth_error');\n window.history.replaceState({}, '', url.toString());\n}\n\nexport function OAuthErrorBanner() {\n const [code, setCode] = useState<string | null>(() => readErrorCode());\n\n useEffect(() => {\n if (code !== null) stripErrorFromUrl();\n }, [code]);\n\n if (!code) return null;\n\n const message = ERROR_MESSAGES[code] ?? 'Não conseguimos conectar ao Google. Tente de novo.';\n return (\n <div\n role=\"alert\"\n data-testid=\"oauth-error-banner\"\n style={{\n padding: '10px 12px',\n marginBottom: 16,\n background: '#fce8e6',\n color: '#a50e0e',\n borderRadius: 8,\n fontSize: 14,\n }}\n >\n {message}\n <button\n type=\"button\"\n onClick={() => setCode(null)}\n aria-label=\"Fechar\"\n style={{\n float: 'right',\n background: 'none',\n border: 'none',\n color: '#a50e0e',\n cursor: 'pointer',\n fontSize: 16,\n lineHeight: 1,\n padding: 0,\n }}\n >\n ×\n </button>\n </div>\n );\n}\n","import { useLoginForm } from '../hooks/useLoginForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport { GoogleSignInButton } from '../internal/GoogleSignInButton';\nimport { OAuthErrorBanner } from '../internal/OAuthErrorBanner';\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 <OAuthErrorBanner />\n\n <GoogleSignInButton onClick={f.loginWithGoogle} testId=\"login-oauth-google\" />\n\n <div\n aria-hidden=\"true\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n margin: '16px 0',\n color: 'rgba(0,0,0,0.45)',\n fontSize: 12,\n }}\n >\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n ou\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n </div>\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 * Dispara OAuth Google: mesmo endpoint que `useLoginForm.loginWithGoogle`.\n * Backend decide entre `signup_new`, `auto_linked`, ou `login_existing`\n * via `linkPolicy` — do ponto de vista do usuário \"criar conta com Google\"\n * e \"entrar com Google\" são o mesmo botão.\n */\n loginWithGoogle: () => void;\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 loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useSignupForm } from '../hooks/useSignupForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport { GoogleSignInButton } from '../internal/GoogleSignInButton';\nimport { OAuthErrorBanner } from '../internal/OAuthErrorBanner';\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\n <OAuthErrorBanner />\n\n <GoogleSignInButton onClick={f.loginWithGoogle} testId=\"signup-oauth-google\" />\n\n <div\n aria-hidden=\"true\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n margin: '16px 0',\n color: 'rgba(0,0,0,0.45)',\n fontSize: 12,\n }}\n >\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n ou\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n </div>\n\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 { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type PushUiState =\n | { kind: 'unsupported' }\n | { kind: 'ios_needs_install' }\n | { kind: 'prompt' }\n | { kind: 'subscribed' }\n | { kind: 'denied' }\n | { kind: 'error'; code: string; message: string };\n\nfunction detectIosNeedsInstall(): boolean {\n if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;\n const ua = navigator.userAgent || '';\n const isIos = /iPhone|iPad|iPod/.test(ua);\n if (!isIos) return false;\n const mm = window.matchMedia?.('(display-mode: standalone)');\n const standalone = mm?.matches === true;\n // @ts-expect-error — legacy iOS property\n const legacyStandalone = typeof navigator.standalone === 'boolean' ? navigator.standalone : false;\n return !(standalone || legacyStandalone);\n}\n\nfunction deriveState(push: ReturnType<typeof useHook>['push']): PushUiState {\n if (!push.isAvailable()) {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n const status = push.status();\n if (status === 'granted') return { kind: 'subscribed' };\n if (status === 'denied') return { kind: 'denied' };\n if (status === 'unsupported') {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n return { kind: 'prompt' };\n}\n\nexport function usePush() {\n const { push } = useHook();\n const [state, setState] = useState<PushUiState>(() => deriveState(push));\n\n useEffect(() => { setState(deriveState(push)); }, [push]);\n\n const subscribe = useCallback(async () => {\n try {\n await push.subscribe();\n setState({ kind: 'subscribed' });\n } catch (e: any) {\n const code = e?.code ?? 'push.unknown';\n const message = e?.message ?? 'Push subscription failed';\n if (code === 'push.permission_denied') setState({ kind: 'denied' });\n else setState({ kind: 'error', code, message });\n throw e;\n }\n }, [push]);\n\n const unsubscribe = useCallback(async () => {\n try {\n await push.unsubscribe();\n setState({ kind: 'prompt' });\n } catch (e: any) {\n setState({ kind: 'error', code: e?.code ?? 'push.unknown', message: e?.message ?? 'failed' });\n throw e;\n }\n }, [push]);\n\n return { state, subscribe, unsubscribe };\n}\n","import { usePush } from '../hooks/usePush';\n\nexport interface PushPromptTexts {\n cta: string;\n declineCta: string;\n iosInstallTitle: string;\n iosInstallBody: string;\n iosInstallCta?: string;\n deniedTitle: string;\n deniedBody: string;\n unsupportedBody: string;\n}\n\nexport interface PushPromptProps {\n texts: PushPromptTexts;\n onSubscribed?: () => void;\n onDeclined?: () => void;\n onInstallRequested?: () => void;\n className?: string;\n}\n\nexport function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps) {\n const { state, subscribe } = usePush();\n\n if (state.kind === 'subscribed') return null;\n\n if (state.kind === 'ios_needs_install') {\n return (\n <div className={className} role=\"region\" aria-label={texts.iosInstallTitle}>\n <h3>{texts.iosInstallTitle}</h3>\n <p>{texts.iosInstallBody}</p>\n {onInstallRequested && texts.iosInstallCta && (\n <button onClick={onInstallRequested}>{texts.iosInstallCta}</button>\n )}\n </div>\n );\n }\n\n if (state.kind === 'denied') {\n return (\n <div className={className} role=\"region\" aria-label={texts.deniedTitle}>\n <h3>{texts.deniedTitle}</h3>\n <p>{texts.deniedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'unsupported') {\n return (\n <div className={className} role=\"region\">\n <p>{texts.unsupportedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <div className={className} role=\"region\" aria-label=\"error\">\n <p>{state.message}</p>\n </div>\n );\n }\n\n // kind === 'prompt'\n return (\n <div className={className} role=\"region\">\n <button\n type=\"button\"\n onClick={async () => {\n try {\n await subscribe();\n onSubscribed?.();\n } catch {\n // state is already set to 'denied' or 'error' by usePush.subscribe\n }\n }}\n >\n {texts.cta}\n </button>\n {onDeclined && (\n <button type=\"button\" onClick={onDeclined}>\n {texts.declineCta}\n </button>\n )}\n </div>\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 { useHook } from '@hook-sdk/sdk';\nimport type { PlanInfo, PlanState } from '@hook-sdk/sdk';\n\n/**\n * Thin wrapper sobre `useHook().plan`. Existe pra apps importarem \"tudo\n * que precisam\" via `@hook-sdk/template` sem mudar de package pra cada\n * primitive, e pra manter espaço pra evoluir a API (ex: expor campos\n * derivados como `monthlyEquivalent()`) sem mexer no SDK.\n *\n * Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:\n *\n * const { data, initialLoadComplete } = usePlan();\n * if (!initialLoadComplete) return <Skeleton />;\n * if (!data) return null;\n * return <span>{formatBRL(data.priceCents)}</span>;\n */\nexport function usePlan(): PlanState {\n const { plan } = useHook();\n return plan;\n}\n\nexport type { PlanInfo, PlanState };\n","/**\n * Helpers de formatação de preço pro Hook.\n *\n * Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço\n * leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam\n * inline. Isso evita os dois patterns errados que já vimos em conversões\n * Lovable→Hook: (a) strings hardcoded \"R$ 19,90\" no JSX, (b) divisões ad-hoc\n * por 100 + `toFixed(2)` que ignoram locale.\n *\n * Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.\n */\n\n/**\n * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência\n * (callers que lidam com `yearlyPriceCents: number | null`).\n *\n * Examples:\n * formatBRL(1990) → \"R$ 19,90\"\n * formatBRL(4999) → \"R$ 49,99\"\n * formatBRL(23988) → \"R$ 239,88\"\n * formatBRL(0) → \"R$ 0,00\"\n * formatBRL(null) → \"\"\n */\nexport function formatBRL(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '';\n const reais = cents / 100;\n return new Intl.NumberFormat('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n }).format(reais);\n}\n\n/**\n * Deriva \"preço mensal\" a partir do preço anual (em centavos). Round half-up\n * pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.\n *\n * Não assume que o creator configurou yearlyPriceCents \"redondo\": se ele\n * setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880\n * (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).\n *\n * Example (papomaterno):\n * monthlyFromYearly(23988) = 1999 → formatBRL = \"R$ 19,99\"\n * monthlyFromYearly(23880) = 1990 → formatBRL = \"R$ 19,90\"\n */\nexport function monthlyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 12);\n}\n\n/**\n * Deriva \"preço por dia\" (365 dias) a partir do anual, em centavos. Útil\n * pra copy tipo \"apenas R$ 0,66 por dia, menos que um café\".\n *\n * Example:\n * dailyFromYearly(23988) = 66 → formatBRL = \"R$ 0,66\"\n */\nexport function dailyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 365);\n}\n\n/**\n * Deriva o preço-ancoragem (valor \"cheio\" riscado) como múltiplo do preço\n * real. Serve pra ancoragem psicológica em telas de paywall: mostra um valor\n * maior riscado antes do preço real pra o usuário sentir desconto.\n *\n * Com `anchorMultiplier` no `paywall_config`, o creator mantém só o preço\n * real no DB; a ancoragem acompanha automaticamente se o preço muda.\n *\n * Retorna `null` quando o multiplier não é utilizável (falta, ≤ 1, NaN,\n * Infinity). Caller deve cair no fallback (valor absoluto em\n * `paywall_config.anchorPriceCents`) ou pular a renderização da ancoragem.\n *\n * Examples:\n * computeAnchorCents(1999, 2.5) = 4998\n * computeAnchorCents(1999, undefined) = null\n * computeAnchorCents(1999, 1) = null // 1× não ancora nada\n * computeAnchorCents(1999, 0) = null\n * computeAnchorCents(1999, NaN) = null\n */\nexport function computeAnchorCents(\n baseCents: number,\n multiplier: number | null | undefined,\n): number | null {\n if (multiplier === null || multiplier === undefined) return null;\n if (!Number.isFinite(multiplier)) return null;\n if (multiplier <= 1) return null;\n return Math.round(baseCents * multiplier);\n}\n\n/**\n * Percentual de desconto (anchor → real), arredondado pra baixo pra nunca\n * overstate. Retorna 0 quando anchor ≤ real (sem desconto a mostrar).\n *\n * Examples:\n * discountPercent(4998, 1999) = 60 // (4998-1999)/4998 = 0.60...\n * discountPercent(3998, 1999) = 50\n * discountPercent(1000, 2000) = 0 // real > anchor\n * discountPercent(2000, 2000) = 0\n */\nexport function discountPercent(anchorCents: number, realCents: number): number {\n if (anchorCents <= realCents) return 0;\n return Math.floor(((anchorCents - realCents) / anchorCents) * 100);\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 { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { ReminderSlot } from '@hook-sdk/sdk';\n\nexport function useReminders() {\n const { push } = useHook();\n const r = push.reminders;\n const [reminders, setReminders] = useState<ReminderSlot[]>([]);\n const [loading, setLoading] = useState(true);\n\n const reload = useCallback(async () => {\n setLoading(true);\n try {\n const next = await r.list();\n setReminders(next);\n } finally {\n setLoading(false);\n }\n }, [r]);\n\n useEffect(() => { void reload(); }, [reload]);\n\n const setReminder = useCallback(async (input: {\n slot: string; timeLocal: string; timezone: string; enabled: boolean;\n }) => {\n await r.set(input);\n await reload();\n }, [r, reload]);\n\n const deleteReminder = useCallback(async (slot: string) => {\n await r.delete(slot);\n await reload();\n }, [r, reload]);\n\n const schedule = useCallback(async (items: Parameters<typeof r.schedule>[0]) => {\n return r.schedule(items);\n }, [r]);\n\n const setFallbacks = useCallback(async (items: Parameters<typeof r.setFallbacks>[0]) => {\n return r.setFallbacks(items);\n }, [r]);\n\n return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };\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","useRef","useState","useHook","jsx","jsx","jsx","useEffect","useState","useHook","Fragment","jsx","useEffect","useState","useHook","Fragment","jsx","useHook","useState","useEffect","useEffect","useRef","useCallback","useEffect","useState","jsx","jsx","jsxs","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","Step","jsx","jsxs","Step","jsx","jsxs","Step","useState","jsx","jsxs","useState","Step","jsx","jsxs","Fragment","jsx","jsxs","useRef","useEffect","Fragment","jsx","jsxs","useCallback","useMemo","useState","useHook","useHook","useState","useMemo","useCallback","jsx","jsxs","useEffect","useState","jsx","jsxs","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","useRef","useState","useCallback","useEffect","overlayStyle","useCallback","useEffect","useState","useHook","jsx","jsxs","PushPrompt","jsx","jsxs","useHook","useEffect","useHook","useHook","useEffect","useHook","useCallback","useEffect","useState","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/components/InstallGate/InstallGate.tsx","../src/hooks/useInstallPrompt.ts","../src/components/InstallGate/copy.ts","../src/components/InstallGate/InstallSplash.tsx","../src/components/InstallGate/icons.tsx","../src/components/InstallGate/variants/AndroidNativeVariant.tsx","../src/components/InstallGate/variants/AndroidManualVariant.tsx","../src/components/InstallGate/Step.tsx","../src/components/InstallGate/variants/IOSafariVariant.tsx","../src/components/InstallGate/variants/IOSOtherVariant.tsx","../src/components/InstallGate/variants/InAppBrowserVariant.tsx","../src/components/InstallGate/variants/DesktopVariant.tsx","../src/defaults/ErrorBoundary.tsx","../src/hooks/useLoginForm.ts","../src/errors.ts","../src/internal/GoogleSignInButton.tsx","../src/internal/OAuthErrorBanner.tsx","../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/hooks/usePlan.ts","../src/utils/price.ts","../src/hooks/usePush.ts","../src/components/PushPrompt.tsx","../src/defaults/EmptyState.tsx","../src/hooks/useAuthPrimitives.ts","../src/hooks/useSubscription.ts","../src/hooks/useReminders.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 { InstallGate } from './components/InstallGate';\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 <InstallGate>\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 </InstallGate>\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, useEffect, useMemo, useRef, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type {\n CheckoutCardData,\n CheckoutHolderInfo,\n CheckoutCycle,\n} from '@hook-sdk/sdk';\n\nexport type SubscriptionStatus = 'active' | 'trialing' | 'expired' | 'canceled' | 'past_due' | 'pending' | 'none';\nexport type PaymentMethod = 'card' | 'pix-auto' | 'pix-once';\n\nexport interface PixPending {\n method: 'pix-auto' | 'pix-once';\n qrCodePayload: string | null;\n qrCodeBase64: string | null;\n expiresAt: string | null;\n /**\n * Flipa `true` quando o polling detecta subscription ACTIVE/TRIAL (webhook\n * PAYMENT_RECEIVED ou AUTHORIZATION_ACTIVATED chegou). UI deve renderizar\n * confirmação visual nesse momento; após 2-3s chama `dismissPix` pra\n * limpar o modal e deixar SubscriptionGate liberar o app.\n */\n paid: boolean;\n}\n\nexport interface PaywallCheckoutArgs {\n cpf: string;\n cycle: CheckoutCycle;\n method: 'card' | 'pix-auto';\n /** Required when method === 'card'. */\n card?: CheckoutCardData;\n /** Required when method === 'card'. */\n holderInfo?: CheckoutHolderInfo;\n /** Optional; backend falls back to X-Forwarded-For when absent. */\n remoteIp?: string;\n}\n\n/**\n * Hook headless pro Paywall. Expõe status da subscription + ação\n * `checkout({cpf, cycle, method, card?, holderInfo?, remoteIp?})`.\n *\n * App Store substrate (2026-04-24, SDK 0.14.0+):\n *\n * - **method='card'** → backend tokeniza via Asaas `/v3/creditCard/tokenize`\n * e cria subscription com `nextDueDate = today + trialDays`. Sem cobrança\n * no day 0; trial corre enquanto Asaas já segura o instrumento. Caller\n * obrigatório passar `card` + `holderInfo`. Nada é persistido/loggado no\n * SDK — PAN/CVV transitam só no request HTTPS direto ao backend. Após\n * success chama `subscription.refresh()` pra SubscriptionGate liberar\n * o app automaticamente (status passa pra `trialing`).\n *\n * - **method='pix-auto'** → Pix Automático BACEN Jornada 3. User escaneia\n * QR 1x, autoriza débito recorrente no app do banco. Retorna QR via\n * `pixPending` (polling existing detecta ativação e flipa `paid=true`).\n *\n * Subscription real é atualizada via webhook (`PAYMENT_RECEIVED` ou\n * `PIX_AUTOMATIC_RECURRING_AUTHORIZATION_ACTIVATED`).\n */\nexport function usePaywallState() {\n const { subscription, plan } = useHook();\n const [opening, setOpening] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [pixPending, setPixPending] = useState<PixPending | null>(null);\n\n const status = subscription.status() as SubscriptionStatus;\n const daysLeftInTrial = subscription.daysLeftInTrial();\n // G68: expõe pra SubscriptionGate evitar piscar paywall enquanto o primeiro\n // /me não voltou. Flipa 1× por (appId, userId) no SDK, safe as render dep.\n const initialLoadComplete = subscription.initialLoadComplete;\n\n const availableMethods = useMemo<ReadonlyArray<'card' | 'pix-auto'>>(\n () => ['card', 'pix-auto'],\n [],\n );\n\n const priceCents = plan.data?.priceCents ?? 0;\n const yearlyPriceCents = plan.data?.yearlyPriceCents ?? null;\n\n const monthlyEquivalent = useCallback(\n (cycle: CheckoutCycle): number => {\n if (cycle === 'YEARLY' && yearlyPriceCents) {\n return Math.round(yearlyPriceCents / 12);\n }\n return priceCents;\n },\n [priceCents, yearlyPriceCents],\n );\n\n const checkout = useCallback(\n async (args: PaywallCheckoutArgs) => {\n setOpening(true);\n setError(null);\n setPixPending(null);\n try {\n if (args.method === 'card') {\n if (!args.card || !args.holderInfo) {\n throw new Error('card and holderInfo are required when method is \"card\"');\n }\n await subscription.checkout({\n method: 'card',\n cycle: args.cycle,\n cpf: args.cpf,\n card: args.card,\n holderInfo: args.holderInfo,\n ...(args.remoteIp ? { remoteIp: args.remoteIp } : {}),\n });\n // App Store model: no invoiceUrl redirect. Subscription is TRIAL\n // immediately; refresh propaga status e SubscriptionGate libera app.\n await subscription.refresh();\n setOpening(false);\n return;\n }\n // method === 'pix-auto'\n const result = await subscription.checkout({\n method: 'pix-auto',\n cycle: args.cycle,\n cpf: args.cpf,\n });\n if (result.method !== 'pix-auto') {\n throw new Error(`unexpected checkout result method: ${result.method}`);\n }\n setPixPending({\n method: 'pix-auto',\n qrCodePayload: result.qrCodePayload,\n qrCodeBase64: result.qrCodeBase64,\n expiresAt: null,\n paid: false,\n });\n setOpening(false);\n } catch (err) {\n setError(err as Error);\n setOpening(false);\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 const dismissPix = useCallback(() => setPixPending(null), []);\n\n // Pix polling: enquanto pixPending && !paid, poll subscription.refresh() a\n // cada 3s. Quando status virar ACTIVE/TRIAL, marca `paid: true` (não limpa\n // pixPending) — UI mostra \"Pagamento confirmado!\". Após ~3min sem detectar,\n // para de pollar (user fecha o modal manualmente ou volta depois e recarrega).\n const subRef = useRef(subscription);\n subRef.current = subscription;\n useEffect(() => {\n if (!pixPending || pixPending.paid) return;\n let attempts = 0;\n const MAX_ATTEMPTS = 60; // 3min @ 3s\n let cancelled = false;\n const tick = async () => {\n if (cancelled || attempts >= MAX_ATTEMPTS) return;\n attempts++;\n try {\n await subRef.current.refresh();\n if (cancelled) return;\n const s = subRef.current.status() as SubscriptionStatus;\n if (s === 'active' || s === 'trialing') {\n setPixPending((prev) => (prev ? { ...prev, paid: true } : prev));\n return;\n }\n } catch {\n // swallow — http.ts já tem retry/backoff pra transient errors\n }\n if (!cancelled) setTimeout(tick, 3000);\n };\n setTimeout(tick, 3000);\n return () => {\n cancelled = true;\n };\n }, [pixPending]);\n\n return {\n status,\n daysLeftInTrial,\n initialLoadComplete,\n checkout,\n cancel,\n opening,\n error,\n pixPending,\n dismissPix,\n availableMethods,\n monthlyEquivalent,\n };\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, initialLoadComplete } = usePaywallState();\n\n // free: nunca bloqueia, independente de status.\n if (mode === 'free') return <>{children}</>;\n // G68: evita flash de paywall no cold start antes do 1º /me resolver.\n // Quando não há cache local (primeiro login, novo device), sub === null e\n // status='none' — BLOCKING dispararia o paywall por ~1-2s até o fetch\n // voltar. Com cache (user já pago), sub já vem populado do localStorage\n // e status reflete o último valor conhecido → sem flash.\n // Render nulo (em vez de paywall/spinner) porque AuthGate/AppShell já\n // cobrem o skeleton visual. Flash rápido de nada > flash de paywall.\n if (!initialLoadComplete && status === 'none') return null;\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, useState, type ReactNode } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport { useTemplateConfig } from './TemplateConfigContext';\n\nconst SAFETY_TIMEOUT_MS = 3000;\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 * Comporta-se como gate: enquanto o bulkRead está em voo, renderiza `null`.\n * Libera children quando o cache vira `primed` (hit) ou `disabled` (falha).\n *\n * **G77**: essa semântica de gate é o que impede o flicker \"receita aparece\n * → some → pede onboarding\" pós-pagamento. Antes (≤ 0.7.3) o componente era\n * fire-and-forget: children montavam com cache `unknown`, `usePersistedState`\n * retornava `defaultValue`, e guards app-side que checavam \"tem filho?\"\n * disparavam redirect com dado fake. Agora o gate garante que `bulkRead`\n * resolveu antes de qualquer render dependente ocorrer.\n *\n * Safety timeout (3s): se `bulkRead` travar em rede adversa, libera render\n * mesmo assim e loga via `console.warn`. Degradação graceful sobre tela\n * branca eterna.\n *\n * Montado dentro de `AuthGate` → só dispara pós-login. Se `persistedKeys`\n * estiver ausente/vazio, é no-op: cache fica `disabled`, gate libera\n * imediatamente e o comportamento legacy (N GETs individuais) permanece.\n */\nexport function PersistedKeysPrefetch({ children }: { children: ReactNode }) {\n const { appData } = useHook();\n const config = useTemplateConfig();\n const hasKeys = !!config.persistedKeys && config.persistedKeys.length > 0;\n const [ready, setReady] = useState<boolean>(!hasKeys);\n\n useEffect(() => {\n const keys = config.persistedKeys;\n if (!keys || keys.length === 0) {\n setReady(true);\n return;\n }\n let cancelled = false;\n appData.cache.startPrefetch(keys, (ks) => appData.bulkRead(ks));\n void appData.cache.waitForPrimed(SAFETY_TIMEOUT_MS).then((result) => {\n if (cancelled) return;\n if (result === 'timeout') {\n console.warn(\n `[@hook-sdk/template] PersistedKeysPrefetch: bulk-read não completou em ${SAFETY_TIMEOUT_MS}ms. Liberando render mesmo assim — usePersistedState pode expor defaultValue até o fetch terminar (G77).`,\n );\n }\n setReady(true);\n });\n return () => {\n cancelled = true;\n };\n }, [appData, config.persistedKeys]);\n\n if (!ready) return null;\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","/**\n * InstallGate — wrapper que decide entre splash bloqueante e pass-through.\n *\n * Colocado em AppRoot entre ThemeProvider e AuthGate. Ver ADR-017 + doc 16.\n *\n * Comportamento:\n * - feature `install_prompt` desabilitado em app.config.json → renderiza children\n * - Standalone detectado → renderiza children\n * - Platform == desktop + !installable → renderiza children (sem banner)\n * - Platform == desktop + installable → renderiza children + banner soft lateral\n * - Mobile/in-app + não-installed + não-dismissed → splash bloqueante (substitui children)\n * - Mobile dismissido → renderiza children\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\nimport { shouldBlockInstall, useInstallPrompt } from '../../hooks/useInstallPrompt';\nimport { AndroidNativeVariant } from './variants/AndroidNativeVariant';\nimport { AndroidManualVariant } from './variants/AndroidManualVariant';\nimport { IOSafariVariant } from './variants/IOSafariVariant';\nimport { IOSOtherVariant } from './variants/IOSOtherVariant';\nimport { InAppBrowserVariant } from './variants/InAppBrowserVariant';\nimport { DesktopVariant } from './variants/DesktopVariant';\n\ninterface InstallGateProps {\n children: ReactNode;\n}\n\nexport function InstallGate({ children }: InstallGateProps) {\n const { slug, features_enabled } = useTemplateConfig();\n const enabled = features_enabled.includes('install_prompt' as never);\n\n const installState = useInstallPrompt(slug);\n const shouldBlock = enabled && shouldBlockInstall(installState);\n\n // Analytics: dispara `pwa_install_splash_shown` 1× por sessão+variant\n const trackedRef = useRef<string | null>(null);\n useEffect(() => {\n if (!shouldBlock) return;\n if (typeof window === 'undefined') return;\n const variantKey = `${slug}:${installState.variant}`;\n if (trackedRef.current === variantKey) return;\n trackedRef.current = variantKey;\n window.posthog?.capture?.('pwa_install_splash_shown', {\n slug,\n platform: installState.platform,\n browser: installState.iosBrowser ?? installState.androidBrowser ?? null,\n in_app_app: installState.inAppApp,\n variant: installState.variant,\n });\n }, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);\n\n if (!enabled) return <>{children}</>;\n if (installState.isInstalled) return <>{children}</>;\n\n // Desktop: banner soft, children renderiza normal em paralelo\n if (installState.variant === 'desktop') {\n const showBanner = !installState.isDismissedSession && !installState.isDismissedPermanent;\n return (\n <>\n {children}\n {showBanner && <DesktopVariant state={installState} actions={installState} />}\n </>\n );\n }\n\n if (!shouldBlock) return <>{children}</>;\n\n // Mobile / in-app: splash bloqueante substitui children\n switch (installState.variant) {\n case 'android-native':\n return <AndroidNativeVariant state={installState} actions={installState} />;\n case 'android-manual':\n return <AndroidManualVariant state={installState} actions={installState} />;\n case 'ios-safari':\n return <IOSafariVariant state={installState} actions={installState} />;\n case 'ios-other':\n return <IOSOtherVariant state={installState} actions={installState} />;\n case 'in-app':\n return <InAppBrowserVariant state={installState} actions={installState} />;\n case 'none':\n default:\n return <>{children}</>;\n }\n}\n","/**\n * useInstallPrompt — headless hook pra PWA install prompt.\n *\n * Responsabilidades:\n * - Detectar plataforma (Android / iOS Safari / iOS outros / in-app / desktop)\n * - Detectar browser específico (Chrome, Firefox, Samsung, Instagram, ...)\n * - Detectar standalone mode (PWA já instalado)\n * - Gerenciar dismissal graduada (session → permanente 14d)\n * - Expor `promptInstall()` que dispara `window.__pwaInstallPrompt.prompt()`\n *\n * Não renderiza UI. Componente `<InstallGate>` consome o hook e renderiza.\n *\n * Porta regexes + lógica de `hook-old/src/hooks/usePWAInstall.ts` com\n * divergências deliberadas (ver docs/adr/017 + P20 plan):\n * - enum InAppApp granular pra copy por rede social (G60 amendment)\n * - dismissal graduada em vez de permanente direto\n * - TTL de 14d no permanent dismiss\n * - tracking `skipCount` separado\n *\n * Gotchas de referência:\n * - G61: beforeinstallprompt capturado pré-React (shell main.tsx faz)\n * - G62: distinção ios-safari vs ios-other (Chrome iOS não instala)\n * - G63: in-app browsers checados ANTES de Android/iOS\n */\n\nimport { useCallback, useEffect, useState } from 'react';\n\n// --- Types ---------------------------------------------------------------\n\nexport type Platform =\n | 'android'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'unknown';\n\nexport type IOSBrowser = 'safari' | 'chrome' | 'firefox' | 'edge' | 'other';\n\nexport type AndroidBrowser =\n | 'chrome'\n | 'firefox'\n | 'opera'\n | 'samsung'\n | 'edge'\n | 'other';\n\nexport type InAppApp =\n | 'instagram'\n | 'facebook'\n | 'tiktok'\n | 'whatsapp'\n | 'twitter'\n | 'linkedin'\n | 'telegram'\n | 'line'\n | 'snapchat'\n | 'pinterest'\n | 'wechat'\n | 'other';\n\nexport type InstallVariant =\n | 'android-native'\n | 'android-manual'\n | 'ios-safari'\n | 'ios-other'\n | 'in-app'\n | 'desktop'\n | 'none';\n\ninterface BeforeInstallPromptEvent extends Event {\n prompt: () => Promise<void>;\n userChoice: Promise<{ outcome: 'accepted' | 'dismissed'; platform: string }>;\n}\n\ndeclare global {\n interface Window {\n __pwaInstallPrompt?: BeforeInstallPromptEvent | null;\n posthog?: { capture?: (event: string, props?: Record<string, unknown>) => void };\n }\n}\n\nexport interface InstallState {\n platform: Platform;\n iosBrowser: IOSBrowser | null;\n androidBrowser: AndroidBrowser | null;\n inAppApp: InAppApp | null;\n isInstallable: boolean;\n isInstalled: boolean;\n isDismissedSession: boolean;\n isDismissedPermanent: boolean;\n skipCount: number;\n variant: InstallVariant;\n}\n\nexport interface InstallActions {\n promptInstall: () => Promise<boolean>;\n dismissSession: () => void;\n dismissPermanent: () => void;\n copyLink: () => Promise<void>;\n reset: () => void;\n}\n\n// --- Regex canônicas (portadas verbatim de hook-old) ---------------------\n\nconst IOS_RE = /iPad|iPhone|iPod/;\nconst IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;\nconst ANDROID_RE = /Android/;\nconst IN_APP_RE =\n /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;\n\n// --- Constants ----------------------------------------------------------\n\nconst PERMANENT_DISMISS_REPROMPT_DAYS = 14;\nconst SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;\n\n// --- Storage keys -------------------------------------------------------\n\nconst storageKey = {\n sessionSkip: (slug: string) => `install:${slug}:session-skip`,\n dismissedAt: (slug: string) => `install:${slug}:dismissed-at`,\n installedAt: (slug: string) => `install:${slug}:installed-at`,\n skipCount: (slug: string) => `install:${slug}:skip-count`,\n};\n\n// --- Detection (pure functions) -----------------------------------------\n\nexport function detectPlatform(ua: string): Platform {\n if (IN_APP_RE.test(ua)) return 'in-app'; // MUST check first (G63)\n const isIOS = IOS_RE.test(ua);\n if (isIOS) {\n const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);\n return isSafari ? 'ios-safari' : 'ios-other';\n }\n if (ANDROID_RE.test(ua)) return 'android';\n return 'desktop';\n}\n\nexport function detectIOSBrowser(ua: string): IOSBrowser | null {\n if (!IOS_RE.test(ua)) return null;\n if (/CriOS/.test(ua)) return 'chrome';\n if (/FxiOS/.test(ua)) return 'firefox';\n if (/EdgiOS/.test(ua)) return 'edge';\n if (/Safari/.test(ua)) return 'safari';\n return 'other';\n}\n\nexport function detectAndroidBrowser(ua: string): AndroidBrowser | null {\n if (!ANDROID_RE.test(ua)) return null;\n if (/EdgA/.test(ua)) return 'edge';\n if (/OPR|OPT/.test(ua)) return 'opera';\n if (/SamsungBrowser/.test(ua)) return 'samsung';\n if (/Firefox/.test(ua)) return 'firefox';\n if (/Chrome/.test(ua)) return 'chrome';\n return 'other';\n}\n\nexport function detectInAppApp(ua: string): InAppApp | null {\n if (!IN_APP_RE.test(ua)) return null;\n if (/Instagram/i.test(ua)) return 'instagram';\n if (/FBAN|FBAV/.test(ua)) return 'facebook';\n if (/BytedanceWebview|TikTok/i.test(ua)) return 'tiktok';\n if (/WhatsApp/i.test(ua)) return 'whatsapp';\n if (/Twitter/i.test(ua)) return 'twitter';\n if (/LinkedIn/i.test(ua)) return 'linkedin';\n if (/Telegram/i.test(ua)) return 'telegram';\n if (/Line\\//i.test(ua)) return 'line';\n if (/Snapchat/i.test(ua)) return 'snapchat';\n if (/Pinterest/i.test(ua)) return 'pinterest';\n if (/MicroMessenger/i.test(ua)) return 'wechat';\n return 'other';\n}\n\nexport function detectStandalone(): { installed: boolean; source: 'match_media' | 'navigator_standalone' | 'storage_marker' | null } {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n return { installed: false, source: null };\n }\n const mm = window.matchMedia?.('(display-mode: standalone)');\n if (mm?.matches) return { installed: true, source: 'match_media' };\n const fs = window.matchMedia?.('(display-mode: fullscreen)');\n if (fs?.matches) return { installed: true, source: 'match_media' };\n // @ts-expect-error — legacy iOS Safari property\n if (navigator.standalone === true) return { installed: true, source: 'navigator_standalone' };\n return { installed: false, source: null };\n}\n\n// --- Analytics helper ----------------------------------------------------\n\nfunction track(event: string, props: Record<string, unknown>): void {\n if (typeof window === 'undefined') return;\n window.posthog?.capture?.(event, props);\n}\n\n// --- Variant picker ------------------------------------------------------\n\nfunction pickVariant(state: Omit<InstallState, 'variant'>): InstallVariant {\n if (state.isInstalled) return 'none';\n switch (state.platform) {\n case 'android':\n return state.isInstallable ? 'android-native' : 'android-manual';\n case 'ios-safari':\n return 'ios-safari';\n case 'ios-other':\n return 'ios-other';\n case 'in-app':\n return 'in-app';\n case 'desktop':\n return state.isInstallable ? 'desktop' : 'none';\n default:\n return 'none';\n }\n}\n\n// --- Hook ---------------------------------------------------------------\n\nfunction safeStorage(): { getItem(k: string): string | null; setItem(k: string, v: string): void; removeItem(k: string): void } | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n localStorage.setItem('__install_probe', '1');\n localStorage.removeItem('__install_probe');\n return localStorage;\n } catch {\n return null;\n }\n}\n\nfunction readPermanentDismiss(slug: string): { dismissed: boolean; dismissedAt: string | null } {\n const storage = safeStorage();\n if (!storage) return { dismissed: false, dismissedAt: null };\n const raw = storage.getItem(storageKey.dismissedAt(slug));\n if (!raw) return { dismissed: false, dismissedAt: null };\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };\n const daysAgo = (Date.now() - parsed) / (1000 * 60 * 60 * 24);\n return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };\n}\n\nfunction readInstalledMarker(slug: string): boolean {\n const storage = safeStorage();\n if (!storage) return false;\n return storage.getItem(storageKey.installedAt(slug)) !== null;\n}\n\nfunction readSkipCount(slug: string): number {\n const storage = safeStorage();\n if (!storage) return 0;\n const raw = storage.getItem(storageKey.skipCount(slug));\n const n = raw ? Number.parseInt(raw, 10) : 0;\n return Number.isFinite(n) && n >= 0 ? n : 0;\n}\n\nfunction readSessionSkip(slug: string): boolean {\n if (typeof sessionStorage === 'undefined') return false;\n try {\n return sessionStorage.getItem(storageKey.sessionSkip(slug)) === 'true';\n } catch {\n return false;\n }\n}\n\n/**\n * Hook principal. Passar o slug do app (usado pra namespacing de storage +\n * analytics). Componentes do template pegam via useTemplateConfig().slug.\n */\nexport function useInstallPrompt(slug: string): InstallState & InstallActions {\n const ua =\n typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string'\n ? navigator.userAgent\n : '';\n\n const platform = detectPlatform(ua);\n const iosBrowser = detectIOSBrowser(ua);\n const androidBrowser = detectAndroidBrowser(ua);\n const inAppApp = detectInAppApp(ua);\n\n const [isInstallable, setIsInstallable] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false;\n return window.__pwaInstallPrompt != null;\n });\n\n const [isInstalled, setIsInstalled] = useState<boolean>(() => {\n const { installed } = detectStandalone();\n return installed || readInstalledMarker(slug);\n });\n\n const [isDismissedSession, setIsDismissedSession] = useState<boolean>(() => readSessionSkip(slug));\n const [isDismissedPermanent, setIsDismissedPermanent] = useState<boolean>(() => readPermanentDismiss(slug).dismissed);\n const [skipCount, setSkipCount] = useState<number>(() => readSkipCount(slug));\n\n // beforeinstallprompt listener (fallback — shell main.tsx já captura antes,\n // mas se evento vier pós-React em algum edge case, pegamos aqui também)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n if (window.__pwaInstallPrompt) {\n setIsInstallable(true);\n }\n const onPrompt = (e: Event) => {\n e.preventDefault();\n window.__pwaInstallPrompt = e as BeforeInstallPromptEvent;\n setIsInstallable(true);\n };\n const onInstalled = () => {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n };\n window.addEventListener('beforeinstallprompt', onPrompt);\n window.addEventListener('appinstalled', onInstalled);\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt);\n window.removeEventListener('appinstalled', onInstalled);\n };\n }, [slug]);\n\n // Standalone changes (user instala durante sessão) → update gate\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const mq = window.matchMedia?.('(display-mode: standalone)');\n if (!mq) return;\n const handler = (e: MediaQueryListEvent) => {\n if (e.matches) {\n setIsInstalled(true);\n track('pwa_install_standalone_detected', { slug, source: 'match_media' });\n }\n };\n mq.addEventListener?.('change', handler);\n return () => mq.removeEventListener?.('change', handler);\n }, [slug]);\n\n const variant = pickVariant({\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n });\n\n const promptInstall = useCallback(async (): Promise<boolean> => {\n if (typeof window === 'undefined') return false;\n const prompt = window.__pwaInstallPrompt;\n if (!prompt) return false;\n\n track('pwa_install_prompt_clicked', { slug });\n\n try {\n await prompt.prompt();\n const { outcome } = await prompt.userChoice;\n track('pwa_install_prompt_outcome', { slug, outcome });\n if (outcome === 'accepted') {\n setIsInstalled(true);\n setIsInstallable(false);\n window.__pwaInstallPrompt = null;\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.installedAt(slug), new Date().toISOString());\n return true;\n }\n return false;\n } catch {\n return false;\n }\n }, [slug]);\n\n const dismissSession = useCallback(() => {\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(storageKey.sessionSkip(slug), 'true');\n } catch {\n /* ignore */\n }\n }\n const storage = safeStorage();\n const newCount = skipCount + 1;\n if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));\n setSkipCount(newCount);\n setIsDismissedSession(true);\n track('pwa_install_session_skip', { slug, platform, skip_count: newCount });\n }, [slug, skipCount, platform]);\n\n const dismissPermanent = useCallback(() => {\n const storage = safeStorage();\n if (storage) storage.setItem(storageKey.dismissedAt(slug), new Date().toISOString());\n setIsDismissedPermanent(true);\n track('pwa_install_permanent_dismiss', { slug, platform, prior_skip_count: skipCount });\n }, [slug, platform, skipCount]);\n\n const copyLink = useCallback(async (): Promise<void> => {\n if (typeof navigator === 'undefined' || typeof location === 'undefined') return;\n try {\n await navigator.clipboard?.writeText?.(location.href);\n } catch {\n /* ignore — caller surfaces via toast */\n }\n }, []);\n\n const reset = useCallback(() => {\n const storage = safeStorage();\n if (storage) {\n storage.removeItem(storageKey.dismissedAt(slug));\n storage.removeItem(storageKey.installedAt(slug));\n storage.removeItem(storageKey.skipCount(slug));\n }\n if (typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.removeItem(storageKey.sessionSkip(slug));\n } catch {\n /* ignore */\n }\n }\n setIsDismissedSession(false);\n setIsDismissedPermanent(false);\n setSkipCount(0);\n }, [slug]);\n\n return {\n platform,\n iosBrowser,\n androidBrowser,\n inAppApp,\n isInstallable,\n isInstalled,\n isDismissedSession,\n isDismissedPermanent,\n skipCount,\n variant,\n promptInstall,\n dismissSession,\n dismissPermanent,\n copyLink,\n reset,\n };\n}\n\n/**\n * Exposto pra InstallGate decidir se renderiza splash (não faz parte do hook\n * retornado pra manter surface pequena — componente usa).\n */\nexport function shouldBlockInstall(state: InstallState, now: number = Date.now()): boolean {\n if (state.isInstalled) return false;\n if (state.variant === 'none') return false;\n if (state.isDismissedSession) return false;\n if (state.isDismissedPermanent) {\n // readPermanentDismiss já checou TTL; redundante, mas explicit pra tests\n void now;\n return false;\n }\n // Desktop só bloqueia se não-installable (banner soft vem por fora)\n if (state.platform === 'desktop' && !state.isInstallable) return false;\n if (state.platform === 'unknown') return false;\n return true;\n}\n\n/**\n * Exposto pra decidir se mostra \"Não me pergunte mais\".\n */\nexport function shouldShowPermanentOption(state: InstallState): boolean {\n return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;\n}\n","/**\n * Copy pt-BR do PWA install prompt. Hardcoded (template não tem i18n).\n * Design doc: docs/superpowers/specs/2026-04-22-p20-pwa-install-prompt-design.md\n */\n\nexport const INSTALL_COPY = {\n android: {\n native: {\n title: 'Instale no seu celular',\n subtitle: 'Acesso rápido, sem precisar do navegador',\n cta: 'Baixar',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n manual: {\n title: 'Instale em 2 toques',\n subtitle: 'Toque no menu do navegador e escolha \"Instalar aplicativo\"',\n step1: 'Toque no menu do navegador',\n step2: 'Escolha \"Instalar aplicativo\"',\n cta: 'Entendi',\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n },\n iosSafari: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Na barra inferior do Safari',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no Safari',\n skipPermanent: 'Não me pergunte mais',\n },\n iosOther: {\n title: 'Adicione à sua Tela de Início',\n subtitle: 'Siga os 3 passos',\n step1: {\n title: 'Toque em Compartilhar',\n subtitle: 'Geralmente no topo ou no menu do navegador',\n },\n step2: {\n title: 'Role e toque em \"Adicionar à Tela de Início\"',\n iconLabel: 'Adicionar à Tela de Início',\n },\n step3: {\n title: 'Toque em \"Adicionar\" pra confirmar',\n buttonLabel: 'Adicionar',\n },\n skip: 'Continuar no navegador',\n skipPermanent: 'Não me pergunte mais',\n },\n inApp: {\n instagram: {\n title: 'Pra instalar, abra fora do Instagram',\n step1: 'Toque em ⋯ (canto superior direito)',\n step2: 'Escolha \"Abrir no navegador externo\"',\n },\n facebook: {\n title: 'Pra instalar, abra fora do Facebook',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n tiktok: {\n title: 'Pra instalar, abra fora do TikTok',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no Safari\" (iOS) ou \"Abrir no Chrome\" (Android)',\n },\n whatsapp: {\n title: 'Pra instalar, abra fora do WhatsApp',\n step1: 'Toque longo no link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n twitter: {\n title: 'Pra instalar, abra fora do Twitter',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n linkedin: {\n title: 'Pra instalar, abra fora do LinkedIn',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n telegram: {\n title: 'Pra instalar, abra fora do Telegram',\n step1: 'Toque em ⋮',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n line: {\n title: 'Pra instalar, abra fora do LINE',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n snapchat: {\n title: 'Pra instalar, abra fora do Snapchat',\n step1: 'Mantenha pressionado o link',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n pinterest: {\n title: 'Pra instalar, abra fora do Pinterest',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n wechat: {\n title: 'Pra instalar, abra fora do WeChat',\n step1: 'Toque em ⋯',\n step2: 'Escolha \"Abrir no navegador\"',\n },\n other: {\n title: 'Abra no navegador do celular',\n step1: 'Toque no menu do app atual',\n step2: 'Escolha \"Abrir no Chrome\" ou \"Abrir no Safari\"',\n },\n copy: 'Copiar link',\n copiedToast: 'Link copiado. Cole no Chrome/Safari.',\n skip: 'Continuar aqui mesmo',\n skipPermanent: 'Não me pergunte mais',\n },\n desktop: {\n title: 'Instale no computador',\n subtitle: 'Acesso rápido',\n cta: 'Baixar',\n close: 'Fechar',\n },\n} as const;\n","/**\n * InstallSplash — layout full-screen compartilhado pras variants.\n * Variant renderiza seu próprio conteúdo via children.\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useTemplateConfig } from '../../internal/TemplateConfigContext';\n\ninterface InstallSplashProps {\n children: ReactNode;\n title: string;\n subtitle?: string;\n}\n\nexport function InstallSplash({ children, title, subtitle }: InstallSplashProps) {\n const { name, theme } = useTemplateConfig();\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"install-splash-title\"\n aria-describedby={subtitle ? 'install-splash-subtitle' : undefined}\n style={overlayStyle}\n >\n <div style={cardStyle}>\n <div style={{ display: 'flex', justifyContent: 'center', marginBottom: 16 }}>\n {iconUrl ? (\n <img\n src={iconUrl}\n alt={`Ícone de ${name}`}\n style={{ width: 80, height: 80, borderRadius: 20, objectFit: 'cover' }}\n />\n ) : (\n <div\n style={{\n width: 80,\n height: 80,\n borderRadius: 20,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 36,\n fontWeight: 700,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n </div>\n\n <h1 id=\"install-splash-title\" style={titleStyle}>\n {title}\n </h1>\n\n {subtitle && (\n <p id=\"install-splash-subtitle\" style={subtitleStyle}>\n {subtitle}\n </p>\n )}\n\n <div style={{ marginTop: 24 }}>{children}</div>\n\n <p style={footerStyle}>por Hook</p>\n </div>\n </div>\n );\n}\n\n// --- Shared styles (exported pra reuso nas variants) -------------------\n\nexport const primaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '14px 20px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 17,\n fontWeight: 600,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const secondaryButtonStyle: CSSProperties = {\n width: '100%',\n padding: '12px 20px',\n background: 'transparent',\n color: 'var(--hook-color-primary)',\n border: '1px solid var(--hook-color-primary)',\n borderRadius: 999,\n fontSize: 15,\n fontWeight: 500,\n cursor: 'pointer',\n marginBottom: 12,\n};\n\nexport const skipLinkStyle: CSSProperties = {\n display: 'block',\n width: '100%',\n padding: '10px',\n marginTop: 8,\n background: 'transparent',\n color: '#555',\n border: 'none',\n fontSize: 14,\n textDecoration: 'underline',\n cursor: 'pointer',\n textAlign: 'center',\n};\n\nexport const skipPermanentLinkStyle: CSSProperties = {\n ...skipLinkStyle,\n color: '#999',\n fontSize: 13,\n marginTop: 4,\n};\n\n// --- Internal layout styles --------------------------------------------\n\nconst overlayStyle: CSSProperties = {\n position: 'fixed',\n inset: 0,\n background: 'var(--hook-color-background, #fafafa)',\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 20,\n overflow: 'auto',\n};\n\nconst cardStyle: CSSProperties = {\n width: '100%',\n maxWidth: 420,\n padding: 24,\n textAlign: 'center',\n};\n\nconst titleStyle: CSSProperties = {\n fontSize: 24,\n fontWeight: 700,\n lineHeight: 1.2,\n margin: '0 0 8px 0',\n color: '#111',\n};\n\nconst subtitleStyle: CSSProperties = {\n fontSize: 15,\n lineHeight: 1.4,\n color: '#555',\n margin: 0,\n};\n\nconst footerStyle: CSSProperties = {\n fontSize: 11,\n color: '#aaa',\n marginTop: 32,\n letterSpacing: 0.5,\n};\n","/**\n * SVG icons inline pro InstallGate. Template não depende de lucide-react;\n * copiamos só os 6 necessários (~1.8 KB total minified).\n *\n * Base: ícones de `lucide-react` com ajustes pra iOS share button (precisa\n * estética específica vs o genérico). Paths conferidos com as versões em\n * hook-old.\n */\n\nimport type { CSSProperties } from 'react';\n\ninterface IconProps {\n size?: number;\n style?: CSSProperties;\n 'aria-hidden'?: boolean | 'true' | 'false';\n className?: string;\n}\n\nconst defaultSvgProps = (size: number) => ({\n width: size,\n height: size,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n});\n\n/** iOS Safari share button — square com seta pra cima */\nexport function ShareIconIOS({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M12 2L12 15\" />\n <path d=\"M8 6L12 2L16 6\" />\n <path d=\"M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9\" />\n </svg>\n );\n}\n\n/** Share genérico — 3 círculos conectados */\nexport function ShareIconGeneric({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"18\" cy=\"5\" r=\"3\" />\n <circle cx=\"6\" cy=\"12\" r=\"3\" />\n <circle cx=\"18\" cy=\"19\" r=\"3\" />\n <path d=\"M8.59 13.51l6.83 3.98\" />\n <path d=\"M15.41 6.51l-6.82 3.98\" />\n </svg>\n );\n}\n\n/** Menu ⋮ (Android Chrome, Facebook) */\nexport function MenuDotsVerticalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"5\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"19\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Menu ⋯ (Instagram, TikTok — horizontal) */\nexport function MenuDotsHorizontalIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"19\" cy=\"12\" r=\"1.5\" />\n </svg>\n );\n}\n\n/** Square + (iOS \"Adicionar à Tela de Início\") */\nexport function SquarePlusIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M12 8v8\" />\n <path d=\"M8 12h8\" />\n </svg>\n );\n}\n\n/** Download (Android Chrome \"Instalar aplicativo\") */\nexport function DownloadIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n );\n}\n\n/** External link (pra in-app \"Abrir no navegador\") */\nexport function ExternalLinkIcon({ size = 24, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <path d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n\n/** X (close) */\nexport function XIcon({ size = 20, style, className }: IconProps) {\n return (\n <svg {...defaultSvgProps(size)} style={style} className={className} aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { DownloadIcon } from '../icons';\n\nexport function AndroidNativeVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.native;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <button\n data-testid=\"install-prompt-cta-android-native\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{ ...primaryButtonStyle, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}\n >\n <DownloadIcon size={18} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsVerticalIcon, DownloadIcon } from '../icons';\n\nexport function AndroidManualVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.android.manual;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title}>\n <Step n={1} icon={<MenuDotsVerticalIcon size={20} />}>\n {copy.step1}\n </Step>\n <Step n={2} icon={<DownloadIcon size={18} />}>\n {copy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-android-manual\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={primaryButtonStyle}\n >\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({ n, icon, children }: { n: number; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 15, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { ReactNode } from 'react';\n\nexport function Step({\n n,\n title,\n subtitle,\n visual,\n}: {\n n: number;\n title: string;\n subtitle?: string;\n visual?: ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 12,\n marginBottom: 16,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 15,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1 }}>\n <p style={{ margin: 0, fontSize: 15, fontWeight: 500, color: '#111', lineHeight: 1.3 }}>\n {title}\n </p>\n {subtitle && (\n <p style={{ margin: '4px 0 0 0', fontSize: 13, color: '#777' }}>{subtitle}</p>\n )}\n {visual}\n </div>\n </div>\n );\n}\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSafariVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosSafari;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\n","import type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport { InstallSplash, skipLinkStyle, skipPermanentLinkStyle } from '../InstallSplash';\nimport { ShareIconIOS, SquarePlusIcon } from '../icons';\nimport { Step } from '../Step';\n\nexport function IOSOtherVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const copy = INSTALL_COPY.iosOther;\n const showPermanent = shouldShowPermanentOption(state);\n\n return (\n <InstallSplash title={copy.title} subtitle={copy.subtitle}>\n <Step\n n={1}\n title={copy.step1.title}\n subtitle={copy.step1.subtitle}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 0',\n marginTop: 8,\n }}\n >\n <ShareIconIOS size={32} style={{ color: 'var(--hook-color-primary)' }} />\n </div>\n }\n />\n\n <Step\n n={2}\n title={copy.step2.title}\n visual={\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '12px 14px',\n marginTop: 8,\n }}\n >\n <SquarePlusIcon size={22} style={{ color: '#555' }} />\n <span style={{ fontSize: 14, color: '#333' }}>{copy.step2.iconLabel}</span>\n </div>\n }\n />\n\n <Step\n n={3}\n title={copy.step3.title}\n visual={\n <div\n style={{\n display: 'flex',\n justifyContent: 'flex-end',\n background: '#f5f5f7',\n borderRadius: 12,\n padding: '10px 14px',\n marginTop: 8,\n }}\n >\n <span\n style={{\n color: 'var(--hook-color-primary)',\n fontSize: 15,\n fontWeight: 600,\n }}\n >\n {copy.step3.buttonLabel}\n </span>\n </div>\n }\n />\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={{ ...skipLinkStyle, marginTop: 16 }}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n","import { useState } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { shouldShowPermanentOption } from '../../../hooks/useInstallPrompt';\nimport { INSTALL_COPY } from '../copy';\nimport {\n InstallSplash,\n primaryButtonStyle,\n skipLinkStyle,\n skipPermanentLinkStyle,\n} from '../InstallSplash';\nimport { MenuDotsHorizontalIcon, MenuDotsVerticalIcon, ExternalLinkIcon } from '../icons';\n\nexport function InAppBrowserVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const app = state.inAppApp ?? 'other';\n const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;\n const copy = INSTALL_COPY.inApp;\n const showPermanent = shouldShowPermanentOption(state);\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await actions.copyLink();\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Ícone varia: FB/Telegram usam ⋮; Instagram/TikTok/Twitter/LinkedIn/Pinterest usam ⋯\n const DotsIcon =\n app === 'facebook' || app === 'telegram' ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;\n\n return (\n <InstallSplash title={appCopy.title}>\n <Step n={1} icon={<DotsIcon size={20} />}>\n {appCopy.step1}\n </Step>\n <Step n={2} icon={<ExternalLinkIcon size={18} />}>\n {appCopy.step2}\n </Step>\n\n <button\n data-testid=\"install-prompt-cta-inapp-copy\"\n type=\"button\"\n onClick={() => void handleCopy()}\n style={{ ...primaryButtonStyle, marginTop: 8 }}\n >\n {copied ? copy.copiedToast : copy.copy}\n </button>\n\n <button\n data-testid=\"install-prompt-skip-session\"\n type=\"button\"\n onClick={actions.dismissSession}\n style={skipLinkStyle}\n >\n {copy.skip}\n </button>\n\n {showPermanent && (\n <button\n data-testid=\"install-prompt-skip-permanent\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n style={skipPermanentLinkStyle}\n >\n {copy.skipPermanent}\n </button>\n )}\n </InstallSplash>\n );\n}\n\nfunction Step({\n n,\n icon,\n children,\n}: {\n n: number;\n icon: React.ReactNode;\n children: React.ReactNode;\n}) {\n return (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: '#f5f5f7',\n borderRadius: 12,\n marginBottom: 10,\n textAlign: 'left',\n }}\n >\n <div\n style={{\n width: 28,\n height: 28,\n borderRadius: '50%',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 14,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {n}\n </div>\n <div style={{ flex: 1, fontSize: 14, color: '#333' }}>{children}</div>\n <div style={{ color: '#888', flexShrink: 0 }}>{icon}</div>\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport type { InstallState, InstallActions } from '../../../hooks/useInstallPrompt';\nimport { useTemplateConfig } from '../../../internal/TemplateConfigContext';\nimport { INSTALL_COPY } from '../copy';\nimport { DownloadIcon, XIcon } from '../icons';\n\n/**\n * Desktop variant — NÃO-bloqueante. Banner soft no canto inferior direito.\n * Só aparece se `beforeinstallprompt` disparou (Chrome/Edge desktop).\n */\nexport function DesktopVariant({\n state,\n actions,\n}: {\n state: InstallState;\n actions: InstallActions;\n}) {\n const { name, theme } = useTemplateConfig();\n const copy = INSTALL_COPY.desktop;\n const iconUrl = theme.icon_url || theme.logo_url || null;\n\n // Guard defensivo: só renderiza se installable\n if (!state.isInstallable) return null;\n\n return (\n <div\n role=\"complementary\"\n aria-label={copy.title}\n style={bannerStyle}\n >\n {iconUrl ? (\n <img\n src={iconUrl}\n alt=\"\"\n style={{ width: 40, height: 40, borderRadius: 10, objectFit: 'cover', flexShrink: 0 }}\n />\n ) : (\n <div\n style={{\n width: 40,\n height: 40,\n borderRadius: 10,\n background: 'var(--hook-color-primary)',\n color: '#fff',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: 18,\n fontWeight: 700,\n flexShrink: 0,\n }}\n >\n {name.charAt(0).toUpperCase()}\n </div>\n )}\n\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 14, fontWeight: 600, color: '#111' }}>{copy.title}</div>\n <div style={{ fontSize: 12, color: '#666' }}>{copy.subtitle}</div>\n </div>\n\n <button\n data-testid=\"install-prompt-cta-desktop\"\n type=\"button\"\n onClick={() => void actions.promptInstall()}\n style={{\n padding: '8px 14px',\n background: 'var(--hook-color-primary)',\n color: '#fff',\n border: 'none',\n borderRadius: 999,\n fontSize: 13,\n fontWeight: 600,\n cursor: 'pointer',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 6,\n flexShrink: 0,\n }}\n >\n <DownloadIcon size={14} />\n {copy.cta}\n </button>\n\n <button\n data-testid=\"install-prompt-desktop-close\"\n type=\"button\"\n onClick={actions.dismissPermanent}\n aria-label={copy.close}\n style={{\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: '#888',\n padding: 4,\n flexShrink: 0,\n }}\n >\n <XIcon size={16} />\n </button>\n </div>\n );\n}\n\nconst bannerStyle: CSSProperties = {\n position: 'fixed',\n bottom: 24,\n right: 24,\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 16px',\n background: '#fff',\n border: '1px solid rgba(0,0,0,0.08)',\n borderRadius: 16,\n boxShadow: '0 10px 30px rgba(0,0,0,0.12)',\n maxWidth: 400,\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 * Dispara OAuth Google: redireciona pro backend `/api/auth/oauth/google/start`.\n * Fire-and-forget — a página é descarregada antes de qualquer retorno.\n * Volta pro app logado (ou com `?oauth_error=...` em falha).\n */\n loginWithGoogle: () => void;\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 loginWithGoogle: () => auth.loginWithGoogle(),\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","/**\n * Google Sign-In button seguindo as brand guidelines:\n * https://developers.google.com/identity/branding-guidelines\n *\n * Fundo branco, \"G\" logo oficial (SVG 4-color), label \"Continuar com Google\".\n * Usado por DefaultLoginScreen e DefaultSignupScreen. Apps podem substituir\n * os screens via props do <AppRoot> se quiserem branding próprio.\n */\n\ninterface GoogleSignInButtonProps {\n onClick: () => void;\n testId?: string;\n label?: string;\n}\n\nexport function GoogleSignInButton({\n onClick,\n testId = 'oauth-google',\n label = 'Continuar com Google',\n}: GoogleSignInButtonProps) {\n return (\n <button\n data-testid={testId}\n type=\"button\"\n onClick={onClick}\n style={{\n width: '100%',\n padding: '10px 12px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 10,\n background: '#fff',\n color: '#1f1f1f',\n border: '1px solid #dadce0',\n borderRadius: 8,\n cursor: 'pointer',\n fontSize: 14,\n fontWeight: 500,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n }}\n >\n <GoogleGlyph />\n {label}\n </button>\n );\n}\n\nfunction GoogleGlyph() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z\"\n fill=\"#EA4335\"\n />\n </svg>\n );\n}\n","import { useEffect, useState } from 'react';\n\n/**\n * Lê `?oauth_error=<code>` na URL (setado pelo backend em falhas de callback)\n * e renderiza banner pt-BR. Remove o query param via `history.replaceState`\n * pra não aparecer de novo em refresh.\n *\n * Códigos vêm de `backend/src/auth/oauth/handler.ts` (ex: invalid_state,\n * access_denied, provider_error). Mapeamento explícito; fallback genérico.\n */\n\nconst ERROR_MESSAGES: Record<string, string> = {\n invalid_state: 'Sessão expirou, tente de novo.',\n access_denied: 'Você cancelou o login com Google.',\n provider_error: 'O Google recusou a autenticação. Tente de novo em alguns segundos.',\n invalid_return_to: 'Link inválido. Tente entrar novamente.',\n};\n\nfunction readErrorCode(): string | null {\n if (typeof window === 'undefined') return null;\n const code = new URLSearchParams(window.location.search).get('oauth_error');\n if (!code) return null;\n return code;\n}\n\nfunction stripErrorFromUrl() {\n if (typeof window === 'undefined') return;\n const url = new URL(window.location.href);\n url.searchParams.delete('oauth_error');\n window.history.replaceState({}, '', url.toString());\n}\n\nexport function OAuthErrorBanner() {\n const [code, setCode] = useState<string | null>(() => readErrorCode());\n\n useEffect(() => {\n if (code !== null) stripErrorFromUrl();\n }, [code]);\n\n if (!code) return null;\n\n const message = ERROR_MESSAGES[code] ?? 'Não conseguimos conectar ao Google. Tente de novo.';\n return (\n <div\n role=\"alert\"\n data-testid=\"oauth-error-banner\"\n style={{\n padding: '10px 12px',\n marginBottom: 16,\n background: '#fce8e6',\n color: '#a50e0e',\n borderRadius: 8,\n fontSize: 14,\n }}\n >\n {message}\n <button\n type=\"button\"\n onClick={() => setCode(null)}\n aria-label=\"Fechar\"\n style={{\n float: 'right',\n background: 'none',\n border: 'none',\n color: '#a50e0e',\n cursor: 'pointer',\n fontSize: 16,\n lineHeight: 1,\n padding: 0,\n }}\n >\n ×\n </button>\n </div>\n );\n}\n","import { useLoginForm } from '../hooks/useLoginForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport { GoogleSignInButton } from '../internal/GoogleSignInButton';\nimport { OAuthErrorBanner } from '../internal/OAuthErrorBanner';\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 <OAuthErrorBanner />\n\n <GoogleSignInButton onClick={f.loginWithGoogle} testId=\"login-oauth-google\" />\n\n <div\n aria-hidden=\"true\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n margin: '16px 0',\n color: 'rgba(0,0,0,0.45)',\n fontSize: 12,\n }}\n >\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n ou\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n </div>\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 * Dispara OAuth Google: mesmo endpoint que `useLoginForm.loginWithGoogle`.\n * Backend decide entre `signup_new`, `auto_linked`, ou `login_existing`\n * via `linkPolicy` — do ponto de vista do usuário \"criar conta com Google\"\n * e \"entrar com Google\" são o mesmo botão.\n */\n loginWithGoogle: () => void;\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 loginWithGoogle: () => auth.loginWithGoogle(),\n };\n}\n","import { useSignupForm } from '../hooks/useSignupForm';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport { GoogleSignInButton } from '../internal/GoogleSignInButton';\nimport { OAuthErrorBanner } from '../internal/OAuthErrorBanner';\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\n <OAuthErrorBanner />\n\n <GoogleSignInButton onClick={f.loginWithGoogle} testId=\"signup-oauth-google\" />\n\n <div\n aria-hidden=\"true\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n margin: '16px 0',\n color: 'rgba(0,0,0,0.45)',\n fontSize: 12,\n }}\n >\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n ou\n <span style={{ flex: 1, height: 1, background: 'rgba(0,0,0,0.1)' }} />\n </div>\n\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 { useMemo, useState } from 'react';\nimport type { CheckoutCycle } from '@hook-sdk/sdk';\nimport { usePaywallState } from '../hooks/usePaywallState';\nimport { usePlan } from '../hooks/usePlan';\nimport { useTemplateConfig } from '../internal/TemplateConfigContext';\nimport {\n computeAnchorCents,\n discountPercent,\n formatBRL,\n monthlyFromYearly,\n} from '../utils/price';\n\ntype Method = 'card' | 'pix-auto';\n\ninterface PaywallConfigShape {\n title: string;\n subtitle?: string;\n benefits: string[];\n cta?: string;\n priceHint?: string;\n footerNote?: string;\n anchorMultiplier?: number;\n anchorPriceCents?: number;\n}\n\nexport function DefaultPaywall() {\n const config = useTemplateConfig();\n const plan = usePlan();\n const {\n checkout, opening, error,\n availableMethods, monthlyEquivalent, pixPending, dismissPix,\n } = usePaywallState();\n\n const p = config.subscription.paywall_config as PaywallConfigShape;\n const paywallCfg = (plan.data?.paywallConfig ?? {}) as Partial<PaywallConfigShape>;\n const anchorMultiplier = paywallCfg.anchorMultiplier ?? p.anchorMultiplier;\n const anchorPriceCents = paywallCfg.anchorPriceCents ?? p.anchorPriceCents;\n\n const [cycle, setCycle] = useState<CheckoutCycle>('MONTHLY');\n const [method, setMethod] = useState<Method>('card');\n const [cpf, setCpf] = useState('');\n\n // Card\n const [cardNumber, setCardNumber] = useState('');\n const [cardHolderName, setCardHolderName] = useState('');\n const [cardExpiryMonth, setCardExpiryMonth] = useState('');\n const [cardExpiryYear, setCardExpiryYear] = useState('');\n const [cardCcv, setCardCcv] = useState('');\n\n // Holder info\n const [holderName, setHolderName] = useState('');\n const [holderEmail, setHolderEmail] = useState('');\n const [holderPostalCode, setHolderPostalCode] = useState('');\n const [holderAddressNumber, setHolderAddressNumber] = useState('');\n const [holderPhone, setHolderPhone] = useState('');\n\n const trialDays = plan.data?.trialDays ?? 0;\n const monthlyCents = plan.data?.priceCents ?? 0;\n const yearlyCents = plan.data?.yearlyPriceCents ?? null;\n\n const activeCents = cycle === 'YEARLY' && yearlyCents\n ? monthlyEquivalent('YEARLY')\n : monthlyCents;\n\n const pct = useMemo(() => {\n if (!yearlyCents || !monthlyCents) return 0;\n const derived = Math.round((1 - (yearlyCents / 12) / monthlyCents) * 100);\n return Math.max(0, derived);\n }, [monthlyCents, yearlyCents]);\n\n const anchorBaseCents = cycle === 'YEARLY' && yearlyCents\n ? monthlyFromYearly(yearlyCents)\n : monthlyCents;\n const anchorCents = computeAnchorCents(anchorBaseCents, anchorMultiplier)\n ?? (anchorPriceCents && anchorPriceCents > anchorBaseCents ? anchorPriceCents : null);\n const anchorDiscount = anchorCents ? discountPercent(anchorCents, activeCents) : 0;\n\n const cpfDigits = cpf.replace(/\\D/g, '');\n const cardFieldsFilled =\n cardNumber.replace(/\\s/g, '').length >= 13 &&\n cardHolderName.trim().length > 0 &&\n cardExpiryMonth.length === 2 &&\n cardExpiryYear.length >= 2 &&\n cardCcv.length >= 3 &&\n holderName.trim().length > 0 &&\n /.+@.+\\..+/.test(holderEmail) &&\n holderPostalCode.replace(/\\D/g, '').length === 8 &&\n holderAddressNumber.trim().length > 0;\n\n const canCheckout =\n cpfDigits.length === 11 &&\n !opening &&\n (method === 'pix-auto' || cardFieldsFilled);\n\n const ctaLabel = useMemo(() => {\n if (opening) return 'Abrindo…';\n if (trialDays > 0) return `Comece trial de ${trialDays} dias grátis`;\n return p.cta ?? 'Assinar agora';\n }, [opening, trialDays, p.cta]);\n\n const footer = useMemo(() => {\n if (trialDays > 0) {\n return `Sem cobrança agora. Cobrança automática em ${trialDays} dias. Cancele quando quiser.`;\n }\n return 'Cobrança imediata. Cancele quando quiser.';\n }, [trialDays]);\n\n const yearSuffix = cardExpiryYear.length === 2 ? `20${cardExpiryYear}` : cardExpiryYear;\n const phoneDigits = holderPhone.replace(/\\D/g, '');\n const postalDigits = holderPostalCode.replace(/\\D/g, '');\n\n const submit = () => {\n if (method === 'card') {\n void checkout({\n cpf: cpfDigits,\n cycle,\n method: 'card',\n card: {\n number: cardNumber.replace(/\\s/g, ''),\n holderName: cardHolderName.trim(),\n expiryMonth: cardExpiryMonth,\n expiryYear: yearSuffix,\n ccv: cardCcv,\n },\n holderInfo: {\n name: holderName.trim(),\n email: holderEmail.trim(),\n cpfCnpj: cpfDigits,\n postalCode: postalDigits,\n addressNumber: holderAddressNumber.trim(),\n ...(phoneDigits ? { phone: phoneDigits } : {}),\n },\n });\n return;\n }\n void checkout({ cpf: cpfDigits, cycle, method: 'pix-auto' });\n };\n\n const inputStyle = {\n width: '100%', padding: 10, fontSize: 14,\n borderRadius: 8, border: '1px solid #ccc',\n boxSizing: 'border-box' as const,\n };\n const labelStyle = { display: 'block', fontSize: 13, opacity: 0.75, marginBottom: 4 };\n const fieldGroup = { marginBottom: 10, textAlign: 'left' as const };\n\n return (\n <main style={{ padding: 24, maxWidth: 480, 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 <div\n role=\"group\"\n aria-label=\"Período de cobrança\"\n style={{ display: 'flex', gap: 8, marginBottom: 16 }}\n >\n <button\n type=\"button\"\n aria-pressed={cycle === 'MONTHLY'}\n onClick={() => setCycle('MONTHLY')}\n style={{\n flex: 1, padding: 12, borderRadius: 8,\n border: cycle === 'MONTHLY' ? '2px solid var(--hook-color-primary)' : '1px solid #ccc',\n background: cycle === 'MONTHLY' ? 'var(--hook-color-primary-soft, #eef)' : 'white',\n cursor: 'pointer',\n }}\n >\n Mensal\n </button>\n <button\n type=\"button\"\n aria-pressed={cycle === 'YEARLY'}\n onClick={() => setCycle('YEARLY')}\n disabled={!yearlyCents}\n style={{\n flex: 1, padding: 12, borderRadius: 8,\n border: cycle === 'YEARLY' ? '2px solid var(--hook-color-primary)' : '1px solid #ccc',\n background: cycle === 'YEARLY' ? 'var(--hook-color-primary-soft, #eef)' : 'white',\n cursor: yearlyCents ? 'pointer' : 'not-allowed',\n opacity: yearlyCents ? 1 : 0.5,\n }}\n >\n Anual{pct > 0 ? ` −${pct}%` : ''}\n </button>\n </div>\n\n <div style={{ marginBottom: 8 }}>\n <div style={{ fontSize: 32, fontWeight: 700, lineHeight: 1 }}>\n {formatBRL(activeCents)}\n <span style={{ fontSize: 16, fontWeight: 400, opacity: 0.7 }}>/mês</span>\n </div>\n {anchorCents && (\n <div style={{ fontSize: 14, opacity: 0.6, marginTop: 4 }}>\n <span style={{ textDecoration: 'line-through' }}>{formatBRL(anchorCents)}</span>\n {anchorDiscount > 0 && <span style={{ marginLeft: 6 }}>−{anchorDiscount}%</span>}\n </div>\n )}\n {cycle === 'YEARLY' && yearlyCents && (\n <div style={{ fontSize: 12, opacity: 0.6, marginTop: 4 }}>\n Cobrado {formatBRL(yearlyCents)} por ano\n </div>\n )}\n </div>\n\n <ul style={{ listStyle: 'none', padding: 0, textAlign: 'left', margin: '24px 0' }}>\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 role=\"tablist\" aria-label=\"Método de pagamento\" style={{ display: 'flex', gap: 8, marginBottom: 16 }}>\n {availableMethods.map((m) => (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={method === m}\n onClick={() => setMethod(m)}\n style={{\n flex: 1, padding: 10, borderRadius: 8,\n border: method === m ? '2px solid var(--hook-color-primary)' : '1px solid #ccc',\n background: method === m ? 'var(--hook-color-primary-soft, #eef)' : 'white',\n cursor: 'pointer',\n }}\n >\n {m === 'card' ? '💳 Cartão' : '📱 Pix Automático'}\n </button>\n ))}\n </div>\n\n {method === 'card' && (\n <fieldset\n data-testid=\"paywall-card-form\"\n style={{ border: 'none', padding: 0, marginBottom: 16 }}\n >\n <legend style={{ fontSize: 13, opacity: 0.75, marginBottom: 8 }}>Dados do cartão</legend>\n <div style={fieldGroup}>\n <label htmlFor=\"pw-card-number\" style={labelStyle}>Número do cartão</label>\n <input\n id=\"pw-card-number\"\n data-testid=\"pw-card-number\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-number\"\n placeholder=\"0000 0000 0000 0000\"\n value={cardNumber}\n onChange={(e) => setCardNumber(e.target.value)}\n style={inputStyle}\n />\n </div>\n <div style={fieldGroup}>\n <label htmlFor=\"pw-card-holder\" style={labelStyle}>Nome impresso no cartão</label>\n <input\n id=\"pw-card-holder\"\n data-testid=\"pw-card-holder\"\n type=\"text\"\n autoComplete=\"cc-name\"\n placeholder=\"NOME SOBRENOME\"\n value={cardHolderName}\n onChange={(e) => setCardHolderName(e.target.value)}\n style={inputStyle}\n />\n </div>\n <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>\n <div style={{ flex: 1, textAlign: 'left' }}>\n <label htmlFor=\"pw-card-exp-m\" style={labelStyle}>Mês</label>\n <input\n id=\"pw-card-exp-m\"\n data-testid=\"pw-card-exp-m\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-exp-month\"\n placeholder=\"MM\"\n maxLength={2}\n value={cardExpiryMonth}\n onChange={(e) => setCardExpiryMonth(e.target.value.replace(/\\D/g, ''))}\n style={inputStyle}\n />\n </div>\n <div style={{ flex: 1, textAlign: 'left' }}>\n <label htmlFor=\"pw-card-exp-y\" style={labelStyle}>Ano</label>\n <input\n id=\"pw-card-exp-y\"\n data-testid=\"pw-card-exp-y\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-exp-year\"\n placeholder=\"AA\"\n maxLength={4}\n value={cardExpiryYear}\n onChange={(e) => setCardExpiryYear(e.target.value.replace(/\\D/g, ''))}\n style={inputStyle}\n />\n </div>\n <div style={{ flex: 1, textAlign: 'left' }}>\n <label htmlFor=\"pw-card-cvv\" style={labelStyle}>CVV</label>\n <input\n id=\"pw-card-cvv\"\n data-testid=\"pw-card-cvv\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"cc-csc\"\n placeholder=\"123\"\n maxLength={4}\n value={cardCcv}\n onChange={(e) => setCardCcv(e.target.value.replace(/\\D/g, ''))}\n style={inputStyle}\n />\n </div>\n </div>\n\n <legend style={{ fontSize: 13, opacity: 0.75, marginBottom: 8, marginTop: 8 }}>\n Dados do titular\n </legend>\n <div style={fieldGroup}>\n <label htmlFor=\"pw-holder-name\" style={labelStyle}>Nome completo</label>\n <input\n id=\"pw-holder-name\"\n data-testid=\"pw-holder-name\"\n type=\"text\"\n autoComplete=\"name\"\n placeholder=\"Nome Sobrenome\"\n value={holderName}\n onChange={(e) => setHolderName(e.target.value)}\n style={inputStyle}\n />\n </div>\n <div style={fieldGroup}>\n <label htmlFor=\"pw-holder-email\" style={labelStyle}>E-mail</label>\n <input\n id=\"pw-holder-email\"\n data-testid=\"pw-holder-email\"\n type=\"email\"\n autoComplete=\"email\"\n placeholder=\"voce@email.com\"\n value={holderEmail}\n onChange={(e) => setHolderEmail(e.target.value)}\n style={inputStyle}\n />\n </div>\n <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>\n <div style={{ flex: 1, textAlign: 'left' }}>\n <label htmlFor=\"pw-holder-cep\" style={labelStyle}>CEP</label>\n <input\n id=\"pw-holder-cep\"\n data-testid=\"pw-holder-cep\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"postal-code\"\n placeholder=\"00000-000\"\n value={holderPostalCode}\n onChange={(e) => setHolderPostalCode(e.target.value)}\n style={inputStyle}\n />\n </div>\n <div style={{ flex: 1, textAlign: 'left' }}>\n <label htmlFor=\"pw-holder-addr-n\" style={labelStyle}>Número</label>\n <input\n id=\"pw-holder-addr-n\"\n data-testid=\"pw-holder-addr-n\"\n type=\"text\"\n inputMode=\"numeric\"\n placeholder=\"123\"\n value={holderAddressNumber}\n onChange={(e) => setHolderAddressNumber(e.target.value)}\n style={inputStyle}\n />\n </div>\n </div>\n <div style={fieldGroup}>\n <label htmlFor=\"pw-holder-phone\" style={labelStyle}>Telefone (opcional)</label>\n <input\n id=\"pw-holder-phone\"\n data-testid=\"pw-holder-phone\"\n type=\"tel\"\n inputMode=\"tel\"\n autoComplete=\"tel\"\n placeholder=\"(11) 99999-9999\"\n value={holderPhone}\n onChange={(e) => setHolderPhone(e.target.value)}\n style={inputStyle}\n />\n </div>\n </fieldset>\n )}\n\n <div style={fieldGroup}>\n <label htmlFor=\"pw-cpf\" style={labelStyle}>Seu CPF</label>\n <input\n id=\"pw-cpf\"\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={inputStyle}\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={submit}\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 cursor: canCheckout ? 'pointer' : 'not-allowed',\n }}\n >\n {ctaLabel}\n </button>\n\n <p style={{ opacity: 0.55, marginTop: 16, fontSize: 12 }}>{footer}</p>\n {p.priceHint && <p style={{ opacity: 0.6, marginTop: 8, fontSize: 12 }}>{p.priceHint}</p>}\n {p.footerNote && <p style={{ opacity: 0.5, marginTop: 8, fontSize: 12 }}>{p.footerNote}</p>}\n\n {pixPending && (\n <div\n data-testid=\"paywall-pix-modal\"\n role=\"dialog\"\n aria-label=\"Pagamento Pix pendente\"\n style={{\n position: 'fixed', inset: 0,\n background: 'rgba(0,0,0,0.6)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n padding: 24, zIndex: 1000,\n }}\n >\n <div style={{\n background: '#fff', borderRadius: 12, padding: 24,\n maxWidth: 360, width: '100%', textAlign: 'center',\n }}>\n {pixPending.paid ? (\n <>\n <h2 style={{ marginTop: 0 }}>Pagamento confirmado!</h2>\n <p style={{ opacity: 0.7 }}>Liberando acesso…</p>\n </>\n ) : (\n <>\n <h2 style={{ marginTop: 0, fontSize: 18 }}>Pague com Pix Automático</h2>\n <p style={{ fontSize: 13, opacity: 0.75 }}>\n Escaneie o QR Code no app do seu banco pra autorizar o débito recorrente.\n </p>\n {pixPending.qrCodeBase64 && (\n <img\n data-testid=\"pix-qr-image\"\n alt=\"QR Code Pix\"\n src={`data:image/png;base64,${pixPending.qrCodeBase64}`}\n style={{ width: '100%', maxWidth: 240, margin: '12px auto', display: 'block' }}\n />\n )}\n {pixPending.qrCodePayload && (\n <textarea\n data-testid=\"pix-qr-payload\"\n readOnly\n value={pixPending.qrCodePayload}\n style={{\n width: '100%', minHeight: 72, padding: 8,\n fontSize: 11, fontFamily: 'monospace',\n borderRadius: 6, border: '1px solid #ccc',\n resize: 'none',\n }}\n />\n )}\n <p style={{ fontSize: 11, opacity: 0.55, marginTop: 12 }}>\n Aguardando confirmação do banco… Pode levar alguns segundos.\n </p>\n </>\n )}\n <button\n type=\"button\"\n onClick={dismissPix}\n style={{\n marginTop: 16, padding: '8px 16px',\n border: '1px solid #ccc', borderRadius: 6,\n background: 'white', cursor: 'pointer',\n }}\n >\n Fechar\n </button>\n </div>\n </div>\n )}\n </main>\n );\n}\n","import { useHook } from '@hook-sdk/sdk';\nimport type { PlanInfo, PlanState } from '@hook-sdk/sdk';\n\n/**\n * Thin wrapper sobre `useHook().plan`. Existe pra apps importarem \"tudo\n * que precisam\" via `@hook-sdk/template` sem mudar de package pra cada\n * primitive, e pra manter espaço pra evoluir a API (ex: expor campos\n * derivados como `monthlyEquivalent()`) sem mexer no SDK.\n *\n * Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:\n *\n * const { data, initialLoadComplete } = usePlan();\n * if (!initialLoadComplete) return <Skeleton />;\n * if (!data) return null;\n * return <span>{formatBRL(data.priceCents)}</span>;\n */\nexport function usePlan(): PlanState {\n const { plan } = useHook();\n return plan;\n}\n\nexport type { PlanInfo, PlanState };\n","/**\n * Helpers de formatação de preço pro Hook.\n *\n * Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço\n * leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam\n * inline. Isso evita os dois patterns errados que já vimos em conversões\n * Lovable→Hook: (a) strings hardcoded \"R$ 19,90\" no JSX, (b) divisões ad-hoc\n * por 100 + `toFixed(2)` que ignoram locale.\n *\n * Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.\n */\n\n/**\n * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência\n * (callers que lidam com `yearlyPriceCents: number | null`).\n *\n * Examples:\n * formatBRL(1990) → \"R$ 19,90\"\n * formatBRL(4999) → \"R$ 49,99\"\n * formatBRL(23988) → \"R$ 239,88\"\n * formatBRL(0) → \"R$ 0,00\"\n * formatBRL(null) → \"\"\n */\nexport function formatBRL(cents: number | null | undefined): string {\n if (cents === null || cents === undefined) return '';\n const reais = cents / 100;\n return new Intl.NumberFormat('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n }).format(reais);\n}\n\n/**\n * Deriva \"preço mensal\" a partir do preço anual (em centavos). Round half-up\n * pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.\n *\n * Não assume que o creator configurou yearlyPriceCents \"redondo\": se ele\n * setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880\n * (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).\n *\n * Example (papomaterno):\n * monthlyFromYearly(23988) = 1999 → formatBRL = \"R$ 19,99\"\n * monthlyFromYearly(23880) = 1990 → formatBRL = \"R$ 19,90\"\n */\nexport function monthlyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 12);\n}\n\n/**\n * Deriva \"preço por dia\" (365 dias) a partir do anual, em centavos. Útil\n * pra copy tipo \"apenas R$ 0,66 por dia, menos que um café\".\n *\n * Example:\n * dailyFromYearly(23988) = 66 → formatBRL = \"R$ 0,66\"\n */\nexport function dailyFromYearly(yearlyCents: number | null | undefined): number {\n if (yearlyCents === null || yearlyCents === undefined) return 0;\n return Math.round(yearlyCents / 365);\n}\n\n/**\n * Deriva o preço-ancoragem (valor \"cheio\" riscado) como múltiplo do preço\n * real. Serve pra ancoragem psicológica em telas de paywall: mostra um valor\n * maior riscado antes do preço real pra o usuário sentir desconto.\n *\n * Com `anchorMultiplier` no `paywall_config`, o creator mantém só o preço\n * real no DB; a ancoragem acompanha automaticamente se o preço muda.\n *\n * Retorna `null` quando o multiplier não é utilizável (falta, ≤ 1, NaN,\n * Infinity). Caller deve cair no fallback (valor absoluto em\n * `paywall_config.anchorPriceCents`) ou pular a renderização da ancoragem.\n *\n * Examples:\n * computeAnchorCents(1999, 2.5) = 4998\n * computeAnchorCents(1999, undefined) = null\n * computeAnchorCents(1999, 1) = null // 1× não ancora nada\n * computeAnchorCents(1999, 0) = null\n * computeAnchorCents(1999, NaN) = null\n */\nexport function computeAnchorCents(\n baseCents: number,\n multiplier: number | null | undefined,\n): number | null {\n if (multiplier === null || multiplier === undefined) return null;\n if (!Number.isFinite(multiplier)) return null;\n if (multiplier <= 1) return null;\n return Math.round(baseCents * multiplier);\n}\n\n/**\n * Percentual de desconto (anchor → real), arredondado pra baixo pra nunca\n * overstate. Retorna 0 quando anchor ≤ real (sem desconto a mostrar).\n *\n * Examples:\n * discountPercent(4998, 1999) = 60 // (4998-1999)/4998 = 0.60...\n * discountPercent(3998, 1999) = 50\n * discountPercent(1000, 2000) = 0 // real > anchor\n * discountPercent(2000, 2000) = 0\n */\nexport function discountPercent(anchorCents: number, realCents: number): number {\n if (anchorCents <= realCents) return 0;\n return Math.floor(((anchorCents - realCents) / anchorCents) * 100);\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\n\nexport type PushUiState =\n | { kind: 'unsupported' }\n | { kind: 'ios_needs_install' }\n | { kind: 'prompt' }\n | { kind: 'subscribed' }\n | { kind: 'denied' }\n | { kind: 'error'; code: string; message: string };\n\nfunction detectIosNeedsInstall(): boolean {\n if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;\n const ua = navigator.userAgent || '';\n const isIos = /iPhone|iPad|iPod/.test(ua);\n if (!isIos) return false;\n const mm = window.matchMedia?.('(display-mode: standalone)');\n const standalone = mm?.matches === true;\n // @ts-expect-error — legacy iOS property\n const legacyStandalone = typeof navigator.standalone === 'boolean' ? navigator.standalone : false;\n return !(standalone || legacyStandalone);\n}\n\nfunction deriveState(push: ReturnType<typeof useHook>['push']): PushUiState {\n if (!push.isAvailable()) {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n const status = push.status();\n if (status === 'granted') return { kind: 'subscribed' };\n if (status === 'denied') return { kind: 'denied' };\n if (status === 'unsupported') {\n if (detectIosNeedsInstall()) return { kind: 'ios_needs_install' };\n return { kind: 'unsupported' };\n }\n return { kind: 'prompt' };\n}\n\nexport function usePush() {\n const { push } = useHook();\n const [state, setState] = useState<PushUiState>(() => deriveState(push));\n\n useEffect(() => { setState(deriveState(push)); }, [push]);\n\n const subscribe = useCallback(async () => {\n try {\n await push.subscribe();\n setState({ kind: 'subscribed' });\n } catch (e: any) {\n const code = e?.code ?? 'push.unknown';\n const message = e?.message ?? 'Push subscription failed';\n if (code === 'push.permission_denied') setState({ kind: 'denied' });\n else setState({ kind: 'error', code, message });\n throw e;\n }\n }, [push]);\n\n const unsubscribe = useCallback(async () => {\n try {\n await push.unsubscribe();\n setState({ kind: 'prompt' });\n } catch (e: any) {\n setState({ kind: 'error', code: e?.code ?? 'push.unknown', message: e?.message ?? 'failed' });\n throw e;\n }\n }, [push]);\n\n return { state, subscribe, unsubscribe };\n}\n","import { usePush } from '../hooks/usePush';\n\nexport interface PushPromptTexts {\n cta: string;\n declineCta: string;\n iosInstallTitle: string;\n iosInstallBody: string;\n iosInstallCta?: string;\n deniedTitle: string;\n deniedBody: string;\n unsupportedBody: string;\n}\n\nexport interface PushPromptProps {\n texts: PushPromptTexts;\n onSubscribed?: () => void;\n onDeclined?: () => void;\n onInstallRequested?: () => void;\n className?: string;\n}\n\nexport function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequested, className }: PushPromptProps) {\n const { state, subscribe } = usePush();\n\n if (state.kind === 'subscribed') return null;\n\n if (state.kind === 'ios_needs_install') {\n return (\n <div className={className} role=\"region\" aria-label={texts.iosInstallTitle}>\n <h3>{texts.iosInstallTitle}</h3>\n <p>{texts.iosInstallBody}</p>\n {onInstallRequested && texts.iosInstallCta && (\n <button onClick={onInstallRequested}>{texts.iosInstallCta}</button>\n )}\n </div>\n );\n }\n\n if (state.kind === 'denied') {\n return (\n <div className={className} role=\"region\" aria-label={texts.deniedTitle}>\n <h3>{texts.deniedTitle}</h3>\n <p>{texts.deniedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'unsupported') {\n return (\n <div className={className} role=\"region\">\n <p>{texts.unsupportedBody}</p>\n </div>\n );\n }\n\n if (state.kind === 'error') {\n return (\n <div className={className} role=\"region\" aria-label=\"error\">\n <p>{state.message}</p>\n </div>\n );\n }\n\n // kind === 'prompt'\n return (\n <div className={className} role=\"region\">\n <button\n type=\"button\"\n onClick={async () => {\n try {\n await subscribe();\n onSubscribed?.();\n } catch {\n // state is already set to 'denied' or 'error' by usePush.subscribe\n }\n }}\n >\n {texts.cta}\n </button>\n {onDeclined && (\n <button type=\"button\" onClick={onDeclined}>\n {texts.declineCta}\n </button>\n )}\n </div>\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 { useCallback, useEffect, useState } from 'react';\nimport { useHook } from '@hook-sdk/sdk';\nimport type { ReminderSlot } from '@hook-sdk/sdk';\n\nexport function useReminders() {\n const { push } = useHook();\n const r = push.reminders;\n const [reminders, setReminders] = useState<ReminderSlot[]>([]);\n const [loading, setLoading] = useState(true);\n\n const reload = useCallback(async () => {\n setLoading(true);\n try {\n const next = await r.list();\n setReminders(next);\n } finally {\n setLoading(false);\n }\n }, [r]);\n\n useEffect(() => { void reload(); }, [reload]);\n\n const setReminder = useCallback(async (input: {\n slot: string; timeLocal: string; timezone: string; enabled: boolean;\n }) => {\n await r.set(input);\n await reload();\n }, [r, reload]);\n\n const deleteReminder = useCallback(async (slot: string) => {\n await r.delete(slot);\n await reload();\n }, [r, reload]);\n\n const schedule = useCallback(async (items: Parameters<typeof r.schedule>[0]) => {\n return r.schedule(items);\n }, [r]);\n\n const setFallbacks = useCallback(async (items: Parameters<typeof r.setFallbacks>[0]) => {\n return r.setFallbacks(items);\n }, [r]);\n\n return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };\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","useRef","useState","useHook","jsx","jsx","jsx","useEffect","useMemo","useState","useHook","Fragment","jsx","useEffect","useState","useHook","Fragment","jsx","useHook","useState","useEffect","useEffect","useRef","useCallback","useEffect","useState","jsx","jsx","jsxs","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","Step","jsx","jsxs","Step","jsx","jsxs","Step","useState","jsx","jsxs","useState","Step","jsx","jsxs","Fragment","jsx","jsxs","useRef","useEffect","Fragment","jsx","jsxs","useCallback","useMemo","useState","useHook","useHook","useState","useMemo","useCallback","jsx","jsxs","useEffect","useState","jsx","jsxs","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","useMemo","useState","useHook","Fragment","jsx","jsxs","useState","useMemo","Fragment","jsx","jsxs","useHook","useRef","useState","useCallback","useEffect","overlayStyle","useCallback","useEffect","useState","useHook","jsx","jsxs","PushPrompt","jsx","jsxs","useEffect","useHook","useHook","useEffect","useHook","useCallback","useEffect","useState","useHook","useCallback","useState"]}