@hook-sdk/template 0.4.1 → 0.5.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 CHANGED
@@ -55,7 +55,7 @@ __export(index_exports, {
55
55
  module.exports = __toCommonJS(index_exports);
56
56
 
57
57
  // src/AppRoot.tsx
58
- var import_react16 = require("react");
58
+ var import_react15 = require("react");
59
59
  var import_sdk9 = require("@hook-sdk/sdk");
60
60
 
61
61
  // src/internal/TemplateConfigContext.tsx
@@ -156,6 +156,7 @@ function usePaywallState() {
156
156
  const [error, setError] = (0, import_react3.useState)(null);
157
157
  const status = subscription.status();
158
158
  const daysLeftInTrial = subscription.daysLeftInTrial();
159
+ const initialLoadComplete = subscription.initialLoadComplete;
159
160
  const checkout = (0, import_react3.useCallback)(
160
161
  async (args) => {
161
162
  setOpening(true);
@@ -181,7 +182,7 @@ function usePaywallState() {
181
182
  setError(err);
182
183
  }
183
184
  }, [subscription]);
184
- return { status, daysLeftInTrial, checkout, cancel, opening, error };
185
+ return { status, daysLeftInTrial, initialLoadComplete, checkout, cancel, opening, error };
185
186
  }
186
187
 
187
188
  // src/internal/SubscriptionGate.tsx
@@ -194,8 +195,9 @@ var BLOCKING = /* @__PURE__ */ new Set([
194
195
  ]);
195
196
  function SubscriptionGate({ Paywall, children }) {
196
197
  const { mode } = useTemplateConfig();
197
- const { status } = usePaywallState();
198
+ const { status, initialLoadComplete } = usePaywallState();
198
199
  if (mode === "free") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
200
+ if (!initialLoadComplete && status === "none") return null;
199
201
  if (BLOCKING.has(status)) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Paywall, {});
200
202
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children });
201
203
  }
@@ -221,7 +223,7 @@ function PushPrompt() {
221
223
  }
222
224
 
223
225
  // src/components/InstallGate/InstallGate.tsx
224
- var import_react8 = require("react");
226
+ var import_react7 = require("react");
225
227
 
226
228
  // src/hooks/useInstallPrompt.ts
227
229
  var import_react5 = require("react");
@@ -458,9 +460,6 @@ function useInstallPrompt(slug) {
458
460
  setIsDismissedPermanent(true);
459
461
  track("pwa_install_permanent_dismiss", { slug, platform, prior_skip_count: skipCount });
460
462
  }, [slug, platform, skipCount]);
