@hook-sdk/template 0.3.0 → 0.4.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 +1442 -206
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +1423 -197
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -28,11 +28,21 @@ __export(index_exports, {
|
|
|
28
28
|
DefaultSignupScreen: () => DefaultSignupScreen,
|
|
29
29
|
EmptyState: () => EmptyState,
|
|
30
30
|
ErrorBoundary: () => ErrorBoundary,
|
|
31
|
+
InstallGate: () => InstallGate,
|
|
32
|
+
InstallSplash: () => InstallSplash,
|
|
31
33
|
LoadingState: () => LoadingState,
|
|
32
34
|
PushPrompt: () => PushPrompt2,
|
|
35
|
+
detectAndroidBrowser: () => detectAndroidBrowser,
|
|
36
|
+
detectIOSBrowser: () => detectIOSBrowser,
|
|
37
|
+
detectInAppApp: () => detectInAppApp,
|
|
38
|
+
detectPlatform: () => detectPlatform,
|
|
39
|
+
detectStandalone: () => detectStandalone,
|
|
40
|
+
shouldBlockInstall: () => shouldBlockInstall,
|
|
41
|
+
shouldShowPermanentOption: () => shouldShowPermanentOption,
|
|
33
42
|
useAuth: () => useAuth,
|
|
34
43
|
useAuthPrimitives: () => useAuthPrimitives,
|
|
35
44
|
useForgotForm: () => useForgotForm,
|
|
45
|
+
useInstallPrompt: () => useInstallPrompt,
|
|
36
46
|
useLoginForm: () => useLoginForm,
|
|
37
47
|
usePaywallState: () => usePaywallState,
|
|
38
48
|
usePush: () => usePush,
|
|
@@ -45,7 +55,7 @@ __export(index_exports, {
|
|
|
45
55
|
module.exports = __toCommonJS(index_exports);
|
|
46
56
|
|
|
47
57
|
// src/AppRoot.tsx
|
|
48
|
-
var
|
|
58
|
+
var import_react16 = require("react");
|
|
49
59
|
var import_sdk9 = require("@hook-sdk/sdk");
|
|
50
60
|
|
|
51
61
|
// src/internal/TemplateConfigContext.tsx
|
|
@@ -210,10 +220,1226 @@ function PushPrompt() {
|
|
|
210
220
|
return null;
|
|
211
221
|
}
|
|
212
222
|
|
|
213
|
-
// src/
|
|
223
|
+
// src/components/InstallGate/InstallGate.tsx
|
|
224
|
+
var import_react8 = require("react");
|
|
225
|
+
|
|
226
|
+
// src/hooks/useInstallPrompt.ts
|
|
214
227
|
var import_react5 = require("react");
|
|
228
|
+
var IOS_RE = /iPad|iPhone|iPod/;
|
|
229
|
+
var IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;
|
|
230
|
+
var ANDROID_RE = /Android/;
|
|
231
|
+
var IN_APP_RE = /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;
|
|
232
|
+
var PERMANENT_DISMISS_REPROMPT_DAYS = 14;
|
|
233
|
+
var SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;
|
|
234
|
+
var storageKey = {
|
|
235
|
+
sessionSkip: (slug) => `install:${slug}:session-skip`,
|
|
236
|
+
dismissedAt: (slug) => `install:${slug}:dismissed-at`,
|
|
237
|
+
installedAt: (slug) => `install:${slug}:installed-at`,
|
|
238
|
+
skipCount: (slug) => `install:${slug}:skip-count`
|
|
239
|
+
};
|
|
240
|
+
function detectPlatform(ua) {
|
|
241
|
+
if (IN_APP_RE.test(ua)) return "in-app";
|
|
242
|
+
const isIOS = IOS_RE.test(ua);
|
|
243
|
+
if (isIOS) {
|
|
244
|
+
const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);
|
|
245
|
+
return isSafari ? "ios-safari" : "ios-other";
|
|
246
|
+
}
|
|
247
|
+
if (ANDROID_RE.test(ua)) return "android";
|
|
248
|
+
return "desktop";
|
|
249
|
+
}
|
|
250
|
+
function detectIOSBrowser(ua) {
|
|
251
|
+
if (!IOS_RE.test(ua)) return null;
|
|
252
|
+
if (/CriOS/.test(ua)) return "chrome";
|
|
253
|
+
if (/FxiOS/.test(ua)) return "firefox";
|
|
254
|
+
if (/EdgiOS/.test(ua)) return "edge";
|
|
255
|
+
if (/Safari/.test(ua)) return "safari";
|
|
256
|
+
return "other";
|
|
257
|
+
}
|
|
258
|
+
function detectAndroidBrowser(ua) {
|
|
259
|
+
if (!ANDROID_RE.test(ua)) return null;
|
|
260
|
+
if (/EdgA/.test(ua)) return "edge";
|
|
261
|
+
if (/OPR|OPT/.test(ua)) return "opera";
|
|
262
|
+
if (/SamsungBrowser/.test(ua)) return "samsung";
|
|
263
|
+
if (/Firefox/.test(ua)) return "firefox";
|
|
264
|
+
if (/Chrome/.test(ua)) return "chrome";
|
|
265
|
+
return "other";
|
|
266
|
+
}
|
|
267
|
+
function detectInAppApp(ua) {
|
|
268
|
+
if (!IN_APP_RE.test(ua)) return null;
|
|
269
|
+
if (/Instagram/i.test(ua)) return "instagram";
|
|
270
|
+
if (/FBAN|FBAV/.test(ua)) return "facebook";
|
|
271
|
+
if (/BytedanceWebview|TikTok/i.test(ua)) return "tiktok";
|
|
272
|
+
if (/WhatsApp/i.test(ua)) return "whatsapp";
|
|
273
|
+
if (/Twitter/i.test(ua)) return "twitter";
|
|
274
|
+
if (/LinkedIn/i.test(ua)) return "linkedin";
|
|
275
|
+
if (/Telegram/i.test(ua)) return "telegram";
|
|
276
|
+
if (/Line\//i.test(ua)) return "line";
|
|
277
|
+
if (/Snapchat/i.test(ua)) return "snapchat";
|
|
278
|
+
if (/Pinterest/i.test(ua)) return "pinterest";
|
|
279
|
+
if (/MicroMessenger/i.test(ua)) return "wechat";
|
|
280
|
+
return "other";
|
|
281
|
+
}
|
|
282
|
+
function detectStandalone() {
|
|
283
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
284
|
+
return { installed: false, source: null };
|
|
285
|
+
}
|
|
286
|
+
const mm = window.matchMedia?.("(display-mode: standalone)");
|
|
287
|
+
if (mm?.matches) return { installed: true, source: "match_media" };
|
|
288
|
+
const fs = window.matchMedia?.("(display-mode: fullscreen)");
|
|
289
|
+
if (fs?.matches) return { installed: true, source: "match_media" };
|
|
290
|
+
if (navigator.standalone === true) return { installed: true, source: "navigator_standalone" };
|
|
291
|
+
return { installed: false, source: null };
|
|
292
|
+
}
|
|
293
|
+
function track(event, props) {
|
|
294
|
+
if (typeof window === "undefined") return;
|
|
295
|
+
window.posthog?.capture?.(event, props);
|
|
296
|
+
}
|
|
297
|
+
function pickVariant(state) {
|
|
298
|
+
if (state.isInstalled) return "none";
|
|
299
|
+
switch (state.platform) {
|
|
300
|
+
case "android":
|
|
301
|
+
return state.isInstallable ? "android-native" : "android-manual";
|
|
302
|
+
case "ios-safari":
|
|
303
|
+
return "ios-safari";
|
|
304
|
+
case "ios-other":
|
|
305
|
+
return "ios-other";
|
|
306
|
+
case "in-app":
|
|
307
|
+
return "in-app";
|
|
308
|
+
case "desktop":
|
|
309
|
+
return state.isInstallable ? "desktop" : "none";
|
|
310
|
+
default:
|
|
311
|
+
return "none";
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function safeStorage() {
|
|
315
|
+
if (typeof localStorage === "undefined") return null;
|
|
316
|
+
try {
|
|
317
|
+
localStorage.setItem("__install_probe", "1");
|
|
318
|
+
localStorage.removeItem("__install_probe");
|
|
319
|
+
return localStorage;
|
|
320
|
+
} catch {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function readPermanentDismiss(slug) {
|
|
325
|
+
const storage = safeStorage();
|
|
326
|
+
if (!storage) return { dismissed: false, dismissedAt: null };
|
|
327
|
+
const raw = storage.getItem(storageKey.dismissedAt(slug));
|
|
328
|
+
if (!raw) return { dismissed: false, dismissedAt: null };
|
|
329
|
+
const parsed = Date.parse(raw);
|
|
330
|
+
if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };
|
|
331
|
+
const daysAgo = (Date.now() - parsed) / (1e3 * 60 * 60 * 24);
|
|
332
|
+
return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };
|
|
333
|
+
}
|
|
334
|
+
function readInstalledMarker(slug) {
|
|
335
|
+
const storage = safeStorage();
|
|
336
|
+
if (!storage) return false;
|
|
337
|
+
return storage.getItem(storageKey.installedAt(slug)) !== null;
|
|
338
|
+
}
|
|
339
|
+
function readSkipCount(slug) {
|
|
340
|
+
const storage = safeStorage();
|
|
341
|
+
if (!storage) return 0;
|
|
342
|
+
const raw = storage.getItem(storageKey.skipCount(slug));
|
|
343
|
+
const n = raw ? Number.parseInt(raw, 10) : 0;
|
|
344
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
345
|
+
}
|
|
346
|
+
function readSessionSkip(slug) {
|
|
347
|
+
if (typeof sessionStorage === "undefined") return false;
|
|
348
|
+
try {
|
|
349
|
+
return sessionStorage.getItem(storageKey.sessionSkip(slug)) === "true";
|
|
350
|
+
} catch {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function useInstallPrompt(slug) {
|
|
355
|
+
const ua = typeof navigator !== "undefined" && typeof navigator.userAgent === "string" ? navigator.userAgent : "";
|
|
356
|
+
const platform = detectPlatform(ua);
|
|
357
|
+
const iosBrowser = detectIOSBrowser(ua);
|
|
358
|
+
const androidBrowser = detectAndroidBrowser(ua);
|
|
359
|
+
const inAppApp = detectInAppApp(ua);
|
|
360
|
+
const [isInstallable, setIsInstallable] = (0, import_react5.useState)(() => {
|
|
361
|
+
if (typeof window === "undefined") return false;
|
|
362
|
+
return window.__pwaInstallPrompt != null;
|
|
363
|
+
});
|
|
364
|
+
const [isInstalled, setIsInstalled] = (0, import_react5.useState)(() => {
|
|
365
|
+
const { installed } = detectStandalone();
|
|
366
|
+
return installed || readInstalledMarker(slug);
|
|
367
|
+
});
|
|
368
|
+
const [isDismissedSession, setIsDismissedSession] = (0, import_react5.useState)(() => readSessionSkip(slug));
|
|
369
|
+
const [isDismissedPermanent, setIsDismissedPermanent] = (0, import_react5.useState)(() => readPermanentDismiss(slug).dismissed);
|
|
370
|
+
const [skipCount, setSkipCount] = (0, import_react5.useState)(() => readSkipCount(slug));
|
|
371
|
+
(0, import_react5.useEffect)(() => {
|
|
372
|
+
if (typeof window === "undefined") return;
|
|
373
|
+
if (window.__pwaInstallPrompt) {
|
|
374
|
+
setIsInstallable(true);
|
|
375
|
+
}
|
|
376
|
+
const onPrompt = (e) => {
|
|
377
|
+
e.preventDefault();
|
|
378
|
+
window.__pwaInstallPrompt = e;
|
|
379
|
+
setIsInstallable(true);
|
|
380
|
+
};
|
|
381
|
+
const onInstalled = () => {
|
|
382
|
+
setIsInstalled(true);
|
|
383
|
+
setIsInstallable(false);
|
|
384
|
+
window.__pwaInstallPrompt = null;
|
|
385
|
+
const storage = safeStorage();
|
|
386
|
+
if (storage) storage.setItem(storageKey.installedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
387
|
+
};
|
|
388
|
+
window.addEventListener("beforeinstallprompt", onPrompt);
|
|
389
|
+
window.addEventListener("appinstalled", onInstalled);
|
|
390
|
+
return () => {
|
|
391
|
+
window.removeEventListener("beforeinstallprompt", onPrompt);
|
|
392
|
+
window.removeEventListener("appinstalled", onInstalled);
|
|
393
|
+
};
|
|
394
|
+
}, [slug]);
|
|
395
|
+
(0, import_react5.useEffect)(() => {
|
|
396
|
+
if (typeof window === "undefined") return;
|
|
397
|
+
const mq = window.matchMedia?.("(display-mode: standalone)");
|
|
398
|
+
if (!mq) return;
|
|
399
|
+
const handler = (e) => {
|
|
400
|
+
if (e.matches) {
|
|
401
|
+
setIsInstalled(true);
|
|
402
|
+
track("pwa_install_standalone_detected", { slug, source: "match_media" });
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
mq.addEventListener?.("change", handler);
|
|
406
|
+
return () => mq.removeEventListener?.("change", handler);
|
|
407
|
+
}, [slug]);
|
|
408
|
+
const variant = pickVariant({
|
|
409
|
+
platform,
|
|
410
|
+
iosBrowser,
|
|
411
|
+
androidBrowser,
|
|
412
|
+
inAppApp,
|
|
413
|
+
isInstallable,
|
|
414
|
+
isInstalled,
|
|
415
|
+
isDismissedSession,
|
|
416
|
+
isDismissedPermanent,
|
|
417
|
+
skipCount
|
|
418
|
+
});
|
|
419
|
+
const promptInstall = (0, import_react5.useCallback)(async () => {
|
|
420
|
+
if (typeof window === "undefined") return false;
|
|
421
|
+
const prompt = window.__pwaInstallPrompt;
|
|
422
|
+
if (!prompt) return false;
|
|
423
|
+
track("pwa_install_prompt_clicked", { slug });
|
|
424
|
+
try {
|
|
425
|
+
await prompt.prompt();
|
|
426
|
+
const { outcome } = await prompt.userChoice;
|
|
427
|
+
track("pwa_install_prompt_outcome", { slug, outcome });
|
|
428
|
+
if (outcome === "accepted") {
|
|
429
|
+
setIsInstalled(true);
|
|
430
|
+
setIsInstallable(false);
|
|
431
|
+
window.__pwaInstallPrompt = null;
|
|
432
|
+
const storage = safeStorage();
|
|
433
|
+
if (storage) storage.setItem(storageKey.installedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
return false;
|
|
437
|
+
} catch {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
}, [slug]);
|
|
441
|
+
const dismissSession = (0, import_react5.useCallback)(() => {
|
|
442
|
+
if (typeof sessionStorage !== "undefined") {
|
|
443
|
+
try {
|
|
444
|
+
sessionStorage.setItem(storageKey.sessionSkip(slug), "true");
|
|
445
|
+
} catch {
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const storage = safeStorage();
|
|
449
|
+
const newCount = skipCount + 1;
|
|
450
|
+
if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));
|
|
451
|
+
setSkipCount(newCount);
|
|
452
|
+
setIsDismissedSession(true);
|
|
453
|
+
track("pwa_install_session_skip", { slug, platform, skip_count: newCount });
|
|
454
|
+
}, [slug, skipCount, platform]);
|
|
455
|
+
const dismissPermanent = (0, import_react5.useCallback)(() => {
|
|
456
|
+
const storage = safeStorage();
|
|
457
|
+
if (storage) storage.setItem(storageKey.dismissedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
458
|
+
setIsDismissedPermanent(true);
|
|
459
|
+
track("pwa_install_permanent_dismiss", { slug, platform, prior_skip_count: skipCount });
|
|
460
|
+
}, [slug, platform, skipCount]);
|
|
461
|
+
const redirectToSafari = (0, import_react5.useCallback)(() => {
|
|
462
|
+
if (typeof location === "undefined") return;
|
|
463
|
+
track("pwa_install_redirect_to_safari", { slug });
|
|
464
|
+
const url = `safari-https://${location.host}${location.pathname}${location.search}${location.hash}`;
|
|
465
|
+
try {
|
|
466
|
+
window.location.href = url;
|
|
467
|
+
} catch {
|
|
468
|
+
}
|
|
469
|
+
}, [slug]);
|
|
470
|
+
const copyLink = (0, import_react5.useCallback)(async () => {
|
|
471
|
+
if (typeof navigator === "undefined" || typeof location === "undefined") return;
|
|
472
|
+
try {
|
|
473
|
+
await navigator.clipboard?.writeText?.(location.href);
|
|
474
|
+
} catch {
|
|
475
|
+
}
|
|
476
|
+
}, []);
|
|
477
|
+
const reset = (0, import_react5.useCallback)(() => {
|
|
478
|
+
const storage = safeStorage();
|
|
479
|
+
if (storage) {
|
|
480
|
+
storage.removeItem(storageKey.dismissedAt(slug));
|
|
481
|
+
storage.removeItem(storageKey.installedAt(slug));
|
|
482
|
+
storage.removeItem(storageKey.skipCount(slug));
|
|
483
|
+
}
|
|
484
|
+
if (typeof sessionStorage !== "undefined") {
|
|
485
|
+
try {
|
|
486
|
+
sessionStorage.removeItem(storageKey.sessionSkip(slug));
|
|
487
|
+
} catch {
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
setIsDismissedSession(false);
|
|
491
|
+
setIsDismissedPermanent(false);
|
|
492
|
+
setSkipCount(0);
|
|
493
|
+
}, [slug]);
|
|
494
|
+
return {
|
|
495
|
+
platform,
|
|
496
|
+
iosBrowser,
|
|
497
|
+
androidBrowser,
|
|
498
|
+
inAppApp,
|
|
499
|
+
isInstallable,
|
|
500
|
+
isInstalled,
|
|
501
|
+
isDismissedSession,
|
|
502
|
+
isDismissedPermanent,
|
|
503
|
+
skipCount,
|
|
504
|
+
variant,
|
|
505
|
+
promptInstall,
|
|
506
|
+
dismissSession,
|
|
507
|
+
dismissPermanent,
|
|
508
|
+
redirectToSafari,
|
|
509
|
+
copyLink,
|
|
510
|
+
reset
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function shouldBlockInstall(state, now = Date.now()) {
|
|
514
|
+
if (state.isInstalled) return false;
|
|
515
|
+
if (state.variant === "none") return false;
|
|
516
|
+
if (state.isDismissedSession) return false;
|
|
517
|
+
if (state.isDismissedPermanent) {
|
|
518
|
+
void now;
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
if (state.platform === "desktop" && !state.isInstallable) return false;
|
|
522
|
+
if (state.platform === "unknown") return false;
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
function shouldShowPermanentOption(state) {
|
|
526
|
+
return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/components/InstallGate/copy.ts
|
|
530
|
+
var INSTALL_COPY = {
|
|
531
|
+
android: {
|
|
532
|
+
native: {
|
|
533
|
+
title: "Instale no seu celular",
|
|
534
|
+
subtitle: "Acesso r\xE1pido, sem precisar do navegador",
|
|
535
|
+
cta: "Baixar",
|
|
536
|
+
skip: "Continuar no navegador",
|
|
537
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
538
|
+
},
|
|
539
|
+
manual: {
|
|
540
|
+
title: "Instale em 2 toques",
|
|
541
|
+
subtitle: 'Toque no menu do navegador e escolha "Instalar aplicativo"',
|
|
542
|
+
step1: "Toque no menu do navegador",
|
|
543
|
+
step2: 'Escolha "Instalar aplicativo"',
|
|
544
|
+
cta: "Entendi",
|
|
545
|
+
skip: "Continuar no navegador",
|
|
546
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
iosSafari: {
|
|
550
|
+
title: "Adicione \xE0 sua Tela de In\xEDcio",
|
|
551
|
+
subtitle: "Siga os 3 passos",
|
|
552
|
+
step1: {
|
|
553
|
+
title: "Toque em Compartilhar",
|
|
554
|
+
subtitle: "Na barra inferior do Safari"
|
|
555
|
+
},
|
|
556
|
+
step2: {
|
|
557
|
+
title: 'Role e toque em "Adicionar \xE0 Tela de In\xEDcio"',
|
|
558
|
+
iconLabel: "Adicionar \xE0 Tela de In\xEDcio"
|
|
559
|
+
},
|
|
560
|
+
step3: {
|
|
561
|
+
title: 'Toque em "Adicionar" pra confirmar',
|
|
562
|
+
buttonLabel: "Adicionar"
|
|
563
|
+
},
|
|
564
|
+
skip: "Continuar no Safari",
|
|
565
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
566
|
+
},
|
|
567
|
+
iosOther: {
|
|
568
|
+
title: "Abra no Safari pra instalar",
|
|
569
|
+
subtitle: "No Chrome/Firefox/Edge do iPhone n\xE3o d\xE1 pra instalar PWA. Abra o link no Safari.",
|
|
570
|
+
ctaPrimary: "Abrir no Safari",
|
|
571
|
+
ctaSecondary: "Copiar link",
|
|
572
|
+
copiedToast: "Link copiado. Cole no Safari.",
|
|
573
|
+
skip: "Continuar mesmo assim",
|
|
574
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
575
|
+
},
|
|
576
|
+
inApp: {
|
|
577
|
+
instagram: {
|
|
578
|
+
title: "Pra instalar, abra fora do Instagram",
|
|
579
|
+
step1: "Toque em \u22EF (canto superior direito)",
|
|
580
|
+
step2: 'Escolha "Abrir no navegador externo"'
|
|
581
|
+
},
|
|
582
|
+
facebook: {
|
|
583
|
+
title: "Pra instalar, abra fora do Facebook",
|
|
584
|
+
step1: "Toque em \u22EE",
|
|
585
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
586
|
+
},
|
|
587
|
+
tiktok: {
|
|
588
|
+
title: "Pra instalar, abra fora do TikTok",
|
|
589
|
+
step1: "Toque em \u22EF",
|
|
590
|
+
step2: 'Escolha "Abrir no Safari" (iOS) ou "Abrir no Chrome" (Android)'
|
|
591
|
+
},
|
|
592
|
+
whatsapp: {
|
|
593
|
+
title: "Pra instalar, abra fora do WhatsApp",
|
|
594
|
+
step1: "Toque longo no link",
|
|
595
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
596
|
+
},
|
|
597
|
+
twitter: {
|
|
598
|
+
title: "Pra instalar, abra fora do Twitter",
|
|
599
|
+
step1: "Toque em \u22EF",
|
|
600
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
601
|
+
},
|
|
602
|
+
linkedin: {
|
|
603
|
+
title: "Pra instalar, abra fora do LinkedIn",
|
|
604
|
+
step1: "Toque em \u22EF",
|
|
605
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
606
|
+
},
|
|
607
|
+
telegram: {
|
|
608
|
+
title: "Pra instalar, abra fora do Telegram",
|
|
609
|
+
step1: "Toque em \u22EE",
|
|
610
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
611
|
+
},
|
|
612
|
+
line: {
|
|
613
|
+
title: "Pra instalar, abra fora do LINE",
|
|
614
|
+
step1: "Toque em \u22EF",
|
|
615
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
616
|
+
},
|
|
617
|
+
snapchat: {
|
|
618
|
+
title: "Pra instalar, abra fora do Snapchat",
|
|
619
|
+
step1: "Mantenha pressionado o link",
|
|
620
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
621
|
+
},
|
|
622
|
+
pinterest: {
|
|
623
|
+
title: "Pra instalar, abra fora do Pinterest",
|
|
624
|
+
step1: "Toque em \u22EF",
|
|
625
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
626
|
+
},
|
|
627
|
+
wechat: {
|
|
628
|
+
title: "Pra instalar, abra fora do WeChat",
|
|
629
|
+
step1: "Toque em \u22EF",
|
|
630
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
631
|
+
},
|
|
632
|
+
other: {
|
|
633
|
+
title: "Abra no navegador do celular",
|
|
634
|
+
step1: "Toque no menu do app atual",
|
|
635
|
+
step2: 'Escolha "Abrir no Chrome" ou "Abrir no Safari"'
|
|
636
|
+
},
|
|
637
|
+
copy: "Copiar link",
|
|
638
|
+
copiedToast: "Link copiado. Cole no Chrome/Safari.",
|
|
639
|
+
skip: "Continuar aqui mesmo",
|
|
640
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
641
|
+
},
|
|
642
|
+
desktop: {
|
|
643
|
+
title: "Instale no computador",
|
|
644
|
+
subtitle: "Acesso r\xE1pido",
|
|
645
|
+
cta: "Baixar",
|
|
646
|
+
close: "Fechar"
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
// src/components/InstallGate/InstallSplash.tsx
|
|
215
651
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
216
|
-
|
|
652
|
+
function InstallSplash({ children, title, subtitle }) {
|
|
653
|
+
const { name, theme } = useTemplateConfig();
|
|
654
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
656
|
+
"div",
|
|
657
|
+
{
|
|
658
|
+
role: "dialog",
|
|
659
|
+
"aria-modal": "true",
|
|
660
|
+
"aria-labelledby": "install-splash-title",
|
|
661
|
+
"aria-describedby": subtitle ? "install-splash-subtitle" : void 0,
|
|
662
|
+
style: overlayStyle,
|
|
663
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: cardStyle, children: [
|
|
664
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { display: "flex", justifyContent: "center", marginBottom: 16 }, children: iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
665
|
+
"img",
|
|
666
|
+
{
|
|
667
|
+
src: iconUrl,
|
|
668
|
+
alt: `\xCDcone de ${name}`,
|
|
669
|
+
style: { width: 80, height: 80, borderRadius: 20, objectFit: "cover" }
|
|
670
|
+
}
|
|
671
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
672
|
+
"div",
|
|
673
|
+
{
|
|
674
|
+
style: {
|
|
675
|
+
width: 80,
|
|
676
|
+
height: 80,
|
|
677
|
+
borderRadius: 20,
|
|
678
|
+
background: "var(--hook-color-primary)",
|
|
679
|
+
color: "#fff",
|
|
680
|
+
display: "flex",
|
|
681
|
+
alignItems: "center",
|
|
682
|
+
justifyContent: "center",
|
|
683
|
+
fontSize: 36,
|
|
684
|
+
fontWeight: 700
|
|
685
|
+
},
|
|
686
|
+
children: name.charAt(0).toUpperCase()
|
|
687
|
+
}
|
|
688
|
+
) }),
|
|
689
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { id: "install-splash-title", style: titleStyle, children: title }),
|
|
690
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { id: "install-splash-subtitle", style: subtitleStyle, children: subtitle }),
|
|
691
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { marginTop: 24 }, children }),
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: footerStyle, children: "por Hook" })
|
|
693
|
+
] })
|
|
694
|
+
}
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
var primaryButtonStyle = {
|
|
698
|
+
width: "100%",
|
|
699
|
+
padding: "14px 20px",
|
|
700
|
+
background: "var(--hook-color-primary)",
|
|
701
|
+
color: "#fff",
|
|
702
|
+
border: "none",
|
|
703
|
+
borderRadius: 999,
|
|
704
|
+
fontSize: 17,
|
|
705
|
+
fontWeight: 600,
|
|
706
|
+
cursor: "pointer",
|
|
707
|
+
marginBottom: 12
|
|
708
|
+
};
|
|
709
|
+
var secondaryButtonStyle = {
|
|
710
|
+
width: "100%",
|
|
711
|
+
padding: "12px 20px",
|
|
712
|
+
background: "transparent",
|
|
713
|
+
color: "var(--hook-color-primary)",
|
|
714
|
+
border: "1px solid var(--hook-color-primary)",
|
|
715
|
+
borderRadius: 999,
|
|
716
|
+
fontSize: 15,
|
|
717
|
+
fontWeight: 500,
|
|
718
|
+
cursor: "pointer",
|
|
719
|
+
marginBottom: 12
|
|
720
|
+
};
|
|
721
|
+
var skipLinkStyle = {
|
|
722
|
+
display: "block",
|
|
723
|
+
width: "100%",
|
|
724
|
+
padding: "10px",
|
|
725
|
+
marginTop: 8,
|
|
726
|
+
background: "transparent",
|
|
727
|
+
color: "#555",
|
|
728
|
+
border: "none",
|
|
729
|
+
fontSize: 14,
|
|
730
|
+
textDecoration: "underline",
|
|
731
|
+
cursor: "pointer",
|
|
732
|
+
textAlign: "center"
|
|
733
|
+
};
|
|
734
|
+
var skipPermanentLinkStyle = {
|
|
735
|
+
...skipLinkStyle,
|
|
736
|
+
color: "#999",
|
|
737
|
+
fontSize: 13,
|
|
738
|
+
marginTop: 4
|
|
739
|
+
};
|
|
740
|
+
var overlayStyle = {
|
|
741
|
+
position: "fixed",
|
|
742
|
+
inset: 0,
|
|
743
|
+
background: "var(--hook-color-background, #fafafa)",
|
|
744
|
+
zIndex: 1e4,
|
|
745
|
+
display: "flex",
|
|
746
|
+
alignItems: "center",
|
|
747
|
+
justifyContent: "center",
|
|
748
|
+
padding: 20,
|
|
749
|
+
overflow: "auto"
|
|
750
|
+
};
|
|
751
|
+
var cardStyle = {
|
|
752
|
+
width: "100%",
|
|
753
|
+
maxWidth: 420,
|
|
754
|
+
padding: 24,
|
|
755
|
+
textAlign: "center"
|
|
756
|
+
};
|
|
757
|
+
var titleStyle = {
|
|
758
|
+
fontSize: 24,
|
|
759
|
+
fontWeight: 700,
|
|
760
|
+
lineHeight: 1.2,
|
|
761
|
+
margin: "0 0 8px 0",
|
|
762
|
+
color: "#111"
|
|
763
|
+
};
|
|
764
|
+
var subtitleStyle = {
|
|
765
|
+
fontSize: 15,
|
|
766
|
+
lineHeight: 1.4,
|
|
767
|
+
color: "#555",
|
|
768
|
+
margin: 0
|
|
769
|
+
};
|
|
770
|
+
var footerStyle = {
|
|
771
|
+
fontSize: 11,
|
|
772
|
+
color: "#aaa",
|
|
773
|
+
marginTop: 32,
|
|
774
|
+
letterSpacing: 0.5
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
// src/components/InstallGate/icons.tsx
|
|
778
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
779
|
+
var defaultSvgProps = (size) => ({
|
|
780
|
+
width: size,
|
|
781
|
+
height: size,
|
|
782
|
+
viewBox: "0 0 24 24",
|
|
783
|
+
fill: "none",
|
|
784
|
+
stroke: "currentColor",
|
|
785
|
+
strokeWidth: 2,
|
|
786
|
+
strokeLinecap: "round",
|
|
787
|
+
strokeLinejoin: "round"
|
|
788
|
+
});
|
|
789
|
+
function ShareIconIOS({ size = 24, style, className }) {
|
|
790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
791
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 2L12 15" }),
|
|
792
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 6L12 2L16 6" }),
|
|
793
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9" })
|
|
794
|
+
] });
|
|
795
|
+
}
|
|
796
|
+
function MenuDotsVerticalIcon({ size = 24, style, className }) {
|
|
797
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
798
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "5", r: "1.5" }),
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
800
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "19", r: "1.5" })
|
|
801
|
+
] });
|
|
802
|
+
}
|
|
803
|
+
function MenuDotsHorizontalIcon({ size = 24, style, className }) {
|
|
804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
805
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
806
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
807
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
808
|
+
] });
|
|
809
|
+
}
|
|
810
|
+
function SquarePlusIcon({ size = 24, style, className }) {
|
|
811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
812
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
813
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M12 8v8" }),
|
|
814
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M8 12h8" })
|
|
815
|
+
] });
|
|
816
|
+
}
|
|
817
|
+
function DownloadIcon({ size = 24, style, className }) {
|
|
818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
819
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" }),
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "7 10 12 15 17 10" }),
|
|
821
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
822
|
+
] });
|
|
823
|
+
}
|
|
824
|
+
function ExternalLinkIcon({ size = 24, style, className }) {
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
826
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" }),
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "15 3 21 3 21 9" }),
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
829
|
+
] });
|
|
830
|
+
}
|
|
831
|
+
function XIcon({ size = 20, style, className }) {
|
|
832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
833
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
834
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
835
|
+
] });
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// src/components/InstallGate/variants/AndroidNativeVariant.tsx
|
|
839
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
840
|
+
function AndroidNativeVariant({
|
|
841
|
+
state,
|
|
842
|
+
actions
|
|
843
|
+
}) {
|
|
844
|
+
const copy = INSTALL_COPY.android.native;
|
|
845
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
848
|
+
"button",
|
|
849
|
+
{
|
|
850
|
+
"data-testid": "install-prompt-cta-android-native",
|
|
851
|
+
type: "button",
|
|
852
|
+
onClick: () => void actions.promptInstall(),
|
|
853
|
+
style: { ...primaryButtonStyle, display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8 },
|
|
854
|
+
children: [
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DownloadIcon, { size: 18 }),
|
|
856
|
+
copy.cta
|
|
857
|
+
]
|
|
858
|
+
}
|
|
859
|
+
),
|
|
860
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
861
|
+
"button",
|
|
862
|
+
{
|
|
863
|
+
"data-testid": "install-prompt-skip-session",
|
|
864
|
+
type: "button",
|
|
865
|
+
onClick: actions.dismissSession,
|
|
866
|
+
style: skipLinkStyle,
|
|
867
|
+
children: copy.skip
|
|
868
|
+
}
|
|
869
|
+
),
|
|
870
|
+
showPermanent && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
871
|
+
"button",
|
|
872
|
+
{
|
|
873
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
874
|
+
type: "button",
|
|
875
|
+
onClick: actions.dismissPermanent,
|
|
876
|
+
style: skipPermanentLinkStyle,
|
|
877
|
+
children: copy.skipPermanent
|
|
878
|
+
}
|
|
879
|
+
)
|
|
880
|
+
] });
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// src/components/InstallGate/variants/AndroidManualVariant.tsx
|
|
884
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
885
|
+
function AndroidManualVariant({
|
|
886
|
+
state,
|
|
887
|
+
actions
|
|
888
|
+
}) {
|
|
889
|
+
const copy = INSTALL_COPY.android.manual;
|
|
890
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
891
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(InstallSplash, { title: copy.title, children: [
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Step, { n: 1, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuDotsVerticalIcon, { size: 20 }), children: copy.step1 }),
|
|
893
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Step, { n: 2, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DownloadIcon, { size: 18 }), children: copy.step2 }),
|
|
894
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
895
|
+
"button",
|
|
896
|
+
{
|
|
897
|
+
"data-testid": "install-prompt-cta-android-manual",
|
|
898
|
+
type: "button",
|
|
899
|
+
onClick: actions.dismissSession,
|
|
900
|
+
style: primaryButtonStyle,
|
|
901
|
+
children: copy.cta
|
|
902
|
+
}
|
|
903
|
+
),
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
905
|
+
"button",
|
|
906
|
+
{
|
|
907
|
+
"data-testid": "install-prompt-skip-session",
|
|
908
|
+
type: "button",
|
|
909
|
+
onClick: actions.dismissSession,
|
|
910
|
+
style: skipLinkStyle,
|
|
911
|
+
children: copy.skip
|
|
912
|
+
}
|
|
913
|
+
),
|
|
914
|
+
showPermanent && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
915
|
+
"button",
|
|
916
|
+
{
|
|
917
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
918
|
+
type: "button",
|
|
919
|
+
onClick: actions.dismissPermanent,
|
|
920
|
+
style: skipPermanentLinkStyle,
|
|
921
|
+
children: copy.skipPermanent
|
|
922
|
+
}
|
|
923
|
+
)
|
|
924
|
+
] });
|
|
925
|
+
}
|
|
926
|
+
function Step({ n, icon, children }) {
|
|
927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
928
|
+
"div",
|
|
929
|
+
{
|
|
930
|
+
style: {
|
|
931
|
+
display: "flex",
|
|
932
|
+
alignItems: "center",
|
|
933
|
+
gap: 12,
|
|
934
|
+
padding: "12px 14px",
|
|
935
|
+
background: "#f5f5f7",
|
|
936
|
+
borderRadius: 12,
|
|
937
|
+
marginBottom: 10,
|
|
938
|
+
textAlign: "left"
|
|
939
|
+
},
|
|
940
|
+
children: [
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
942
|
+
"div",
|
|
943
|
+
{
|
|
944
|
+
style: {
|
|
945
|
+
width: 28,
|
|
946
|
+
height: 28,
|
|
947
|
+
borderRadius: "50%",
|
|
948
|
+
background: "var(--hook-color-primary)",
|
|
949
|
+
color: "#fff",
|
|
950
|
+
display: "flex",
|
|
951
|
+
alignItems: "center",
|
|
952
|
+
justifyContent: "center",
|
|
953
|
+
fontSize: 14,
|
|
954
|
+
fontWeight: 700,
|
|
955
|
+
flexShrink: 0
|
|
956
|
+
},
|
|
957
|
+
children: n
|
|
958
|
+
}
|
|
959
|
+
),
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { flex: 1, fontSize: 15, color: "#333" }, children }),
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
962
|
+
]
|
|
963
|
+
}
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// src/components/InstallGate/variants/IOSafariVariant.tsx
|
|
968
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
969
|
+
function IOSafariVariant({
|
|
970
|
+
state,
|
|
971
|
+
actions
|
|
972
|
+
}) {
|
|
973
|
+
const copy = INSTALL_COPY.iosSafari;
|
|
974
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
976
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
977
|
+
Step2,
|
|
978
|
+
{
|
|
979
|
+
n: 1,
|
|
980
|
+
title: copy.step1.title,
|
|
981
|
+
subtitle: copy.step1.subtitle,
|
|
982
|
+
visual: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
983
|
+
"div",
|
|
984
|
+
{
|
|
985
|
+
style: {
|
|
986
|
+
display: "flex",
|
|
987
|
+
justifyContent: "center",
|
|
988
|
+
alignItems: "center",
|
|
989
|
+
background: "#f5f5f7",
|
|
990
|
+
borderRadius: 12,
|
|
991
|
+
padding: "12px 0",
|
|
992
|
+
marginTop: 8
|
|
993
|
+
},
|
|
994
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ShareIconIOS, { size: 32, style: { color: "var(--hook-color-primary)" } })
|
|
995
|
+
}
|
|
996
|
+
)
|
|
997
|
+
}
|
|
998
|
+
),
|
|
999
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1000
|
+
Step2,
|
|
1001
|
+
{
|
|
1002
|
+
n: 2,
|
|
1003
|
+
title: copy.step2.title,
|
|
1004
|
+
visual: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1005
|
+
"div",
|
|
1006
|
+
{
|
|
1007
|
+
style: {
|
|
1008
|
+
display: "flex",
|
|
1009
|
+
alignItems: "center",
|
|
1010
|
+
gap: 10,
|
|
1011
|
+
background: "#f5f5f7",
|
|
1012
|
+
borderRadius: 12,
|
|
1013
|
+
padding: "12px 14px",
|
|
1014
|
+
marginTop: 8
|
|
1015
|
+
},
|
|
1016
|
+
children: [
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SquarePlusIcon, { size: 22, style: { color: "#555" } }),
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { fontSize: 14, color: "#333" }, children: copy.step2.iconLabel })
|
|
1019
|
+
]
|
|
1020
|
+
}
|
|
1021
|
+
)
|
|
1022
|
+
}
|
|
1023
|
+
),
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1025
|
+
Step2,
|
|
1026
|
+
{
|
|
1027
|
+
n: 3,
|
|
1028
|
+
title: copy.step3.title,
|
|
1029
|
+
visual: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1030
|
+
"div",
|
|
1031
|
+
{
|
|
1032
|
+
style: {
|
|
1033
|
+
display: "flex",
|
|
1034
|
+
justifyContent: "flex-end",
|
|
1035
|
+
background: "#f5f5f7",
|
|
1036
|
+
borderRadius: 12,
|
|
1037
|
+
padding: "10px 14px",
|
|
1038
|
+
marginTop: 8
|
|
1039
|
+
},
|
|
1040
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1041
|
+
"span",
|
|
1042
|
+
{
|
|
1043
|
+
style: {
|
|
1044
|
+
color: "var(--hook-color-primary)",
|
|
1045
|
+
fontSize: 15,
|
|
1046
|
+
fontWeight: 600
|
|
1047
|
+
},
|
|
1048
|
+
children: copy.step3.buttonLabel
|
|
1049
|
+
}
|
|
1050
|
+
)
|
|
1051
|
+
}
|
|
1052
|
+
)
|
|
1053
|
+
}
|
|
1054
|
+
),
|
|
1055
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1056
|
+
"button",
|
|
1057
|
+
{
|
|
1058
|
+
"data-testid": "install-prompt-skip-session",
|
|
1059
|
+
type: "button",
|
|
1060
|
+
onClick: actions.dismissSession,
|
|
1061
|
+
style: { ...skipLinkStyle, marginTop: 16 },
|
|
1062
|
+
children: copy.skip
|
|
1063
|
+
}
|
|
1064
|
+
),
|
|
1065
|
+
showPermanent && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1066
|
+
"button",
|
|
1067
|
+
{
|
|
1068
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1069
|
+
type: "button",
|
|
1070
|
+
onClick: actions.dismissPermanent,
|
|
1071
|
+
style: skipPermanentLinkStyle,
|
|
1072
|
+
children: copy.skipPermanent
|
|
1073
|
+
}
|
|
1074
|
+
)
|
|
1075
|
+
] });
|
|
1076
|
+
}
|
|
1077
|
+
function Step2({
|
|
1078
|
+
n,
|
|
1079
|
+
title,
|
|
1080
|
+
subtitle,
|
|
1081
|
+
visual
|
|
1082
|
+
}) {
|
|
1083
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1084
|
+
"div",
|
|
1085
|
+
{
|
|
1086
|
+
style: {
|
|
1087
|
+
display: "flex",
|
|
1088
|
+
alignItems: "flex-start",
|
|
1089
|
+
gap: 12,
|
|
1090
|
+
marginBottom: 16,
|
|
1091
|
+
textAlign: "left"
|
|
1092
|
+
},
|
|
1093
|
+
children: [
|
|
1094
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1095
|
+
"div",
|
|
1096
|
+
{
|
|
1097
|
+
style: {
|
|
1098
|
+
width: 32,
|
|
1099
|
+
height: 32,
|
|
1100
|
+
borderRadius: 10,
|
|
1101
|
+
background: "var(--hook-color-primary)",
|
|
1102
|
+
color: "#fff",
|
|
1103
|
+
display: "flex",
|
|
1104
|
+
alignItems: "center",
|
|
1105
|
+
justifyContent: "center",
|
|
1106
|
+
fontSize: 15,
|
|
1107
|
+
fontWeight: 700,
|
|
1108
|
+
flexShrink: 0
|
|
1109
|
+
},
|
|
1110
|
+
children: n
|
|
1111
|
+
}
|
|
1112
|
+
),
|
|
1113
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { style: { flex: 1 }, children: [
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { style: { margin: 0, fontSize: 15, fontWeight: 500, color: "#111", lineHeight: 1.3 }, children: title }),
|
|
1115
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { style: { margin: "4px 0 0 0", fontSize: 13, color: "#777" }, children: subtitle }),
|
|
1116
|
+
visual
|
|
1117
|
+
] })
|
|
1118
|
+
]
|
|
1119
|
+
}
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
// src/components/InstallGate/variants/IOSOtherVariant.tsx
|
|
1124
|
+
var import_react6 = require("react");
|
|
1125
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1126
|
+
function IOSOtherVariant({
|
|
1127
|
+
state,
|
|
1128
|
+
actions
|
|
1129
|
+
}) {
|
|
1130
|
+
const copy = INSTALL_COPY.iosOther;
|
|
1131
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1132
|
+
const [copied, setCopied] = (0, import_react6.useState)(false);
|
|
1133
|
+
const handleCopy = async () => {
|
|
1134
|
+
await actions.copyLink();
|
|
1135
|
+
setCopied(true);
|
|
1136
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1137
|
+
};
|
|
1138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1140
|
+
"button",
|
|
1141
|
+
{
|
|
1142
|
+
"data-testid": "install-prompt-cta-ios-other-primary",
|
|
1143
|
+
type: "button",
|
|
1144
|
+
onClick: actions.redirectToSafari,
|
|
1145
|
+
style: primaryButtonStyle,
|
|
1146
|
+
children: copy.ctaPrimary
|
|
1147
|
+
}
|
|
1148
|
+
),
|
|
1149
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1150
|
+
"button",
|
|
1151
|
+
{
|
|
1152
|
+
"data-testid": "install-prompt-cta-ios-other-secondary",
|
|
1153
|
+
type: "button",
|
|
1154
|
+
onClick: () => void handleCopy(),
|
|
1155
|
+
style: secondaryButtonStyle,
|
|
1156
|
+
children: copied ? copy.copiedToast : copy.ctaSecondary
|
|
1157
|
+
}
|
|
1158
|
+
),
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1160
|
+
"button",
|
|
1161
|
+
{
|
|
1162
|
+
"data-testid": "install-prompt-skip-session",
|
|
1163
|
+
type: "button",
|
|
1164
|
+
onClick: actions.dismissSession,
|
|
1165
|
+
style: skipLinkStyle,
|
|
1166
|
+
children: copy.skip
|
|
1167
|
+
}
|
|
1168
|
+
),
|
|
1169
|
+
showPermanent && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1170
|
+
"button",
|
|
1171
|
+
{
|
|
1172
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1173
|
+
type: "button",
|
|
1174
|
+
onClick: actions.dismissPermanent,
|
|
1175
|
+
style: skipPermanentLinkStyle,
|
|
1176
|
+
children: copy.skipPermanent
|
|
1177
|
+
}
|
|
1178
|
+
)
|
|
1179
|
+
] });
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/components/InstallGate/variants/InAppBrowserVariant.tsx
|
|
1183
|
+
var import_react7 = require("react");
|
|
1184
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1185
|
+
function InAppBrowserVariant({
|
|
1186
|
+
state,
|
|
1187
|
+
actions
|
|
1188
|
+
}) {
|
|
1189
|
+
const app = state.inAppApp ?? "other";
|
|
1190
|
+
const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
|
|
1191
|
+
const copy = INSTALL_COPY.inApp;
|
|
1192
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1193
|
+
const [copied, setCopied] = (0, import_react7.useState)(false);
|
|
1194
|
+
const handleCopy = async () => {
|
|
1195
|
+
await actions.copyLink();
|
|
1196
|
+
setCopied(true);
|
|
1197
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1198
|
+
};
|
|
1199
|
+
const DotsIcon = app === "facebook" || app === "telegram" ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;
|
|
1200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(InstallSplash, { title: appCopy.title, children: [
|
|
1201
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Step3, { n: 1, icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DotsIcon, { size: 20 }), children: appCopy.step1 }),
|
|
1202
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Step3, { n: 2, icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ExternalLinkIcon, { size: 18 }), children: appCopy.step2 }),
|
|
1203
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1204
|
+
"button",
|
|
1205
|
+
{
|
|
1206
|
+
"data-testid": "install-prompt-cta-inapp-copy",
|
|
1207
|
+
type: "button",
|
|
1208
|
+
onClick: () => void handleCopy(),
|
|
1209
|
+
style: { ...primaryButtonStyle, marginTop: 8 },
|
|
1210
|
+
children: copied ? copy.copiedToast : copy.copy
|
|
1211
|
+
}
|
|
1212
|
+
),
|
|
1213
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1214
|
+
"button",
|
|
1215
|
+
{
|
|
1216
|
+
"data-testid": "install-prompt-skip-session",
|
|
1217
|
+
type: "button",
|
|
1218
|
+
onClick: actions.dismissSession,
|
|
1219
|
+
style: skipLinkStyle,
|
|
1220
|
+
children: copy.skip
|
|
1221
|
+
}
|
|
1222
|
+
),
|
|
1223
|
+
showPermanent && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1224
|
+
"button",
|
|
1225
|
+
{
|
|
1226
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1227
|
+
type: "button",
|
|
1228
|
+
onClick: actions.dismissPermanent,
|
|
1229
|
+
style: skipPermanentLinkStyle,
|
|
1230
|
+
children: copy.skipPermanent
|
|
1231
|
+
}
|
|
1232
|
+
)
|
|
1233
|
+
] });
|
|
1234
|
+
}
|
|
1235
|
+
function Step3({
|
|
1236
|
+
n,
|
|
1237
|
+
icon,
|
|
1238
|
+
children
|
|
1239
|
+
}) {
|
|
1240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1241
|
+
"div",
|
|
1242
|
+
{
|
|
1243
|
+
style: {
|
|
1244
|
+
display: "flex",
|
|
1245
|
+
alignItems: "center",
|
|
1246
|
+
gap: 12,
|
|
1247
|
+
padding: "12px 14px",
|
|
1248
|
+
background: "#f5f5f7",
|
|
1249
|
+
borderRadius: 12,
|
|
1250
|
+
marginBottom: 10,
|
|
1251
|
+
textAlign: "left"
|
|
1252
|
+
},
|
|
1253
|
+
children: [
|
|
1254
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1255
|
+
"div",
|
|
1256
|
+
{
|
|
1257
|
+
style: {
|
|
1258
|
+
width: 28,
|
|
1259
|
+
height: 28,
|
|
1260
|
+
borderRadius: "50%",
|
|
1261
|
+
background: "var(--hook-color-primary)",
|
|
1262
|
+
color: "#fff",
|
|
1263
|
+
display: "flex",
|
|
1264
|
+
alignItems: "center",
|
|
1265
|
+
justifyContent: "center",
|
|
1266
|
+
fontSize: 14,
|
|
1267
|
+
fontWeight: 700,
|
|
1268
|
+
flexShrink: 0
|
|
1269
|
+
},
|
|
1270
|
+
children: n
|
|
1271
|
+
}
|
|
1272
|
+
),
|
|
1273
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { flex: 1, fontSize: 14, color: "#333" }, children }),
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
1275
|
+
]
|
|
1276
|
+
}
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// src/components/InstallGate/variants/DesktopVariant.tsx
|
|
1281
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1282
|
+
function DesktopVariant({
|
|
1283
|
+
state,
|
|
1284
|
+
actions
|
|
1285
|
+
}) {
|
|
1286
|
+
const { name, theme } = useTemplateConfig();
|
|
1287
|
+
const copy = INSTALL_COPY.desktop;
|
|
1288
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
1289
|
+
if (!state.isInstallable) return null;
|
|
1290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1291
|
+
"div",
|
|
1292
|
+
{
|
|
1293
|
+
role: "complementary",
|
|
1294
|
+
"aria-label": copy.title,
|
|
1295
|
+
style: bannerStyle,
|
|
1296
|
+
children: [
|
|
1297
|
+
iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1298
|
+
"img",
|
|
1299
|
+
{
|
|
1300
|
+
src: iconUrl,
|
|
1301
|
+
alt: "",
|
|
1302
|
+
style: { width: 40, height: 40, borderRadius: 10, objectFit: "cover", flexShrink: 0 }
|
|
1303
|
+
}
|
|
1304
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1305
|
+
"div",
|
|
1306
|
+
{
|
|
1307
|
+
style: {
|
|
1308
|
+
width: 40,
|
|
1309
|
+
height: 40,
|
|
1310
|
+
borderRadius: 10,
|
|
1311
|
+
background: "var(--hook-color-primary)",
|
|
1312
|
+
color: "#fff",
|
|
1313
|
+
display: "flex",
|
|
1314
|
+
alignItems: "center",
|
|
1315
|
+
justifyContent: "center",
|
|
1316
|
+
fontSize: 18,
|
|
1317
|
+
fontWeight: 700,
|
|
1318
|
+
flexShrink: 0
|
|
1319
|
+
},
|
|
1320
|
+
children: name.charAt(0).toUpperCase()
|
|
1321
|
+
}
|
|
1322
|
+
),
|
|
1323
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 14, fontWeight: 600, color: "#111" }, children: copy.title }),
|
|
1325
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontSize: 12, color: "#666" }, children: copy.subtitle })
|
|
1326
|
+
] }),
|
|
1327
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1328
|
+
"button",
|
|
1329
|
+
{
|
|
1330
|
+
"data-testid": "install-prompt-cta-desktop",
|
|
1331
|
+
type: "button",
|
|
1332
|
+
onClick: () => void actions.promptInstall(),
|
|
1333
|
+
style: {
|
|
1334
|
+
padding: "8px 14px",
|
|
1335
|
+
background: "var(--hook-color-primary)",
|
|
1336
|
+
color: "#fff",
|
|
1337
|
+
border: "none",
|
|
1338
|
+
borderRadius: 999,
|
|
1339
|
+
fontSize: 13,
|
|
1340
|
+
fontWeight: 600,
|
|
1341
|
+
cursor: "pointer",
|
|
1342
|
+
display: "inline-flex",
|
|
1343
|
+
alignItems: "center",
|
|
1344
|
+
gap: 6,
|
|
1345
|
+
flexShrink: 0
|
|
1346
|
+
},
|
|
1347
|
+
children: [
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DownloadIcon, { size: 14 }),
|
|
1349
|
+
copy.cta
|
|
1350
|
+
]
|
|
1351
|
+
}
|
|
1352
|
+
),
|
|
1353
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1354
|
+
"button",
|
|
1355
|
+
{
|
|
1356
|
+
"data-testid": "install-prompt-desktop-close",
|
|
1357
|
+
type: "button",
|
|
1358
|
+
onClick: actions.dismissPermanent,
|
|
1359
|
+
"aria-label": copy.close,
|
|
1360
|
+
style: {
|
|
1361
|
+
background: "transparent",
|
|
1362
|
+
border: "none",
|
|
1363
|
+
cursor: "pointer",
|
|
1364
|
+
color: "#888",
|
|
1365
|
+
padding: 4,
|
|
1366
|
+
flexShrink: 0
|
|
1367
|
+
},
|
|
1368
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(XIcon, { size: 16 })
|
|
1369
|
+
}
|
|
1370
|
+
)
|
|
1371
|
+
]
|
|
1372
|
+
}
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
var bannerStyle = {
|
|
1376
|
+
position: "fixed",
|
|
1377
|
+
bottom: 24,
|
|
1378
|
+
right: 24,
|
|
1379
|
+
zIndex: 1e4,
|
|
1380
|
+
display: "flex",
|
|
1381
|
+
alignItems: "center",
|
|
1382
|
+
gap: 12,
|
|
1383
|
+
padding: "12px 16px",
|
|
1384
|
+
background: "#fff",
|
|
1385
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
1386
|
+
borderRadius: 16,
|
|
1387
|
+
boxShadow: "0 10px 30px rgba(0,0,0,0.12)",
|
|
1388
|
+
maxWidth: 400
|
|
1389
|
+
};
|
|
1390
|
+
|
|
1391
|
+
// src/components/InstallGate/InstallGate.tsx
|
|
1392
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1393
|
+
function InstallGate({ children }) {
|
|
1394
|
+
const { slug, features_enabled } = useTemplateConfig();
|
|
1395
|
+
const enabled = features_enabled.includes("install_prompt");
|
|
1396
|
+
const installState = useInstallPrompt(slug);
|
|
1397
|
+
const shouldBlock = enabled && shouldBlockInstall(installState);
|
|
1398
|
+
const trackedRef = (0, import_react8.useRef)(null);
|
|
1399
|
+
(0, import_react8.useEffect)(() => {
|
|
1400
|
+
if (!shouldBlock) return;
|
|
1401
|
+
if (typeof window === "undefined") return;
|
|
1402
|
+
const variantKey = `${slug}:${installState.variant}`;
|
|
1403
|
+
if (trackedRef.current === variantKey) return;
|
|
1404
|
+
trackedRef.current = variantKey;
|
|
1405
|
+
window.posthog?.capture?.("pwa_install_splash_shown", {
|
|
1406
|
+
slug,
|
|
1407
|
+
platform: installState.platform,
|
|
1408
|
+
browser: installState.iosBrowser ?? installState.androidBrowser ?? null,
|
|
1409
|
+
in_app_app: installState.inAppApp,
|
|
1410
|
+
variant: installState.variant
|
|
1411
|
+
});
|
|
1412
|
+
}, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);
|
|
1413
|
+
if (!enabled) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
|
|
1414
|
+
if (installState.isInstalled) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
|
|
1415
|
+
if (installState.variant === "desktop") {
|
|
1416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1417
|
+
children,
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DesktopVariant, { state: installState, actions: installState })
|
|
1419
|
+
] });
|
|
1420
|
+
}
|
|
1421
|
+
if (!shouldBlock) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
|
|
1422
|
+
switch (installState.variant) {
|
|
1423
|
+
case "android-native":
|
|
1424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AndroidNativeVariant, { state: installState, actions: installState });
|
|
1425
|
+
case "android-manual":
|
|
1426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AndroidManualVariant, { state: installState, actions: installState });
|
|
1427
|
+
case "ios-safari":
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IOSafariVariant, { state: installState, actions: installState });
|
|
1429
|
+
case "ios-other":
|
|
1430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IOSOtherVariant, { state: installState, actions: installState });
|
|
1431
|
+
case "in-app":
|
|
1432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InAppBrowserVariant, { state: installState, actions: installState });
|
|
1433
|
+
case "none":
|
|
1434
|
+
default:
|
|
1435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// src/defaults/ErrorBoundary.tsx
|
|
1440
|
+
var import_react9 = require("react");
|
|
1441
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1442
|
+
var ErrorBoundary = class extends import_react9.Component {
|
|
217
1443
|
state = { error: null };
|
|
218
1444
|
static getDerivedStateFromError(error) {
|
|
219
1445
|
return { error };
|
|
@@ -223,17 +1449,17 @@ var ErrorBoundary = class extends import_react5.Component {
|
|
|
223
1449
|
}
|
|
224
1450
|
render() {
|
|
225
1451
|
if (this.state.error) {
|
|
226
|
-
return this.props.fallback ?? /* @__PURE__ */ (0,
|
|
227
|
-
/* @__PURE__ */ (0,
|
|
228
|
-
/* @__PURE__ */ (0,
|
|
1452
|
+
return this.props.fallback ?? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
1453
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { children: "Algo deu errado" }),
|
|
1454
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
229
1455
|
] });
|
|
230
1456
|
}
|
|
231
|
-
return /* @__PURE__ */ (0,
|
|
1457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: this.props.children });
|
|
232
1458
|
}
|
|
233
1459
|
};
|
|
234
1460
|
|
|
235
1461
|
// src/hooks/useLoginForm.ts
|
|
236
|
-
var
|
|
1462
|
+
var import_react10 = require("react");
|
|
237
1463
|
var import_sdk5 = require("@hook-sdk/sdk");
|
|
238
1464
|
|
|
239
1465
|
// src/errors.ts
|
|
@@ -270,22 +1496,22 @@ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
270
1496
|
var MIN_PASSWORD = 8;
|
|
271
1497
|
function useLoginForm() {
|
|
272
1498
|
const { auth } = (0, import_sdk5.useHook)();
|
|
273
|
-
const [email, setEmail] = (0,
|
|
274
|
-
const [password, setPassword] = (0,
|
|
275
|
-
const [submitting, setSubmitting] = (0,
|
|
276
|
-
const [error, setError] = (0,
|
|
277
|
-
const emailError = (0,
|
|
1499
|
+
const [email, setEmail] = (0, import_react10.useState)("");
|
|
1500
|
+
const [password, setPassword] = (0, import_react10.useState)("");
|
|
1501
|
+
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
1502
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
1503
|
+
const emailError = (0, import_react10.useMemo)(() => {
|
|
278
1504
|
if (email.length === 0) return null;
|
|
279
1505
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
280
1506
|
return null;
|
|
281
1507
|
}, [email]);
|
|
282
|
-
const passwordError = (0,
|
|
1508
|
+
const passwordError = (0, import_react10.useMemo)(() => {
|
|
283
1509
|
if (password.length === 0) return null;
|
|
284
1510
|
if (password.length < MIN_PASSWORD) return `M\xEDnimo de ${MIN_PASSWORD} caracteres.`;
|
|
285
1511
|
return null;
|
|
286
1512
|
}, [password]);
|
|
287
1513
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
|
|
288
|
-
const submit = (0,
|
|
1514
|
+
const submit = (0, import_react10.useCallback)(async () => {
|
|
289
1515
|
if (!canSubmit) return false;
|
|
290
1516
|
setSubmitting(true);
|
|
291
1517
|
setError(null);
|
|
@@ -315,13 +1541,13 @@ function useLoginForm() {
|
|
|
315
1541
|
}
|
|
316
1542
|
|
|
317
1543
|
// src/internal/GoogleSignInButton.tsx
|
|
318
|
-
var
|
|
1544
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
319
1545
|
function GoogleSignInButton({
|
|
320
1546
|
onClick,
|
|
321
1547
|
testId = "oauth-google",
|
|
322
1548
|
label = "Continuar com Google"
|
|
323
1549
|
}) {
|
|
324
|
-
return /* @__PURE__ */ (0,
|
|
1550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
325
1551
|
"button",
|
|
326
1552
|
{
|
|
327
1553
|
"data-testid": testId,
|
|
@@ -344,36 +1570,36 @@ function GoogleSignInButton({
|
|
|
344
1570
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
345
1571
|
},
|
|
346
1572
|
children: [
|
|
347
|
-
/* @__PURE__ */ (0,
|
|
1573
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(GoogleGlyph, {}),
|
|
348
1574
|
label
|
|
349
1575
|
]
|
|
350
1576
|
}
|
|
351
1577
|
);
|
|
352
1578
|
}
|
|
353
1579
|
function GoogleGlyph() {
|
|
354
|
-
return /* @__PURE__ */ (0,
|
|
355
|
-
/* @__PURE__ */ (0,
|
|
1580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
|
|
1581
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
356
1582
|
"path",
|
|
357
1583
|
{
|
|
358
1584
|
d: "M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.874 2.684-6.615z",
|
|
359
1585
|
fill: "#4285F4"
|
|
360
1586
|
}
|
|
361
1587
|
),
|
|
362
|
-
/* @__PURE__ */ (0,
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
363
1589
|
"path",
|
|
364
1590
|
{
|
|
365
1591
|
d: "M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z",
|
|
366
1592
|
fill: "#34A853"
|
|
367
1593
|
}
|
|
368
1594
|
),
|
|
369
|
-
/* @__PURE__ */ (0,
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
370
1596
|
"path",
|
|
371
1597
|
{
|
|
372
1598
|
d: "M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z",
|
|
373
1599
|
fill: "#FBBC05"
|
|
374
1600
|
}
|
|
375
1601
|
),
|
|
376
|
-
/* @__PURE__ */ (0,
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
377
1603
|
"path",
|
|
378
1604
|
{
|
|
379
1605
|
d: "M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z",
|
|
@@ -384,8 +1610,8 @@ function GoogleGlyph() {
|
|
|
384
1610
|
}
|
|
385
1611
|
|
|
386
1612
|
// src/internal/OAuthErrorBanner.tsx
|
|
387
|
-
var
|
|
388
|
-
var
|
|
1613
|
+
var import_react11 = require("react");
|
|
1614
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
389
1615
|
var ERROR_MESSAGES = {
|
|
390
1616
|
invalid_state: "Sess\xE3o expirou, tente de novo.",
|
|
391
1617
|
access_denied: "Voc\xEA cancelou o login com Google.",
|
|
@@ -405,13 +1631,13 @@ function stripErrorFromUrl() {
|
|
|
405
1631
|
window.history.replaceState({}, "", url.toString());
|
|
406
1632
|
}
|
|
407
1633
|
function OAuthErrorBanner() {
|
|
408
|
-
const [code, setCode] = (0,
|
|
409
|
-
(0,
|
|
1634
|
+
const [code, setCode] = (0, import_react11.useState)(() => readErrorCode());
|
|
1635
|
+
(0, import_react11.useEffect)(() => {
|
|
410
1636
|
if (code !== null) stripErrorFromUrl();
|
|
411
1637
|
}, [code]);
|
|
412
1638
|
if (!code) return null;
|
|
413
1639
|
const message = ERROR_MESSAGES[code] ?? "N\xE3o conseguimos conectar ao Google. Tente de novo.";
|
|
414
|
-
return /* @__PURE__ */ (0,
|
|
1640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
415
1641
|
"div",
|
|
416
1642
|
{
|
|
417
1643
|
role: "alert",
|
|
@@ -426,7 +1652,7 @@ function OAuthErrorBanner() {
|
|
|
426
1652
|
},
|
|
427
1653
|
children: [
|
|
428
1654
|
message,
|
|
429
|
-
/* @__PURE__ */ (0,
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
430
1656
|
"button",
|
|
431
1657
|
{
|
|
432
1658
|
type: "button",
|
|
@@ -451,16 +1677,16 @@ function OAuthErrorBanner() {
|
|
|
451
1677
|
}
|
|
452
1678
|
|
|
453
1679
|
// src/defaults/DefaultLoginScreen.tsx
|
|
454
|
-
var
|
|
1680
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
455
1681
|
function DefaultLoginScreen({ onNavigate }) {
|
|
456
1682
|
const { name } = useTemplateConfig();
|
|
457
1683
|
const f = useLoginForm();
|
|
458
|
-
return /* @__PURE__ */ (0,
|
|
459
|
-
/* @__PURE__ */ (0,
|
|
460
|
-
/* @__PURE__ */ (0,
|
|
461
|
-
/* @__PURE__ */ (0,
|
|
462
|
-
/* @__PURE__ */ (0,
|
|
463
|
-
/* @__PURE__ */ (0,
|
|
1684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1685
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Entre na sua conta" }),
|
|
1687
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(OAuthErrorBanner, {}),
|
|
1688
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "login-oauth-google" }),
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
464
1690
|
"div",
|
|
465
1691
|
{
|
|
466
1692
|
"aria-hidden": "true",
|
|
@@ -473,19 +1699,19 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
473
1699
|
fontSize: 12
|
|
474
1700
|
},
|
|
475
1701
|
children: [
|
|
476
|
-
/* @__PURE__ */ (0,
|
|
1702
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
477
1703
|
"ou",
|
|
478
|
-
/* @__PURE__ */ (0,
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
479
1705
|
]
|
|
480
1706
|
}
|
|
481
1707
|
),
|
|
482
|
-
/* @__PURE__ */ (0,
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("form", { onSubmit: (e) => {
|
|
483
1709
|
e.preventDefault();
|
|
484
1710
|
void f.submit();
|
|
485
1711
|
}, children: [
|
|
486
|
-
/* @__PURE__ */ (0,
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
487
1713
|
"E-mail",
|
|
488
|
-
/* @__PURE__ */ (0,
|
|
1714
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
489
1715
|
"input",
|
|
490
1716
|
{
|
|
491
1717
|
"data-testid": "login-email",
|
|
@@ -495,11 +1721,11 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
495
1721
|
style: { display: "block", width: "100%" }
|
|
496
1722
|
}
|
|
497
1723
|
),
|
|
498
|
-
f.emailError && /* @__PURE__ */ (0,
|
|
1724
|
+
f.emailError && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("small", { style: { color: "#c00" }, children: f.emailError })
|
|
499
1725
|
] }),
|
|
500
|
-
/* @__PURE__ */ (0,
|
|
1726
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
501
1727
|
"Senha",
|
|
502
|
-
/* @__PURE__ */ (0,
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
503
1729
|
"input",
|
|
504
1730
|
{
|
|
505
1731
|
"data-testid": "login-password",
|
|
@@ -509,10 +1735,10 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
509
1735
|
style: { display: "block", width: "100%" }
|
|
510
1736
|
}
|
|
511
1737
|
),
|
|
512
|
-
f.passwordError && /* @__PURE__ */ (0,
|
|
1738
|
+
f.passwordError && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
513
1739
|
] }),
|
|
514
|
-
f.error && /* @__PURE__ */ (0,
|
|
515
|
-
/* @__PURE__ */ (0,
|
|
1740
|
+
f.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1741
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
516
1742
|
"button",
|
|
517
1743
|
{
|
|
518
1744
|
"data-testid": "login-submit",
|
|
@@ -531,42 +1757,42 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
531
1757
|
}
|
|
532
1758
|
)
|
|
533
1759
|
] }),
|
|
534
|
-
/* @__PURE__ */ (0,
|
|
535
|
-
/* @__PURE__ */ (0,
|
|
536
|
-
/* @__PURE__ */ (0,
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { marginTop: 16, display: "flex", justifyContent: "space-between" }, children: [
|
|
1761
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { "data-testid": "login-goto-signup", type: "button", onClick: () => onNavigate("signup"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Criar conta" }),
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { "data-testid": "login-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Esqueci senha" })
|
|
537
1763
|
] })
|
|
538
1764
|
] });
|
|
539
1765
|
}
|
|
540
1766
|
|
|
541
1767
|
// src/hooks/useSignupForm.ts
|
|
542
|
-
var
|
|
1768
|
+
var import_react12 = require("react");
|
|
543
1769
|
var import_sdk6 = require("@hook-sdk/sdk");
|
|
544
1770
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
545
1771
|
var MIN_PASSWORD2 = 8;
|
|
546
1772
|
function useSignupForm() {
|
|
547
1773
|
const { auth } = (0, import_sdk6.useHook)();
|
|
548
|
-
const [name, setName] = (0,
|
|
549
|
-
const [email, setEmail] = (0,
|
|
550
|
-
const [password, setPassword] = (0,
|
|
551
|
-
const [submitting, setSubmitting] = (0,
|
|
552
|
-
const [error, setError] = (0,
|
|
553
|
-
const nameError = (0,
|
|
1774
|
+
const [name, setName] = (0, import_react12.useState)("");
|
|
1775
|
+
const [email, setEmail] = (0, import_react12.useState)("");
|
|
1776
|
+
const [password, setPassword] = (0, import_react12.useState)("");
|
|
1777
|
+
const [submitting, setSubmitting] = (0, import_react12.useState)(false);
|
|
1778
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1779
|
+
const nameError = (0, import_react12.useMemo)(() => {
|
|
554
1780
|
if (name.length === 0) return null;
|
|
555
1781
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
556
1782
|
return null;
|
|
557
1783
|
}, [name]);
|
|
558
|
-
const emailError = (0,
|
|
1784
|
+
const emailError = (0, import_react12.useMemo)(() => {
|
|
559
1785
|
if (email.length === 0) return null;
|
|
560
1786
|
if (!EMAIL_RE2.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
561
1787
|
return null;
|
|
562
1788
|
}, [email]);
|
|
563
|
-
const passwordError = (0,
|
|
1789
|
+
const passwordError = (0, import_react12.useMemo)(() => {
|
|
564
1790
|
if (password.length === 0) return null;
|
|
565
1791
|
if (password.length < MIN_PASSWORD2) return `M\xEDnimo de ${MIN_PASSWORD2} caracteres.`;
|
|
566
1792
|
return null;
|
|
567
1793
|
}, [password]);
|
|
568
1794
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
|
|
569
|
-
const submit = (0,
|
|
1795
|
+
const submit = (0, import_react12.useCallback)(async () => {
|
|
570
1796
|
if (!canSubmit) return false;
|
|
571
1797
|
setSubmitting(true);
|
|
572
1798
|
setError(null);
|
|
@@ -599,16 +1825,16 @@ function useSignupForm() {
|
|
|
599
1825
|
}
|
|
600
1826
|
|
|
601
1827
|
// src/defaults/DefaultSignupScreen.tsx
|
|
602
|
-
var
|
|
1828
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
603
1829
|
function DefaultSignupScreen({ onNavigate }) {
|
|
604
1830
|
const { name } = useTemplateConfig();
|
|
605
1831
|
const f = useSignupForm();
|
|
606
|
-
return /* @__PURE__ */ (0,
|
|
607
|
-
/* @__PURE__ */ (0,
|
|
608
|
-
/* @__PURE__ */ (0,
|
|
609
|
-
/* @__PURE__ */ (0,
|
|
610
|
-
/* @__PURE__ */ (0,
|
|
611
|
-
/* @__PURE__ */ (0,
|
|
1832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1833
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1834
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Criar sua conta" }),
|
|
1835
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(OAuthErrorBanner, {}),
|
|
1836
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "signup-oauth-google" }),
|
|
1837
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
612
1838
|
"div",
|
|
613
1839
|
{
|
|
614
1840
|
"aria-hidden": "true",
|
|
@@ -621,55 +1847,55 @@ function DefaultSignupScreen({ onNavigate }) {
|
|
|
621
1847
|
fontSize: 12
|
|
622
1848
|
},
|
|
623
1849
|
children: [
|
|
624
|
-
/* @__PURE__ */ (0,
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
625
1851
|
"ou",
|
|
626
|
-
/* @__PURE__ */ (0,
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
627
1853
|
]
|
|
628
1854
|
}
|
|
629
1855
|
),
|
|
630
|
-
/* @__PURE__ */ (0,
|
|
1856
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { onSubmit: (e) => {
|
|
631
1857
|
e.preventDefault();
|
|
632
1858
|
void f.submit();
|
|
633
1859
|
}, children: [
|
|
634
|
-
/* @__PURE__ */ (0,
|
|
1860
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
635
1861
|
"Nome",
|
|
636
|
-
/* @__PURE__ */ (0,
|
|
637
|
-
f.nameError && /* @__PURE__ */ (0,
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { "data-testid": "signup-name", value: f.name, onChange: (e) => f.setName(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1863
|
+
f.nameError && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("small", { style: { color: "#c00" }, children: f.nameError })
|
|
638
1864
|
] }),
|
|
639
|
-
/* @__PURE__ */ (0,
|
|
1865
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
640
1866
|
"E-mail",
|
|
641
|
-
/* @__PURE__ */ (0,
|
|
642
|
-
f.emailError && /* @__PURE__ */ (0,
|
|
1867
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { "data-testid": "signup-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1868
|
+
f.emailError && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("small", { style: { color: "#c00" }, children: f.emailError })
|
|
643
1869
|
] }),
|
|
644
|
-
/* @__PURE__ */ (0,
|
|
1870
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
645
1871
|
"Senha",
|
|
646
|
-
/* @__PURE__ */ (0,
|
|
647
|
-
f.passwordError && /* @__PURE__ */ (0,
|
|
1872
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("input", { "data-testid": "signup-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1873
|
+
f.passwordError && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
648
1874
|
] }),
|
|
649
|
-
f.error && /* @__PURE__ */ (0,
|
|
650
|
-
/* @__PURE__ */ (0,
|
|
1875
|
+
f.error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1876
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { "data-testid": "signup-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Criando..." : "Criar conta" })
|
|
651
1877
|
] }),
|
|
652
|
-
/* @__PURE__ */ (0,
|
|
1878
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { "data-testid": "signup-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "J\xE1 tem conta? Entre" }) })
|
|
653
1879
|
] });
|
|
654
1880
|
}
|
|
655
1881
|
|
|
656
1882
|
// src/hooks/useForgotForm.ts
|
|
657
|
-
var
|
|
1883
|
+
var import_react13 = require("react");
|
|
658
1884
|
var import_sdk7 = require("@hook-sdk/sdk");
|
|
659
1885
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
660
1886
|
function useForgotForm() {
|
|
661
1887
|
const { auth } = (0, import_sdk7.useHook)();
|
|
662
|
-
const [email, setEmail] = (0,
|
|
663
|
-
const [submitting, setSubmitting] = (0,
|
|
664
|
-
const [sent, setSent] = (0,
|
|
665
|
-
const [error, setError] = (0,
|
|
666
|
-
const emailError = (0,
|
|
1888
|
+
const [email, setEmail] = (0, import_react13.useState)("");
|
|
1889
|
+
const [submitting, setSubmitting] = (0, import_react13.useState)(false);
|
|
1890
|
+
const [sent, setSent] = (0, import_react13.useState)(false);
|
|
1891
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1892
|
+
const emailError = (0, import_react13.useMemo)(() => {
|
|
667
1893
|
if (email.length === 0) return null;
|
|
668
1894
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
669
1895
|
return null;
|
|
670
1896
|
}, [email]);
|
|
671
1897
|
const canSubmit = email.length > 0 && emailError === null && !submitting;
|
|
672
|
-
const submit = (0,
|
|
1898
|
+
const submit = (0, import_react13.useCallback)(async () => {
|
|
673
1899
|
if (!canSubmit) return false;
|
|
674
1900
|
setSubmitting(true);
|
|
675
1901
|
setError(null);
|
|
@@ -697,66 +1923,66 @@ function useForgotForm() {
|
|
|
697
1923
|
}
|
|
698
1924
|
|
|
699
1925
|
// src/defaults/DefaultForgotScreen.tsx
|
|
700
|
-
var
|
|
1926
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
701
1927
|
function DefaultForgotScreen({ onNavigate }) {
|
|
702
1928
|
const { name } = useTemplateConfig();
|
|
703
1929
|
const f = useForgotForm();
|
|
704
1930
|
if (f.sent) {
|
|
705
|
-
return /* @__PURE__ */ (0,
|
|
706
|
-
/* @__PURE__ */ (0,
|
|
707
|
-
/* @__PURE__ */ (0,
|
|
708
|
-
/* @__PURE__ */ (0,
|
|
1931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
1932
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { children: "Verifique seu e-mail" }),
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { opacity: 0.7 }, children: "Enviamos um link pra redefinir sua senha." }),
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { "data-testid": "forgot-back-login", type: "button", onClick: () => onNavigate("login"), children: "Voltar pro login" })
|
|
709
1935
|
] });
|
|
710
1936
|
}
|
|
711
|
-
return /* @__PURE__ */ (0,
|
|
712
|
-
/* @__PURE__ */ (0,
|
|
713
|
-
/* @__PURE__ */ (0,
|
|
714
|
-
/* @__PURE__ */ (0,
|
|
1937
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1939
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Redefinir senha" }),
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { onSubmit: (e) => {
|
|
715
1941
|
e.preventDefault();
|
|
716
1942
|
void f.submit();
|
|
717
1943
|
}, children: [
|
|
718
|
-
/* @__PURE__ */ (0,
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
719
1945
|
"E-mail",
|
|
720
|
-
/* @__PURE__ */ (0,
|
|
721
|
-
f.emailError && /* @__PURE__ */ (0,
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("input", { "data-testid": "forgot-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1947
|
+
f.emailError && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("small", { style: { color: "#c00" }, children: f.emailError })
|
|
722
1948
|
] }),
|
|
723
|
-
f.error && /* @__PURE__ */ (0,
|
|
724
|
-
/* @__PURE__ */ (0,
|
|
1949
|
+
f.error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1950
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { "data-testid": "forgot-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Enviando..." : "Enviar link" })
|
|
725
1951
|
] }),
|
|
726
|
-
/* @__PURE__ */ (0,
|
|
1952
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { "data-testid": "forgot-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Voltar pro login" }) })
|
|
727
1953
|
] });
|
|
728
1954
|
}
|
|
729
1955
|
|
|
730
1956
|
// src/hooks/useResetForm.ts
|
|
731
|
-
var
|
|
1957
|
+
var import_react14 = require("react");
|
|
732
1958
|
var import_sdk8 = require("@hook-sdk/sdk");
|
|
733
1959
|
var MIN_PASSWORD3 = 12;
|
|
734
1960
|
function useResetForm() {
|
|
735
1961
|
const { auth } = (0, import_sdk8.useHook)();
|
|
736
|
-
const [token, setToken] = (0,
|
|
737
|
-
const [password, setPassword] = (0,
|
|
738
|
-
const [confirm, setConfirm] = (0,
|
|
739
|
-
const [submitting, setSubmitting] = (0,
|
|
740
|
-
const [done, setDone] = (0,
|
|
741
|
-
const [error, setError] = (0,
|
|
742
|
-
(0,
|
|
1962
|
+
const [token, setToken] = (0, import_react14.useState)(null);
|
|
1963
|
+
const [password, setPassword] = (0, import_react14.useState)("");
|
|
1964
|
+
const [confirm, setConfirm] = (0, import_react14.useState)("");
|
|
1965
|
+
const [submitting, setSubmitting] = (0, import_react14.useState)(false);
|
|
1966
|
+
const [done, setDone] = (0, import_react14.useState)(false);
|
|
1967
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
1968
|
+
(0, import_react14.useEffect)(() => {
|
|
743
1969
|
if (typeof window === "undefined") return;
|
|
744
1970
|
const params = new URLSearchParams(window.location.search);
|
|
745
1971
|
const t = params.get("token");
|
|
746
1972
|
setToken(t && t.length > 0 ? t : null);
|
|
747
1973
|
}, []);
|
|
748
|
-
const passwordError = (0,
|
|
1974
|
+
const passwordError = (0, import_react14.useMemo)(() => {
|
|
749
1975
|
if (password.length === 0) return null;
|
|
750
1976
|
if (password.length < MIN_PASSWORD3) return `M\xEDnimo de ${MIN_PASSWORD3} caracteres.`;
|
|
751
1977
|
return null;
|
|
752
1978
|
}, [password]);
|
|
753
|
-
const confirmError = (0,
|
|
1979
|
+
const confirmError = (0, import_react14.useMemo)(() => {
|
|
754
1980
|
if (confirm.length === 0) return null;
|
|
755
1981
|
if (confirm !== password) return "Senhas n\xE3o coincidem.";
|
|
756
1982
|
return null;
|
|
757
1983
|
}, [confirm, password]);
|
|
758
1984
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && passwordError === null && confirmError === null && !submitting && !done;
|
|
759
|
-
const submit = (0,
|
|
1985
|
+
const submit = (0, import_react14.useCallback)(async () => {
|
|
760
1986
|
if (!canSubmit || token === null) return;
|
|
761
1987
|
setSubmitting(true);
|
|
762
1988
|
setError(null);
|
|
@@ -792,67 +2018,67 @@ function useResetForm() {
|
|
|
792
2018
|
}
|
|
793
2019
|
|
|
794
2020
|
// src/defaults/DefaultResetScreen.tsx
|
|
795
|
-
var
|
|
2021
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
796
2022
|
function DefaultResetScreen({ onNavigate }) {
|
|
797
2023
|
const { name } = useTemplateConfig();
|
|
798
2024
|
const f = useResetForm();
|
|
799
2025
|
if (f.done) {
|
|
800
|
-
return /* @__PURE__ */ (0,
|
|
801
|
-
/* @__PURE__ */ (0,
|
|
802
|
-
/* @__PURE__ */ (0,
|
|
803
|
-
/* @__PURE__ */ (0,
|
|
2026
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
2027
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { children: "Senha alterada" }),
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { opacity: 0.7 }, children: "Agora \xE9 s\xF3 fazer login com a nova senha." }),
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { "data-testid": "reset-back-login", type: "button", onClick: () => onNavigate("login"), children: "Ir pro login" })
|
|
804
2030
|
] });
|
|
805
2031
|
}
|
|
806
2032
|
if (f.token === null) {
|
|
807
|
-
return /* @__PURE__ */ (0,
|
|
808
|
-
/* @__PURE__ */ (0,
|
|
809
|
-
/* @__PURE__ */ (0,
|
|
810
|
-
/* @__PURE__ */ (0,
|
|
2033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { children: "Link inv\xE1lido" }),
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { opacity: 0.7 }, children: "Pe\xE7a um novo link de reset." }),
|
|
2036
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { "data-testid": "reset-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), children: "Pedir novo link" })
|
|
811
2037
|
] });
|
|
812
2038
|
}
|
|
813
|
-
return /* @__PURE__ */ (0,
|
|
814
|
-
/* @__PURE__ */ (0,
|
|
815
|
-
/* @__PURE__ */ (0,
|
|
816
|
-
/* @__PURE__ */ (0,
|
|
2039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
2040
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { style: { marginBottom: 8 }, children: name }),
|
|
2041
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Escolha uma nova senha" }),
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { onSubmit: (e) => {
|
|
817
2043
|
e.preventDefault();
|
|
818
2044
|
void f.submit();
|
|
819
2045
|
}, children: [
|
|
820
|
-
/* @__PURE__ */ (0,
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
821
2047
|
"Nova senha",
|
|
822
|
-
/* @__PURE__ */ (0,
|
|
823
|
-
f.passwordError && /* @__PURE__ */ (0,
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("input", { "data-testid": "reset-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
|
|
2049
|
+
f.passwordError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
824
2050
|
] }),
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
2051
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
826
2052
|
"Confirmar senha",
|
|
827
|
-
/* @__PURE__ */ (0,
|
|
828
|
-
f.confirmError && /* @__PURE__ */ (0,
|
|
2053
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("input", { "data-testid": "reset-confirm", type: "password", value: f.confirm, onChange: (e) => f.setConfirm(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
|
|
2054
|
+
f.confirmError && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("small", { style: { color: "#c00" }, children: f.confirmError })
|
|
829
2055
|
] }),
|
|
830
|
-
f.error && /* @__PURE__ */ (0,
|
|
831
|
-
/* @__PURE__ */ (0,
|
|
2056
|
+
f.error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
2057
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { "data-testid": "reset-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Alterando..." : "Alterar senha" })
|
|
832
2058
|
] })
|
|
833
2059
|
] });
|
|
834
2060
|
}
|
|
835
2061
|
|
|
836
2062
|
// src/defaults/DefaultPaywall.tsx
|
|
837
|
-
var
|
|
838
|
-
var
|
|
2063
|
+
var import_react15 = require("react");
|
|
2064
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
839
2065
|
function DefaultPaywall() {
|
|
840
2066
|
const config = useTemplateConfig();
|
|
841
2067
|
const { checkout, opening, error } = usePaywallState();
|
|
842
2068
|
const p = config.subscription.paywall_config;
|
|
843
|
-
const [cpf, setCpf] = (0,
|
|
2069
|
+
const [cpf, setCpf] = (0, import_react15.useState)("");
|
|
844
2070
|
const cpfDigits = cpf.replace(/\D/g, "");
|
|
845
2071
|
const canCheckout = cpfDigits.length === 11 && !opening;
|
|
846
|
-
return /* @__PURE__ */ (0,
|
|
847
|
-
/* @__PURE__ */ (0,
|
|
848
|
-
p.subtitle && /* @__PURE__ */ (0,
|
|
849
|
-
/* @__PURE__ */ (0,
|
|
850
|
-
/* @__PURE__ */ (0,
|
|
851
|
-
/* @__PURE__ */ (0,
|
|
2072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
|
|
2073
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { style: { marginBottom: 8 }, children: p.title }),
|
|
2074
|
+
p.subtitle && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", marginBottom: 24 }, children: p.benefits.map((b) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: b })
|
|
852
2078
|
] }, b)) }),
|
|
853
|
-
/* @__PURE__ */ (0,
|
|
854
|
-
/* @__PURE__ */ (0,
|
|
855
|
-
/* @__PURE__ */ (0,
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { textAlign: "left", marginBottom: 16 }, children: [
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { style: { display: "block", fontSize: 14, opacity: 0.7, marginBottom: 4 }, children: "Seu CPF (pra emiss\xE3o de recibo)" }),
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
856
2082
|
"input",
|
|
857
2083
|
{
|
|
858
2084
|
"data-testid": "paywall-cpf",
|
|
@@ -865,8 +2091,8 @@ function DefaultPaywall() {
|
|
|
865
2091
|
}
|
|
866
2092
|
)
|
|
867
2093
|
] }),
|
|
868
|
-
error && /* @__PURE__ */ (0,
|
|
869
|
-
/* @__PURE__ */ (0,
|
|
2094
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: error.message }),
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
870
2096
|
"button",
|
|
871
2097
|
{
|
|
872
2098
|
"data-testid": "paywall-cta",
|
|
@@ -887,21 +2113,21 @@ function DefaultPaywall() {
|
|
|
887
2113
|
children: opening ? "Abrindo..." : p.cta
|
|
888
2114
|
}
|
|
889
2115
|
),
|
|
890
|
-
p.priceHint && /* @__PURE__ */ (0,
|
|
891
|
-
p.footerNote && /* @__PURE__ */ (0,
|
|
2116
|
+
p.priceHint && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { opacity: 0.6, marginTop: 12 }, children: p.priceHint }),
|
|
2117
|
+
p.footerNote && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { opacity: 0.5, marginTop: 16, fontSize: 12 }, children: p.footerNote })
|
|
892
2118
|
] });
|
|
893
2119
|
}
|
|
894
2120
|
|
|
895
2121
|
// src/AppRoot.tsx
|
|
896
|
-
var
|
|
2122
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
897
2123
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
898
2124
|
function PaymentReturnHandler({ children }) {
|
|
899
2125
|
const { subscription } = (0, import_sdk9.useHook)();
|
|
900
|
-
const subRef = (0,
|
|
2126
|
+
const subRef = (0, import_react16.useRef)(subscription);
|
|
901
2127
|
subRef.current = subscription;
|
|
902
|
-
const runIdRef = (0,
|
|
903
|
-
const [state, setState] = (0,
|
|
904
|
-
const runPoll = (0,
|
|
2128
|
+
const runIdRef = (0, import_react16.useRef)(0);
|
|
2129
|
+
const [state, setState] = (0, import_react16.useState)("idle");
|
|
2130
|
+
const runPoll = (0, import_react16.useCallback)(() => {
|
|
905
2131
|
const runId = ++runIdRef.current;
|
|
906
2132
|
setState("confirming");
|
|
907
2133
|
let attempts = 0;
|
|
@@ -930,7 +2156,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
930
2156
|
};
|
|
931
2157
|
void tick();
|
|
932
2158
|
}, []);
|
|
933
|
-
(0,
|
|
2159
|
+
(0, import_react16.useEffect)(() => {
|
|
934
2160
|
if (typeof window === "undefined") return;
|
|
935
2161
|
const url = new URL(window.location.href);
|
|
936
2162
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -940,20 +2166,20 @@ function PaymentReturnHandler({ children }) {
|
|
|
940
2166
|
};
|
|
941
2167
|
}, [runPoll]);
|
|
942
2168
|
if (state === "confirming") {
|
|
943
|
-
return /* @__PURE__ */ (0,
|
|
2169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
944
2170
|
"div",
|
|
945
2171
|
{
|
|
946
2172
|
role: "status",
|
|
947
2173
|
"aria-live": "polite",
|
|
948
|
-
style:
|
|
2174
|
+
style: overlayStyle2,
|
|
949
2175
|
children: "Confirmando pagamento\u2026"
|
|
950
2176
|
}
|
|
951
2177
|
);
|
|
952
2178
|
}
|
|
953
2179
|
if (state === "waiting") {
|
|
954
|
-
return /* @__PURE__ */ (0,
|
|
955
|
-
/* @__PURE__ */ (0,
|
|
956
|
-
/* @__PURE__ */ (0,
|
|
2180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
957
2183
|
"button",
|
|
958
2184
|
{
|
|
959
2185
|
type: "button",
|
|
@@ -964,9 +2190,9 @@ function PaymentReturnHandler({ children }) {
|
|
|
964
2190
|
)
|
|
965
2191
|
] }) });
|
|
966
2192
|
}
|
|
967
|
-
return /* @__PURE__ */ (0,
|
|
2193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children });
|
|
968
2194
|
}
|
|
969
|
-
var
|
|
2195
|
+
var overlayStyle2 = {
|
|
970
2196
|
position: "fixed",
|
|
971
2197
|
inset: 0,
|
|
972
2198
|
display: "flex",
|
|
@@ -997,14 +2223,14 @@ function AppRoot({
|
|
|
997
2223
|
Reset = DefaultResetScreen,
|
|
998
2224
|
Paywall = DefaultPaywall
|
|
999
2225
|
}) {
|
|
1000
|
-
return /* @__PURE__ */ (0,
|
|
2226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentReturnHandler, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TemplateConfigProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(InstallGate, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PersistedKeysPrefetch, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(SubscriptionGate, { Paywall, children: [
|
|
1001
2227
|
children,
|
|
1002
|
-
/* @__PURE__ */ (0,
|
|
1003
|
-
] }) }) }) }) }) }) });
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PushPrompt, {})
|
|
2229
|
+
] }) }) }) }) }) }) }) });
|
|
1004
2230
|
}
|
|
1005
2231
|
|
|
1006
2232
|
// src/hooks/usePush.ts
|
|
1007
|
-
var
|
|
2233
|
+
var import_react17 = require("react");
|
|
1008
2234
|
var import_sdk10 = require("@hook-sdk/sdk");
|
|
1009
2235
|
function detectIosNeedsInstall() {
|
|
1010
2236
|
if (typeof navigator === "undefined" || typeof window === "undefined") return false;
|
|
@@ -1032,11 +2258,11 @@ function deriveState(push) {
|
|
|
1032
2258
|
}
|
|
1033
2259
|
function usePush() {
|
|
1034
2260
|
const { push } = (0, import_sdk10.useHook)();
|
|
1035
|
-
const [state, setState] = (0,
|
|
1036
|
-
(0,
|
|
2261
|
+
const [state, setState] = (0, import_react17.useState)(() => deriveState(push));
|
|
2262
|
+
(0, import_react17.useEffect)(() => {
|
|
1037
2263
|
setState(deriveState(push));
|
|
1038
2264
|
}, [push]);
|
|
1039
|
-
const subscribe = (0,
|
|
2265
|
+
const subscribe = (0, import_react17.useCallback)(async () => {
|
|
1040
2266
|
try {
|
|
1041
2267
|
await push.subscribe();
|
|
1042
2268
|
setState({ kind: "subscribed" });
|
|
@@ -1048,7 +2274,7 @@ function usePush() {
|
|
|
1048
2274
|
throw e;
|
|
1049
2275
|
}
|
|
1050
2276
|
}, [push]);
|
|
1051
|
-
const unsubscribe = (0,
|
|
2277
|
+
const unsubscribe = (0, import_react17.useCallback)(async () => {
|
|
1052
2278
|
try {
|
|
1053
2279
|
await push.unsubscribe();
|
|
1054
2280
|
setState({ kind: "prompt" });
|
|
@@ -1061,31 +2287,31 @@ function usePush() {
|
|
|
1061
2287
|
}
|
|
1062
2288
|
|
|
1063
2289
|
// src/components/PushPrompt.tsx
|
|
1064
|
-
var
|
|
2290
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1065
2291
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
1066
2292
|
const { state, subscribe } = usePush();
|
|
1067
2293
|
if (state.kind === "subscribed") return null;
|
|
1068
2294
|
if (state.kind === "ios_needs_install") {
|
|
1069
|
-
return /* @__PURE__ */ (0,
|
|
1070
|
-
/* @__PURE__ */ (0,
|
|
1071
|
-
/* @__PURE__ */ (0,
|
|
1072
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0,
|
|
2295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: texts.iosInstallTitle }),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { children: texts.iosInstallBody }),
|
|
2298
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
1073
2299
|
] });
|
|
1074
2300
|
}
|
|
1075
2301
|
if (state.kind === "denied") {
|
|
1076
|
-
return /* @__PURE__ */ (0,
|
|
1077
|
-
/* @__PURE__ */ (0,
|
|
1078
|
-
/* @__PURE__ */ (0,
|
|
2302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
|
|
2303
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { children: texts.deniedTitle }),
|
|
2304
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { children: texts.deniedBody })
|
|
1079
2305
|
] });
|
|
1080
2306
|
}
|
|
1081
2307
|
if (state.kind === "unsupported") {
|
|
1082
|
-
return /* @__PURE__ */ (0,
|
|
2308
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className, role: "region", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { children: texts.unsupportedBody }) });
|
|
1083
2309
|
}
|
|
1084
2310
|
if (state.kind === "error") {
|
|
1085
|
-
return /* @__PURE__ */ (0,
|
|
2311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { children: state.message }) });
|
|
1086
2312
|
}
|
|
1087
|
-
return /* @__PURE__ */ (0,
|
|
1088
|
-
/* @__PURE__ */ (0,
|
|
2313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className, role: "region", children: [
|
|
2314
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1089
2315
|
"button",
|
|
1090
2316
|
{
|
|
1091
2317
|
type: "button",
|
|
@@ -1099,27 +2325,27 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
1099
2325
|
children: texts.cta
|
|
1100
2326
|
}
|
|
1101
2327
|
),
|
|
1102
|
-
onDeclined && /* @__PURE__ */ (0,
|
|
2328
|
+
onDeclined && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
1103
2329
|
] });
|
|
1104
2330
|
}
|
|
1105
2331
|
|
|
1106
2332
|
// src/defaults/EmptyState.tsx
|
|
1107
|
-
var
|
|
2333
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1108
2334
|
function EmptyState({ title, description, action }) {
|
|
1109
|
-
return /* @__PURE__ */ (0,
|
|
1110
|
-
/* @__PURE__ */ (0,
|
|
1111
|
-
description && /* @__PURE__ */ (0,
|
|
1112
|
-
action && /* @__PURE__ */ (0,
|
|
2335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2337
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { style: { opacity: 0.7 }, children: description }),
|
|
2338
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { marginTop: 16 }, children: action })
|
|
1113
2339
|
] });
|
|
1114
2340
|
}
|
|
1115
2341
|
|
|
1116
2342
|
// src/hooks/useAuthPrimitives.ts
|
|
1117
|
-
var
|
|
2343
|
+
var import_react18 = require("react");
|
|
1118
2344
|
var import_sdk11 = require("@hook-sdk/sdk");
|
|
1119
2345
|
var warned = false;
|
|
1120
2346
|
function useAuthPrimitives() {
|
|
1121
2347
|
const { auth } = (0, import_sdk11.useHook)();
|
|
1122
|
-
(0,
|
|
2348
|
+
(0, import_react18.useEffect)(() => {
|
|
1123
2349
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
1124
2350
|
warned = true;
|
|
1125
2351
|
console.warn(
|
|
@@ -1150,14 +2376,14 @@ function useSubscription() {
|
|
|
1150
2376
|
}
|
|
1151
2377
|
|
|
1152
2378
|
// src/hooks/useReminders.ts
|
|
1153
|
-
var
|
|
2379
|
+
var import_react19 = require("react");
|
|
1154
2380
|
var import_sdk13 = require("@hook-sdk/sdk");
|
|
1155
2381
|
function useReminders() {
|
|
1156
2382
|
const { push } = (0, import_sdk13.useHook)();
|
|
1157
2383
|
const r = push.reminders;
|
|
1158
|
-
const [reminders, setReminders] = (0,
|
|
1159
|
-
const [loading, setLoading] = (0,
|
|
1160
|
-
const reload = (0,
|
|
2384
|
+
const [reminders, setReminders] = (0, import_react19.useState)([]);
|
|
2385
|
+
const [loading, setLoading] = (0, import_react19.useState)(true);
|
|
2386
|
+
const reload = (0, import_react19.useCallback)(async () => {
|
|
1161
2387
|
setLoading(true);
|
|
1162
2388
|
try {
|
|
1163
2389
|
const next = await r.list();
|
|
@@ -1166,38 +2392,38 @@ function useReminders() {
|
|
|
1166
2392
|
setLoading(false);
|
|
1167
2393
|
}
|
|
1168
2394
|
}, [r]);
|
|
1169
|
-
(0,
|
|
2395
|
+
(0, import_react19.useEffect)(() => {
|
|
1170
2396
|
void reload();
|
|
1171
2397
|
}, [reload]);
|
|
1172
|
-
const setReminder = (0,
|
|
2398
|
+
const setReminder = (0, import_react19.useCallback)(async (input) => {
|
|
1173
2399
|
await r.set(input);
|
|
1174
2400
|
await reload();
|
|
1175
2401
|
}, [r, reload]);
|
|
1176
|
-
const deleteReminder = (0,
|
|
2402
|
+
const deleteReminder = (0, import_react19.useCallback)(async (slot) => {
|
|
1177
2403
|
await r.delete(slot);
|
|
1178
2404
|
await reload();
|
|
1179
2405
|
}, [r, reload]);
|
|
1180
|
-
const schedule = (0,
|
|
2406
|
+
const schedule = (0, import_react19.useCallback)(async (items) => {
|
|
1181
2407
|
return r.schedule(items);
|
|
1182
2408
|
}, [r]);
|
|
1183
|
-
const setFallbacks = (0,
|
|
2409
|
+
const setFallbacks = (0, import_react19.useCallback)(async (items) => {
|
|
1184
2410
|
return r.setFallbacks(items);
|
|
1185
2411
|
}, [r]);
|
|
1186
2412
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
1187
2413
|
}
|
|
1188
2414
|
|
|
1189
2415
|
// src/hooks/useToast.ts
|
|
1190
|
-
var
|
|
2416
|
+
var import_react20 = require("react");
|
|
1191
2417
|
function useToast() {
|
|
1192
|
-
const [items, setItems] = (0,
|
|
1193
|
-
const show = (0,
|
|
2418
|
+
const [items, setItems] = (0, import_react20.useState)([]);
|
|
2419
|
+
const show = (0, import_react20.useCallback)((message, kind = "info") => {
|
|
1194
2420
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1195
2421
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
1196
2422
|
setTimeout(() => {
|
|
1197
2423
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1198
2424
|
}, 4e3);
|
|
1199
2425
|
}, []);
|
|
1200
|
-
const dismiss = (0,
|
|
2426
|
+
const dismiss = (0, import_react20.useCallback)((id) => {
|
|
1201
2427
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1202
2428
|
}, []);
|
|
1203
2429
|
return { items, show, dismiss };
|
|
@@ -1212,11 +2438,21 @@ function useToast() {
|
|
|
1212
2438
|
DefaultSignupScreen,
|
|
1213
2439
|
EmptyState,
|
|
1214
2440
|
ErrorBoundary,
|
|
2441
|
+
InstallGate,
|
|
2442
|
+
InstallSplash,
|
|
1215
2443
|
LoadingState,
|
|
1216
2444
|
PushPrompt,
|
|
2445
|
+
detectAndroidBrowser,
|
|
2446
|
+
detectIOSBrowser,
|
|
2447
|
+
detectInAppApp,
|
|
2448
|
+
detectPlatform,
|
|
2449
|
+
detectStandalone,
|
|
2450
|
+
shouldBlockInstall,
|
|
2451
|
+
shouldShowPermanentOption,
|
|
1217
2452
|
useAuth,
|
|
1218
2453
|
useAuthPrimitives,
|
|
1219
2454
|
useForgotForm,
|
|
2455
|
+
useInstallPrompt,
|
|
1220
2456
|
useLoginForm,
|
|
1221
2457
|
usePaywallState,
|
|
1222
2458
|
usePush,
|