@hook-sdk/template 0.12.0 → 0.14.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,28 +1835,32 @@ 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];
1852
+ var MAX_CYCLES = 3;
1853
+ var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
1793
1854
  function PaymentReturnHandler({ children }) {
1794
- const { subscription } = useHook3();
1795
- const subRef = useRef2(subscription);
1855
+ const { subscription } = useHook4();
1856
+ const subRef = useRef3(subscription);
1796
1857
  subRef.current = subscription;
1797
- const runIdRef = useRef2(0);
1798
- const [state, setState] = useState4("idle");
1858
+ const runIdRef = useRef3(0);
1859
+ const cyclesRef = useRef3(0);
1860
+ const [state, setState] = useState5("idle");
1799
1861
  const runPoll = useCallback3(() => {
1800
1862
  const runId = ++runIdRef.current;
1863
+ cyclesRef.current += 1;
1801
1864
  setState("confirming");
1802
1865
  let attempts = 0;
1803
1866
  const tick = async () => {
@@ -1813,37 +1876,88 @@ function PaymentReturnHandler({ children }) {
1813
1876
  const cleanUrl = new URL(window.location.href);
1814
1877
  cleanUrl.searchParams.delete("paymentReturn");
1815
1878
  window.history.replaceState({}, "", cleanUrl.toString());
1879
+ cyclesRef.current = 0;
1816
1880
  setState("idle");
1817
1881
  return;
1818
1882
  }
1819
1883
  const delay = BACKOFF_MS[attempts - 1];
1820
1884
  if (delay === void 0) {
1821
- setState("waiting");
1885
+ if (cyclesRef.current >= MAX_CYCLES) {
1886
+ setState("timeout");
1887
+ } else {
1888
+ setState("waiting");
1889
+ }
1822
1890
  return;
1823
1891
  }
1824
1892
  setTimeout(tick, delay);
1825
1893
  };
1826
1894
  void tick();
1827
1895
  }, []);
1828
- useEffect5(() => {
1896
+ useEffect6(() => {
1829
1897
  if (typeof window === "undefined") return;
1830
1898
  const url = new URL(window.location.href);
1831
1899
  if (url.searchParams.get("paymentReturn") !== "1") return;
1900
+ cyclesRef.current = 0;
1832
1901
  runPoll();
1833
1902
  return () => {
1834
1903
  runIdRef.current++;
1835
1904
  };
1836
1905
  }, [runPoll]);
1906
+ const goHome = useCallback3(() => {
1907
+ const cleanUrl = new URL(window.location.href);
1908
+ cleanUrl.searchParams.delete("paymentReturn");
1909
+ cleanUrl.pathname = "/app/home";
1910
+ window.location.href = cleanUrl.toString();
1911
+ }, []);
1837
1912
  if (state === "confirming") {
1838
- return /* @__PURE__ */ jsx17("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
1913
+ return /* @__PURE__ */ jsx18("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
1839
1914
  }
1840
1915
  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" })
1916
+ return /* @__PURE__ */ jsx18("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs13("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
1917
+ /* @__PURE__ */ jsx18("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
1918
+ /* @__PURE__ */ jsx18("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
1919
+ ] }) });
1920
+ }
1921
+ if (state === "timeout") {
1922
+ return /* @__PURE__ */ jsx18("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ jsxs13("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
1923
+ /* @__PURE__ */ jsx18("div", { style: { marginBottom: 16 }, children: "Ainda n\xE3o conseguimos confirmar seu pagamento com o banco. Voc\xEA pode tentar de novo, voltar pro app, ou falar com a gente." }),
1924
+ /* @__PURE__ */ jsxs13("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
1925
+ /* @__PURE__ */ jsx18(
1926
+ "button",
1927
+ {
1928
+ type: "button",
1929
+ onClick: () => {
1930
+ cyclesRef.current = 0;
1931
+ runPoll();
1932
+ },
1933
+ style: buttonStyle,
1934
+ "data-testid": "payment-timeout-retry",
1935
+ children: "Tentar de novo"
1936
+ }
1937
+ ),
1938
+ /* @__PURE__ */ jsx18(
1939
+ "button",
1940
+ {
1941
+ type: "button",
1942
+ onClick: goHome,
1943
+ style: secondaryButtonStyle,
1944
+ "data-testid": "payment-timeout-home",
1945
+ children: "Voltar pro app"
1946
+ }
1947
+ ),
1948
+ /* @__PURE__ */ jsx18(
1949
+ "a",
1950
+ {
1951
+ href: SUPPORT_MAILTO,
1952
+ style: linkStyle,
1953
+ "data-testid": "payment-timeout-support",
1954
+ children: "Falar com suporte"
1955
+ }
1956
+ )
1957
+ ] })
1844
1958
  ] }) });