461
- const showIOSOtherHelp = (0, import_react5.useCallback)(() => {
462
- track("pwa_install_ios_other_help_shown", { slug });
463
- }, [slug]);
464
463
  const copyLink = (0, import_react5.useCallback)(async () => {
465
464
  if (typeof navigator === "undefined" || typeof location === "undefined") return;
466
465
  try {
@@ -499,7 +498,6 @@ function useInstallPrompt(slug) {
499
498
  promptInstall,
500
499
  dismissSession,
501
500
  dismissPermanent,
502
- showIOSOtherHelp,
503
501
  copyLink,
504
502
  reset
505
503
  };
@@ -559,23 +557,22 @@ var INSTALL_COPY = {
559
557
  skipPermanent: "N\xE3o me pergunte mais"
560
558
  },
561
559
  iosOther: {
562
- title: "Abra no Safari pra instalar",
563
- subtitle: "No Chrome/Firefox/Edge do iPhone n\xE3o d\xE1 pra instalar PWA. Abra o link no Safari.",
564
- ctaPrimary: "Abrir no Safari",
565
- ctaSecondary: "Copiar link",
566
- copiedToast: "Link copiado. Cole no Safari.",
567
- skip: "Continuar mesmo assim",
568
- skipPermanent: "N\xE3o me pergunte mais",
569
- help: {
570
- step1: {
571
- title: "Toque em \u22EF ou no bot\xE3o compartilhar",
572
- subtitle: "Na barra inferior ou superior do navegador"
573
- },
574
- step2: {
575
- title: 'Escolha "Abrir no Safari"',
576
- subtitle: "O app vai abrir direto no Safari"
577
- }
578
- }
560
+ title: "Adicione \xE0 sua Tela de In\xEDcio",
561
+ subtitle: "Siga os 3 passos",
562
+ step1: {
563
+ title: "Toque em Compartilhar",
564
+ subtitle: "Geralmente no topo ou no menu do navegador"
565
+ },
566
+ step2: {
567
+ title: 'Role e toque em "Adicionar \xE0 Tela de In\xEDcio"',
568
+ iconLabel: "Adicionar \xE0 Tela de In\xEDcio"
569
+ },
570
+ step3: {
571
+ title: 'Toque em "Adicionar" pra confirmar',
572
+ buttonLabel: "Adicionar"
573
+ },
574
+ skip: "Continuar no navegador",
575
+ skipPermanent: "N\xE3o me pergunte mais"
579
576
  },
580
577
  inApp: {
581
578
  instagram: {
@@ -710,18 +707,6 @@ var primaryButtonStyle = {
710
707
  cursor: "pointer",
711
708
  marginBottom: 12
712
709
  };
713
- var secondaryButtonStyle = {
714
- width: "100%",
715
- padding: "12px 20px",
716
- background: "transparent",
717
- color: "var(--hook-color-primary)",
718
- border: "1px solid var(--hook-color-primary)",
719
- borderRadius: 999,
720
- fontSize: 15,
721
- fontWeight: 500,
722
- cursor: "pointer",
723
- marginBottom: 12
724
- };
725
710
  var skipLinkStyle = {
726
711
  display: "block",
727
712
  width: "100%",
@@ -1128,7 +1113,6 @@ function IOSafariVariant({
1128
1113
  }
1129
1114
 
1130
1115
  // src/components/InstallGate/variants/IOSOtherVariant.tsx
1131
- var import_react6 = require("react");
1132
1116
  var import_jsx_runtime13 = require("react/jsx-runtime");
1133
1117
  function IOSOtherVariant({
1134
1118
  state,
@@ -1136,101 +1120,84 @@ function IOSOtherVariant({
1136
1120
  }) {
1137
1121
  const copy = INSTALL_COPY.iosOther;
1138
1122
  const showPermanent = shouldShowPermanentOption(state);
1139
- const [copied, setCopied] = (0, import_react6.useState)(false);
1140
- const [helpOpen, setHelpOpen] = (0, import_react6.useState)(false);
1141
- const handleCopy = async () => {
1142
- await actions.copyLink();
1143
- setCopied(true);
1144
- setTimeout(() => setCopied(false), 2e3);
1145
- };
1146
- const handleShowHelp = () => {
1147
- if (!helpOpen) actions.showIOSOtherHelp();
1148
- setHelpOpen(true);
1149
- };
1150
1123
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
1151
1124
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1152
- "button",
1125
+ Step2,
1153
1126
  {
1154
- "data-testid": "install-prompt-cta-ios-other-primary",
1155
- type: "button",
1156
- onClick: handleShowHelp,
1157
- "aria-expanded": helpOpen,
1158
- style: primaryButtonStyle,
1159
- children: copy.ctaPrimary
1127
+ n: 1,
1128
+ title: copy.step1.title,
1129
+ subtitle: copy.step1.subtitle,
1130
+ visual: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1131
+ "div",
1132
+ {
1133
+ style: {
1134
+ display: "flex",
1135
+ justifyContent: "center",
1136
+ alignItems: "center",
1137
+ background: "#f5f5f7",
1138
+ borderRadius: 12,
1139
+ padding: "12px 0",
1140
+ marginTop: 8
1141
+ },
1142
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ShareIconIOS, { size: 32, style: { color: "var(--hook-color-primary)" } })
1143
+ }
1144
+ )
1160
1145
  }
1161
1146
  ),
1162
1147
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1163
- "button",
1148
+ Step2,
1164
1149
  {
1165
- "data-testid": "install-prompt-cta-ios-other-secondary",
1166
- type: "button",
1167
- onClick: () => void handleCopy(),
1168
- style: secondaryButtonStyle,
1169
- children: copied ? copy.copiedToast : copy.ctaSecondary
1150
+ n: 2,
1151
+ title: copy.step2.title,
1152
+ visual: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1153
+ "div",
1154
+ {
1155
+ style: {
1156
+ display: "flex",
1157
+ alignItems: "center",
1158
+ gap: 10,
1159
+ background: "#f5f5f7",
1160
+ borderRadius: 12,
1161
+ padding: "12px 14px",
1162
+ marginTop: 8
1163
+ },
1164
+ children: [
1165
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SquarePlusIcon, { size: 22, style: { color: "#555" } }),
1166
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 14, color: "#333" }, children: copy.step2.iconLabel })
1167
+ ]
1168
+ }
1169
+ )
1170
1170
  }
1171
1171
  ),
1172
- helpOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1173
- "div",
1172
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1173
+ Step2,
1174
1174
  {
1175
- "data-testid": "install-prompt-ios-other-help",
1176
- style: { marginTop: 20, textAlign: "left" },
1177
- children: [
1178
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1179
- Step2,
1180
- {
1181
- n: 1,
1182
- title: copy.help.step1.title,
1183
- subtitle: copy.help.step1.subtitle,
1184
- visual: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1185
- "div",
1186
- {
1187
- style: {
1188
- display: "flex",
1189
- justifyContent: "center",
1190
- alignItems: "center",
1191
- background: "#f5f5f7",
1192
- borderRadius: 12,
1193
- padding: "12px 0",
1194
- marginTop: 8
1195
- },
1196
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1197
- MenuDotsHorizontalIcon,
1198
- {
1199
- size: 28,
1200
- style: { color: "var(--hook-color-primary)" }
1201
- }
1202
- )
1203
- }
1204
- )
1205
- }
1206
- ),
1207
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1208
- Step2,
1209
- {
1210
- n: 2,
1211
- title: copy.help.step2.title,
1212
- subtitle: copy.help.step2.subtitle,
1213
- visual: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1214
- "div",
1215
- {
1216
- style: {
1217
- display: "flex",
1218
- alignItems: "center",
1219
- gap: 10,
1220
- background: "#f5f5f7",
1221
- borderRadius: 12,
1222
- padding: "12px 14px",
1223
- marginTop: 8
1224
- },
1225
- children: [
1226
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ExternalLinkIcon, { size: 22, style: { color: "#555" } }),
1227
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: 14, color: "#333" }, children: "Abrir no Safari" })
1228
- ]
1229
- }
1230
- )
1231
- }
1232
- )
1233
- ]
1175
+ n: 3,
1176
+ title: copy.step3.title,
1177
+ visual: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1178
+ "div",
1179
+ {
1180
+ style: {
1181
+ display: "flex",
1182
+ justifyContent: "flex-end",
1183
+ background: "#f5f5f7",
1184
+ borderRadius: 12,
1185
+ padding: "10px 14px",
1186
+ marginTop: 8
1187
+ },
1188
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1189
+ "span",
1190
+ {
1191
+ style: {
1192
+ color: "var(--hook-color-primary)",
1193
+ fontSize: 15,
1194
+ fontWeight: 600
1195
+ },
1196
+ children: copy.step3.buttonLabel
1197
+ }
1198
+ )
1199
+ }
1200
+ )
1234
1201
  }
