@hook-sdk/template 0.11.0 → 0.13.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/AppRoot.tsx
2
2
  import { useMemo as useMemo3 } from "react";
3
3
  import { BrowserRouter, MemoryRouter, Navigate, Route, Routes } from "react-router-dom";
4
- import { useHook as useHook4 } from "@hook-sdk/sdk";
4
+ import { useHook as useHook5 } from "@hook-sdk/sdk";
5
5
 
6
6
  // src/config/AppConfigContext.tsx
7
7
  import { createContext, useContext } from "react";
@@ -1756,9 +1756,68 @@ function PushPrompt() {
1756
1756
  return null;
1757
1757
  }
1758
1758
 
1759
+ // src/internal/SessionExpiredBanner.tsx
1760
+ import { useEffect as useEffect5, useRef as useRef2, useState as useState4 } from "react";
1761
+ import { useHook as useHook3 } from "@hook-sdk/sdk";
1762
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1763
+ var DISMISS_KEY = "hook:session-expired-dismissed-until";
1764
+ var DISMISS_TTL_MS = 60 * 60 * 1e3;
1765
+ function SessionExpiredBanner() {
1766
+ const { authStatus } = useHook3();
1767
+ const wasAuthRef = useRef2(false);
1768
+ const [show, setShow] = useState4(false);
1769
+ useEffect5(() => {
1770
+ if (authStatus === "authenticated") {
1771
+ wasAuthRef.current = true;
1772
+ setShow(false);
1773
+ return;
1774
+ }
1775
+ if (authStatus === "anonymous" && wasAuthRef.current) {
1776
+ const until = Number(localStorage.getItem(DISMISS_KEY) ?? "0");
1777
+ if (Date.now() < until) {
1778
+ setShow(false);
1779
+ return;
1780
+ }
1781
+ setShow(true);
1782
+ }
1783
+ }, [authStatus]);
1784
+ if (!show) return null;
1785
+ function dismiss() {
1786
+ localStorage.setItem(DISMISS_KEY, String(Date.now() + DISMISS_TTL_MS));
1787
+ setShow(false);
1788
+ }
1789
+ return /* @__PURE__ */ jsxs11("div", { role: "alert", className: "fixed top-0 inset-x-0 bg-red-600 text-white px-4 py-2 flex items-center justify-between gap-3 text-sm shadow", style: { zIndex: 10001 }, children: [
1790
+ /* @__PURE__ */ jsxs11("span", { children: [
1791
+ /* @__PURE__ */ jsx16("strong", { children: "Sua sess\xE3o expirou." }),
1792
+ " Fa\xE7a login novamente para continuar."
1793
+ ] }),
1794
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
1795
+ /* @__PURE__ */ jsx16(
1796
+ "button",
1797
+ {
1798
+ type: "button",
1799
+ onClick: dismiss,
1800
+ className: "px-3 py-1 bg-white text-red-700 rounded text-xs font-medium hover:bg-red-50",
1801
+ children: "Fazer login"
1802
+ }
1803
+ ),
1804
+ /* @__PURE__ */ jsx16(
1805
+ "button",
1806
+ {
1807
+ type: "button",
1808
+ onClick: dismiss,
1809
+ "aria-label": "Fechar",
1810
+ className: "px-2 py-1 text-white/80 hover:text-white text-xs",
1811
+ children: "Fechar"
1812
+ }
1813
+ )
1814
+ ] })
1815
+ ] });
1816
+ }
1817
+
1759
1818
  // src/defaults/ErrorBoundary.tsx
1760
1819
  import { Component } from "react";
