@hook-sdk/template 0.14.1 → 0.16.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 +229 -173
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +110 -55
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -64,14 +64,15 @@ __export(index_exports, {
|
|
|
64
64
|
useResetForm: () => useResetForm,
|
|
65
65
|
useSignupForm: () => useSignupForm,
|
|
66
66
|
useSubscription: () => useSubscription,
|
|
67
|
-
useToast: () => useToast
|
|
67
|
+
useToast: () => useToast,
|
|
68
|
+
useTrackOnboardingStep: () => import_sdk19.useTrackOnboardingStep
|
|
68
69
|
});
|
|
69
70
|
module.exports = __toCommonJS(index_exports);
|
|
70
71
|
|
|
71
72
|
// src/AppRoot.tsx
|
|
72
|
-
var
|
|
73
|
+
var import_react13 = require("react");
|
|
73
74
|
var import_react_router_dom2 = require("react-router-dom");
|
|
74
|
-
var
|
|
75
|
+
var import_sdk6 = require("@hook-sdk/sdk");
|
|
75
76
|
|
|
76
77
|
// src/config/AppConfigContext.tsx
|
|
77
78
|
var import_react = require("react");
|
|
@@ -248,8 +249,8 @@ function ThemeProvider({ children }) {
|
|
|
248
249
|
}
|
|
249
250
|
|
|
250
251
|
// src/hooks/usePaywallState.ts
|
|
251
|
-
var
|
|
252
|
-
var
|
|
252
|
+
var import_react6 = require("react");
|
|
253
|
+
var import_sdk3 = require("@hook-sdk/sdk");
|
|
253
254
|
|
|
254
255
|
// src/errors/asaas-pt-br.ts
|
|
255
256
|
var MAP = {
|
|
@@ -270,6 +271,35 @@ function asaasErrorMessage(code) {
|
|
|
270
271
|
return MAP[code] ?? "Ocorreu um erro inesperado. Tente novamente em instantes.";
|
|
271
272
|
}
|
|
272
273
|
|
|
274
|
+
// src/hooks/usePaywallTracker.ts
|
|
275
|
+
var import_react5 = require("react");
|
|
276
|
+
var import_sdk2 = require("@hook-sdk/sdk");
|
|
277
|
+
function deriveStep(s) {
|
|
278
|
+
if (s.pixPaid) return "success";
|
|
279
|
+
if (s.hasError) return "error";
|
|
280
|
+
if (s.pixPendingShown) return "pix_qr_shown";
|
|
281
|
+
if (s.selectedMethod === "card" && s.cpfValid) return "card_form";
|
|
282
|
+
if (s.cpfRequired && !s.cpfValid) return "cpf_input";
|
|
283
|
+
if (s.selectedMethod) return "method_select";
|
|
284
|
+
return "plan_select";
|
|
285
|
+
}
|
|
286
|
+
function usePaywallTracker(snapshot) {
|
|
287
|
+
const ctx = (0, import_sdk2.useHook)();
|
|
288
|
+
const track2 = typeof ctx.track === "function" ? ctx.track : void 0;
|
|
289
|
+
const lastStepRef = (0, import_react5.useRef)(null);
|
|
290
|
+
const step = deriveStep(snapshot);
|
|
291
|
+
(0, import_react5.useEffect)(() => {
|
|
292
|
+
if (lastStepRef.current === step) return;
|
|
293
|
+
lastStepRef.current = step;
|
|
294
|
+
if (!track2) return;
|
|
295
|
+
track2("paywall_step_viewed", {
|
|
296
|
+
step,
|
|
297
|
+
method: snapshot.selectedMethod,
|
|
298
|
+
cycle: snapshot.cycle
|
|
299
|
+
});
|
|
300
|
+
}, [step]);
|
|
301
|
+
}
|
|
302
|
+
|
|
273
303
|
// src/hooks/usePaywallState.ts
|
|
274
304
|
function isCheckoutFailure(r) {
|
|
275
305
|
return "ok" in r && r.ok === false;
|
|
@@ -284,11 +314,11 @@ var FALLBACK_PAYWALL = {
|
|
|
284
314
|
};
|
|
285
315
|
var isMethodAvailable = (availability, method) => availability[method] !== false;
|
|
286
316
|
function usePaywallState() {
|
|
287
|
-
const { subscription, plan } = (0,
|
|
288
|
-
const configFromCtx = (0,
|
|
317
|
+
const { subscription, plan } = (0, import_sdk3.useHook)();
|
|
318
|
+
const configFromCtx = (0, import_react6.useContext)(AppConfigContext);
|
|
289
319
|
const paywall = configFromCtx?.paywall ?? FALLBACK_PAYWALL;
|
|
290
320
|
const isFree = paywall.mode === "free";
|
|
291
|
-
const declaredMethods = (0,
|
|
321
|
+
const declaredMethods = (0, import_react6.useMemo)(
|
|
292
322
|
() => isFree ? [] : paywall.checkoutMethods,
|
|
293
323
|
[isFree, paywall]
|
|
294
324
|
);
|
|
@@ -297,33 +327,33 @@ function usePaywallState() {
|
|
|
297
327
|
"pix-auto": null,
|
|
298
328
|
"pix-once": null
|
|
299
329
|
};
|
|
300
|
-
const methods = (0,
|
|
330
|
+
const methods = (0, import_react6.useMemo)(
|
|
301
331
|
() => declaredMethods.filter((m) => isMethodAvailable(availability, m)),
|
|
302
332
|
[declaredMethods, availability]
|
|
303
333
|
);
|
|
304
334
|
const defaultMethod = methods[0] ?? declaredMethods[0] ?? "card";
|
|
305
|
-
const [selectedMethodRaw, setSelectedMethod] = (0,
|
|
335
|
+
const [selectedMethodRaw, setSelectedMethod] = (0, import_react6.useState)(defaultMethod);
|
|
306
336
|
const selectedMethod = methods.includes(selectedMethodRaw) ? selectedMethodRaw : methods[0] ?? selectedMethodRaw;
|
|
307
337
|
const initialCycle = isFree ? "MONTHLY" : paywall.cycles[0] ?? "MONTHLY";
|
|
308
|
-
const [cycle, setCycle] = (0,
|
|
338
|
+
const [cycle, setCycle] = (0, import_react6.useState)(initialCycle);
|
|
309
339
|
const cpfRequired = !isFree && paywall.requiresCpf;
|
|
310
|
-
const [cpf, setCpf] = (0,
|
|
311
|
-
const cpfValid = (0,
|
|
312
|
-
const [card, setCardState] = (0,
|
|
340
|
+
const [cpf, setCpf] = (0, import_react6.useState)("");
|
|
341
|
+
const cpfValid = (0, import_react6.useMemo)(() => /^[0-9]{11}$/.test(cpf), [cpf]);
|
|
342
|
+
const [card, setCardState] = (0, import_react6.useState)({
|
|
313
343
|
number: "",
|
|
314
344
|
cvv: "",
|
|
315
345
|
expiry: "",
|
|
316
346
|
holder: ""
|
|
317
347
|
});
|
|
318
|
-
const setCard = (0,
|
|
348
|
+
const setCard = (0, import_react6.useCallback)((patch) => {
|
|
319
349
|
setCardState((prev) => ({ ...prev, ...patch }));
|
|
320
350
|
}, []);
|
|
321
|
-
const [error, setError] = (0,
|
|
322
|
-
const [submitting, setSubmitting] = (0,
|
|
351
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
352
|
+
const [submitting, setSubmitting] = (0, import_react6.useState)(false);
|
|
323
353
|
const status = subscription.status();
|
|
324
354
|
const daysLeftInTrial = subscription.daysLeftInTrial();
|
|
325
355
|
const initialLoadComplete = subscription.initialLoadComplete;
|
|
326
|
-
const pixPending = (0,
|
|
356
|
+
const pixPending = (0, import_react6.useMemo)(() => {
|
|
327
357
|
const sdkPix = subscription.pixPending;
|
|
328
358
|
if (!sdkPix) return null;
|
|
329
359
|
const liveStatus = subscription.current?.status;
|
|
@@ -336,7 +366,7 @@ function usePaywallState() {
|
|
|
336
366
|
paid
|
|
337
367
|
};
|
|
338
368
|
}, [subscription.pixPending, subscription.current]);
|
|
339
|
-
const monthlyEquivalent = (0,
|
|
369
|
+
const monthlyEquivalent = (0, import_react6.useCallback)(
|
|
340
370
|
(c) => {
|
|
341
371
|
const monthlyCents = plan.data?.priceCents ?? (isFree ? 0 : paywall.prices.monthlyCents);
|
|
342
372
|
const yearlyCents = plan.data?.yearlyPriceCents ?? (isFree ? null : paywall.prices.yearlyCents);
|
|
@@ -345,7 +375,7 @@ function usePaywallState() {
|
|
|
345
375
|
},
|
|
346
376
|
[plan, paywall, isFree]
|
|
347
377
|
);
|
|
348
|
-
const planDerived = (0,
|
|
378
|
+
const planDerived = (0, import_react6.useMemo)(() => {
|
|
349
379
|
if (isFree) return null;
|
|
350
380
|
const monthlyCents = paywall.prices.monthlyCents;
|
|
351
381
|
const yearlyCents = paywall.prices.yearlyCents;
|
|
@@ -361,7 +391,7 @@ function usePaywallState() {
|
|
|
361
391
|
};
|
|
362
392
|
}, [paywall, cycle, isFree]);
|
|
363
393
|
const useDefaultMessages = paywall.mode !== "free" && paywall.errorMessages === "default";
|
|
364
|
-
const buildError = (0,
|
|
394
|
+
const buildError = (0, import_react6.useCallback)(
|
|
365
395
|
(code, fallbackMessage) => ({
|
|
366
396
|
code,
|
|
367
397
|
message: fallbackMessage,
|
|
@@ -369,7 +399,7 @@ function usePaywallState() {
|
|
|
369
399
|
}),
|
|
370
400
|
[useDefaultMessages]
|
|
371
401
|
);
|
|
372
|
-
const submit = (0,
|
|
402
|
+
const submit = (0, import_react6.useCallback)(async () => {
|
|
373
403
|
setSubmitting(true);
|
|
374
404
|
setError(null);
|
|
375
405
|
const methodToUse = selectedMethod;
|
|
@@ -431,7 +461,7 @@ function usePaywallState() {
|
|
|
431
461
|
return void 0;
|
|
432
462
|
}
|
|
433
463
|
}, [selectedMethod, availability, subscription, cycle, cpf, card, buildError]);
|
|
434
|
-
const checkout = (0,
|
|
464
|
+
const checkout = (0, import_react6.useCallback)(
|
|
435
465
|
async (args) => {
|
|
436
466
|
setSubmitting(true);
|
|
437
467
|
setError(null);
|
|
@@ -495,7 +525,7 @@ function usePaywallState() {
|
|
|
495
525
|
},
|
|
496
526
|
[subscription, buildError]
|
|
497
527
|
);
|
|
498
|
-
const cancel = (0,
|
|
528
|
+
const cancel = (0, import_react6.useCallback)(async () => {
|
|
499
529
|
try {
|
|
500
530
|
await subscription.cancel();
|
|
501
531
|
await subscription.refresh();
|
|
@@ -505,14 +535,24 @@ function usePaywallState() {
|
|
|
505
535
|
setError(buildError(code, message));
|
|
506
536
|
}
|
|
507
537
|
}, [subscription, buildError]);
|
|
508
|
-
const cardState = (0,
|
|
538
|
+
const cardState = (0, import_react6.useMemo)(
|
|
509
539
|
() => ({ ...card, set: setCard }),
|
|
510
540
|
[card, setCard]
|
|
511
541
|
);
|
|
512
|
-
const cpfState = (0,
|
|
542
|
+
const cpfState = (0, import_react6.useMemo)(
|
|
513
543
|
() => ({ required: cpfRequired, value: cpf, set: setCpf, valid: cpfValid }),
|
|
514
544
|
[cpfRequired, cpf, cpfValid]
|
|
515
545
|
);
|
|
546
|
+
usePaywallTracker({
|
|
547
|
+
selectedMethod,
|
|
548
|
+
cycle,
|
|
549
|
+
cpfRequired,
|
|
550
|
+
cpfValid,
|
|
551
|
+
pixPendingShown: pixPending !== null,
|
|
552
|
+
pixPaid: pixPending?.paid === true,
|
|
553
|
+
hasError: error !== null,
|
|
554
|
+
submitting
|
|
555
|
+
});
|
|
516
556
|
return {
|
|
517
557
|
// Subscription status (reactive, proxied from SDK)
|
|
518
558
|
status,
|
|
@@ -567,10 +607,10 @@ function SubscriptionGate({ Paywall, children }) {
|
|
|
567
607
|
}
|
|
568
608
|
|
|
569
609
|
// src/components/InstallGate/InstallGate.tsx
|
|
570
|
-
var
|
|
610
|
+
var import_react9 = require("react");
|
|
571
611
|
|
|
572
612
|
// src/hooks/useInstallPrompt.ts
|
|
573
|
-
var
|
|
613
|
+
var import_react7 = require("react");
|
|
574
614
|
var ANDROID_PROMPT_WAIT_MS = 3e3;
|
|
575
615
|
var IOS_RE = /iPad|iPhone|iPod/;
|
|
576
616
|
var IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;
|
|
@@ -705,27 +745,27 @@ function useInstallPrompt(slug) {
|
|
|
705
745
|
const iosBrowser = detectIOSBrowser(ua);
|
|
706
746
|
const androidBrowser = detectAndroidBrowser(ua);
|
|
707
747
|
const inAppApp = detectInAppApp(ua);
|
|
708
|
-
const [isInstallable, setIsInstallable] = (0,
|
|
748
|
+
const [isInstallable, setIsInstallable] = (0, import_react7.useState)(() => {
|
|
709
749
|
if (typeof window === "undefined") return false;
|
|
710
750
|
return window.__pwaInstallPrompt != null;
|
|
711
751
|
});
|
|
712
|
-
const [isInstalled, setIsInstalled] = (0,
|
|
752
|
+
const [isInstalled, setIsInstalled] = (0, import_react7.useState)(() => {
|
|
713
753
|
const { installed } = detectStandalone();
|
|
714
754
|
return installed || readInstalledMarker(slug);
|
|
715
755
|
});
|
|
716
|
-
const [isDismissedSession, setIsDismissedSession] = (0,
|
|
717
|
-
const [isDismissedPermanent, setIsDismissedPermanent] = (0,
|
|
718
|
-
const [skipCount, setSkipCount] = (0,
|
|
719
|
-
const [promptWaitElapsed, setPromptWaitElapsed] = (0,
|
|
756
|
+
const [isDismissedSession, setIsDismissedSession] = (0, import_react7.useState)(() => readSessionSkip(slug));
|
|
757
|
+
const [isDismissedPermanent, setIsDismissedPermanent] = (0, import_react7.useState)(() => readPermanentDismiss(slug).dismissed);
|
|
758
|
+
const [skipCount, setSkipCount] = (0, import_react7.useState)(() => readSkipCount(slug));
|
|
759
|
+
const [promptWaitElapsed, setPromptWaitElapsed] = (0, import_react7.useState)(() => {
|
|
720
760
|
if (typeof window === "undefined") return true;
|
|
721
761
|
return window.__pwaInstallPrompt != null;
|
|
722
762
|
});
|
|
723
|
-
(0,
|
|
763
|
+
(0, import_react7.useEffect)(() => {
|
|
724
764
|
if (promptWaitElapsed) return;
|
|
725
765
|
const id = setTimeout(() => setPromptWaitElapsed(true), ANDROID_PROMPT_WAIT_MS);
|
|
726
766
|
return () => clearTimeout(id);
|
|
727
767
|
}, [promptWaitElapsed]);
|
|
728
|
-
(0,
|
|
768
|
+
(0, import_react7.useEffect)(() => {
|
|
729
769
|
if (typeof window === "undefined") return;
|
|
730
770
|
if (window.__pwaInstallPrompt) {
|
|
731
771
|
setIsInstallable(true);
|
|
@@ -749,7 +789,7 @@ function useInstallPrompt(slug) {
|
|
|
749
789
|
window.removeEventListener("appinstalled", onInstalled);
|
|
750
790
|
};
|
|
751
791
|
}, [slug]);
|
|
752
|
-
(0,
|
|
792
|
+
(0, import_react7.useEffect)(() => {
|
|
753
793
|
if (typeof window === "undefined") return;
|
|
754
794
|
const mq = window.matchMedia?.("(display-mode: standalone)");
|
|
755
795
|
if (!mq) return;
|
|
@@ -776,7 +816,7 @@ function useInstallPrompt(slug) {
|
|
|
776
816
|
},
|
|
777
817
|
promptWaitElapsed
|
|
778
818
|
);
|
|
779
|
-
const promptInstall = (0,
|
|
819
|
+
const promptInstall = (0, import_react7.useCallback)(async () => {
|
|
780
820
|
if (typeof window === "undefined") return false;
|
|
781
821
|
const prompt = window.__pwaInstallPrompt;
|
|
782
822
|
if (!prompt) return false;
|
|
@@ -798,7 +838,7 @@ function useInstallPrompt(slug) {
|
|
|
798
838
|
return false;
|
|
799
839
|
}
|
|
800
840
|
}, [slug]);
|
|
801
|
-
const dismissSession = (0,
|
|
841
|
+
const dismissSession = (0, import_react7.useCallback)(() => {
|
|
802
842
|
if (typeof sessionStorage !== "undefined") {
|
|
803
843
|
try {
|
|
804
844
|
sessionStorage.setItem(storageKey.sessionSkip(slug), "true");
|
|
@@ -812,20 +852,20 @@ function useInstallPrompt(slug) {
|
|
|
812
852
|
setIsDismissedSession(true);
|
|
813
853
|
track("pwa_install_session_skip", { slug, platform, skip_count: newCount });
|
|
814
854
|
}, [slug, skipCount, platform]);
|
|
815
|
-
const dismissPermanent = (0,
|
|
855
|
+
const dismissPermanent = (0, import_react7.useCallback)(() => {
|
|
816
856
|
const storage = safeStorage();
|
|
817
857
|
if (storage) storage.setItem(storageKey.dismissedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
818
858
|
setIsDismissedPermanent(true);
|
|
819
859
|
track("pwa_install_permanent_dismiss", { slug, platform, prior_skip_count: skipCount });
|
|
820
860
|
}, [slug, platform, skipCount]);
|
|
821
|
-
const copyLink = (0,
|
|
861
|
+
const copyLink = (0, import_react7.useCallback)(async () => {
|
|
822
862
|
if (typeof navigator === "undefined" || typeof location === "undefined") return;
|
|
823
863
|
try {
|
|
824
864
|
await navigator.clipboard?.writeText?.(location.href);
|
|
825
865
|
} catch {
|
|
826
866
|
}
|
|
827
867
|
}, []);
|
|
828
|
-
const reset = (0,
|
|
868
|
+
const reset = (0, import_react7.useCallback)(() => {
|
|
829
869
|
const storage = safeStorage();
|
|
830
870
|
if (storage) {
|
|
831
871
|
storage.removeItem(storageKey.dismissedAt(slug));
|
|
@@ -1618,7 +1658,7 @@ function IOSOtherVariant({
|
|
|
1618
1658
|
}
|
|
1619
1659
|
|
|
1620
1660
|
// src/components/InstallGate/variants/InAppBrowserVariant.tsx
|
|
1621
|
-
var
|
|
1661
|
+
var import_react8 = require("react");
|
|
1622
1662
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1623
1663
|
function InAppBrowserVariant({
|
|
1624
1664
|
state,
|
|
@@ -1628,7 +1668,7 @@ function InAppBrowserVariant({
|
|
|
1628
1668
|
const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
|
|
1629
1669
|
const copy = INSTALL_COPY.inApp;
|
|
1630
1670
|
const showPermanent = shouldShowPermanentOption(state);
|
|
1631
|
-
const [copied, setCopied] = (0,
|
|
1671
|
+
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
1632
1672
|
const handleCopy = async () => {
|
|
1633
1673
|
await actions.copyLink();
|
|
1634
1674
|
setCopied(true);
|
|
@@ -1833,8 +1873,8 @@ function InstallGate({ children }) {
|
|
|
1833
1873
|
const enabled = features_enabled.includes("install_prompt");
|
|
1834
1874
|
const installState = useInstallPrompt(slug);
|
|
1835
1875
|
const shouldBlock = enabled && shouldBlockInstall(installState);
|
|
1836
|
-
const trackedRef = (0,
|
|
1837
|
-
(0,
|
|
1876
|
+
const trackedRef = (0, import_react9.useRef)(null);
|
|
1877
|
+
(0, import_react9.useEffect)(() => {
|
|
1838
1878
|
if (!shouldBlock) return;
|
|
1839
1879
|
if (typeof window === "undefined") return;
|
|
1840
1880
|
const variantKey = `${slug}:${installState.variant}`;
|
|
@@ -1883,16 +1923,16 @@ function PushPrompt() {
|
|
|
1883
1923
|
}
|
|
1884
1924
|
|
|
1885
1925
|
// src/internal/SessionExpiredBanner.tsx
|
|
1886
|
-
var
|
|
1887
|
-
var
|
|
1926
|
+
var import_react10 = require("react");
|
|
1927
|
+
var import_sdk4 = require("@hook-sdk/sdk");
|
|
1888
1928
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1889
1929
|
var DISMISS_KEY = "hook:session-expired-dismissed-until";
|
|
1890
1930
|
var DISMISS_TTL_MS = 60 * 60 * 1e3;
|
|
1891
1931
|
function SessionExpiredBanner() {
|
|
1892
|
-
const { authStatus } = (0,
|
|
1893
|
-
const wasAuthRef = (0,
|
|
1894
|
-
const [show, setShow] = (0,
|
|
1895
|
-
(0,
|
|
1932
|
+
const { authStatus } = (0, import_sdk4.useHook)();
|
|
1933
|
+
const wasAuthRef = (0, import_react10.useRef)(false);
|
|
1934
|
+
const [show, setShow] = (0, import_react10.useState)(false);
|
|
1935
|
+
(0, import_react10.useEffect)(() => {
|
|
1896
1936
|
if (authStatus === "authenticated") {
|
|
1897
1937
|
wasAuthRef.current = true;
|
|
1898
1938
|
setShow(false);
|
|
@@ -1942,9 +1982,9 @@ function SessionExpiredBanner() {
|
|
|
1942
1982
|
}
|
|
1943
1983
|
|
|
1944
1984
|
// src/defaults/ErrorBoundary.tsx
|
|
1945
|
-
var
|
|
1985
|
+
var import_react11 = require("react");
|
|
1946
1986
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1947
|
-
var ErrorBoundary = class extends
|
|
1987
|
+
var ErrorBoundary = class extends import_react11.Component {
|
|
1948
1988
|
state = { error: null };
|
|
1949
1989
|
static getDerivedStateFromError(error) {
|
|
1950
1990
|
return { error };
|
|
@@ -1971,20 +2011,20 @@ var ErrorBoundary = class extends import_react10.Component {
|
|
|
1971
2011
|
};
|
|
1972
2012
|
|
|
1973
2013
|
// src/internal/PaymentReturnHandler.tsx
|
|
1974
|
-
var
|
|
1975
|
-
var
|
|
2014
|
+
var import_react12 = require("react");
|
|
2015
|
+
var import_sdk5 = require("@hook-sdk/sdk");
|
|
1976
2016
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1977
2017
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
1978
2018
|
var MAX_CYCLES = 3;
|
|
1979
2019
|
var SUPPORT_MAILTO = "mailto:suporte@usehook.net?subject=Pagamento%20pendente";
|
|
1980
2020
|
function PaymentReturnHandler({ children }) {
|
|
1981
|
-
const { subscription } = (0,
|
|
1982
|
-
const subRef = (0,
|
|
2021
|
+
const { subscription } = (0, import_sdk5.useHook)();
|
|
2022
|
+
const subRef = (0, import_react12.useRef)(subscription);
|
|
1983
2023
|
subRef.current = subscription;
|
|
1984
|
-
const runIdRef = (0,
|
|
1985
|
-
const cyclesRef = (0,
|
|
1986
|
-
const [state, setState] = (0,
|
|
1987
|
-
const runPoll = (0,
|
|
2024
|
+
const runIdRef = (0, import_react12.useRef)(0);
|
|
2025
|
+
const cyclesRef = (0, import_react12.useRef)(0);
|
|
2026
|
+
const [state, setState] = (0, import_react12.useState)("idle");
|
|
2027
|
+
const runPoll = (0, import_react12.useCallback)(() => {
|
|
1988
2028
|
const runId = ++runIdRef.current;
|
|
1989
2029
|
cyclesRef.current += 1;
|
|
1990
2030
|
setState("confirming");
|
|
@@ -2019,7 +2059,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2019
2059
|
};
|
|
2020
2060
|
void tick();
|
|
2021
2061
|
}, []);
|
|
2022
|
-
(0,
|
|
2062
|
+
(0, import_react12.useEffect)(() => {
|
|
2023
2063
|
if (typeof window === "undefined") return;
|
|
2024
2064
|
const url = new URL(window.location.href);
|
|
2025
2065
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -2029,7 +2069,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
2029
2069
|
runIdRef.current++;
|
|
2030
2070
|
};
|
|
2031
2071
|
}, [runPoll]);
|
|
2032
|
-
const goHome = (0,
|
|
2072
|
+
const goHome = (0, import_react12.useCallback)(() => {
|
|
2033
2073
|
const cleanUrl = new URL(window.location.href);
|
|
2034
2074
|
cleanUrl.searchParams.delete("paymentReturn");
|
|
2035
2075
|
cleanUrl.pathname = "/app/home";
|
|
@@ -2195,7 +2235,7 @@ function AppRoot(props) {
|
|
|
2195
2235
|
"[hook-template] <AppRoot>: PreAuthFlow slot prop is required when config.onboarding.trigger === 'pre_signup_custom'."
|
|
2196
2236
|
);
|
|
2197
2237
|
}
|
|
2198
|
-
const legacyShim = (0,
|
|
2238
|
+
const legacyShim = (0, import_react13.useMemo)(() => buildLegacyConfigShim(config), [config]);
|
|
2199
2239
|
const Router = testRouter === "memory" ? import_react_router_dom2.MemoryRouter : import_react_router_dom2.BrowserRouter;
|
|
2200
2240
|
const basename = `/app/${config.slug}`;
|
|
2201
2241
|
const routerProps = testRouter === "memory" ? { basename, initialEntries: testInitialEntries } : { basename };
|
|
@@ -2232,7 +2272,7 @@ function AuthGated({
|
|
|
2232
2272
|
EmailVerify,
|
|
2233
2273
|
PreAuthFlow
|
|
2234
2274
|
}) {
|
|
2235
|
-
const { authStatus } = (0,
|
|
2275
|
+
const { authStatus } = (0, import_sdk6.useHook)();
|
|
2236
2276
|
if (authStatus === "loading") return null;
|
|
2237
2277
|
if (authStatus !== "authenticated") {
|
|
2238
2278
|
if (config.onboarding?.trigger === "pre_signup_custom" && PreAuthFlow) {
|
|
@@ -2261,8 +2301,8 @@ function FallbackPaywall() {
|
|
|
2261
2301
|
}
|
|
2262
2302
|
|
|
2263
2303
|
// src/hooks/usePush.ts
|
|
2264
|
-
var
|
|
2265
|
-
var
|
|
2304
|
+
var import_react14 = require("react");
|
|
2305
|
+
var import_sdk7 = require("@hook-sdk/sdk");
|
|
2266
2306
|
var DISMISS_STORAGE_KEY = "push:dismissed-until";
|
|
2267
2307
|
var DISMISS_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
|
|
2268
2308
|
function detectIosNeedsInstall() {
|
|
@@ -2306,12 +2346,12 @@ function deriveState(push) {
|
|
|
2306
2346
|
return { kind: "prompt" };
|
|
2307
2347
|
}
|
|
2308
2348
|
function usePush() {
|
|
2309
|
-
const { push } = (0,
|
|
2310
|
-
const [state, setState] = (0,
|
|
2311
|
-
(0,
|
|
2349
|
+
const { push } = (0, import_sdk7.useHook)();
|
|
2350
|
+
const [state, setState] = (0, import_react14.useState)(() => deriveState(push));
|
|
2351
|
+
(0, import_react14.useEffect)(() => {
|
|
2312
2352
|
setState(deriveState(push));
|
|
2313
2353
|
}, [push]);
|
|
2314
|
-
const subscribe = (0,
|
|
2354
|
+
const subscribe = (0, import_react14.useCallback)(async () => {
|
|
2315
2355
|
try {
|
|
2316
2356
|
await push.subscribe();
|
|
2317
2357
|
setState({ kind: "subscribed" });
|
|
@@ -2323,7 +2363,7 @@ function usePush() {
|
|
|
2323
2363
|
throw e;
|
|
2324
2364
|
}
|
|
2325
2365
|
}, [push]);
|
|
2326
|
-
const unsubscribe = (0,
|
|
2366
|
+
const unsubscribe = (0, import_react14.useCallback)(async () => {
|
|
2327
2367
|
try {
|
|
2328
2368
|
await push.unsubscribe();
|
|
2329
2369
|
setState({ kind: "prompt" });
|
|
@@ -2332,7 +2372,7 @@ function usePush() {
|
|
|
2332
2372
|
throw e;
|
|
2333
2373
|
}
|
|
2334
2374
|
}, [push]);
|
|
2335
|
-
const dismiss = (0,
|
|
2375
|
+
const dismiss = (0, import_react14.useCallback)(() => {
|
|
2336
2376
|
if (typeof localStorage !== "undefined") {
|
|
2337
2377
|
try {
|
|
2338
2378
|
localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS2));
|
|
@@ -2424,20 +2464,20 @@ function EmptyState({ title, description, action }) {
|
|
|
2424
2464
|
}
|
|
2425
2465
|
|
|
2426
2466
|
// src/hooks/useLoginForm.ts
|
|
2427
|
-
var
|
|
2428
|
-
var
|
|
2467
|
+
var import_react15 = require("react");
|
|
2468
|
+
var import_sdk9 = require("@hook-sdk/sdk");
|
|
2429
2469
|
|
|
2430
2470
|
// src/errors.ts
|
|
2431
|
-
var
|
|
2471
|
+
var import_sdk8 = require("@hook-sdk/sdk");
|
|
2432
2472
|
function mapSdkError(err) {
|
|
2433
|
-
if (err instanceof
|
|
2473
|
+
if (err instanceof import_sdk8.SdkRateLimitError) {
|
|
2434
2474
|
return {
|
|
2435
2475
|
code: "rate_limited",
|
|
2436
2476
|
message: `Aguarde ${err.retryAfter}s e tente novamente.`,
|
|
2437
2477
|
retryAfter: err.retryAfter
|
|
2438
2478
|
};
|
|
2439
2479
|
}
|
|
2440
|
-
if (err instanceof
|
|
2480
|
+
if (err instanceof import_sdk8.SdkAuthError) {
|
|
2441
2481
|
const detail = err.detail;
|
|
2442
2482
|
if (detail === "email_unverified") {
|
|
2443
2483
|
return { code: "email_unverified", message: "Confirme seu e-mail antes de entrar." };
|
|
@@ -2447,7 +2487,7 @@ function mapSdkError(err) {
|
|
|
2447
2487
|
}
|
|
2448
2488
|
return { code: "invalid_credentials", message: "E-mail ou senha inv\xE1lidos." };
|
|
2449
2489
|
}
|
|
2450
|
-
if (err instanceof
|
|
2490
|
+
if (err instanceof import_sdk8.SdkError && err.httpStatus === 0) {
|
|
2451
2491
|
return { code: "network", message: "Sem conex\xE3o com o servidor. Verifique sua internet." };
|
|
2452
2492
|
}
|
|
2453
2493
|
if (err instanceof TypeError) {
|
|
@@ -2460,20 +2500,20 @@ function mapSdkError(err) {
|
|
|
2460
2500
|
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2461
2501
|
var MIN_PASSWORD = 8;
|
|
2462
2502
|
function useLoginForm() {
|
|
2463
|
-
const { auth } = (0,
|
|
2464
|
-
const [email, setEmail] = (0,
|
|
2465
|
-
const [password, setPassword] = (0,
|
|
2466
|
-
const [submitting, setSubmitting] = (0,
|
|
2467
|
-
const [error, setError] = (0,
|
|
2468
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2469
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2470
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2471
|
-
const validateEmail = (0,
|
|
2503
|
+
const { auth } = (0, import_sdk9.useHook)();
|
|
2504
|
+
const [email, setEmail] = (0, import_react15.useState)("");
|
|
2505
|
+
const [password, setPassword] = (0, import_react15.useState)("");
|
|
2506
|
+
const [submitting, setSubmitting] = (0, import_react15.useState)(false);
|
|
2507
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
2508
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react15.useState)(false);
|
|
2509
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react15.useState)(false);
|
|
2510
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react15.useState)(false);
|
|
2511
|
+
const validateEmail = (0, import_react15.useMemo)(() => {
|
|
2472
2512
|
if (email.length === 0) return null;
|
|
2473
2513
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2474
2514
|
return null;
|
|
2475
2515
|
}, [email]);
|
|
2476
|
-
const validatePassword = (0,
|
|
2516
|
+
const validatePassword = (0, import_react15.useMemo)(() => {
|
|
2477
2517
|
if (password.length === 0) return null;
|
|
2478
2518
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
2479
2519
|
return null;
|
|
@@ -2481,7 +2521,7 @@ function useLoginForm() {
|
|
|
2481
2521
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2482
2522
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2483
2523
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && validateEmail === null && validatePassword === null && !submitting;
|
|
2484
|
-
const submit = (0,
|
|
2524
|
+
const submit = (0, import_react15.useCallback)(async () => {
|
|
2485
2525
|
setFormSubmitAttempted(true);
|
|
2486
2526
|
if (!canSubmit) return false;
|
|
2487
2527
|
setSubmitting(true);
|
|
@@ -2515,32 +2555,32 @@ function useLoginForm() {
|
|
|
2515
2555
|
}
|
|
2516
2556
|
|
|
2517
2557
|
// src/hooks/useSignupForm.ts
|
|
2518
|
-
var
|
|
2519
|
-
var
|
|
2558
|
+
var import_react16 = require("react");
|
|
2559
|
+
var import_sdk10 = require("@hook-sdk/sdk");
|
|
2520
2560
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2521
2561
|
var MIN_PASSWORD2 = 8;
|
|
2522
2562
|
function useSignupForm() {
|
|
2523
|
-
const { auth } = (0,
|
|
2524
|
-
const [name, setName] = (0,
|
|
2525
|
-
const [email, setEmail] = (0,
|
|
2526
|
-
const [password, setPassword] = (0,
|
|
2527
|
-
const [submitting, setSubmitting] = (0,
|
|
2528
|
-
const [error, setError] = (0,
|
|
2529
|
-
const [touchedName, setTouchedName] = (0,
|
|
2530
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2531
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2532
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2533
|
-
const validateName = (0,
|
|
2563
|
+
const { auth } = (0, import_sdk10.useHook)();
|
|
2564
|
+
const [name, setName] = (0, import_react16.useState)("");
|
|
2565
|
+
const [email, setEmail] = (0, import_react16.useState)("");
|
|
2566
|
+
const [password, setPassword] = (0, import_react16.useState)("");
|
|
2567
|
+
const [submitting, setSubmitting] = (0, import_react16.useState)(false);
|
|
2568
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
2569
|
+
const [touchedName, setTouchedName] = (0, import_react16.useState)(false);
|
|
2570
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react16.useState)(false);
|
|
2571
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react16.useState)(false);
|
|
2572
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react16.useState)(false);
|
|
2573
|
+
const validateName = (0, import_react16.useMemo)(() => {
|
|
2534
2574
|
if (name.length === 0) return null;
|
|
2535
2575
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
2536
2576
|
return null;
|
|
2537
2577
|
}, [name]);
|
|
2538
|
-
const validateEmail = (0,
|
|
2578
|
+
const validateEmail = (0, import_react16.useMemo)(() => {
|
|
2539
2579
|
if (email.length === 0) return null;
|
|
2540
2580
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2541
2581
|
return null;
|
|
2542
2582
|
}, [email]);
|
|
2543
|
-
const validatePassword = (0,
|
|
2583
|
+
const validatePassword = (0, import_react16.useMemo)(() => {
|
|
2544
2584
|
if (password.length === 0) return null;
|
|
2545
2585
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
2546
2586
|
return null;
|
|
@@ -2549,7 +2589,7 @@ function useSignupForm() {
|
|
|
2549
2589
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2550
2590
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2551
2591
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && validateName === null && validateEmail === null && validatePassword === null && !submitting;
|
|
2552
|
-
const submit = (0,
|
|
2592
|
+
const submit = (0, import_react16.useCallback)(async () => {
|
|
2553
2593
|
setFormSubmitAttempted(true);
|
|
2554
2594
|
if (!canSubmit) return false;
|
|
2555
2595
|
setSubmitting(true);
|
|
@@ -2587,25 +2627,25 @@ function useSignupForm() {
|
|
|
2587
2627
|
}
|
|
2588
2628
|
|
|
2589
2629
|
// src/hooks/useForgotForm.ts
|
|
2590
|
-
var
|
|
2591
|
-
var
|
|
2630
|
+
var import_react17 = require("react");
|
|
2631
|
+
var import_sdk11 = require("@hook-sdk/sdk");
|
|
2592
2632
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
2593
2633
|
function useForgotForm() {
|
|
2594
|
-
const { auth } = (0,
|
|
2595
|
-
const [email, setEmail] = (0,
|
|
2596
|
-
const [submitting, setSubmitting] = (0,
|
|
2597
|
-
const [sent, setSent] = (0,
|
|
2598
|
-
const [error, setError] = (0,
|
|
2599
|
-
const [touchedEmail, setTouchedEmail] = (0,
|
|
2600
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2601
|
-
const validateEmail = (0,
|
|
2634
|
+
const { auth } = (0, import_sdk11.useHook)();
|
|
2635
|
+
const [email, setEmail] = (0, import_react17.useState)("");
|
|
2636
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
2637
|
+
const [sent, setSent] = (0, import_react17.useState)(false);
|
|
2638
|
+
const [error, setError] = (0, import_react17.useState)(null);
|
|
2639
|
+
const [touchedEmail, setTouchedEmail] = (0, import_react17.useState)(false);
|
|
2640
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react17.useState)(false);
|
|
2641
|
+
const validateEmail = (0, import_react17.useMemo)(() => {
|
|
2602
2642
|
if (email.length === 0) return null;
|
|
2603
2643
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
2604
2644
|
return null;
|
|
2605
2645
|
}, [email]);
|
|
2606
2646
|
const emailError = touchedEmail || formSubmitAttempted ? validateEmail : null;
|
|
2607
2647
|
const canSubmit = email.length > 0 && validateEmail === null && !submitting;
|
|
2608
|
-
const submit = (0,
|
|
2648
|
+
const submit = (0, import_react17.useCallback)(async () => {
|
|
2609
2649
|
setFormSubmitAttempted(true);
|
|
2610
2650
|
if (!canSubmit) return false;
|
|
2611
2651
|
setSubmitting(true);
|
|
@@ -2636,32 +2676,32 @@ function useForgotForm() {
|
|
|
2636
2676
|
}
|
|
2637
2677
|
|
|
2638
2678
|
// src/hooks/useResetForm.ts
|
|
2639
|
-
var
|
|
2640
|
-
var
|
|
2679
|
+
var import_react18 = require("react");
|
|
2680
|
+
var import_sdk12 = require("@hook-sdk/sdk");
|
|
2641
2681
|
var MIN_PASSWORD3 = 12;
|
|
2642
2682
|
function useResetForm() {
|
|
2643
|
-
const { auth } = (0,
|
|
2644
|
-
const [token, setToken] = (0,
|
|
2645
|
-
const [password, setPassword] = (0,
|
|
2646
|
-
const [confirm, setConfirm] = (0,
|
|
2647
|
-
const [submitting, setSubmitting] = (0,
|
|
2648
|
-
const [done, setDone] = (0,
|
|
2649
|
-
const [error, setError] = (0,
|
|
2650
|
-
const [touchedPassword, setTouchedPassword] = (0,
|
|
2651
|
-
const [touchedConfirm, setTouchedConfirm] = (0,
|
|
2652
|
-
const [formSubmitAttempted, setFormSubmitAttempted] = (0,
|
|
2653
|
-
(0,
|
|
2683
|
+
const { auth } = (0, import_sdk12.useHook)();
|
|
2684
|
+
const [token, setToken] = (0, import_react18.useState)(null);
|
|
2685
|
+
const [password, setPassword] = (0, import_react18.useState)("");
|
|
2686
|
+
const [confirm, setConfirm] = (0, import_react18.useState)("");
|
|
2687
|
+
const [submitting, setSubmitting] = (0, import_react18.useState)(false);
|
|
2688
|
+
const [done, setDone] = (0, import_react18.useState)(false);
|
|
2689
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
2690
|
+
const [touchedPassword, setTouchedPassword] = (0, import_react18.useState)(false);
|
|
2691
|
+
const [touchedConfirm, setTouchedConfirm] = (0, import_react18.useState)(false);
|
|
2692
|
+
const [formSubmitAttempted, setFormSubmitAttempted] = (0, import_react18.useState)(false);
|
|
2693
|
+
(0, import_react18.useEffect)(() => {
|
|
2654
2694
|
if (typeof window === "undefined") return;
|
|
2655
2695
|
const params = new URLSearchParams(window.location.search);
|
|
2656
2696
|
const t = params.get("token");
|
|
2657
2697
|
setToken(t && t.length > 0 ? t : null);
|
|
2658
2698
|
}, []);
|
|
2659
|
-
const validatePassword = (0,
|
|
2699
|
+
const validatePassword = (0, import_react18.useMemo)(() => {
|
|
2660
2700
|
if (password.length === 0) return null;
|
|
2661
2701
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
2662
2702
|
return null;
|
|
2663
2703
|
}, [password]);
|
|
2664
|
-
const validateConfirm = (0,
|
|
2704
|
+
const validateConfirm = (0, import_react18.useMemo)(() => {
|
|
2665
2705
|
if (confirm.length === 0) return null;
|
|
2666
2706
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
2667
2707
|
return null;
|
|
@@ -2669,7 +2709,7 @@ function useResetForm() {
|
|
|
2669
2709
|
const passwordError = touchedPassword || formSubmitAttempted ? validatePassword : null;
|
|
2670
2710
|
const confirmError = touchedConfirm || formSubmitAttempted ? validateConfirm : null;
|
|
2671
2711
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && validatePassword === null && validateConfirm === null && !submitting && !done;
|
|
2672
|
-
const submit = (0,
|
|
2712
|
+
const submit = (0, import_react18.useCallback)(async () => {
|
|
2673
2713
|
setFormSubmitAttempted(true);
|
|
2674
2714
|
if (!canSubmit || token === null) return;
|
|
2675
2715
|
setSubmitting(true);
|
|
@@ -2709,9 +2749,9 @@ function useResetForm() {
|
|
|
2709
2749
|
}
|
|
2710
2750
|
|
|
2711
2751
|
// src/hooks/usePlan.ts
|
|
2712
|
-
var
|
|
2752
|
+
var import_sdk13 = require("@hook-sdk/sdk");
|
|
2713
2753
|
function usePlan() {
|
|
2714
|
-
const { plan } = (0,
|
|
2754
|
+
const { plan } = (0, import_sdk13.useHook)();
|
|
2715
2755
|
return plan;
|
|
2716
2756
|
}
|
|
2717
2757
|
|
|
@@ -2744,12 +2784,12 @@ function discountPercent(anchorCents, realCents) {
|
|
|
2744
2784
|
}
|
|
2745
2785
|
|
|
2746
2786
|
// src/hooks/useAuthPrimitives.ts
|
|
2747
|
-
var
|
|
2748
|
-
var
|
|
2787
|
+
var import_react19 = require("react");
|
|
2788
|
+
var import_sdk14 = require("@hook-sdk/sdk");
|
|
2749
2789
|
var warned = false;
|
|
2750
2790
|
function useAuthPrimitives() {
|
|
2751
|
-
const { auth } = (0,
|
|
2752
|
-
(0,
|
|
2791
|
+
const { auth } = (0, import_sdk14.useHook)();
|
|
2792
|
+
(0, import_react19.useEffect)(() => {
|
|
2753
2793
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
2754
2794
|
warned = true;
|
|
2755
2795
|
console.warn(
|
|
@@ -2771,9 +2811,9 @@ function useAuthPrimitives() {
|
|
|
2771
2811
|
}
|
|
2772
2812
|
|
|
2773
2813
|
// src/hooks/useAuth.ts
|
|
2774
|
-
var
|
|
2814
|
+
var import_sdk15 = require("@hook-sdk/sdk");
|
|
2775
2815
|
function useAuth() {
|
|
2776
|
-
const { user, authStatus, auth } = (0,
|
|
2816
|
+
const { user, authStatus, auth } = (0, import_sdk15.useHook)();
|
|
2777
2817
|
return {
|
|
2778
2818
|
user,
|
|
2779
2819
|
authStatus,
|
|
@@ -2781,24 +2821,27 @@ function useAuth() {
|
|
|
2781
2821
|
};
|
|
2782
2822
|
}
|
|
2783
2823
|
|
|
2824
|
+
// src/index.ts
|
|
2825
|
+
var import_sdk19 = require("@hook-sdk/sdk");
|
|
2826
|
+
|
|
2784
2827
|
// src/hooks/useSubscription.ts
|
|
2785
|
-
var
|
|
2828
|
+
var import_sdk16 = require("@hook-sdk/sdk");
|
|
2786
2829
|
function useSubscription() {
|
|
2787
|
-
const { subscription } = (0,
|
|
2830
|
+
const { subscription } = (0, import_sdk16.useHook)();
|
|
2788
2831
|
return {
|
|
2789
2832
|
status: subscription.status()
|
|
2790
2833
|
};
|
|
2791
2834
|
}
|
|
2792
2835
|
|
|
2793
2836
|
// src/hooks/useReminders.ts
|
|
2794
|
-
var
|
|
2795
|
-
var
|
|
2837
|
+
var import_react20 = require("react");
|
|
2838
|
+
var import_sdk17 = require("@hook-sdk/sdk");
|
|
2796
2839
|
function useReminders() {
|
|
2797
|
-
const { push } = (0,
|
|
2840
|
+
const { push } = (0, import_sdk17.useHook)();
|
|
2798
2841
|
const r = push.reminders;
|
|
2799
|
-
const [reminders, setReminders] = (0,
|
|
2800
|
-
const [loading, setLoading] = (0,
|
|
2801
|
-
const reload = (0,
|
|
2842
|
+
const [reminders, setReminders] = (0, import_react20.useState)([]);
|
|
2843
|
+
const [loading, setLoading] = (0, import_react20.useState)(true);
|
|
2844
|
+
const reload = (0, import_react20.useCallback)(async () => {
|
|
2802
2845
|
setLoading(true);
|
|
2803
2846
|
try {
|
|
2804
2847
|
const next = await r.list();
|
|
@@ -2807,38 +2850,38 @@ function useReminders() {
|
|
|
2807
2850
|
setLoading(false);
|
|
2808
2851
|
}
|
|
2809
2852
|
}, [r]);
|
|
2810
|
-
(0,
|
|
2853
|
+
(0, import_react20.useEffect)(() => {
|
|
2811
2854
|
void reload();
|
|
2812
2855
|
}, [reload]);
|
|
2813
|
-
const setReminder = (0,
|
|
2856
|
+
const setReminder = (0, import_react20.useCallback)(async (input) => {
|
|
2814
2857
|
await r.set(input);
|
|
2815
2858
|
await reload();
|
|
2816
2859
|
}, [r, reload]);
|
|
2817
|
-
const deleteReminder = (0,
|
|
2860
|
+
const deleteReminder = (0, import_react20.useCallback)(async (slot) => {
|
|
2818
2861
|
await r.delete(slot);
|
|
2819
2862
|
await reload();
|
|
2820
2863
|
}, [r, reload]);
|
|
2821
|
-
const schedule = (0,
|
|
2864
|
+
const schedule = (0, import_react20.useCallback)(async (items) => {
|
|
2822
2865
|
return r.schedule(items);
|
|
2823
2866
|
}, [r]);
|
|
2824
|
-
const setFallbacks = (0,
|
|
2867
|
+
const setFallbacks = (0, import_react20.useCallback)(async (items) => {
|
|
2825
2868
|
return r.setFallbacks(items);
|
|
2826
2869
|
}, [r]);
|
|
2827
2870
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
2828
2871
|
}
|
|
2829
2872
|
|
|
2830
2873
|
// src/hooks/useToast.ts
|
|
2831
|
-
var
|
|
2874
|
+
var import_react21 = require("react");
|
|
2832
2875
|
function useToast() {
|
|
2833
|
-
const [items, setItems] = (0,
|
|
2834
|
-
const show = (0,
|
|
2876
|
+
const [items, setItems] = (0, import_react21.useState)([]);
|
|
2877
|
+
const show = (0, import_react21.useCallback)((message, kind = "info") => {
|
|
2835
2878
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
2836
2879
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
2837
2880
|
setTimeout(() => {
|
|
2838
2881
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2839
2882
|
}, 4e3);
|
|
2840
2883
|
}, []);
|
|
2841
|
-
const dismiss = (0,
|
|
2884
|
+
const dismiss = (0, import_react21.useCallback)((id) => {
|
|
2842
2885
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
2843
2886
|
}, []);
|
|
2844
2887
|
return { items, show, dismiss };
|
|
@@ -2873,14 +2916,14 @@ function PreAuthShell({
|
|
|
2873
2916
|
}
|
|
2874
2917
|
|
|
2875
2918
|
// src/OnboardingFlow.tsx
|
|
2876
|
-
var
|
|
2877
|
-
var
|
|
2919
|
+
var import_react23 = require("react");
|
|
2920
|
+
var import_sdk18 = require("@hook-sdk/sdk");
|
|
2878
2921
|
|
|
2879
2922
|
// src/hooks/useOnboardingStep.ts
|
|
2880
|
-
var
|
|
2881
|
-
var OnboardingStepContext = (0,
|
|
2923
|
+
var import_react22 = require("react");
|
|
2924
|
+
var OnboardingStepContext = (0, import_react22.createContext)(null);
|
|
2882
2925
|
function useOnboardingStep() {
|
|
2883
|
-
const ctx = (0,
|
|
2926
|
+
const ctx = (0, import_react22.useContext)(OnboardingStepContext);
|
|
2884
2927
|
if (!ctx) {
|
|
2885
2928
|
throw new Error(
|
|
2886
2929
|
"[hook-template] useOnboardingStep must be used inside <OnboardingFlow>. (G75)"
|
|
@@ -2903,12 +2946,12 @@ function OnboardingFlow({
|
|
|
2903
2946
|
onComplete,
|
|
2904
2947
|
persistKey
|
|
2905
2948
|
}) {
|
|
2906
|
-
const [draft, setDraft, status] = (0,
|
|
2907
|
-
const draftRef = (0,
|
|
2949
|
+
const [draft, setDraft, status] = (0, import_sdk18.usePersistedState)(persistKey, {});
|
|
2950
|
+
const draftRef = (0, import_react23.useRef)(draft);
|
|
2908
2951
|
draftRef.current = draft;
|
|
2909
2952
|
const idx = readPersistedStepIdx(draft);
|
|
2910
2953
|
const clampedIdx = Math.min(Math.max(idx, 0), Math.max(steps.length - 1, 0));
|
|
2911
|
-
const setIdx = (0,
|
|
2954
|
+
const setIdx = (0, import_react23.useCallback)(
|
|
2912
2955
|
(n) => {
|
|
2913
2956
|
setDraft((prev) => {
|
|
2914
2957
|
const prevIdx = readPersistedStepIdx(prev);
|
|
@@ -2918,7 +2961,7 @@ function OnboardingFlow({
|
|
|
2918
2961
|
},
|
|
2919
2962
|
[setDraft]
|
|
2920
2963
|
);
|
|
2921
|
-
const setValue = (0,
|
|
2964
|
+
const setValue = (0, import_react23.useCallback)(
|
|
2922
2965
|
(patch) => {
|
|
2923
2966
|
draftRef.current = { ...draftRef.current, ...patch };
|
|
2924
2967
|
setDraft((prev) => ({ ...prev, ...patch }));
|
|
@@ -2926,11 +2969,23 @@ function OnboardingFlow({
|
|
|
2926
2969
|
[setDraft]
|
|
2927
2970
|
);
|
|
2928
2971
|
const step = steps[clampedIdx];
|
|
2929
|
-
const
|
|
2972
|
+
const hookCtx = (0, import_sdk18.useHook)();
|
|
2973
|
+
const track2 = typeof hookCtx.track === "function" ? hookCtx.track : void 0;
|
|
2974
|
+
(0, import_react23.useEffect)(() => {
|
|
2975
|
+
if (status.loading) return;
|
|
2976
|
+
if (!step) return;
|
|
2977
|
+
if (!track2) return;
|
|
2978
|
+
track2("onboarding_step_viewed", {
|
|
2979
|
+
step: step.id,
|
|
2980
|
+
step_index: clampedIdx,
|
|
2981
|
+
total_steps: steps.length
|
|
2982
|
+
});
|
|
2983
|
+
}, [step?.id, clampedIdx, steps.length, status.loading, track2]);
|
|
2984
|
+
const valid = (0, import_react23.useMemo)(
|
|
2930
2985
|
() => step ? (step.validates ?? []).every((field) => isFilled(draft[field])) : false,
|
|
2931
2986
|
[draft, step]
|
|
2932
2987
|
);
|
|
2933
|
-
const next = (0,
|
|
2988
|
+
const next = (0, import_react23.useCallback)(() => {
|
|
2934
2989
|
if (!step) return;
|
|
2935
2990
|
const current = draftRef.current;
|
|
2936
2991
|
const validNow = (step.validates ?? []).every((field) => isFilled(current[field]));
|
|
@@ -2941,8 +2996,8 @@ function OnboardingFlow({
|
|
|
2941
2996
|
setIdx(clampedIdx + 1);
|
|
2942
2997
|
}
|
|
2943
2998
|
}, [clampedIdx, onComplete, step, steps.length, setIdx]);
|
|
2944
|
-
const prevStep = (0,
|
|
2945
|
-
const ctx = (0,
|
|
2999
|
+
const prevStep = (0, import_react23.useCallback)(() => setIdx((i) => Math.max(0, i - 1)), [setIdx]);
|
|
3000
|
+
const ctx = (0, import_react23.useMemo)(
|
|
2946
3001
|
() => ({
|
|
2947
3002
|
stepIndex: clampedIdx,
|
|
2948
3003
|
totalSteps: steps.length,
|
|
@@ -3022,6 +3077,7 @@ function useFeature(name) {
|
|
|
3022
3077
|
useResetForm,
|
|
3023
3078
|
useSignupForm,
|
|
3024
3079
|
useSubscription,
|
|
3025
|
-
useToast
|
|
3080
|
+
useToast,
|
|
3081
|
+
useTrackOnboardingStep
|
|
3026
3082
|
});
|
|
3027
3083
|
//# sourceMappingURL=index.cjs.map
|