@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.cjs +340 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +307 -143
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -69,9 +69,9 @@ __export(index_exports, {
|
|
|
69
69
|
module.exports = __toCommonJS(index_exports);
|
|
70
70
|
|
|
71
71
|
// src/AppRoot.tsx
|
|
72
|
-
var
|
|
72
|
+
var import_react12 = require("react");
|
|
73
73
|
var import_react_router_dom2 = require("react-router-dom");
|
|
74
|
-
var
|
|
74
|
+
var import_sdk5 = require("@hook-sdk/sdk");
|
|
75
75
|
|
|
76
76
|
// src/config/AppConfigContext.tsx
|
|
77
77
|
var import_react = require("react");
|
|
@@ -1826,10 +1826,69 @@ function PushPrompt() {
|
|
|
1826
1826
|
return null;
|
|
1827
1827
|
}
|
|
1828
1828
|
|
|
1829
|
-
// src/
|
|
1829
|
+
// src/internal/SessionExpiredBanner.tsx
|
|
1830
1830
|
var import_react9 = require("react");
|
|
1831
|
+
var import_sdk3 = require("@hook-sdk/sdk");
|
|
1831
1832
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1832
|
-
var
|
|
1833
|
+
var DISMISS_KEY = "hook:session-expired-dismissed-until";
|
|
1834
|
+
var DISMISS_TTL_MS = 60 * 60 * 1e3;
|
|
1835
|
+
function SessionExpiredBanner() {
|
|
1836
|
+
const { authStatus } = (0, import_sdk3.useHook)();
|
|
1837
|
+
const wasAuthRef = (0, import_react9.useRef)(false);
|
|
1838
|
+
const [show, setShow] = (0, import_react9.useState)(false);
|
|
1839
|
+
(0, import_react9.useEffect)(() => {
|
|
1840
|
+
if (authStatus === "authenticated") {
|
|
1841
|
+
wasAuthRef.current = true;
|
|
1842
|
+
setShow(false);
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
if (authStatus === "anonymous" && wasAuthRef.current) {
|
|
1846
|
+
const until = Number(localStorage.getItem(DISMISS_KEY) ?? "0");
|
|
1847
|
+
if (Date.now() < until) {
|
|
1848
|
+
setShow(false);
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
setShow(true);
|
|
1852
|
+
}
|
|
1853
|
+
}, [authStatus]);
|
|
1854
|
+
if (!show) return null;
|
|
1855
|
+
function dismiss() {
|
|
1856
|
+
localStorage.setItem(DISMISS_KEY, String(Date.now() + DISMISS_TTL_MS));
|
|
1857
|
+
setShow(false);
|
|
1858
|
+
}
|
|
1859
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("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: [
|
|
1860
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { children: [
|
|
1861
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Sua sess\xE3o expirou." }),
|
|
1862
|
+
" Fa\xE7a login novamente para continuar."
|
|
1863
|
+
] }),
|
|
1864
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1865
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1866
|
+
"button",
|
|
1867
|
+
{
|
|
1868
|
+
type: "button",
|
|
1869
|
+
onClick: dismiss,
|
|
1870
|
+
className: "px-3 py-1 bg-white text-red-700 rounded text-xs font-medium hover:bg-red-50",
|
|
1871
|
+
children: "Fazer login"
|
|
1872
|
+
}
|
|
1873
|
+
),
|
|
1874
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1875
|
+
"button",
|
|
1876
|
+
{
|
|
1877
|
+
type: "button",
|
|
1878
|
+
onClick: dismiss,
|
|
1879
|
+
"aria-label": "Fechar",
|
|
1880
|
+
className: "px-2 py-1 text-white/80 hover:text-white text-xs",
|
|
1881
|
+
children: "Fechar"
|
|
1882
|
+
}
|
|
1883
|
+
)
|
|
1884
|
+
] })
|
|
1885
|
+
] });
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
// src/defaults/ErrorBoundary.tsx
|
|
1889
|
+
var import_react10 = require("react");
|
|
1890
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1891
|
+
var ErrorBoundary = class extends import_react10.Component {
|
|
1833
1892
|
state = { error: null };
|
|
1834
1893
|
static getDerivedStateFromError(error) {
|
|
1835
1894
|
return { error };
|
|
@@ -1846,28 +1905,32 @@ var ErrorBoundary = class extends import_react9.Component {
|
|
|
1846
1905
|
}
|
|
1847
1906
|
render() {
|
|
1848
1907
|
if (this.state.error) {
|
|
1849
|
-
return this.props.fallback ?? /* @__PURE__ */ (0,
|
|
1850
|
-
/* @__PURE__ */ (0,
|
|
1851
|
-
/* @__PURE__ */ (0,
|
|
1908
|
+
return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
1909
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { children: "Algo deu errado" }),
|
|
1910
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
1852
1911
|
] });
|
|
1853
1912
|
}
|
|
1854
|
-
return /* @__PURE__ */ (0,
|
|
1913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_jsx_runtime17.Fragment, { children: this.props.children });
|
|
1855
1914
|
}
|
|
1856
1915
|
};
|
|
1857
1916
|
|
|
1858
1917
|
// src/internal/PaymentReturnHandler.tsx
|
|
1859
|
-
var
|
|
1860
|
-
var
|
|
1861
|
-
var
|
|
1918
|
+
var import_react11 = require("react");
|
|
1919
|
+
var import_sdk4 = require("@hook-sdk/sdk");
|
|
1920
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1862
1921
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
1922
|
+
var MAX_CYCLES = 3;
|
|
1923
|
+
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
1863
1924
|
function PaymentReturnHandler({ children }) {
|
|
1864
|
-
const { subscription } = (0,
|
|
1865
|
-
const subRef = (0,
|
|
1925
|
+
const { subscription } = (0, import_sdk4.useHook)();
|
|
1926
|
+
const subRef = (0, import_react11.useRef)(subscription);
|
|
1866
1927
|
subRef.current = subscription;
|
|
1867
|
-
const runIdRef = (0,
|
|
1868
|
-
const
|
|
1869
|
-
const
|
|
1928
|
+
const runIdRef = (0, import_react11.useRef)(0);
|
|
1929
|
+
const cyclesRef = (0, import_react11.useRef)(0);
|
|
1930
|
+
const [state, setState] = (0, import_react11.useState)("idle");
|
|
1931
|
+
const runPoll = (0, import_react11.useCallback)(() => {
|
|
1870
1932
|
const runId = ++runIdRef.current;
|
|
1933
|
+
cyclesRef.current += 1;
|
|
1871
1934
|
setState("confirming");
|
|
1872
1935
|
let attempts = 0;
|
|
1873
1936
|
const tick = async () => {
|
|
@@ -1883,37 +1946,88 @@ function PaymentReturnHandler({ children }) {
|
|
|
1883
1946
|
const cleanUrl = new URL(window.location.href);
|
|
1884
1947
|
cleanUrl.searchParams.delete("paymentReturn");
|
|
1885
1948
|
window.history.replaceState({}, "", cleanUrl.toString());
|
|
1949
|
+
cyclesRef.current = 0;
|
|
1886
1950
|
setState("idle");
|
|
1887
1951
|
return;
|
|
1888
1952
|
}
|
|
1889
1953
|
const delay = BACKOFF_MS[attempts - 1];
|
|
1890
1954
|
if (delay === void 0) {
|
|
1891
|
-
|
|
1955
|
+
if (cyclesRef.current >= MAX_CYCLES) {
|
|
1956
|
+
setState("timeout");
|
|
1957
|
+
} else {
|
|
1958
|
+
setState("waiting");
|
|
1959
|
+
}
|
|
1892
1960
|
return;
|
|
1893
1961
|
}
|
|
1894
1962
|
setTimeout(tick, delay);
|
|
1895
1963
|
};
|
|
1896
1964
|
void tick();
|
|
1897
1965
|
}, []);
|
|
1898
|
-
(0,
|
|
1966
|
+
(0, import_react11.useEffect)(() => {
|
|
1899
1967
|
if (typeof window === "undefined") return;
|
|
1900
1968
|
const url = new URL(window.location.href);
|
|
1901
1969
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
1970
|
+
cyclesRef.current = 0;
|
|
1902
1971
|
runPoll();
|
|
1903
1972
|
return () => {
|
|
1904
1973
|
runIdRef.current++;
|
|
1905
1974
|
};
|
|
1906
1975
|
}, [runPoll]);
|
|
1976
|
+
const goHome = (0, import_react11.useCallback)(() => {
|
|
1977
|
+
const cleanUrl = new URL(window.location.href);
|
|
1978
|
+
cleanUrl.searchParams.delete("paymentReturn");
|
|
1979
|
+
cleanUrl.pathname = "/app/home";
|
|
1980
|
+
window.location.href = cleanUrl.toString();
|
|
1981
|
+
}, []);
|
|
1907
1982
|
if (state === "confirming") {
|
|
1908
|
-
return /* @__PURE__ */ (0,
|
|
1983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: "Confirmando pagamento\u2026" });
|
|
1909
1984
|
}
|
|
1910
1985
|
if (state === "waiting") {
|
|
1911
|
-
return /* @__PURE__ */ (0,
|
|
1912
|
-
/* @__PURE__ */ (0,
|
|
1913
|
-
/* @__PURE__ */ (0,
|
|
1986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "button", onClick: runPoll, style: buttonStyle, children: "Atualizar" })
|
|
1989
|
+
] }) });
|
|
1990
|
+
}
|
|
1991
|
+
if (state === "timeout") {
|
|
1992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { role: "alert", "aria-live": "assertive", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { maxWidth: 360, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
1993
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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." }),
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
1995
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1996
|
+
"button",
|
|
1997
|
+
{
|
|
1998
|
+
type: "button",
|
|
1999
|
+
onClick: () => {
|
|
2000
|
+
cyclesRef.current = 0;
|
|
2001
|
+
runPoll();
|
|
2002
|
+
},
|
|
2003
|
+
style: buttonStyle,
|
|
2004
|
+
"data-testid": "payment-timeout-retry",
|
|
2005
|
+
children: "Tentar de novo"
|
|
2006
|
+
}
|
|
2007
|
+
),
|
|
2008
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2009
|
+
"button",
|
|
2010
|
+
{
|
|
2011
|
+
type: "button",
|
|
2012
|
+
onClick: goHome,
|
|
2013
|
+
style: secondaryButtonStyle,
|
|
2014
|
+
"data-testid": "payment-timeout-home",
|
|
2015
|
+
children: "Voltar pro app"
|
|
2016
|
+
}
|
|
2017
|
+
),
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2019
|
+
"a",
|
|
2020
|
+
{
|
|
2021
|
+
href: SUPPORT_MAILTO,
|
|
2022
|
+
style: linkStyle,
|
|
2023
|
+
"data-testid": "payment-timeout-support",
|
|
2024
|
+
children: "Falar com suporte"
|
|
2025
|
+
}
|
|
2026
|
+
)
|
|
2027
|
+
] })
|
|
1914
2028
|
] }) });
|
|
1915
2029
|
}
|
|
1916
|
-
return /* @__PURE__ */ (0,
|
|
2030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_jsx_runtime18.Fragment, { children });
|
|
1917
2031
|
}
|
|
1918
2032
|
var overlayStyle2 = {
|
|
1919
2033
|
position: "fixed",
|
|
@@ -1937,9 +2051,22 @@ var buttonStyle = {
|
|
|
1937
2051
|
fontWeight: 600,
|
|
1938
2052
|
cursor: "pointer"
|
|
1939
2053
|
};
|
|
2054
|
+
var secondaryButtonStyle = {
|
|
2055
|
+
...buttonStyle,
|
|
2056
|
+
background: "transparent",
|
|
2057
|
+
color: "white",
|
|
2058
|
+
border: "1px solid rgba(255,255,255,0.5)"
|
|
2059
|
+
};
|
|
2060
|
+
var linkStyle = {
|
|
2061
|
+
color: "white",
|
|
2062
|
+
textDecoration: "underline",
|
|
2063
|
+
fontSize: "0.9rem",
|
|
2064
|
+
marginTop: 4,
|
|
2065
|
+
textAlign: "center"
|
|
2066
|
+
};
|
|
1940
2067
|
|
|
1941
2068
|
// src/AppRoot.tsx
|
|
1942
|
-
var
|
|
2069
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1943
2070
|
function buildLegacyConfigShim(config) {
|
|
1944
2071
|
const paywall = config.paywall;
|
|
1945
2072
|
const isFree = paywall.mode === "free";
|
|
@@ -2003,13 +2130,14 @@ function AppRoot(props) {
|
|
|
2003
2130
|
"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
|
|
2004
2131
|
);
|
|
2005
2132
|
}
|
|
2006
|
-
const legacyShim = (0,
|
|
2133
|
+
const legacyShim = (0, import_react12.useMemo)(() => buildLegacyConfigShim(config), [config]);
|
|
2007
2134
|
const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
|
|
2008
2135
|
const basename = `/app/${config.slug}`;
|
|
2009
2136
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
2010
|
-
return /* @__PURE__ */ (0,
|
|
2011
|
-
/* @__PURE__ */ (0,
|
|
2012
|
-
/* @__PURE__ */ (0,
|
|
2137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(AppConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TemplateConfigProvider, { config: legacyShim, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PersistenceRegistry, { config: config.persistedKeys, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Router, { ...routerProps, children: [
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DeepLinkHandler, { deepLinks: config.deepLinks }),
|
|
2139
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SessionExpiredBanner, {}),
|
|
2140
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InstallGate, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2013
2141
|
AuthGated,
|
|
2014
2142
|
{
|
|
2015
2143
|
config,
|
|
@@ -2021,9 +2149,9 @@ function AppRoot(props) {
|
|
|
2021
2149
|
Paywall,
|
|
2022
2150
|
Onboarding,
|
|
2023
2151
|
PreAuthFlow,
|
|
2024
|
-
children: /* @__PURE__ */ (0,
|
|
2152
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(SubscriptionGate, { Paywall: Paywall ?? FallbackPaywall, children: [
|
|
2025
2153
|
children,
|
|
2026
|
-
/* @__PURE__ */ (0,
|
|
2154
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PushPrompt, {})
|
|
2027
2155
|
] })
|
|
2028
2156
|
}
|
|
2029
2157
|
) })
|
|
@@ -2039,39 +2167,39 @@ function AuthGated({
|
|
|
2039
2167
|
EmailVerify,
|
|
2040
2168
|
PreAuthFlow
|
|
2041
2169
|
}) {
|
|
2042
|
-
const { authStatus } = (0,
|
|
2170
|
+
const { authStatus } = (0, import_sdk5.useHook)();
|
|
2043
2171
|
if (authStatus === "loading") return null;
|
|
2044
2172
|
if (authStatus !== "authenticated") {
|
|
2045
2173
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
2046
|
-
return /* @__PURE__ */ (0,
|
|
2047
|
-
/* @__PURE__ */ (0,
|
|
2048
|
-
/* @__PURE__ */ (0,
|
|
2049
|
-
/* @__PURE__ */ (0,
|
|
2050
|
-
/* @__PURE__ */ (0,
|
|
2051
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2052
|
-
/* @__PURE__ */ (0,
|
|
2174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2175
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/signin", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Login, {}) }),
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Signup, {}) }),
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Forgot, {}) }),
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Reset, {}) }),
|
|
2179
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EmailVerify, {}) }) : null,
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/*", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PreAuthFlow, {}) })
|
|
2053
2181
|
] });
|
|
2054
2182
|
}
|
|
2055
|
-
return /* @__PURE__ */ (0,
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2057
|
-
/* @__PURE__ */ (0,
|
|
2058
|
-
/* @__PURE__ */ (0,
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2060
|
-
EmailVerify ? /* @__PURE__ */ (0,
|
|
2061
|
-
/* @__PURE__ */ (0,
|
|
2183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_router_dom2.Routes, { children: [
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Login, {}) }),
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/signup", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Signup, {}) }),
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/forgot", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Forgot, {}) }),
|
|
2187
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/reset", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Reset, {}) }),
|
|
2188
|
+
EmailVerify ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "/verify", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EmailVerify, {}) }) : null,
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_router_dom2.Navigate, { to: "/", replace: true }) })
|
|
2062
2190
|
] });
|
|
2063
2191
|
}
|
|
2064
|
-
return /* @__PURE__ */ (0,
|
|
2192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children });
|
|
2065
2193
|
}
|
|
2066
2194
|
function FallbackPaywall() {
|
|
2067
2195
|
return null;
|
|
2068
2196
|
}
|
|
2069
2197
|
|
|
2070
2198
|
// src/hooks/usePush.ts
|
|
2071
|
-
var
|
|
2072
|
-
var
|
|
2199
|
+
var import_react13 = require("react");
|
|
2200
|
+
var import_sdk6 = require("@hook-sdk/sdk");
|
|
2073
2201
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2074
|
-
var
|
|
2202
|
+
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2075
2203
|
function detectIosNeedsInstall() {
|
|
2076
2204
|
if (typeof navigator === "undefined" || typeof window === "undefined") return false;
|
|
2077
2205
|
const ua = navigator.userAgent || "";
|
|
@@ -2113,12 +2241,12 @@ function deriveState(push) {
|
|
|
2113
2241
|
return { kind: "prompt" };
|
|
2114
2242
|
}
|
|
2115
2243
|
function usePush() {
|
|
2116
|
-
const { push } = (0,
|
|
2117
|
-
const [state, setState] = (0,
|
|
2118
|
-
(0,
|
|
2244
|
+
const { push } = (0, import_sdk6.useHook)();
|
|
2245
|
+
const [state, setState] = (0, import_react13.useState)(() => deriveState(push));
|
|
2246
|
+
(0, import_react13.useEffect)(() => {
|
|
2119
2247
|
setState(deriveState(push));
|
|
2120
2248
|
}, [push]);
|
|
2121
|
-
const subscribe = (0,
|
|
2249
|
+
const subscribe = (0, import_react13.useCallback)(async () => {
|
|
2122
2250
|
try {
|
|
2123
2251
|
await push.subscribe();
|
|
2124
2252
|
setState({ kind: "subscribed" });
|
|
@@ -2130,7 +2258,7 @@ function usePush() {
|
|
|
2130
2258
|
throw e;
|
|
2131
2259
|
}
|
|
2132
2260
|
}, [push]);
|
|
2133
|
-
const unsubscribe = (0,
|
|
2261
|
+
const unsubscribe = (0, import_react13.useCallback)(async () => {
|
|
2134
2262
|
try {
|
|
2135
2263
|
await push.unsubscribe();
|
|
2136
2264
|
setState({ kind: "prompt" });
|
|
@@ -2139,10 +2267,10 @@ function usePush() {
|
|
|
2139
2267
|
throw e;
|
|
2140
2268
|
}
|
|
2141
2269
|
}, [push]);
|
|
2142
|
-
const dismiss = (0,
|
|
2270
|
+
const dismiss = (0, import_react13.useCallback)(() => {
|
|
2143
2271
|
if (typeof localStorage !== "undefined") {
|
|
2144
2272
|
try {
|
|
2145
|
-
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() +
|
|
2273
|
+
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
|
|
2146
2274
|
} catch {
|
|
2147
2275
|
}
|
|
2148
2276
|
}
|
|
@@ -2152,7 +2280,7 @@ function usePush() {
|
|
|
2152
2280
|
}
|
|
2153
2281
|
|
|
2154
2282
|
// src/components/PushPrompt.tsx
|
|
2155
|
-
var
|
|
2283
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2156
2284
|
function platformRecoveryCopy(texts) {
|
|
2157
2285
|
if (typeof navigator === "undefined") return null;
|
|
2158
2286
|
const ua = navigator.userAgent || "";
|
|
@@ -2175,28 +2303,28 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2175
2303
|
const { state, subscribe } = usePush();
|
|
2176
2304
|
if (state.kind === "subscribed" || state.kind === "dismissed") return null;
|
|
2177
2305
|
if (state.kind === "ios_needs_install") {
|
|
2178
|
-
return /* @__PURE__ */ (0,
|
|
2179
|
-
/* @__PURE__ */ (0,
|
|
2180
|
-
/* @__PURE__ */ (0,
|
|
2181
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0,
|
|
2306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { children: texts.iosInstallTitle }),
|
|
2308
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: texts.iosInstallBody }),
|
|
2309
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
2182
2310
|
] });
|
|
2183
2311
|
}
|
|
2184
2312
|
if (state.kind === "denied") {
|
|
2185
2313
|
const recovery = platformRecoveryCopy(texts);
|
|
2186
|
-
return /* @__PURE__ */ (0,
|
|
2187
|
-
/* @__PURE__ */ (0,
|
|
2188
|
-
/* @__PURE__ */ (0,
|
|
2189
|
-
recovery && /* @__PURE__ */ (0,
|
|
2314
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
|
|
2315
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { children: texts.deniedTitle }),
|
|
2316
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: texts.deniedBody }),
|
|
2317
|
+
recovery && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { "data-testid": "denied-recovery", children: recovery })
|
|
2190
2318
|
] });
|
|
2191
2319
|
}
|
|
2192
2320
|
if (state.kind === "unsupported") {
|
|
2193
|
-
return /* @__PURE__ */ (0,
|
|
2321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: texts.unsupportedBody }) });
|
|
2194
2322
|
}
|
|
2195
2323
|
if (state.kind === "error") {
|
|
2196
|
-
return /* @__PURE__ */ (0,
|
|
2324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { children: state.message }) });
|
|
2197
2325
|
}
|
|
2198
|
-
return /* @__PURE__ */ (0,
|
|
2199
|
-
/* @__PURE__ */ (0,
|
|
2326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className, role: "region", children: [
|
|
2327
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2200
2328
|
"button",
|
|
2201
2329
|
{
|
|
2202
2330
|
type: "button",
|
|
@@ -2210,41 +2338,41 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
2210
2338
|
children: texts.cta
|
|
2211
2339
|
}
|
|
2212
2340
|
),
|
|
2213
|
-
onDeclined && /* @__PURE__ */ (0,
|
|
2341
|
+
onDeclined && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
2214
2342
|
] });
|
|
2215
2343
|
}
|
|
2216
2344
|
|
|
2217
2345
|
// src/defaults/LoadingState.tsx
|
|
2218
|
-
var
|
|
2346
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2219
2347
|
function LoadingState({ message }) {
|
|
2220
|
-
return /* @__PURE__ */ (0,
|
|
2348
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "status", "aria-live": "polite", style: { padding: 24, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: message ?? "Carregando..." }) });
|
|
2221
2349
|
}
|
|
2222
2350
|
|
|
2223
2351
|
// src/defaults/EmptyState.tsx
|
|
2224
|
-
var
|
|
2352
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2225
2353
|
function EmptyState({ title, description, action }) {
|
|
2226
|
-
return /* @__PURE__ */ (0,
|
|
2227
|
-
/* @__PURE__ */ (0,
|
|
2228
|
-
description && /* @__PURE__ */ (0,
|
|
2229
|
-
action && /* @__PURE__ */ (0,
|
|
2354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2355
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2356
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { opacity: 0.7 }, children: description }),
|
|
2357
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginTop: 16 }, children: action })
|
|
2230
2358
|
] });
|
|
2231
2359
|
}
|
|
2232
2360
|
|
|
2233
2361
|
// src/hooks/useLoginForm.ts
|
|
2234
|
-
var
|
|
2235
|
-
var
|
|
2362
|
+
var import_react14 = require("react");
|
|
2363
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
2236
2364
|
|
|
2237
2365
|
// src/errors.ts
|
|
2238
|
-
var
|
|
2366
|
+
var import_sdk7 = require("@hook-sdk/sdk");
|
|
2239
2367
|
function mapSdkError(err) {
|
|
2240
|
-
if (err instanceof
|
|
2368
|
+
if (err instanceof import_sdk7.SdkRateLimitError) {
|
|
2241
2369
|
return {
|
|
2242
2370
|
code: "rate_limited",
|
|
2243
2371
|
message: `Aguarde ${err.retryAfter}s e tente novamente.`,
|
|
2244
2372
|
retryAfter: err.retryAfter
|
|
2245
2373
|
};
|
|
2246
2374
|
}
|
|
2247
|
-
if (err instanceof
|
|
2375
|
+
if (err instanceof import_sdk7.SdkAuthError) {
|
|
2248
2376
|
const detail = err.detail;
|
|
2249
2377
|
if (detail === "email_unverified") {
|
|
2250
2378
|
return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
|
|
@@ -2254,7 +2382,7 @@ function mapSdkError(err) {
|
|
|
2254
2382
|
}
|
|
2255
2383
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2256
2384
|
}
|
|
2257
|
-
if (err instanceof
|
|
2385
|
+
if (err instanceof import_sdk7.SdkError && err.httpStatus === 0) {
|
|
2258
2386
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2259
2387
|
}
|
|
2260
2388
|
if (err instanceof TypeError) {
|
|
@@ -2267,23 +2395,29 @@ function mapSdkError(err) {
|
|
|
2267
2395
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2268
2396
|
var MIN_PASSWORD = 8;
|
|
2269
2397
|
function useLoginForm() {
|
|
2270
|
-
const { auth } = (0,
|
|
2271
|
-
const [email, setEmail] = (0,
|
|
2272
|
-
const [password, setPassword] = (0,
|
|
2273
|
-
const [submitting, setSubmitting] = (0,
|
|
2274
|
-
const [error, setError] = (0,
|
|
2275
|
-
const
|
|
2398
|
+
const { auth } = (0, import_sdk8.useHook)();
|
|
2399
|
+
const [email, setEmail] = (0, import_react14.useState)("");
|
|
2400
|
+
const [password, setPassword] = (0, import_react14.useState)("");
|
|
2401
|
+
const [submitting, setSubmitting] = (0, import_react14.useState)(false);
|
|
2402
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
2403
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react14.useState)(false);
|
|
2404
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react14.useState)(false);
|
|
2405
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react14.useState)(false);
|
|
2406
|
+
const validateEmail = (0, import_react14.useMemo)(() => {
|
|
2276
2407
|
if (email.length === 0) return null;
|
|
2277
2408
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2278
2409
|
return null;
|
|
2279
2410
|
}, [email]);
|
|
2280
|
-
const
|
|
2411
|
+
const validatePassword = (0, import_react14.useMemo)(() => {
|
|
2281
2412
|
if (password.length === 0) return null;
|
|
2282
2413
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
2283
2414
|
return null;
|
|
2284
2415
|
}, [password]);
|
|
2285
|
-
const
|
|
2286
|
-
const
|
|
2416
|
+
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2417
|
+
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2418
|
+
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
|
|
2419
|
+
const submit = (0, import_react14.useCallback)(async () => {
|
|
2420
|
+
setFormSubmitAttempted(true);
|
|
2287
2421
|
if (!canSubmit) return false;
|
|
2288
2422
|
setSubmitting(true);
|
|
2289
2423
|
setError(null);
|
|
@@ -2301,9 +2435,12 @@ function useLoginForm() {
|
|
|
2301
2435
|
email,
|
|
2302
2436
|
setEmail,
|
|
2303
2437
|
emailError,
|
|
2438
|
+
markEmailTouched: () => setTouchedEmail(true),
|
|
2304
2439
|
password,
|
|
2305
2440
|
setPassword,
|
|
2306
2441
|
passwordError,
|
|
2442
|
+
markPasswordTouched: () => setTouchedPassword(true),
|
|
2443
|
+
formSubmitAttempted,
|
|
2307
2444
|
submit,
|
|
2308
2445
|
submitting,
|
|
2309
2446
|
canSubmit,
|
|
@@ -2313,34 +2450,42 @@ function useLoginForm() {
|
|
|
2313
2450
|
}
|
|
2314
2451
|
|
|
2315
2452
|
// src/hooks/useSignupForm.ts
|
|
2316
|
-
var
|
|
2317
|
-
var
|
|
2453
|
+
var import_react15 = require("react");
|
|
2454
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
2318
2455
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2319
2456
|
var MIN_PASSWORD2 = 8;
|
|
2320
2457
|
function useSignupForm() {
|
|
2321
|
-
const { auth } = (0,
|
|
2322
|
-
const [name, setName] = (0,
|
|
2323
|
-
const [email, setEmail] = (0,
|
|
2324
|
-
const [password, setPassword] = (0,
|
|
2325
|
-
const [submitting, setSubmitting] = (0,
|
|
2326
|
-
const [error, setError] = (0,
|
|
2327
|
-
const
|
|
2458
|
+
const { auth } = (0, import_sdk9.useHook)();
|
|
2459
|
+
const [name, setName] = (0, import_react15.useState)("");
|
|
2460
|
+
const [email, setEmail] = (0, import_react15.useState)("");
|
|
2461
|
+
const [password, setPassword] = (0, import_react15.useState)("");
|
|
2462
|
+
const [submitting, setSubmitting] = (0, import_react15.useState)(false);
|
|
2463
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
2464
|
+
const [touchedName, setTouchedName] = (0, import_react15.useState)(false);
|
|
2465
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react15.useState)(false);
|
|
2466
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react15.useState)(false);
|
|
2467
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react15.useState)(false);
|
|
2468
|
+
const validateName = (0, import_react15.useMemo)(() => {
|
|
2328
2469
|
if (name.length === 0) return null;
|
|
2329
2470
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2330
2471
|
return null;
|
|
2331
2472
|
}, [name]);
|
|
2332
|
-
const
|
|
2473
|
+
const validateEmail = (0, import_react15.useMemo)(() => {
|
|
2333
2474
|
if (email.length === 0) return null;
|
|
2334
2475
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2335
2476
|
return null;
|
|
2336
2477
|
}, [email]);
|
|
2337
|
-
const
|
|
2478
|
+
const validatePassword = (0, import_react15.useMemo)(() => {
|
|
2338
2479
|
if (password.length === 0) return null;
|
|
2339
2480
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
2340
2481
|
return null;
|
|
2341
2482
|
}, [password]);
|
|
2342
|
-
const
|
|
2343
|
-
const
|
|
2483
|
+
const nameError = touchedName || formSubmitAttempted ? validateName : null;
|
|
2484
|
+
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2485
|
+
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2486
|
+
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
|
|
2487
|
+
const submit = (0, import_react15.useCallback)(async () => {
|
|
2488
|
+
setFormSubmitAttempted(true);
|
|
2344
2489
|
if (!canSubmit) return false;
|
|
2345
2490
|
setSubmitting(true);
|
|
2346
2491
|
setError(null);
|
|
@@ -2358,12 +2503,16 @@ function useSignupForm() {
|
|
|
2358
2503
|
name,
|
|
2359
2504
|
setName,
|
|
2360
2505
|
nameError,
|
|
2506
|
+
markNameTouched: () => setTouchedName(true),
|
|
2361
2507
|
email,
|
|
2362
2508
|
setEmail,
|
|
2363
2509
|
emailError,
|
|
2510
|
+
markEmailTouched: () => setTouchedEmail(true),
|
|
2364
2511
|
password,
|
|
2365
2512
|
setPassword,
|
|
2366
2513
|
passwordError,
|
|
2514
|
+
markPasswordTouched: () => setTouchedPassword(true),
|
|
2515
|
+
formSubmitAttempted,
|
|
2367
2516
|
submit,
|
|
2368
2517
|
submitting,
|
|
2369
2518
|
canSubmit,
|
|
@@ -2373,22 +2522,26 @@ function useSignupForm() {
|
|
|
2373
2522
|
}
|
|
2374
2523
|
|
|
2375
2524
|
// src/hooks/useForgotForm.ts
|
|
2376
|
-
var
|
|
2377
|
-
var
|
|
2525
|
+
var import_react16 = require("react");
|
|
2526
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
2378
2527
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2379
2528
|
function useForgotForm() {
|
|
2380
|
-
const { auth } = (0,
|
|
2381
|
-
const [email, setEmail] = (0,
|
|
2382
|
-
const [submitting, setSubmitting] = (0,
|
|
2383
|
-
const [sent, setSent] = (0,
|
|
2384
|
-
const [error, setError] = (0,
|
|
2385
|
-
const
|
|
2529
|
+
const { auth } = (0, import_sdk10.useHook)();
|
|
2530
|
+
const [email, setEmail] = (0, import_react16.useState)("");
|
|
2531
|
+
const [submitting, setSubmitting] = (0, import_react16.useState)(false);
|
|
2532
|
+
const [sent, setSent] = (0, import_react16.useState)(false);
|
|
2533
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
2534
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react16.useState)(false);
|
|
2535
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react16.useState)(false);
|
|
2536
|
+
const validateEmail = (0, import_react16.useMemo)(() => {
|
|
2386
2537
|
if (email.length === 0) return null;
|
|
2387
2538
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2388
2539
|
return null;
|
|
2389
2540
|
}, [email]);
|
|
2390
|
-
const
|
|
2391
|
-
const
|
|
2541
|
+
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2542
|
+
const canSubmit = email.length > 0 && validateEmail === null && !submitting;
|
|
2543
|
+
const submit = (0, import_react16.useCallback)(async () => {
|
|
2544
|
+
setFormSubmitAttempted(true);
|
|
2392
2545
|
if (!canSubmit) return false;
|
|
2393
2546
|
setSubmitting(true);
|
|
2394
2547
|
setError(null);
|
|
@@ -2407,6 +2560,8 @@ function useForgotForm() {
|
|
|
2407
2560
|
email,
|
|
2408
2561
|
setEmail,
|
|
2409
2562
|
emailError,
|
|
2563
|
+
markEmailTouched: () => setTouchedEmail(true),
|
|
2564
|
+
formSubmitAttempted,
|
|
2410
2565
|
submit,
|
|
2411
2566
|
submitting,
|
|
2412
2567
|
canSubmit,
|
|
@@ -2416,35 +2571,41 @@ function useForgotForm() {
|
|
|
2416
2571
|
}
|
|
2417
2572
|
|
|
2418
2573
|
// src/hooks/useResetForm.ts
|
|
2419
|
-
var
|
|
2420
|
-
var
|
|
2574
|
+
var import_react17 = require("react");
|
|
2575
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
2421
2576
|
var MIN_PASSWORD3 = 12;
|
|
2422
2577
|
function useResetForm() {
|
|
2423
|
-
const { auth } = (0,
|
|
2424
|
-
const [token, setToken] = (0,
|
|
2425
|
-
const [password, setPassword] = (0,
|
|
2426
|
-
const [confirm, setConfirm] = (0,
|
|
2427
|
-
const [submitting, setSubmitting] = (0,
|
|
2428
|
-
const [done, setDone] = (0,
|
|
2429
|
-
const [error, setError] = (0,
|
|
2430
|
-
(0,
|
|
2578
|
+
const { auth } = (0, import_sdk11.useHook)();
|
|
2579
|
+
const [token, setToken] = (0, import_react17.useState)(null);
|
|
2580
|
+
const [password, setPassword] = (0, import_react17.useState)("");
|
|
2581
|
+
const [confirm, setConfirm] = (0, import_react17.useState)("");
|
|
2582
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2583
|
+
const [done, setDone] = (0, import_react17.useState)(false);
|
|
2584
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2585
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react17.useState)(false);
|
|
2586
|
+
const [touchedConfirm, setTouchedConfirm] = (0, import_react17.useState)(false);
|
|
2587
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react17.useState)(false);
|
|
2588
|
+
(0, import_react17.useEffect)(() => {
|
|
2431
2589
|
if (typeof window === "undefined") return;
|
|
2432
2590
|
const params = new URLSearchParams(window.location.search);
|
|
2433
2591
|
const t = params.get("token");
|
|
2434
2592
|
setToken(t && t.length > 0 ? t : null);
|
|
2435
2593
|
}, []);
|
|
2436
|
-
const
|
|
2594
|
+
const validatePassword = (0, import_react17.useMemo)(() => {
|
|
2437
2595
|
if (password.length === 0) return null;
|
|
2438
2596
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
2439
2597
|
return null;
|
|
2440
2598
|
}, [password]);
|
|
2441
|
-
const
|
|
2599
|
+
const validateConfirm = (0, import_react17.useMemo)(() => {
|
|
2442
2600
|
if (confirm.length === 0) return null;
|
|
2443
2601
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
2444
2602
|
return null;
|
|
2445
2603
|
}, [confirm, password]);
|
|
2446
|
-
const
|
|
2447
|
-
const
|
|
2604
|
+
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2605
|
+
const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
|
|
2606
|
+
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
|
|
2607
|
+
const submit = (0, import_react17.useCallback)(async () => {
|
|
2608
|
+
setFormSubmitAttempted(true);
|
|
2448
2609
|
if (!canSubmit || token === null) return;
|
|
2449
2610
|
setSubmitting(true);
|
|
2450
2611
|
setError(null);
|
|
@@ -2468,9 +2629,12 @@ function useResetForm() {
|
|
|
2468
2629
|
password,
|
|
2469
2630
|
setPassword,
|
|
2470
2631
|
passwordError,
|
|
2632
|
+
markPasswordTouched: () => setTouchedPassword(true),
|
|
2471
2633
|
confirm,
|
|
2472
2634
|
setConfirm,
|
|
2473
2635
|
confirmError,
|
|
2636
|
+
markConfirmTouched: () => setTouchedConfirm(true),
|
|
2637
|
+
formSubmitAttempted,
|
|
2474
2638
|
submit,
|
|
2475
2639
|
submitting,
|
|
2476
2640
|
canSubmit,
|
|
@@ -2480,9 +2644,9 @@ function useResetForm() {
|
|
|
2480
2644
|
}
|
|
2481
2645
|
|
|
2482
2646
|
// src/hooks/usePlan.ts
|
|
2483
|
-
var
|
|
2647
|
+
var import_sdk12 = require("@hook-sdk/sdk");
|
|
2484
2648
|
function usePlan() {
|
|
2485
|
-
const { plan } = (0,
|
|
2649
|
+
const { plan } = (0, import_sdk12.useHook)();
|
|
2486
2650
|
return plan;
|
|
2487
2651
|
}
|
|
2488
2652
|
|
|
@@ -2515,12 +2679,12 @@ function discountPercent(anchorCents, realCents) {
|
|
|
2515
2679
|
}
|
|
2516
2680
|
|
|
2517
2681
|
// src/hooks/useAuthPrimitives.ts
|
|
2518
|
-
var
|
|
2519
|
-
var
|
|
2682
|
+
var import_react18 = require("react");
|
|
2683
|
+
var import_sdk13 = require("@hook-sdk/sdk");
|
|
2520
2684
|
var warned = false;
|
|
2521
2685
|
function useAuthPrimitives() {
|
|
2522
|
-
const { auth } = (0,
|
|
2523
|
-
(0,
|
|
2686
|
+
const { auth } = (0, import_sdk13.useHook)();
|
|
2687
|
+
(0, import_react18.useEffect)(() => {
|
|
2524
2688
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
2525
2689
|
warned = true;
|
|
2526
2690
|
console.warn(
|
|
@@ -2542,9 +2706,9 @@ function useAuthPrimitives() {
|
|
|
2542
2706
|
}
|
|
2543
2707
|
|
|
2544
2708
|
// src/hooks/useAuth.ts
|
|
2545
|
-
var
|
|
2709
|
+
var import_sdk14 = require("@hook-sdk/sdk");
|
|
2546
2710
|
function useAuth() {
|
|
2547
|
-
const { user, authStatus, auth } = (0,
|
|
2711
|
+
const { user, authStatus, auth } = (0, import_sdk14.useHook)();
|
|
2548
2712
|
return {
|
|
2549
2713
|
user,
|
|
2550
2714
|
authStatus,
|
|
@@ -2553,23 +2717,23 @@ function useAuth() {
|
|
|
2553
2717
|
}
|
|
2554
2718
|
|
|
2555
2719
|
// src/hooks/useSubscription.ts
|
|
2556
|
-
var
|
|
2720
|
+
var import_sdk15 = require("@hook-sdk/sdk");
|
|
2557
2721
|
function useSubscription() {
|
|
2558
|
-
const { subscription } = (0,
|
|
2722
|
+
const { subscription } = (0, import_sdk15.useHook)();
|
|
2559
2723
|
return {
|
|
2560
2724
|
status: subscription.status()
|
|
2561
2725
|
};
|
|
2562
2726
|
}
|
|
2563
2727
|
|
|
2564
2728
|
// src/hooks/useReminders.ts
|
|
2565
|
-
var
|
|
2566
|
-
var
|
|
2729
|
+
var import_react19 = require("react");
|
|
2730
|
+
var import_sdk16 = require("@hook-sdk/sdk");
|
|
2567
2731
|
function useReminders() {
|
|
2568
|
-
const { push } = (0,
|
|
2732
|
+
const { push } = (0, import_sdk16.useHook)();
|
|
2569
2733
|
const r = push.reminders;
|
|
2570
|
-
const [reminders, setReminders] = (0,
|
|
2571
|
-
const [loading, setLoading] = (0,
|
|
2572
|
-
const reload = (0,
|
|
2734
|
+
const [reminders, setReminders] = (0, import_react19.useState)([]);
|
|
2735
|
+
const [loading, setLoading] = (0, import_react19.useState)(true);
|
|
2736
|
+
const reload = (0, import_react19.useCallback)(async () => {
|
|
2573
2737
|
setLoading(true);
|
|
2574
2738
|
try {
|
|
2575
2739
|
const next = await r.list();
|
|
@@ -2578,38 +2742,38 @@ function useReminders() {
|
|
|
2578
2742
|
setLoading(false);
|
|
2579
2743
|
}
|
|
2580
2744
|
}, [r]);
|
|
2581
|
-
(0,
|
|
2745
|
+
(0, import_react19.useEffect)(() => {
|
|
2582
2746
|
void reload();
|
|
2583
2747
|
}, [reload]);
|
|
2584
|
-
const setReminder = (0,
|
|
2748
|
+
const setReminder = (0, import_react19.useCallback)(async (input) => {
|
|
2585
2749
|
await r.set(input);
|
|
2586
2750
|
await reload();
|
|
2587
2751
|
}, [r, reload]);
|
|
2588
|
-
const deleteReminder = (0,
|
|
2752
|
+
const deleteReminder = (0, import_react19.useCallback)(async (slot) => {
|
|
2589
2753
|
await r.delete(slot);
|
|
2590
2754
|
await reload();
|
|
2591
2755
|
}, [r, reload]);
|
|
2592
|
-
const schedule = (0,
|
|
2756
|
+
const schedule = (0, import_react19.useCallback)(async (items) => {
|
|
2593
2757
|
return r.schedule(items);
|
|
2594
2758
|
}, [r]);
|
|
2595
|
-
const setFallbacks = (0,
|
|
2759
|
+
const setFallbacks = (0, import_react19.useCallback)(async (items) => {
|
|
2596
2760
|
return r.setFallbacks(items);
|
|
2597
2761
|
}, [r]);
|
|
2598
2762
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
2599
2763
|
}
|
|
2600
2764
|
|
|
2601
2765
|
// src/hooks/useToast.ts
|
|
2602
|
-
var
|
|
2766
|
+
var import_react20 = require("react");
|
|
2603
2767
|
function useToast() {
|
|
2604
|
-
const [items, setItems] = (0,
|
|
2605
|
-
const show = (0,
|
|
2768
|
+
const [items, setItems] = (0, import_react20.useState)([]);
|
|
2769
|
+
const show = (0, import_react20.useCallback)((message, kind = "info") => {
|
|
2606
2770
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2607
2771
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
2608
2772
|
setTimeout(() => {
|
|
2609
2773
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2610
2774
|
}, 4e3);
|
|
2611
2775
|
}, []);
|
|
2612
|
-
const dismiss = (0,
|
|
2776
|
+
const dismiss = (0, import_react20.useCallback)((id) => {
|
|
2613
2777
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2614
2778
|
}, []);
|
|
2615
2779
|
return { items, show, dismiss };
|
|
@@ -2617,20 +2781,20 @@ function useToast() {
|
|
|
2617
2781
|
|
|
2618
2782
|
// src/RouteBoundary.tsx
|
|
2619
2783
|
var import_react_router_dom3 = require("react-router-dom");
|
|
2620
|
-
var
|
|
2784
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2621
2785
|
function RouteBoundary({ children }) {
|
|
2622
|
-
return /* @__PURE__ */ (0,
|
|
2786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react_router_dom3.Routes, { children: [
|
|
2623
2787
|
children,
|
|
2624
|
-
/* @__PURE__ */ (0,
|
|
2788
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_router_dom3.Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DefaultNotFound, {}) })
|
|
2625
2789
|
] });
|
|
2626
2790
|
}
|
|
2627
2791
|
function DefaultNotFound() {
|
|
2628
|
-
return /* @__PURE__ */ (0,
|
|
2792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { role: "alert", children: "P\xE1gina n\xE3o encontrada" });
|
|
2629
2793
|
}
|
|
2630
2794
|
|
|
2631
2795
|
// src/PreAuthShell.tsx
|
|
2632
2796
|
var import_react_router_dom4 = require("react-router-dom");
|
|
2633
|
-
var
|
|
2797
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2634
2798
|
function PreAuthShell({
|
|
2635
2799
|
basename,
|
|
2636
2800
|
testRouter,
|
|
@@ -2638,20 +2802,20 @@ function PreAuthShell({
|
|
|
2638
2802
|
children
|
|
2639
2803
|
}) {
|
|
2640
2804
|
if (testRouter === "memory") {
|
|
2641
|
-
return /* @__PURE__ */ (0,
|
|
2805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_router_dom4.MemoryRouter, { basename, initialEntries: testInitialEntries, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
2642
2806
|
}
|
|
2643
|
-
return /* @__PURE__ */ (0,
|
|
2807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_router_dom4.BrowserRouter, { basename, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_router_dom4.Routes, { children }) });
|
|
2644
2808
|
}
|
|
2645
2809
|
|
|
2646
2810
|
// src/OnboardingFlow.tsx
|
|
2647
|
-
var
|
|
2648
|
-
var
|
|
2811
|
+
var import_react22 = require("react");
|
|
2812
|
+
var import_sdk17 = require("@hook-sdk/sdk");
|
|
2649
2813
|
|
|
2650
2814
|
// src/hooks/useOnboardingStep.ts
|
|
2651
|
-
var
|
|
2652
|
-
var OnboardingStepContext = (0,
|
|
2815
|
+
var import_react21 = require("react");
|
|
2816
|
+
var OnboardingStepContext = (0, import_react21.createContext)(null);
|
|
2653
2817
|
function useOnboardingStep() {
|
|
2654
|
-
const ctx = (0,
|
|
2818
|
+
const ctx = (0, import_react21.useContext)(OnboardingStepContext);
|
|
2655
2819
|
if (!ctx) {
|
|
2656
2820
|
throw new Error(
|
|
2657
2821
|
"[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
|
|
@@ -2661,7 +2825,7 @@ function useOnboardingStep() {
|
|
|
2661
2825
|
}
|
|
2662
2826
|
|
|
2663
2827
|
// src/OnboardingFlow.tsx
|
|
2664
|
-
var
|
|
2828
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2665
2829
|
var isFilled = (v) => v != null && v !== "";
|
|
2666
2830
|
var CURRENT_STEP_FIELD = "currentStep";
|
|
2667
2831
|
function readPersistedStepIdx(draft) {
|
|
@@ -2674,12 +2838,12 @@ function OnboardingFlow({
|
|
|
2674
2838
|
onComplete,
|
|
2675
2839
|
persistKey
|
|
2676
2840
|
}) {
|
|
2677
|
-
const [draft, setDraft, status] = (0,
|
|
2678
|
-
const draftRef = (0,
|
|
2841
|
+
const [draft, setDraft, status] = (0, import_sdk17.usePersistedState)(persistKey, {});
|
|
2842
|
+
const draftRef = (0, import_react22.useRef)(draft);
|
|
2679
2843
|
draftRef.current = draft;
|
|
2680
2844
|
const idx = readPersistedStepIdx(draft);
|
|
2681
2845
|
const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
|
|
2682
|
-
const setIdx = (0,
|
|
2846
|
+
const setIdx = (0, import_react22.useCallback)(
|
|
2683
2847
|
(n) => {
|
|
2684
2848
|
setDraft((prev) => {
|
|
2685
2849
|
const prevIdx = readPersistedStepIdx(prev);
|
|
@@ -2689,7 +2853,7 @@ function OnboardingFlow({
|
|
|
2689
2853
|
},
|
|
2690
2854
|
[setDraft]
|
|
2691
2855
|
);
|
|
2692
|
-
const setValue = (0,
|
|
2856
|
+
const setValue = (0, import_react22.useCallback)(
|
|
2693
2857
|
(patch) => {
|
|
2694
2858
|
draftRef.current = { ...draftRef.current, ...patch };
|
|
2695
2859
|
setDraft((prev) => ({ ...prev, ...patch }));
|
|
@@ -2697,11 +2861,11 @@ function OnboardingFlow({
|
|
|
2697
2861
|
[setDraft]
|
|
2698
2862
|
);
|
|
2699
2863
|
const step = steps[clampedIdx];
|
|
2700
|
-
const valid = (0,
|
|
2864
|
+
const valid = (0, import_react22.useMemo)(
|
|
2701
2865
|
() => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
|
|
2702
2866
|
[draft, step]
|
|
2703
2867
|
);
|
|
2704
|
-
const next = (0,
|
|
2868
|
+
const next = (0, import_react22.useCallback)(() => {
|
|
2705
2869
|
if (!step) return;
|
|
2706
2870
|
const current = draftRef.current;
|
|
2707
2871
|
const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
|
|
@@ -2712,8 +2876,8 @@ function OnboardingFlow({
|
|
|
2712
2876
|
setIdx(clampedIdx + 1);
|
|
2713
2877
|
}
|
|
2714
2878
|
}, [clampedIdx, onComplete, step, steps.length, setIdx]);
|
|
2715
|
-
const prevStep = (0,
|
|
2716
|
-
const ctx = (0,
|
|
2879
|
+
const prevStep = (0, import_react22.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
|
|
2880
|
+
const ctx = (0, import_react22.useMemo)(
|
|
2717
2881
|
() => ({
|
|
2718
2882
|
stepIndex: clampedIdx,
|
|
2719
2883
|
totalSteps: steps.length,
|
|
@@ -2739,7 +2903,7 @@ function OnboardingFlow({
|
|
|
2739
2903
|
`[hook-template] OnboardingFlow: missing screen component for step '${step.id}' (expected key '${step.screen}' in screens prop)`
|
|
2740
2904
|
);
|
|
2741
2905
|
}
|
|
2742
|
-
return /* @__PURE__ */ (0,
|
|
2906
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(OnboardingStepContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Screen, {}) });
|
|
2743
2907
|
}
|
|
2744
2908
|
|
|
2745
2909
|
// src/hooks/useFeature.ts
|