1845
1959
  }
1846
- return /* @__PURE__ */ jsx17(Fragment5, { children });
1960
+ return /* @__PURE__ */ jsx18(Fragment5, { children });
1847
1961
  }
1848
1962
  var overlayStyle2 = {
1849
1963
  position: "fixed",
@@ -1867,9 +1981,22 @@ var buttonStyle = {
1867
1981
  fontWeight: 600,
1868
1982
  cursor: "pointer"
1869
1983
  };
1984
+ var secondaryButtonStyle = {
1985
+ ...buttonStyle,
1986
+ background: "transparent",
1987
+ color: "white",
1988
+ border: "1px solid rgba(255,255,255,0.5)"
1989
+ };
1990
+ var linkStyle = {
1991
+ color: "white",
1992
+ textDecoration: "underline",
1993
+ fontSize: "0.9rem",
1994
+ marginTop: 4,
1995
+ textAlign: "center"
1996
+ };
1870
1997
 
1871
1998
  // src/AppRoot.tsx
1872
- import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
1999
+ import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
1873
2000
  function buildLegacyConfigShim(config) {
1874
2001
  const paywall = config.paywall;
1875
2002
  const isFree = paywall.mode === "free";
@@ -1937,9 +2064,10 @@ function AppRoot(props) {
1937
2064
  const Router = testRouter === "memory" ? MemoryRouter : BrowserRouter;
1938
2065
  const basename = `/app/${config.slug}`;
1939
2066
  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(
2067
+ 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: [
2068
+ /* @__PURE__ */ jsx19(DeepLinkHandler, { deepLinks: config.deepLinks }),
2069
+ /* @__PURE__ */ jsx19(SessionExpiredBanner, {}),
2070
+ /* @__PURE__ */ jsx19(InstallGate, { children: /* @__PURE__ */ jsx19(
1943
2071
  AuthGated,
1944
2072
  {
1945
2073
  config,
@@ -1951,9 +2079,9 @@ function AppRoot(props) {
1951
2079
  Paywall,
1952
2080
  Onboarding,
1953
2081
  PreAuthFlow,
1954
- children: /* @__PURE__ */ jsxs13(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: [
2082
+ children: /* @__PURE__ */ jsxs14(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: [
1955
2083
  children,
1956
- /* @__PURE__ */ jsx18(PushPrompt, {})
2084
+ /* @__PURE__ */ jsx19(PushPrompt, {})
1957
2085
  ] })
1958
2086
  }
1959
2087
  ) })
@@ -1969,39 +2097,39 @@ function AuthGated({
1969
2097
  EmailVerify,
1970
2098
  PreAuthFlow
1971
2099
  }) {
1972
- const { authStatus } = useHook4();
2100
+ const { authStatus } = useHook5();
1973
2101
  if (authStatus === "loading") return null;
1974
2102
  if (authStatus !== "authenticated") {
1975
2103
  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, {}) })
2104
+ return /* @__PURE__ */ jsxs14(Routes, { children: [
2105
+ /* @__PURE__ */ jsx19(Route, { path: "/signin", element: /* @__PURE__ */ jsx19(Login, {}) }),
2106
+ /* @__PURE__ */ jsx19(Route, { path: "/signup", element: /* @__PURE__ */ jsx19(Signup, {}) }),
2107
+ /* @__PURE__ */ jsx19(Route, { path: "/forgot", element: /* @__PURE__ */ jsx19(Forgot, {}) }),
2108
+ /* @__PURE__ */ jsx19(Route, { path: "/reset", element: /* @__PURE__ */ jsx19(Reset, {}) }),
2109
+ EmailVerify ? /* @__PURE__ */ jsx19(Route, { path: "/verify", element: /* @__PURE__ */ jsx19(EmailVerify, {}) }) : null,
2110
+ /* @__PURE__ */ jsx19(Route, { path: "/*", element: /* @__PURE__ */ jsx19(PreAuthFlow, {}) })
1983
2111
  ] });
1984
2112
  }
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 }) })
2113
+ return /* @__PURE__ */ jsxs14(Routes, { children: [
2114
+ /* @__PURE__ */ jsx19(Route, { path: "/", element: /* @__PURE__ */ jsx19(Login, {}) }),
2115
+ /* @__PURE__ */ jsx19(Route, { path: "/signup", element: /* @__PURE__ */ jsx19(Signup, {}) }),
2116
+ /* @__PURE__ */ jsx19(Route, { path: "/forgot", element: /* @__PURE__ */ jsx19(Forgot, {}) }),
2117
+ /* @__PURE__ */ jsx19(Route, { path: "/reset", element: /* @__PURE__ */ jsx19(Reset, {}) }),
2118
+ EmailVerify ? /* @__PURE__ */ jsx19(Route, { path: "/verify", element: /* @__PURE__ */ jsx19(EmailVerify, {}) }) : null,
2119
+ /* @__PURE__ */ jsx19(Route, { path: "*", element: /* @__PURE__ */ jsx19(Navigate, { to: "/", replace: true }) })
1992
2120
  ] });
1993
2121
  }