1761
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
1820
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
1762
1821
  var ErrorBoundary = class extends Component {
1763
1822
  state = { error: null };
1764
1823
  static getDerivedStateFromError(error) {
@@ -1776,26 +1835,26 @@ var ErrorBoundary = class extends Component {
1776
1835
  }
1777
1836
  render() {
1778
1837
  if (this.state.error) {
1779
- return this.props.fallback ?? /* @__PURE__ */ jsxs11("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
1780
- /* @__PURE__ */ jsx16("h2", { children: "Algo deu errado" }),
1781
- /* @__PURE__ */ jsx16("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
1838
+ return this.props.fallback ?? /* @__PURE__ */ jsxs12("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
1839
+ /* @__PURE__ */ jsx17("h2", { children: "Algo deu errado" }),
1840
+ /* @__PURE__ */ jsx17("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
1782
1841
  ] });
1783
1842
  }
1784
- return /* @__PURE__ */ jsx16(Fragment4, { children: this.props.children });
1843
+ return /* @__PURE__ */ jsx17(Fragment4, { children: this.props.children });
1785
1844
  }
1786
1845
  };
1787
1846
 
1788
1847
  // src/internal/PaymentReturnHandler.tsx
1789
- import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef2, useState as useState4 } from "react";
1790
- import { useHook as useHook3 } from "@hook-sdk/sdk";
1791
- import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
1848
+ import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef3, useState as useState5 } from "react";
1849
+ import { useHook as useHook4 } from "@hook-sdk/sdk";
1850
+ import { Fragment as Fragment5, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
1792
1851
  var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
1793
1852
  function PaymentReturnHandler({ children }) {
1794
- const { subscription } = useHook3();
1795
- const subRef = useRef2(subscription);
1853
+ const { subscription } = useHook4();
1854
+ const subRef = useRef3(subscription);
1796
1855
  subRef.current = subscription;
1797
- const runIdRef = useRef2(0);
1798
- const [state, setState] = useState4("idle");
1856
+ const runIdRef = useRef3(0);
1857
+ const [state, setState] = useState5("idle");
1799
1858
  const runPoll = useCallback3(() => {
1800
1859
  const runId = ++runIdRef.current;
1801
1860
  setState("confirming");
@@ -1825,7 +1884,7 @@ function PaymentReturnHandler({ children }) {
1825
1884
  };
1826
1885
  void tick();
1827
1886
  }, []);
1828
- useEffect5(() => {
1887
+ useEffect6(() => {
1829
1888
  if (typeof window === "undefined") return;
1830
1889
  const url = new URL(window.location.href);
1831
1890
  if (url.searchParams.get("paymentReturn") !== "1") return;
@@ -1835,15 +1894,15 @@ function PaymentReturnHandler({ children }) {
1835
1894
  };
1836
1895
  }, [runPoll]);
1837
1896
  if (state === "confirming") {
1838
- return /* @__PURE__ */ jsx17("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
1897
+ return /* @__PURE__ */ jsx18("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
1839
1898
  }
1840
1899
  if (state === "waiting") {
1841
- return /* @__PURE__ */ jsx17("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs12("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
1842
- /* @__PURE__ */ jsx17("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
1843
- /* @__PURE__ */ jsx17("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
1900
+ return /* @__PURE__ */ jsx18("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs13("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
1901
+ /* @__PURE__ */ jsx18("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
1902
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
1844
1903
  ] }) });
1845
1904
  }
1846
- return /* @__PURE__ */ jsx17(Fragment5, { children });
1905
+ return /* @__PURE__ */ jsx18(Fragment5, { children });
1847
1906
  }
1848
1907
  var overlayStyle2 = {
1849
1908
  position: "fixed",
@@ -1869,7 +1928,7 @@ var buttonStyle = {
1869
1928
  };
1870
1929
 
1871
1930
  // src/AppRoot.tsx
1872
- import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
1931
+ import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
1873
1932
  function buildLegacyConfigShim(config) {
1874
1933
  const paywall = config.paywall;
1875
1934
  const isFree = paywall.mode === "free";
@@ -1937,9 +1996,10 @@ function AppRoot(props) {
1937
1996
  const Router = testRouter === "memory" ? MemoryRouter : BrowserRouter;
1938
1997
  const basename = `/app/${config.slug}`;
1939
1998
  const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
1940
- return /* @__PURE__ */ jsx18(ErrorBoundary, { children: /* @__PURE__ */ jsx18(AppConfigProvider, { config, children: /* @__PURE__ */ jsx18(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ jsx18(ThemeProvider, { children: /* @__PURE__ */ jsx18(PersistenceRegistry, { config: config.persistedKeys, children: /* @__PURE__ */ jsxs13(Router, { ...routerProps, children: [
1941
- /* @__PURE__ */ jsx18(DeepLinkHandler, { deepLinks: config.deepLinks }),
1942
- /* @__PURE__ */ jsx18(InstallGate, { children: /* @__PURE__ */ jsx18(
1999
+ return /* @__PURE__ */ jsx19(ErrorBoundary, { children: /* @__PURE__ */ jsx19(AppConfigProvider, { config, children: /* @__PURE__ */ jsx19(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ jsx19(ThemeProvider, { children: /* @__PURE__ */ jsx19(PersistenceRegistry, { config: config.persistedKeys, children: /* @__PURE__ */ jsxs14(Router, { ...routerProps, children: [
2000
+ /* @__PURE__ */ jsx19(DeepLinkHandler, { deepLinks: config.deepLinks }),
2001
+ /* @__PURE__ */ jsx19(SessionExpiredBanner, {}),
2002
+ /* @__PURE__ */ jsx19(InstallGate, { children: /* @__PURE__ */ jsx19(
1943
2003
  AuthGated,
1944
2004
  {
1945
2005
  config,
@@ -1951,9 +2011,9 @@ function AppRoot(props) {
1951
2011
  Paywall,
1952
2012
  Onboarding,
1953
2013
  PreAuthFlow,
1954
- children: /* @__PURE__ */ jsxs13(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: [
2014
+ children: /* @__PURE__ */ jsxs14(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: [
1955
2015
  children,
1956
- /* @__PURE__ */ jsx18(PushPrompt, {})
2016
+ /* @__PURE__ */ jsx19(PushPrompt, {})
1957
2017
  ] })
1958
2018
  }
1959
2019
  ) })
@@ -1969,37 +2029,39 @@ function AuthGated({
1969
2029
  EmailVerify,
1970
2030
  PreAuthFlow
1971
2031
  }) {
1972
- const { authStatus } = useHook4();
2032
+ const { authStatus } = useHook5();
1973
2033
  if (authStatus === "loading") return null;
1974
2034
  if (authStatus !== "authenticated") {
1975
2035
  if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
1976
- return /* @__PURE__ */ jsxs13(Routes, { children: [
1977
- /* @__PURE__ */ jsx18(Route, { path: "/signin", element: /* @__PURE__ */ jsx18(Login, {}) }),
1978
- /* @__PURE__ */ jsx18(Route, { path: "/signup", element: /* @__PURE__ */ jsx18(Signup, {}) }),
1979
- /* @__PURE__ */ jsx18(Route, { path: "/forgot", element: /* @__PURE__ */ jsx18(Forgot, {}) }),
1980
- /* @__PURE__ */ jsx18(Route, { path: "/reset", element: /* @__PURE__ */ jsx18(Reset, {}) }),
1981
- EmailVerify ? /* @__PURE__ */ jsx18(Route, { path: "/verify", element: /* @__PURE__ */ jsx18(EmailVerify, {}) }) : null,
1982
- /* @__PURE__ */ jsx18(Route, { path: "/*", element: /* @__PURE__ */ jsx18(PreAuthFlow, {}) })
2036
+ return /* @__PURE__ */ jsxs14(Routes, { children: [
2037
+ /* @__PURE__ */ jsx19(Route, { path: "/signin", element: /* @__PURE__ */ jsx19(Login, {}) }),
2038
+ /* @__PURE__ */ jsx19(Route, { path: "/signup", element: /* @__PURE__ */ jsx19(Signup, {}) }),
2039
+ /* @__PURE__ */ jsx19(Route, { path: "/forgot", element: /* @__PURE__ */ jsx19(Forgot, {}) }),
2040
+ /* @__PURE__ */ jsx19(Route, { path: "/reset", element: /* @__PURE__ */ jsx19(Reset, {}) }),
2041
+ EmailVerify ? /* @__PURE__ */ jsx19(Route, { path: "/verify", element: /* @__PURE__ */ jsx19(EmailVerify, {}) }) : null,
2042
+ /* @__PURE__ */ jsx19(Route, { path: "/*", element: /* @__PURE__ */ jsx19(PreAuthFlow, {}) })
1983
2043
  ] });
1984
2044
  }
1985
- return /* @__PURE__ */ jsxs13(Routes, { children: [
1986
- /* @__PURE__ */ jsx18(Route, { path: "/", element: /* @__PURE__ */ jsx18(Login, {}) }),
1987
- /* @__PURE__ */ jsx18(Route, { path: "/signup", element: /* @__PURE__ */ jsx18(Signup, {}) }),
1988
- /* @__PURE__ */ jsx18(Route, { path: "/forgot", element: /* @__PURE__ */ jsx18(Forgot, {}) }),
1989
- /* @__PURE__ */ jsx18(Route, { path: "/reset", element: /* @__PURE__ */ jsx18(Reset, {}) }),
1990
- EmailVerify ? /* @__PURE__ */ jsx18(Route, { path: "/verify", element: /* @__PURE__ */ jsx18(EmailVerify, {}) }) : null,
1991
- /* @__PURE__ */ jsx18(Route, { path: "*", element: /* @__PURE__ */ jsx18(Navigate, { to: "/", replace: true }) })
2045
+ return /* @__PURE__ */ jsxs14(Routes, { children: [
2046
+ /* @__PURE__ */ jsx19(Route, { path: "/", element: /* @__PURE__ */ jsx19(Login, {}) }),
2047
+ /* @__PURE__ */ jsx19(Route, { path: "/signup", element: /* @__PURE__ */ jsx19(Signup, {}) }),
2048
+ /* @__PURE__ */ jsx19(Route, { path: "/forgot", element: /* @__PURE__ */ jsx19(Forgot, {}) }),
2049
+ /* @__PURE__ */ jsx19(Route, { path: "/reset", element: /* @__PURE__ */ jsx19(Reset, {}) }),
2050
+ EmailVerify ? /* @__PURE__ */ jsx19(Route, { path: "/verify", element: /* @__PURE__ */ jsx19(EmailVerify, {}) }) : null,
2051
+ /* @__PURE__ */ jsx19(Route, { path: "*", element: /* @__PURE__ */ jsx19(Navigate, { to: "/", replace: true }) })
1992
2052
  ] });
1993
2053
  }
1994
- return /* @__PURE__ */ jsx18(Fragment6, { children });
2054
+ return /* @__PURE__ */ jsx19(Fragment6, { children });
1995
2055
  }
1996
2056
  function FallbackPaywall() {
1997
2057
  return null;
1998
2058
  }
1999
2059
 
2000
2060
  // src/hooks/usePush.ts
2001
- import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
2002
- import { useHook as useHook5 } from "@hook-sdk/sdk";
2061
+ import { useCallback as useCallback4, useEffect as useEffect7, useState as useState6 } from "react";
2062
+ import { useHook as useHook6 } from "@hook-sdk/sdk";
2063
+ var DISMISS_STORAGE_KEY = "push:dismissed-until";
2064
+ var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
2003
2065
  function detectIosNeedsInstall() {
2004
2066
  if (typeof navigator === "undefined" || typeof window === "undefined") return false;
2005
2067
  const ua = navigator.userAgent || "";
@@ -2010,6 +2072,21 @@ function detectIosNeedsInstall() {
2010
2072
  const legacyStandalone = typeof navigator.standalone === "boolean" ? navigator.standalone : false;
2011
2073
  return !(standalone || legacyStandalone);
2012
2074
  }
2075
+ function readDismissedUntil() {
2076
+ if (typeof localStorage === "undefined") return null;
2077
+ try {
2078
+ const raw = localStorage.getItem(DISMISS_STORAGE_KEY);
2079
+ if (raw === null) return null;
2080
+ const n = Number.parseInt(raw, 10);
2081
+ return Number.isFinite(n) ? n : null;
2082
+ } catch {
2083
+ return null;
2084
+ }
2085
+ }
2086
+ function isDismissedNow() {
2087
+ const until = readDismissedUntil();
2088
+ return until !== null && until > Date.now();
2089
+ }
2013
2090
  function deriveState(push) {
2014
2091
  if (!push.isAvailable()) {
2015
2092
  if (detectIosNeedsInstall()) return { kind: "ios_needs_install" };
@@ -2022,12 +2099,13 @@ function deriveState(push) {
2022
2099
  if (detectIosNeedsInstall()) return { kind: "ios_needs_install" };
2023
2100
  return { kind: "unsupported" };
2024
2101
  }
2102
+ if (isDismissedNow()) return { kind: "dismissed" };
2025
2103
  return { kind: "prompt" };
2026
2104
  }
2027
2105
  function usePush() {
2028
- const { push } = useHook5();
2029
- const [state, setState] = useState5(() => deriveState(push));
2030
- useEffect6(() => {
2106
+ const { push } = useHook6();
2107
+ const [state, setState] = useState6(() => deriveState(push));
2108
+ useEffect7(() => {
2031
2109
  setState(deriveState(push));
2032
2110
  }, [push]);
2033
2111
  const subscribe = useCallback4(async () => {
@@ -2051,35 +2129,64 @@ function usePush() {
2051
2129
  throw e;
2052
2130
  }
2053
2131
  }, [push]);
2054
- return { state, subscribe, unsubscribe };
2132
+ const dismiss = useCallback4(() => {
2133
+ if (typeof localStorage !== "undefined") {
2134
+ try {
2135
+ localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
2136
+ } catch {
2137
+ }
2138
+ }
2139
+ setState({ kind: "dismissed" });
2140
+ }, []);
2141
+ return { state, subscribe, unsubscribe, dismiss };
2055
2142
  }
2056
2143
 
2057
2144
  // src/components/PushPrompt.tsx
2058
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
2145
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
2146
+ function platformRecoveryCopy(texts) {
2147
+ if (typeof navigator === "undefined") return null;
2148
+ const ua = navigator.userAgent || "";
2149
+ const platform = detectPlatform(ua);
2150
+ switch (platform) {
2151
+ case "ios-safari":
2152
+ case "ios-other":
2153
+ return texts.deniedRecoveryIos ?? null;
2154
+ case "android":
2155
+ return texts.deniedRecoveryAndroid ?? null;
2156
+ case "desktop":
2157
+ return texts.deniedRecoveryDesktop ?? null;
2158
+ case "in-app":
2159
+ return texts.deniedRecoveryInApp ?? null;
2160
+ default:
2161
+ return null;
2162
+ }
2163
+ }
2059
2164
  function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
2060
2165
  const { state, subscribe } = usePush();
2061
- if (state.kind === "subscribed") return null;
2166
+ if (state.kind === "subscribed" || state.kind === "dismissed") return null;
2062
2167
  if (state.kind === "ios_needs_install") {
2063
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2064
- /* @__PURE__ */ jsx19("h3", { children: texts.iosInstallTitle }),
2065
- /* @__PURE__ */ jsx19("p", { children: texts.iosInstallBody }),
2066
- onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx19("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2168
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2169
+ /* @__PURE__ */ jsx20("h3", { children: texts.iosInstallTitle }),
2170
+ /* @__PURE__ */ jsx20("p", { children: texts.iosInstallBody }),
2171
+ onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx20("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2067
2172
  ] });
2068
2173
  }
2069
2174
  if (state.kind === "denied") {
2070
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
2071
- /* @__PURE__ */ jsx19("h3", { children: texts.deniedTitle }),
2072
- /* @__PURE__ */ jsx19("p", { children: texts.deniedBody })
2175
+ const recovery = platformRecoveryCopy(texts);
2176
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
2177
+ /* @__PURE__ */ jsx20("h3", { children: texts.deniedTitle }),
2178
+ /* @__PURE__ */ jsx20("p", { children: texts.deniedBody }),
2179
+ recovery && /* @__PURE__ */ jsx20("p", { "data-testid": "denied-recovery", children: recovery })
2073
2180
  ] });
2074
2181
  }
2075
2182
  if (state.kind === "unsupported") {
2076
- return /* @__PURE__ */ jsx19("div", { className, role: "region", children: /* @__PURE__ */ jsx19("p", { children: texts.unsupportedBody }) });
2183
+ return /* @__PURE__ */ jsx20("div", { className, role: "region", children: /* @__PURE__ */ jsx20("p", { children: texts.unsupportedBody }) });
2077
2184
  }
2078
2185
  if (state.kind === "error") {
2079
- return /* @__PURE__ */ jsx19("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx19("p", { children: state.message }) });
2186
+ return /* @__PURE__ */ jsx20("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx20("p", { children: state.message }) });
2080
2187
  }
2081
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", children: [
2082
- /* @__PURE__ */ jsx19(
2188
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", children: [
2189
+ /* @__PURE__ */ jsx20(
2083
2190
  "button",
2084
2191
  {
2085
2192
  type: "button",
@@ -2093,29 +2200,29 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
2093
2200
  children: texts.cta
2094
2201
  }
2095
2202
  ),
2096
- onDeclined && /* @__PURE__ */ jsx19("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2203
+ onDeclined && /* @__PURE__ */ jsx20("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2097
2204
  ] });
2098
2205
  }
2099
2206
 
2100
2207
  // src/defaults/LoadingState.tsx
2101
- import { jsx as jsx20 } from "react/jsx-runtime";
2208
+ import { jsx as jsx21 } from "react/jsx-runtime";
2102
2209
  function LoadingState({ message }) {
2103
- return /* @__PURE__ */ jsx20("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ jsx20("span", { children: message ?? "Carregando..." }) });
2210
+ return /* @__PURE__ */ jsx21("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ jsx21("span", { children: message ?? "Carregando..." }) });
2104
2211
  }
2105
2212
 
2106
2213
  // src/defaults/EmptyState.tsx
2107
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
2214
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2108
2215
  function EmptyState({ title, description, action }) {
2109
- return /* @__PURE__ */ jsxs15("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2110
- /* @__PURE__ */ jsx21("h2", { style: { marginBottom: 8 }, children: title }),
2111
- description && /* @__PURE__ */ jsx21("p", { style: { opacity: 0.7 }, children: description }),
2112
- action && /* @__PURE__ */ jsx21("div", { style: { marginTop: 16 }, children: action })
2216
+ return /* @__PURE__ */ jsxs16("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2217
+ /* @__PURE__ */ jsx22("h2", { style: { marginBottom: 8 }, children: title }),
2218
+ description && /* @__PURE__ */ jsx22("p", { style: { opacity: 0.7 }, children: description }),
2219
+ action && /* @__PURE__ */ jsx22("div", { style: { marginTop: 16 }, children: action })
2113
2220
  ] });
2114
2221
  }
2115
2222
 
2116
2223
  // src/hooks/useLoginForm.ts
2117
- import { useCallback as useCallback5, useMemo as useMemo4, useState as useState6 } from "react";
2118
- import { useHook as useHook6 } from "@hook-sdk/sdk";
2224
+ import { useCallback as useCallback5, useMemo as useMemo4, useState as useState7 } from "react";
2225
+ import { useHook as useHook7 } from "@hook-sdk/sdk";
2119
2226
 
2120
2227
  // src/errors.ts
2121
2228
  import { SdkError, SdkAuthError, SdkRateLimitError } from "@hook-sdk/sdk";
@@ -2150,11 +2257,11 @@ function mapSdkError(err) {
2150
2257
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2151
2258
  var MIN_PASSWORD = 8;
2152
2259
  function useLoginForm() {
2153
- const { auth } = useHook6();
2154
- const [email, setEmail] = useState6("");
2155
- const [password, setPassword] = useState6("");
2156
- const [submitting, setSubmitting] = useState6(false);
2157
- const [error, setError] = useState6(null);
2260
+ const { auth } = useHook7();
2261
+ const [email, setEmail] = useState7("");
2262
+ const [password, setPassword] = useState7("");
2263
+ const [submitting, setSubmitting] = useState7(false);
2264
+ const [error, setError] = useState7(null);
2158
2265
  const emailError = useMemo4(() => {
2159
2266
  if (email.length === 0) return null;
2160
2267
  if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
@@ -2196,17 +2303,17 @@ function useLoginForm() {
2196
2303
  }
2197
2304
 
2198
2305
  // src/hooks/useSignupForm.ts
2199
- import { useCallback as useCallback6, useMemo as useMemo5, useState as useState7 } from "react";
2200
- import { useHook as useHook7 } from "@hook-sdk/sdk";
2306
+ import { useCallback as useCallback6, useMemo as useMemo5, useState as useState8 } from "react";
2307
+ import { useHook as useHook8 } from "@hook-sdk/sdk";
2201
2308
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2202
2309
  var MIN_PASSWORD2 = 8;
2203
2310
  function useSignupForm() {
2204
- const { auth } = useHook7();
2205
- const [name, setName] = useState7("");
2206
- const [email, setEmail] = useState7("");
2207
- const [password, setPassword] = useState7("");
2208
- const [submitting, setSubmitting] = useState7(false);
2209
- const [error, setError] = useState7(null);
2311
+ const { auth } = useHook8();
2312
+ const [name, setName] = useState8("");
2313
+ const [email, setEmail] = useState8("");
2314
+ const [password, setPassword] = useState8("");
2315
+ const [submitting, setSubmitting] = useState8(false);
2316
+ const [error, setError] = useState8(null);
2210
2317
  const nameError = useMemo5(() => {
2211
2318
  if (name.length === 0) return null;
2212
2319
  if (name.trim().length < 2) return "Nome muito curto.";
@@ -2256,15 +2363,15 @@ function useSignupForm() {
2256
2363
  }
2257
2364
 
2258
2365
  // src/hooks/useForgotForm.ts
2259
- import { useCallback as useCallback7, useMemo as useMemo6, useState as useState8 } from "react";
2260
- import { useHook as useHook8 } from "@hook-sdk/sdk";
2366
+ import { useCallback as useCallback7, useMemo as useMemo6, useState as useState9 } from "react";
2367
+ import { useHook as useHook9 } from "@hook-sdk/sdk";
2261
2368
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2262
2369
  function useForgotForm() {
2263
- const { auth } = useHook8();
2264
- const [email, setEmail] = useState8("");
2265
- const [submitting, setSubmitting] = useState8(false);
2266
- const [sent, setSent] = useState8(false);
2267
- const [error, setError] = useState8(null);
2370
+ const { auth } = useHook9();
2371
+ const [email, setEmail] = useState9("");
2372
+ const [submitting, setSubmitting] = useState9(false);
2373
+ const [sent, setSent] = useState9(false);
2374
+ const [error, setError] = useState9(null);
2268
2375
  const emailError = useMemo6(() => {
2269
2376
  if (email.length === 0) return null;
2270
2377
  if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
@@ -2299,18 +2406,18 @@ function useForgotForm() {
2299
2406
  }
2300
2407
 
2301
2408
  // src/hooks/useResetForm.ts
2302
- import { useCallback as useCallback8, useEffect as useEffect7, useMemo as useMemo7, useState as useState9 } from "react";
2303
- import { useHook as useHook9 } from "@hook-sdk/sdk";
2409
+ import { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo7, useState as useState10 } from "react";
2410
+ import { useHook as useHook10 } from "@hook-sdk/sdk";
2304
2411
  var MIN_PASSWORD3 = 12;
2305
2412
  function useResetForm() {
2306
- const { auth } = useHook9();
2307
- const [token, setToken] = useState9(null);
2308
- const [password, setPassword] = useState9("");
2309
- const [confirm, setConfirm] = useState9("");
2310
- const [submitting, setSubmitting] = useState9(false);
2311
- const [done, setDone] = useState9(false);
2312
- const [error, setError] = useState9(null);
2313
- useEffect7(() => {
2413
+ const { auth } = useHook10();
2414
+ const [token, setToken] = useState10(null);
2415
+ const [password, setPassword] = useState10("");
2416
+ const [confirm, setConfirm] = useState10("");
2417
+ const [submitting, setSubmitting] = useState10(false);
2418
+ const [done, setDone] = useState10(false);
2419
+ const [error, setError] = useState10(null);
2420
+ useEffect8(() => {
2314
2421
  if (typeof window === "undefined") return;
2315
2422
  const params = new URLSearchParams(window.location.search);
2316
2423
  const t = params.get("token");
@@ -2363,9 +2470,9 @@ function useResetForm() {
2363
2470
  }
2364
2471
 
2365
2472
  // src/hooks/usePlan.ts
2366
- import { useHook as useHook10 } from "@hook-sdk/sdk";
2473
+ import { useHook as useHook11 } from "@hook-sdk/sdk";
2367
2474
  function usePlan() {
2368
- const { plan } = useHook10();
2475
+ const { plan } = useHook11();
2369
2476
  return plan;
2370
2477
  }
2371
2478
 
@@ -2398,12 +2505,12 @@ function discountPercent(anchorCents, realCents) {
2398
2505
  }
2399
2506
 
2400
2507
  // src/hooks/useAuthPrimitives.ts
2401
- import { useEffect as useEffect8 } from "react";
2402
- import { useHook as useHook11 } from "@hook-sdk/sdk";
2508
+ import { useEffect as useEffect9 } from "react";
2509
+ import { useHook as useHook12 } from "@hook-sdk/sdk";
2403
2510
  var warned = false;
2404
2511
  function useAuthPrimitives() {
2405
- const { auth } = useHook11();
2406
- useEffect8(() => {
2512
+ const { auth } = useHook12();
2513
+ useEffect9(() => {
2407
2514
  if (!warned && process.env.NODE_ENV !== "production") {
2408
2515
  warned = true;
2409
2516
  console.warn(
@@ -2425,9 +2532,9 @@ function useAuthPrimitives() {
2425
2532
  }
2426
2533
 
2427
2534
  // src/hooks/useAuth.ts
2428
- import { useHook as useHook12 } from "@hook-sdk/sdk";
2535
+ import { useHook as useHook13 } from "@hook-sdk/sdk";
2429
2536
  function useAuth() {
2430
- const { user, authStatus, auth } = useHook12();
2537
+ const { user, authStatus, auth } = useHook13();
2431
2538
  return {
2432
2539
  user,
2433
2540
  authStatus,
@@ -2436,22 +2543,22 @@ function useAuth() {
2436
2543
  }
2437
2544
 
2438
2545
  // src/hooks/useSubscription.ts
2439
- import { useHook as useHook13 } from "@hook-sdk/sdk";
2546
+ import { useHook as useHook14 } from "@hook-sdk/sdk";
2440
2547
  function useSubscription() {
2441
- const { subscription } = useHook13();
2548
+ const { subscription } = useHook14();
2442
2549
  return {
2443
2550
  status: subscription.status()
2444
2551
  };
2445
2552
  }
2446
2553
 
2447
2554
  // src/hooks/useReminders.ts
2448
- import { useCallback as useCallback9, useEffect as useEffect9, useState as useState10 } from "react";
2449
- import { useHook as useHook14 } from "@hook-sdk/sdk";
2555
+ import { useCallback as useCallback9, useEffect as useEffect10, useState as useState11 } from "react";
2556
+ import { useHook as useHook15 } from "@hook-sdk/sdk";
2450
2557
  function useReminders() {
2451
- const { push } = useHook14();
2558
+ const { push } = useHook15();
2452
2559
  const r = push.reminders;
2453
- const [reminders, setReminders] = useState10([]);
2454
- const [loading, setLoading] = useState10(true);
2560
+ const [reminders, setReminders] = useState11([]);
2561
+ const [loading, setLoading] = useState11(true);
2455
2562
  const reload = useCallback9(async () => {
2456
2563
  setLoading(true);
2457
2564
  try {
@@ -2461,7 +2568,7 @@ function useReminders() {
2461
2568
  setLoading(false);
2462
2569
  }
2463
2570
  }, [r]);
2464
- useEffect9(() => {
2571
+ useEffect10(() => {
2465
2572
  void reload();
2466
2573
  }, [reload]);
2467
2574
  const setReminder = useCallback9(async (input) => {
@@ -2482,9 +2589,9 @@ function useReminders() {
2482
2589
  }
2483
2590
 
2484
2591
  // src/hooks/useToast.ts
2485
- import { useCallback as useCallback10, useState as useState11 } from "react";
2592
+ import { useCallback as useCallback10, useState as useState12 } from "react";
2486
2593
  function useToast() {
2487
- const [items, setItems] = useState11([]);
2594
+ const [items, setItems] = useState12([]);
2488
2595
  const show = useCallback10((message, kind = "info") => {
2489
2596
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2490
2597
  setItems((prev) => [...prev, { id, message, kind }]);
@@ -2500,20 +2607,20 @@ function useToast() {
2500
2607
 
2501
2608
  // src/RouteBoundary.tsx
2502
2609
  import { Routes as Routes2, Route as Route2 } from "react-router-dom";
2503
- import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2610
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
2504
2611
  function RouteBoundary({ children }) {
2505
- return /* @__PURE__ */ jsxs16(Routes2, { children: [
2612
+ return /* @__PURE__ */ jsxs17(Routes2, { children: [
2506
2613
  children,
2507
- /* @__PURE__ */ jsx22(Route2, { path: "*", element: /* @__PURE__ */ jsx22(DefaultNotFound, {}) })
2614
+ /* @__PURE__ */ jsx23(Route2, { path: "*", element: /* @__PURE__ */ jsx23(DefaultNotFound, {}) })
2508
2615
  ] });
2509
2616
  }
2510
2617
  function DefaultNotFound() {
2511
- return /* @__PURE__ */ jsx22("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
2618
+ return /* @__PURE__ */ jsx23("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
2512
2619
  }
2513
2620
 
2514
2621
  // src/PreAuthShell.tsx
2515
2622
  import { BrowserRouter as BrowserRouter2, MemoryRouter as MemoryRouter2, Routes as Routes3 } from "react-router-dom";
2516
- import { jsx as jsx23 } from "react/jsx-runtime";
2623
+ import { jsx as jsx24 } from "react/jsx-runtime";
2517
2624
  function PreAuthShell({
2518
2625
  basename,
2519
2626
  testRouter,
@@ -2521,13 +2628,13 @@ function PreAuthShell({
2521
2628
  children
2522
2629
  }) {
2523
2630
  if (testRouter === "memory") {
2524
- return /* @__PURE__ */ jsx23(MemoryRouter2, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ jsx23(Routes3, { children }) });
2631
+ return /* @__PURE__ */ jsx24(MemoryRouter2, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ jsx24(Routes3, { children }) });
2525
2632
  }
2526
- return /* @__PURE__ */ jsx23(BrowserRouter2, { basename, children: /* @__PURE__ */ jsx23(Routes3, { children }) });
2633
+ return /* @__PURE__ */ jsx24(BrowserRouter2, { basename, children: /* @__PURE__ */ jsx24(Routes3, { children }) });
2527
2634
  }
2528
2635
 
2529
2636
  // src/OnboardingFlow.tsx
2530
- import { useCallback as useCallback11, useMemo as useMemo8, useRef as useRef3 } from "react";
2637
+ import { useCallback as useCallback11, useMemo as useMemo8, useRef as useRef4 } from "react";
2531
2638
  import { usePersistedState } from "@hook-sdk/sdk";
2532
2639
 
2533
2640
  // src/hooks/useOnboardingStep.ts
@@ -2544,7 +2651,7 @@ function useOnboardingStep() {
2544
2651
  }
2545
2652
 
2546
2653
  // src/OnboardingFlow.tsx
2547
- import { jsx as jsx24 } from "react/jsx-runtime";
2654
+ import { jsx as jsx25 } from "react/jsx-runtime";
2548
2655
  var isFilled = (v) => v != null && v !== "";
2549
2656
  var CURRENT_STEP_FIELD = "currentStep";
2550
2657
  function readPersistedStepIdx(draft) {
@@ -2558,7 +2665,7 @@ function OnboardingFlow({
2558
2665
  persistKey
2559
2666
  }) {
2560
2667
  const [draft, setDraft, status] = usePersistedState(persistKey, {});
2561
- const draftRef = useRef3(draft);
2668
+ const draftRef = useRef4(draft);
2562
2669
  draftRef.current = draft;
2563
2670
  const idx = readPersistedStepIdx(draft);
2564
2671
  const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
@@ -2622,7 +2729,7 @@ function OnboardingFlow({
2622
2729
  `[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
2623
2730
  );
2624
2731
  }
2625
- return /* @__PURE__ */ jsx24(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx24(Screen, {}) });
2732
+ return /* @__PURE__ */ jsx25(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx25(Screen, {}) });
2626
2733
  }
2627
2734
 
2628
2735
  // src/hooks/useFeature.ts