1235
1202
  ),
1236
1203
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -1239,7 +1206,7 @@ function IOSOtherVariant({
1239
1206
  "data-testid": "install-prompt-skip-session",
1240
1207
  type: "button",
1241
1208
  onClick: actions.dismissSession,
1242
- style: skipLinkStyle,
1209
+ style: { ...skipLinkStyle, marginTop: 16 },
1243
1210
  children: copy.skip
1244
1211
  }
1245
1212
  ),
@@ -1257,7 +1224,7 @@ function IOSOtherVariant({
1257
1224
  }
1258
1225
 
1259
1226
  // src/components/InstallGate/variants/InAppBrowserVariant.tsx
1260
- var import_react7 = require("react");
1227
+ var import_react6 = require("react");
1261
1228
  var import_jsx_runtime14 = require("react/jsx-runtime");
1262
1229
  function InAppBrowserVariant({
1263
1230
  state,
@@ -1267,7 +1234,7 @@ function InAppBrowserVariant({
1267
1234
  const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
1268
1235
  const copy = INSTALL_COPY.inApp;
1269
1236
  const showPermanent = shouldShowPermanentOption(state);
1270
- const [copied, setCopied] = (0, import_react7.useState)(false);
1237
+ const [copied, setCopied] = (0, import_react6.useState)(false);
1271
1238
  const handleCopy = async () => {
1272
1239
  await actions.copyLink();
1273
1240
  setCopied(true);
@@ -1472,8 +1439,8 @@ function InstallGate({ children }) {
1472
1439
  const enabled = features_enabled.includes("install_prompt");
1473
1440
  const installState = useInstallPrompt(slug);
1474
1441
  const shouldBlock = enabled && shouldBlockInstall(installState);
1475
- const trackedRef = (0, import_react8.useRef)(null);
1476
- (0, import_react8.useEffect)(() => {
1442
+ const trackedRef = (0, import_react7.useRef)(null);
1443
+ (0, import_react7.useEffect)(() => {
1477
1444
  if (!shouldBlock) return;
1478
1445
  if (typeof window === "undefined") return;
1479
1446
  const variantKey = `${slug}:${installState.variant}`;
@@ -1514,9 +1481,9 @@ function InstallGate({ children }) {
1514
1481
  }
1515
1482
 
1516
1483
  // src/defaults/ErrorBoundary.tsx
1517
- var import_react9 = require("react");
1484
+ var import_react8 = require("react");
1518
1485
  var import_jsx_runtime17 = require("react/jsx-runtime");
1519
- var ErrorBoundary = class extends import_react9.Component {
1486
+ var ErrorBoundary = class extends import_react8.Component {
1520
1487
  state = { error: null };
1521
1488
  static getDerivedStateFromError(error) {
1522
1489
  return { error };
@@ -1536,7 +1503,7 @@ var ErrorBoundary = class extends import_react9.Component {
1536
1503
  };
1537
1504
 
1538
1505
  // src/hooks/useLoginForm.ts
1539
- var import_react10 = require("react");
1506
+ var import_react9 = require("react");
1540
1507
  var import_sdk5 = require("@hook-sdk/sdk");
1541
1508
 
1542
1509
  // src/errors.ts
@@ -1573,22 +1540,22 @@ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1573
1540
  var MIN_PASSWORD = 8;
1574
1541
  function useLoginForm() {
1575
1542
  const { auth } = (0, import_sdk5.useHook)();
1576
- const [email, setEmail] = (0, import_react10.useState)("");
1577
- const [password, setPassword] = (0, import_react10.useState)("");
1578
- const [submitting, setSubmitting] = (0, import_react10.useState)(false);
1579
- const [error, setError] = (0, import_react10.useState)(null);
1580
- const emailError = (0, import_react10.useMemo)(() => {
1543
+ const [email, setEmail] = (0, import_react9.useState)("");
1544
+ const [password, setPassword] = (0, import_react9.useState)("");
1545
+ const [submitting, setSubmitting] = (0, import_react9.useState)(false);
1546
+ const [error, setError] = (0, import_react9.useState)(null);
1547
+ const emailError = (0, import_react9.useMemo)(() => {
1581
1548
  if (email.length === 0) return null;
1582
1549
  if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
1583
1550
  return null;
1584
1551
  }, [email]);
1585
- const passwordError = (0, import_react10.useMemo)(() => {
1552
+ const passwordError = (0, import_react9.useMemo)(() => {
1586
1553
  if (password.length === 0) return null;
1587
1554
  if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
1588
1555
  return null;
1589
1556
  }, [password]);
1590
1557
  const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
1591
- const submit = (0, import_react10.useCallback)(async () => {
1558
+ const submit = (0, import_react9.useCallback)(async () => {
1592
1559
  if (!canSubmit) return false;
1593
1560
  setSubmitting(true);
1594
1561
  setError(null);
@@ -1687,7 +1654,7 @@ function GoogleGlyph() {
1687
1654
  }
1688
1655
 
1689
1656
  // src/internal/OAuthErrorBanner.tsx
1690
- var import_react11 = require("react");
1657
+ var import_react10 = require("react");
1691
1658
  var import_jsx_runtime19 = require("react/jsx-runtime");
1692
1659
  var ERROR_MESSAGES = {
1693
1660
  invalid_state: "Sess\xE3o expirou, tente de novo.",
@@ -1708,8 +1675,8 @@ function stripErrorFromUrl() {
1708
1675
  window.history.replaceState({}, "", url.toString());
1709
1676
  }
1710
1677
  function OAuthErrorBanner() {
1711
- const [code, setCode] = (0, import_react11.useState)(() => readErrorCode());
1712
- (0, import_react11.useEffect)(() => {
1678
+ const [code, setCode] = (0, import_react10.useState)(() => readErrorCode());
1679
+ (0, import_react10.useEffect)(() => {
1713
1680
  if (code !== null) stripErrorFromUrl();
1714
1681
  }, [code]);
1715
1682
  if (!code) return null;
@@ -1842,34 +1809,34 @@ function DefaultLoginScreen({ onNavigate }) {
1842
1809
  }
1843
1810
 
1844
1811
  // src/hooks/useSignupForm.ts
1845
- var import_react12 = require("react");
1812
+ var import_react11 = require("react");
1846
1813
  var import_sdk6 = require("@hook-sdk/sdk");
1847
1814
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1848
1815
  var MIN_PASSWORD2 = 8;
1849
1816
  function useSignupForm() {
1850
1817
  const { auth } = (0, import_sdk6.useHook)();
1851
- const [name, setName] = (0, import_react12.useState)("");
1852
- const [email, setEmail] = (0, import_react12.useState)("");
1853
- const [password, setPassword] = (0, import_react12.useState)("");
1854
- const [submitting, setSubmitting] = (0, import_react12.useState)(false);
1855
- const [error, setError] = (0, import_react12.useState)(null);
1856
- const nameError = (0, import_react12.useMemo)(() => {
1818
+ const [name, setName] = (0, import_react11.useState)("");
1819
+ const [email, setEmail] = (0, import_react11.useState)("");
1820
+ const [password, setPassword] = (0, import_react11.useState)("");
1821
+ const [submitting, setSubmitting] = (0, import_react11.useState)(false);
1822
+ const [error, setError] = (0, import_react11.useState)(null);
1823
+ const nameError = (0, import_react11.useMemo)(() => {
1857
1824
  if (name.length === 0) return null;
1858
1825
  if (name.trim().length < 2) return "Nome muito curto.";
1859
1826
  return null;
1860
1827
  }, [name]);
1861
- const emailError = (0, import_react12.useMemo)(() => {
1828
+ const emailError = (0, import_react11.useMemo)(() => {
1862
1829
  if (email.length === 0) return null;
1863
1830
  if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
1864
1831
  return null;
1865
1832
  }, [email]);
1866
- const passwordError = (0, import_react12.useMemo)(() => {
1833
+ const passwordError = (0, import_react11.useMemo)(() => {
1867
1834
  if (password.length === 0) return null;
1868
1835
  if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
1869
1836
  return null;
1870
1837
  }, [password]);
1871
1838
  const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
1872
- const submit = (0, import_react12.useCallback)(async () => {
1839
+ const submit = (0, import_react11.useCallback)(async () => {
1873
1840
  if (!canSubmit) return false;
1874
1841
  setSubmitting(true);
1875
1842
  setError(null);
@@ -1957,22 +1924,22 @@ function DefaultSignupScreen({ onNavigate }) {
1957
1924
  }
1958
1925
 
1959
1926
  // src/hooks/useForgotForm.ts
1960
- var import_react13 = require("react");
1927
+ var import_react12 = require("react");
1961
1928
  var import_sdk7 = require("@hook-sdk/sdk");
1962
1929
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1963
1930
  function useForgotForm() {
1964
1931
  const { auth } = (0, import_sdk7.useHook)();
1965
- const [email, setEmail] = (0, import_react13.useState)("");
1966
- const [submitting, setSubmitting] = (0, import_react13.useState)(false);
1967
- const [sent, setSent] = (0, import_react13.useState)(false);
1968
- const [error, setError] = (0, import_react13.useState)(null);
1969
- const emailError = (0, import_react13.useMemo)(() => {
1932
+ const [email, setEmail] = (0, import_react12.useState)("");
1933
+ const [submitting, setSubmitting] = (0, import_react12.useState)(false);
1934
+ const [sent, setSent] = (0, import_react12.useState)(false);
1935
+ const [error, setError] = (0, import_react12.useState)(null);
1936
+ const emailError = (0, import_react12.useMemo)(() => {
1970
1937
  if (email.length === 0) return null;
1971
1938
  if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
1972
1939
  return null;
1973
1940
  }, [email]);
1974
1941
  const canSubmit = email.length > 0 && emailError === null && !submitting;
1975
- const submit = (0, import_react13.useCallback)(async () => {
1942
+ const submit = (0, import_react12.useCallback)(async () => {
1976
1943
  if (!canSubmit) return false;
1977
1944
  setSubmitting(true);
1978
1945
  setError(null);
@@ -2031,35 +1998,35 @@ function DefaultForgotScreen({ onNavigate }) {
2031
1998
  }
2032
1999
 
2033
2000
  // src/hooks/useResetForm.ts
2034
- var import_react14 = require("react");
2001
+ var import_react13 = require("react");
2035
2002
  var import_sdk8 = require("@hook-sdk/sdk");
2036
2003
  var MIN_PASSWORD3 = 12;
2037
2004
  function useResetForm() {
2038
2005
  const { auth } = (0, import_sdk8.useHook)();
2039
- const [token, setToken] = (0, import_react14.useState)(null);
2040
- const [password, setPassword] = (0, import_react14.useState)("");
2041
- const [confirm, setConfirm] = (0, import_react14.useState)("");
2042
- const [submitting, setSubmitting] = (0, import_react14.useState)(false);
2043
- const [done, setDone] = (0, import_react14.useState)(false);
2044
- const [error, setError] = (0, import_react14.useState)(null);
2045
- (0, import_react14.useEffect)(() => {
2006
+ const [token, setToken] = (0, import_react13.useState)(null);
2007
+ const [password, setPassword] = (0, import_react13.useState)("");
2008
+ const [confirm, setConfirm] = (0, import_react13.useState)("");
2009
+ const [submitting, setSubmitting] = (0, import_react13.useState)(false);
2010
+ const [done, setDone] = (0, import_react13.useState)(false);
2011
+ const [error, setError] = (0, import_react13.useState)(null);
2012
+ (0, import_react13.useEffect)(() => {
2046
2013
  if (typeof window === "undefined") return;
2047
2014
  const params = new URLSearchParams(window.location.search);
2048
2015
  const t = params.get("token");
2049
2016
  setToken(t && t.length > 0 ? t : null);
2050
2017
  }, []);
2051
- const passwordError = (0, import_react14.useMemo)(() => {
2018
+ const passwordError = (0, import_react13.useMemo)(() => {
2052
2019
  if (password.length === 0) return null;
2053
2020
  if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
2054
2021
  return null;
2055
2022
  }, [password]);
2056
- const confirmError = (0, import_react14.useMemo)(() => {
2023
+ const confirmError = (0, import_react13.useMemo)(() => {
2057
2024
  if (confirm.length === 0) return null;
2058
2025
  if (confirm !== password) return "Senhas n\xE3o coincidem.";
2059
2026
  return null;
2060
2027
  }, [confirm, password]);
2061
2028
  const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && passwordError === null && confirmError === null && !submitting && !done;
2062
- const submit = (0, import_react14.useCallback)(async () => {
2029
+ const submit = (0, import_react13.useCallback)(async () => {
2063
2030
  if (!canSubmit || token === null) return;
2064
2031
  setSubmitting(true);
2065
2032
  setError(null);
@@ -2137,13 +2104,13 @@ function DefaultResetScreen({ onNavigate }) {
2137
2104
  }
2138
2105
 
2139
2106
  // src/defaults/DefaultPaywall.tsx
2140
- var import_react15 = require("react");
2107
+ var import_react14 = require("react");
2141
2108
  var import_jsx_runtime24 = require("react/jsx-runtime");
2142
2109
  function DefaultPaywall() {
2143
2110
  const config = useTemplateConfig();
2144
2111
  const { checkout, opening, error } = usePaywallState();
2145
2112
  const p = config.subscription.paywall_config;
2146
- const [cpf, setCpf] = (0, import_react15.useState)("");
2113
+ const [cpf, setCpf] = (0, import_react14.useState)("");
2147
2114
  const cpfDigits = cpf.replace(/\D/g, "");
2148
2115
  const canCheckout = cpfDigits.length === 11 && !opening;
2149
2116
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
@@ -2200,11 +2167,11 @@ var import_jsx_runtime25 = require("react/jsx-runtime");
2200
2167
  var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
2201
2168
  function PaymentReturnHandler({ children }) {
2202
2169
  const { subscription } = (0, import_sdk9.useHook)();
2203
- const subRef = (0, import_react16.useRef)(subscription);
2170
+ const subRef = (0, import_react15.useRef)(subscription);
2204
2171
  subRef.current = subscription;
2205
- const runIdRef = (0, import_react16.useRef)(0);
2206
- const [state, setState] = (0, import_react16.useState)("idle");
2207
- const runPoll = (0, import_react16.useCallback)(() => {
2172
+ const runIdRef = (0, import_react15.useRef)(0);
2173
+ const [state, setState] = (0, import_react15.useState)("idle");
2174
+ const runPoll = (0, import_react15.useCallback)(() => {
2208
2175
  const runId = ++runIdRef.current;
2209
2176
  setState("confirming");
2210
2177
  let attempts = 0;
@@ -2233,7 +2200,7 @@ function PaymentReturnHandler({ children }) {
2233
2200
  };
2234
2201
  void tick();
2235
2202
  }, []);
2236
- (0, import_react16.useEffect)(() => {
2203
+ (0, import_react15.useEffect)(() => {
2237
2204
  if (typeof window === "undefined") return;
2238
2205
  const url = new URL(window.location.href);
2239
2206
  if (url.searchParams.get("paymentReturn") !== "1") return;
@@ -2307,7 +2274,7 @@ function AppRoot({
2307
2274
  }
2308
2275
 
2309
2276
  // src/hooks/usePush.ts
2310
- var import_react17 = require("react");
2277
+ var import_react16 = require("react");
2311
2278
  var import_sdk10 = require("@hook-sdk/sdk");
2312
2279
  function detectIosNeedsInstall() {
2313
2280
  if (typeof navigator === "undefined" || typeof window === "undefined") return false;
@@ -2335,11 +2302,11 @@ function deriveState(push) {
2335
2302
  }
2336
2303
  function usePush() {
2337
2304
  const { push } = (0, import_sdk10.useHook)();
2338
- const [state, setState] = (0, import_react17.useState)(() => deriveState(push));
2339
- (0, import_react17.useEffect)(() => {
2305
+ const [state, setState] = (0, import_react16.useState)(() => deriveState(push));
2306
+ (0, import_react16.useEffect)(() => {
2340
2307
  setState(deriveState(push));
2341
2308
  }, [push]);
2342
- const subscribe = (0, import_react17.useCallback)(async () => {
2309
+ const subscribe = (0, import_react16.useCallback)(async () => {
2343
2310
  try {
2344
2311
  await push.subscribe();
2345
2312
  setState({ kind: "subscribed" });
@@ -2351,7 +2318,7 @@ function usePush() {
2351
2318
  throw e;
2352
2319
  }
2353
2320
  }, [push]);
2354
- const unsubscribe = (0, import_react17.useCallback)(async () => {
2321
+ const unsubscribe = (0, import_react16.useCallback)(async () => {
2355
2322
  try {
2356
2323
  await push.unsubscribe();
2357
2324
  setState({ kind: "prompt" });
@@ -2417,12 +2384,12 @@ function EmptyState({ title, description, action }) {
2417
2384
  }
2418
2385
 
2419
2386
  // src/hooks/useAuthPrimitives.ts
2420
- var import_react18 = require("react");
2387
+ var import_react17 = require("react");
2421
2388
  var import_sdk11 = require("@hook-sdk/sdk");
2422
2389
  var warned = false;
2423
2390
  function useAuthPrimitives() {
2424
2391
  const { auth } = (0, import_sdk11.useHook)();
2425
- (0, import_react18.useEffect)(() => {
2392
+ (0, import_react17.useEffect)(() => {
2426
2393
  if (!warned && process.env.NODE_ENV !== "production") {
2427
2394
  warned = true;
2428
2395
  console.warn(
@@ -2453,14 +2420,14 @@ function useSubscription() {
2453
2420
  }
2454
2421
 
2455
2422
  // src/hooks/useReminders.ts
2456
- var import_react19 = require("react");
2423
+ var import_react18 = require("react");
2457
2424
  var import_sdk13 = require("@hook-sdk/sdk");
2458
2425
  function useReminders() {
2459
2426
  const { push } = (0, import_sdk13.useHook)();
2460
2427
  const r = push.reminders;
2461
- const [reminders, setReminders] = (0, import_react19.useState)([]);
2462
- const [loading, setLoading] = (0, import_react19.useState)(true);
2463
- const reload = (0, import_react19.useCallback)(async () => {
2428
+ const [reminders, setReminders] = (0, import_react18.useState)([]);
2429
+ const [loading, setLoading] = (0, import_react18.useState)(true);
2430
+ const reload = (0, import_react18.useCallback)(async () => {
2464
2431
  setLoading(true);
2465
2432
  try {
2466
2433
  const next = await r.list();
@@ -2469,38 +2436,38 @@ function useReminders() {
2469
2436
  setLoading(false);
2470
2437
  }
2471
2438
  }, [r]);
2472
- (0, import_react19.useEffect)(() => {
2439
+ (0, import_react18.useEffect)(() => {
2473
2440
  void reload();
2474
2441
  }, [reload]);
2475
- const setReminder = (0, import_react19.useCallback)(async (input) => {
2442
+ const setReminder = (0, import_react18.useCallback)(async (input) => {
2476
2443
  await r.set(input);
2477
2444
  await reload();
2478
2445
  }, [r, reload]);
2479
- const deleteReminder = (0, import_react19.useCallback)(async (slot) => {
2446
+ const deleteReminder = (0, import_react18.useCallback)(async (slot) => {
2480
2447
  await r.delete(slot);
2481
2448
  await reload();
2482
2449
  }, [r, reload]);
2483
- const schedule = (0, import_react19.useCallback)(async (items) => {
2450
+ const schedule = (0, import_react18.useCallback)(async (items) => {
2484
2451
  return r.schedule(items);
2485
2452
  }, [r]);
2486
- const setFallbacks = (0, import_react19.useCallback)(async (items) => {
2453
+ const setFallbacks = (0, import_react18.useCallback)(async (items) => {
2487
2454
  return r.setFallbacks(items);
2488
2455
  }, [r]);
2489
2456
  return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
2490
2457
  }
2491
2458
 
2492
2459
  // src/hooks/useToast.ts
2493
- var import_react20 = require("react");
2460
+ var import_react19 = require("react");
2494
2461
  function useToast() {
2495
- const [items, setItems] = (0, import_react20.useState)([]);
2496
- const show = (0, import_react20.useCallback)((message, kind = "info") => {
2462
+ const [items, setItems] = (0, import_react19.useState)([]);
2463
+ const show = (0, import_react19.useCallback)((message, kind = "info") => {
2497
2464
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2498
2465
  setItems((prev) => [...prev, { id, message, kind }]);
2499
2466
  setTimeout(() => {
2500
2467
  setItems((prev) => prev.filter((t) => t.id !== id));
2501
2468
  }, 4e3);
2502
2469
  }, []);
2503
- const dismiss = (0, import_react20.useCallback)((id) => {
2470
+ const dismiss = (0, import_react19.useCallback)((id) => {
2504
2471
  setItems((prev) => prev.filter((t) => t.id !== id));
2505
2472
  }, []);
2506
2473
  return { items, show, dismiss };