1994
- return /* @__PURE__ */ jsx18(Fragment6, { children });
2122
+ return /* @__PURE__ */ jsx19(Fragment6, { children });
1995
2123
  }
1996
2124
  function FallbackPaywall() {
1997
2125
  return null;
1998
2126
  }
1999
2127
 
2000
2128
  // 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";
2129
+ import { useCallback as useCallback4, useEffect as useEffect7, useState as useState6 } from "react";
2130
+ import { useHook as useHook6 } from "@hook-sdk/sdk";
2003
2131
  var DISMISS_STORAGE_KEY = "push:dismissed-until";
2004
- var DISMISS_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
2132
+ var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
2005
2133
  function detectIosNeedsInstall() {
2006
2134
  if (typeof navigator === "undefined" || typeof window === "undefined") return false;
2007
2135
  const ua = navigator.userAgent || "";
@@ -2043,9 +2171,9 @@ function deriveState(push) {
2043
2171
  return { kind: "prompt" };
2044
2172
  }
2045
2173
  function usePush() {
2046
- const { push } = useHook5();
2047
- const [state, setState] = useState5(() => deriveState(push));
2048
- useEffect6(() => {
2174
+ const { push } = useHook6();
2175
+ const [state, setState] = useState6(() => deriveState(push));
2176
+ useEffect7(() => {
2049
2177
  setState(deriveState(push));
2050
2178
  }, [push]);
2051
2179
  const subscribe = useCallback4(async () => {
@@ -2072,7 +2200,7 @@ function usePush() {
2072
2200
  const dismiss = useCallback4(() => {
2073
2201
  if (typeof localStorage !== "undefined") {
2074
2202
  try {
2075
- localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS));
2203
+ localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
2076
2204
  } catch {
2077
2205
  }
2078
2206
  }
@@ -2082,7 +2210,7 @@ function usePush() {
2082
2210
  }
2083
2211
 
2084
2212
  // src/components/PushPrompt.tsx
2085
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
2213
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
2086
2214
  function platformRecoveryCopy(texts) {
2087
2215
  if (typeof navigator === "undefined") return null;
2088
2216
  const ua = navigator.userAgent || "";
@@ -2105,28 +2233,28 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
2105
2233
  const { state, subscribe } = usePush();
2106
2234
  if (state.kind === "subscribed" || state.kind === "dismissed") return null;
2107
2235
  if (state.kind === "ios_needs_install") {
2108
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2109
- /* @__PURE__ */ jsx19("h3", { children: texts.iosInstallTitle }),
2110
- /* @__PURE__ */ jsx19("p", { children: texts.iosInstallBody }),
2111
- onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx19("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2236
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2237
+ /* @__PURE__ */ jsx20("h3", { children: texts.iosInstallTitle }),
2238
+ /* @__PURE__ */ jsx20("p", { children: texts.iosInstallBody }),
2239
+ onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx20("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
2112
2240
  ] });
2113
2241
  }
2114
2242
  if (state.kind === "denied") {
2115
2243
  const recovery = platformRecoveryCopy(texts);
2116
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
2117
- /* @__PURE__ */ jsx19("h3", { children: texts.deniedTitle }),
2118
- /* @__PURE__ */ jsx19("p", { children: texts.deniedBody }),
2119
- recovery && /* @__PURE__ */ jsx19("p", { "data-testid": "denied-recovery", children: recovery })
2244
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
2245
+ /* @__PURE__ */ jsx20("h3", { children: texts.deniedTitle }),
2246
+ /* @__PURE__ */ jsx20("p", { children: texts.deniedBody }),
2247
+ recovery && /* @__PURE__ */ jsx20("p", { "data-testid": "denied-recovery", children: recovery })
2120
2248
  ] });
2121
2249
  }
2122
2250
  if (state.kind === "unsupported") {
2123
- return /* @__PURE__ */ jsx19("div", { className, role: "region", children: /* @__PURE__ */ jsx19("p", { children: texts.unsupportedBody }) });
2251
+ return /* @__PURE__ */ jsx20("div", { className, role: "region", children: /* @__PURE__ */ jsx20("p", { children: texts.unsupportedBody }) });
2124
2252
  }
2125
2253
  if (state.kind === "error") {
2126
- return /* @__PURE__ */ jsx19("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx19("p", { children: state.message }) });
2254
+ return /* @__PURE__ */ jsx20("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx20("p", { children: state.message }) });
2127
2255
  }
2128
- return /* @__PURE__ */ jsxs14("div", { className, role: "region", children: [
2129
- /* @__PURE__ */ jsx19(
2256
+ return /* @__PURE__ */ jsxs15("div", { className, role: "region", children: [
2257
+ /* @__PURE__ */ jsx20(
2130
2258
  "button",
2131
2259
  {
2132
2260
  type: "button",
@@ -2140,29 +2268,29 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
2140
2268
  children: texts.cta
2141
2269
  }
2142
2270
  ),
2143
- onDeclined && /* @__PURE__ */ jsx19("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2271
+ onDeclined && /* @__PURE__ */ jsx20("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
2144
2272
  ] });
2145
2273
  }
2146
2274
 
2147
2275
  // src/defaults/LoadingState.tsx
2148
- import { jsx as jsx20 } from "react/jsx-runtime";
2276
+ import { jsx as jsx21 } from "react/jsx-runtime";
2149
2277
  function LoadingState({ message }) {
2150
- return /* @__PURE__ */ jsx20("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ jsx20("span", { children: message ?? "Carregando..." }) });
2278
+ return /* @__PURE__ */ jsx21("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ jsx21("span", { children: message ?? "Carregando..." }) });
2151
2279
  }
2152
2280
 
2153
2281
  // src/defaults/EmptyState.tsx
2154
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
2282
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2155
2283
  function EmptyState({ title, description, action }) {
2156
- return /* @__PURE__ */ jsxs15("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2157
- /* @__PURE__ */ jsx21("h2", { style: { marginBottom: 8 }, children: title }),
2158
- description && /* @__PURE__ */ jsx21("p", { style: { opacity: 0.7 }, children: description }),
2159
- action && /* @__PURE__ */ jsx21("div", { style: { marginTop: 16 }, children: action })
2284
+ return /* @__PURE__ */ jsxs16("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
2285
+ /* @__PURE__ */ jsx22("h2", { style: { marginBottom: 8 }, children: title }),
2286
+ description && /* @__PURE__ */ jsx22("p", { style: { opacity: 0.7 }, children: description }),
2287
+ action && /* @__PURE__ */ jsx22("div", { style: { marginTop: 16 }, children: action })
2160
2288
  ] });
2161
2289
  }
2162
2290
 
2163
2291
  // src/hooks/useLoginForm.ts
2164
- import { useCallback as useCallback5, useMemo as useMemo4, useState as useState6 } from "react";
2165
- import { useHook as useHook6 } from "@hook-sdk/sdk";
2292
+ import { useCallback as useCallback5, useMemo as useMemo4, useState as useState7 } from "react";
2293
+ import { useHook as useHook7 } from "@hook-sdk/sdk";
2166
2294
 
2167
2295
  // src/errors.ts
2168
2296
  import { SdkError, SdkAuthError, SdkRateLimitError } from "@hook-sdk/sdk";
@@ -2197,23 +2325,29 @@ function mapSdkError(err) {
2197
2325
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2198
2326
  var MIN_PASSWORD = 8;
2199
2327
  function useLoginForm() {
2200
- const { auth } = useHook6();
2201
- const [email, setEmail] = useState6("");
2202
- const [password, setPassword] = useState6("");
2203
- const [submitting, setSubmitting] = useState6(false);
2204
- const [error, setError] = useState6(null);
2205
- const emailError = useMemo4(() => {
2328
+ const { auth } = useHook7();
2329
+ const [email, setEmail] = useState7("");
2330
+ const [password, setPassword] = useState7("");
2331
+ const [submitting, setSubmitting] = useState7(false);
2332
+ const [error, setError] = useState7(null);
2333
+ const [touchedEmail, setTouchedEmail] = useState7(false);
2334
+ const [touchedPassword, setTouchedPassword] = useState7(false);
2335
+ const [formSubmitAttempted, setFormSubmitAttempted] = useState7(false);
2336
+ const validateEmail = useMemo4(() => {
2206
2337
  if (email.length === 0) return null;
2207
2338
  if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
2208
2339
  return null;
2209
2340
  }, [email]);
2210
- const passwordError = useMemo4(() => {
2341
+ const validatePassword = useMemo4(() => {
2211
2342
  if (password.length === 0) return null;
2212
2343
  if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
2213
2344
  return null;
2214
2345
  }, [password]);
2215
- const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
2346
+ const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2347
+ const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
2348
+ const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
2216
2349
  const submit = useCallback5(async () => {
2350
+ setFormSubmitAttempted(true);
2217
2351
  if (!canSubmit) return false;
2218
2352
  setSubmitting(true);
2219
2353
  setError(null);
@@ -2231,9 +2365,12 @@ function useLoginForm() {
2231
2365
  email,
2232
2366
  setEmail,
2233
2367
  emailError,
2368
+ markEmailTouched: () => setTouchedEmail(true),
2234
2369
  password,
2235
2370
  setPassword,
2236
2371
  passwordError,
2372
+ markPasswordTouched: () => setTouchedPassword(true),
2373
+ formSubmitAttempted,
2237
2374
  submit,
2238
2375
  submitting,
2239
2376
  canSubmit,
@@ -2243,34 +2380,42 @@ function useLoginForm() {
2243
2380
  }
2244
2381
 
2245
2382
  // src/hooks/useSignupForm.ts
2246
- import { useCallback as useCallback6, useMemo as useMemo5, useState as useState7 } from "react";
2247
- import { useHook as useHook7 } from "@hook-sdk/sdk";
2383
+ import { useCallback as useCallback6, useMemo as useMemo5, useState as useState8 } from "react";
2384
+ import { useHook as useHook8 } from "@hook-sdk/sdk";
2248
2385
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2249
2386
  var MIN_PASSWORD2 = 8;
2250
2387
  function useSignupForm() {
2251
- const { auth } = useHook7();
2252
- const [name, setName] = useState7("");
2253
- const [email, setEmail] = useState7("");
2254
- const [password, setPassword] = useState7("");
2255
- const [submitting, setSubmitting] = useState7(false);
2256
- const [error, setError] = useState7(null);
2257
- const nameError = useMemo5(() => {
2388
+ const { auth } = useHook8();
2389
+ const [name, setName] = useState8("");
2390
+ const [email, setEmail] = useState8("");
2391
+ const [password, setPassword] = useState8("");
2392
+ const [submitting, setSubmitting] = useState8(false);
2393
+ const [error, setError] = useState8(null);
2394
+ const [touchedName, setTouchedName] = useState8(false);
2395
+ const [touchedEmail, setTouchedEmail] = useState8(false);
2396
+ const [touchedPassword, setTouchedPassword] = useState8(false);
2397
+ const [formSubmitAttempted, setFormSubmitAttempted] = useState8(false);
2398
+ const validateName = useMemo5(() => {
2258
2399
  if (name.length === 0) return null;
2259
2400
  if (name.trim().length < 2) return "Nome muito curto.";
2260
2401
  return null;
2261
2402
  }, [name]);
2262
- const emailError = useMemo5(() => {
2403
+ const validateEmail = useMemo5(() => {
2263
2404
  if (email.length === 0) return null;
2264
2405
  if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
2265
2406
  return null;
2266
2407
  }, [email]);
2267
- const passwordError = useMemo5(() => {
2408
+ const validatePassword = useMemo5(() => {
2268
2409
  if (password.length === 0) return null;
2269
2410
  if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
2270
2411
  return null;
2271
2412
  }, [password]);
2272
- const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
2413
+ const nameError = touchedName || formSubmitAttempted ? validateName : null;
2414
+ const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2415
+ const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
2416
+ const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
2273
2417
  const submit = useCallback6(async () => {
2418
+ setFormSubmitAttempted(true);
2274
2419
  if (!canSubmit) return false;
2275
2420
  setSubmitting(true);
2276
2421
  setError(null);
@@ -2288,12 +2433,16 @@ function useSignupForm() {
2288
2433
  name,
2289
2434
  setName,
2290
2435
  nameError,
2436
+ markNameTouched: () => setTouchedName(true),
2291
2437
  email,
2292
2438
  setEmail,
2293
2439
  emailError,
2440
+ markEmailTouched: () => setTouchedEmail(true),
2294
2441
  password,
2295
2442
  setPassword,
2296
2443
  passwordError,
2444
+ markPasswordTouched: () => setTouchedPassword(true),
2445
+ formSubmitAttempted,
2297
2446
  submit,
2298
2447
  submitting,
2299
2448
  canSubmit,
@@ -2303,22 +2452,26 @@ function useSignupForm() {
2303
2452
  }
2304
2453
 
2305
2454
  // src/hooks/useForgotForm.ts
2306
- import { useCallback as useCallback7, useMemo as useMemo6, useState as useState8 } from "react";
2307
- import { useHook as useHook8 } from "@hook-sdk/sdk";
2455
+ import { useCallback as useCallback7, useMemo as useMemo6, useState as useState9 } from "react";
2456
+ import { useHook as useHook9 } from "@hook-sdk/sdk";
2308
2457
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
2309
2458
  function useForgotForm() {
2310
- const { auth } = useHook8();
2311
- const [email, setEmail] = useState8("");
2312
- const [submitting, setSubmitting] = useState8(false);
2313
- const [sent, setSent] = useState8(false);
2314
- const [error, setError] = useState8(null);
2315
- const emailError = useMemo6(() => {
2459
+ const { auth } = useHook9();
2460
+ const [email, setEmail] = useState9("");
2461
+ const [submitting, setSubmitting] = useState9(false);
2462
+ const [sent, setSent] = useState9(false);
2463
+ const [error, setError] = useState9(null);
2464
+ const [touchedEmail, setTouchedEmail] = useState9(false);
2465
+ const [formSubmitAttempted, setFormSubmitAttempted] = useState9(false);
2466
+ const validateEmail = useMemo6(() => {
2316
2467
  if (email.length === 0) return null;
2317
2468
  if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
2318
2469
  return null;
2319
2470
  }, [email]);
2320
- const canSubmit = email.length > 0 && emailError === null && !submitting;
2471
+ const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
2472
+ const canSubmit = email.length > 0 && validateEmail === null && !submitting;
2321
2473
  const submit = useCallback7(async () => {
2474
+ setFormSubmitAttempted(true);
2322
2475
  if (!canSubmit) return false;
2323
2476
  setSubmitting(true);
2324
2477
  setError(null);
@@ -2337,6 +2490,8 @@ function useForgotForm() {
2337
2490
  email,
2338
2491
  setEmail,
2339
2492
  emailError,
2493
+ markEmailTouched: () => setTouchedEmail(true),
2494
+ formSubmitAttempted,
2340
2495
  submit,
2341
2496
  submitting,
2342
2497
  canSubmit,
@@ -2346,35 +2501,41 @@ function useForgotForm() {
2346
2501
  }
2347
2502
 
2348
2503
  // src/hooks/useResetForm.ts
2349
- import { useCallback as useCallback8, useEffect as useEffect7, useMemo as useMemo7, useState as useState9 } from "react";
2350
- import { useHook as useHook9 } from "@hook-sdk/sdk";
2504
+ import { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo7, useState as useState10 } from "react";
2505
+ import { useHook as useHook10 } from "@hook-sdk/sdk";
2351
2506
  var MIN_PASSWORD3 = 12;
2352
2507
  function useResetForm() {
2353
- const { auth } = useHook9();
2354
- const [token, setToken] = useState9(null);
2355
- const [password, setPassword] = useState9("");
2356
- const [confirm, setConfirm] = useState9("");
2357
- const [submitting, setSubmitting] = useState9(false);
2358
- const [done, setDone] = useState9(false);
2359
- const [error, setError] = useState9(null);
2360
- useEffect7(() => {
2508
+ const { auth } = useHook10();
2509
+ const [token, setToken] = useState10(null);
2510
+ const [password, setPassword] = useState10("");
2511
+ const [confirm, setConfirm] = useState10("");
2512
+ const [submitting, setSubmitting] = useState10(false);
2513
+ const [done, setDone] = useState10(false);
2514
+ const [error, setError] = useState10(null);
2515
+ const [touchedPassword, setTouchedPassword] = useState10(false);
2516
+ const [touchedConfirm, setTouchedConfirm] = useState10(false);
2517
+ const [formSubmitAttempted, setFormSubmitAttempted] = useState10(false);
2518
+ useEffect8(() => {
2361
2519
  if (typeof window === "undefined") return;
2362
2520
  const params = new URLSearchParams(window.location.search);
2363
2521
  const t = params.get("token");
2364
2522
  setToken(t && t.length > 0 ? t : null);
2365
2523
  }, []);
2366
- const passwordError = useMemo7(() => {
2524
+ const validatePassword = useMemo7(() => {
2367
2525
  if (password.length === 0) return null;
2368
2526
  if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
2369
2527
  return null;
2370
2528
  }, [password]);
2371
- const confirmError = useMemo7(() => {
2529
+ const validateConfirm = useMemo7(() => {
2372
2530
  if (confirm.length === 0) return null;
2373
2531
  if (confirm !== password) return "Senhas n\xE3o coincidem.";
2374
2532
  return null;
2375
2533
  }, [confirm, password]);
2376
- const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && passwordError === null && confirmError === null && !submitting && !done;
2534
+ const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
2535
+ const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
2536
+ const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
2377
2537
  const submit = useCallback8(async () => {
2538
+ setFormSubmitAttempted(true);
2378
2539
  if (!canSubmit || token === null) return;
2379
2540
  setSubmitting(true);
2380
2541
  setError(null);
@@ -2398,9 +2559,12 @@ function useResetForm() {
2398
2559
  password,
2399
2560
  setPassword,
2400
2561
  passwordError,
2562
+ markPasswordTouched: () => setTouchedPassword(true),
2401
2563
  confirm,
2402
2564
  setConfirm,
2403
2565
  confirmError,
2566
+ markConfirmTouched: () => setTouchedConfirm(true),
2567
+ formSubmitAttempted,
2404
2568
  submit,
2405
2569
  submitting,
2406
2570
  canSubmit,
@@ -2410,9 +2574,9 @@ function useResetForm() {
2410
2574
  }
2411
2575
 
2412
2576
  // src/hooks/usePlan.ts
2413
- import { useHook as useHook10 } from "@hook-sdk/sdk";
2577
+ import { useHook as useHook11 } from "@hook-sdk/sdk";
2414
2578
  function usePlan() {
2415
- const { plan } = useHook10();
2579
+ const { plan } = useHook11();
2416
2580
  return plan;
2417
2581
  }
2418
2582
 
@@ -2445,12 +2609,12 @@ function discountPercent(anchorCents, realCents) {
2445
2609
  }
2446
2610
 
2447
2611
  // src/hooks/useAuthPrimitives.ts
2448
- import { useEffect as useEffect8 } from "react";
2449
- import { useHook as useHook11 } from "@hook-sdk/sdk";
2612
+ import { useEffect as useEffect9 } from "react";
2613
+ import { useHook as useHook12 } from "@hook-sdk/sdk";
2450
2614
  var warned = false;
2451
2615
  function useAuthPrimitives() {
2452
- const { auth } = useHook11();
2453
- useEffect8(() => {
2616
+ const { auth } = useHook12();
2617
+ useEffect9(() => {
2454
2618
  if (!warned && process.env.NODE_ENV !== "production") {
2455
2619
  warned = true;
2456
2620
  console.warn(
@@ -2472,9 +2636,9 @@ function useAuthPrimitives() {
2472
2636
  }
2473
2637
 
2474
2638
  // src/hooks/useAuth.ts
2475
- import { useHook as useHook12 } from "@hook-sdk/sdk";
2639
+ import { useHook as useHook13 } from "@hook-sdk/sdk";
2476
2640
  function useAuth() {
2477
- const { user, authStatus, auth } = useHook12();
2641
+ const { user, authStatus, auth } = useHook13();
2478
2642
  return {
2479
2643
  user,
2480
2644
  authStatus,
@@ -2483,22 +2647,22 @@ function useAuth() {
2483
2647
  }
2484
2648
 
2485
2649
  // src/hooks/useSubscription.ts
2486
- import { useHook as useHook13 } from "@hook-sdk/sdk";
2650
+ import { useHook as useHook14 } from "@hook-sdk/sdk";
2487
2651
  function useSubscription() {
2488
- const { subscription } = useHook13();
2652
+ const { subscription } = useHook14();
2489
2653
  return {
2490
2654
  status: subscription.status()
2491
2655
  };
2492
2656
  }
2493
2657
 
2494
2658
  // src/hooks/useReminders.ts
2495
- import { useCallback as useCallback9, useEffect as useEffect9, useState as useState10 } from "react";
2496
- import { useHook as useHook14 } from "@hook-sdk/sdk";
2659
+ import { useCallback as useCallback9, useEffect as useEffect10, useState as useState11 } from "react";
2660
+ import { useHook as useHook15 } from "@hook-sdk/sdk";
2497
2661
  function useReminders() {
2498
- const { push } = useHook14();
2662
+ const { push } = useHook15();
2499
2663
  const r = push.reminders;
2500
- const [reminders, setReminders] = useState10([]);
2501
- const [loading, setLoading] = useState10(true);
2664
+ const [reminders, setReminders] = useState11([]);
2665
+ const [loading, setLoading] = useState11(true);
2502
2666
  const reload = useCallback9(async () => {
2503
2667
  setLoading(true);
2504
2668
  try {
@@ -2508,7 +2672,7 @@ function useReminders() {
2508
2672
  setLoading(false);
2509
2673
  }
2510
2674
  }, [r]);
2511
- useEffect9(() => {
2675
+ useEffect10(() => {
2512
2676
  void reload();
2513
2677
  }, [reload]);
2514
2678
  const setReminder = useCallback9(async (input) => {
@@ -2529,9 +2693,9 @@ function useReminders() {
2529
2693
  }
2530
2694
 
2531
2695
  // src/hooks/useToast.ts
2532
- import { useCallback as useCallback10, useState as useState11 } from "react";
2696
+ import { useCallback as useCallback10, useState as useState12 } from "react";
2533
2697
  function useToast() {
2534
- const [items, setItems] = useState11([]);
2698
+ const [items, setItems] = useState12([]);
2535
2699
  const show = useCallback10((message, kind = "info") => {
2536
2700
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2537
2701
  setItems((prev) => [...prev, { id, message, kind }]);
@@ -2547,20 +2711,20 @@ function useToast() {
2547
2711
 
2548
2712
  // src/RouteBoundary.tsx
2549
2713
  import { Routes as Routes2, Route as Route2 } from "react-router-dom";
2550
- import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
2714
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
2551
2715
  function RouteBoundary({ children }) {
2552
- return /* @__PURE__ */ jsxs16(Routes2, { children: [
2716
+ return /* @__PURE__ */ jsxs17(Routes2, { children: [
2553
2717
  children,
2554
- /* @__PURE__ */ jsx22(Route2, { path: "*", element: /* @__PURE__ */ jsx22(DefaultNotFound, {}) })
2718
+ /* @__PURE__ */ jsx23(Route2, { path: "*", element: /* @__PURE__ */ jsx23(DefaultNotFound, {}) })
2555
2719
  ] });
2556
2720
  }
2557
2721
  function DefaultNotFound() {
2558
- return /* @__PURE__ */ jsx22("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
2722
+ return /* @__PURE__ */ jsx23("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
2559
2723
  }
2560
2724
 
2561
2725
  // src/PreAuthShell.tsx
2562
2726
  import { BrowserRouter as BrowserRouter2, MemoryRouter as MemoryRouter2, Routes as Routes3 } from "react-router-dom";
2563
- import { jsx as jsx23 } from "react/jsx-runtime";
2727
+ import { jsx as jsx24 } from "react/jsx-runtime";
2564
2728
  function PreAuthShell({
2565
2729
  basename,
2566
2730
  testRouter,
@@ -2568,13 +2732,13 @@ function PreAuthShell({
2568
2732
  children
2569
2733
  }) {
2570
2734
  if (testRouter === "memory") {
2571
- return /* @__PURE__ */ jsx23(MemoryRouter2, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ jsx23(Routes3, { children }) });
2735
+ return /* @__PURE__ */ jsx24(MemoryRouter2, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ jsx24(Routes3, { children }) });
2572
2736
  }
2573
- return /* @__PURE__ */ jsx23(BrowserRouter2, { basename, children: /* @__PURE__ */ jsx23(Routes3, { children }) });
2737
+ return /* @__PURE__ */ jsx24(BrowserRouter2, { basename, children: /* @__PURE__ */ jsx24(Routes3, { children }) });
2574
2738
  }
2575
2739
 
2576
2740
  // src/OnboardingFlow.tsx
2577
- import { useCallback as useCallback11, useMemo as useMemo8, useRef as useRef3 } from "react";
2741
+ import { useCallback as useCallback11, useMemo as useMemo8, useRef as useRef4 } from "react";
2578
2742
  import { usePersistedState } from "@hook-sdk/sdk";
2579
2743
 
2580
2744
  // src/hooks/useOnboardingStep.ts
@@ -2591,7 +2755,7 @@ function useOnboardingStep() {
2591
2755
  }
2592
2756
 
2593
2757
  // src/OnboardingFlow.tsx
2594
- import { jsx as jsx24 } from "react/jsx-runtime";
2758
+ import { jsx as jsx25 } from "react/jsx-runtime";
2595
2759
  var isFilled = (v) => v != null && v !== "";
2596
2760
  var CURRENT_STEP_FIELD = "currentStep";
2597
2761
  function readPersistedStepIdx(draft) {
@@ -2605,7 +2769,7 @@ function OnboardingFlow({
2605
2769
  persistKey
2606
2770
  }) {
2607
2771
  const [draft, setDraft, status] = usePersistedState(persistKey, {});
2608
- const draftRef = useRef3(draft);
2772
+ const draftRef = useRef4(draft);
2609
2773
  draftRef.current = draft;
2610
2774
  const idx = readPersistedStepIdx(draft);
2611
2775
  const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
@@ -2669,7 +2833,7 @@ function OnboardingFlow({
2669
2833
  `[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
2670
2834
  );
2671
2835
  }
2672
- return /* @__PURE__ */ jsx24(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx24(Screen, {}) });
2836
+ return /* @__PURE__ */ jsx25(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx25(Screen, {}) });
2673
2837
  }
2674
2838
 
2675
2839
  // src/hooks/useFeature.ts