@hook-sdk/template 0.3.0 → 0.4.1
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 +1519 -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 +1500 -197
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/AppRoot.tsx
|
|
2
|
-
import { useCallback as
|
|
2
|
+
import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef2, useState as useState12 } from "react";
|
|
3
3
|
import { useHook as useHook8 } from "@hook-sdk/sdk";
|
|
4
4
|
|
|
5
5
|
// src/internal/TemplateConfigContext.tsx
|
|
@@ -164,9 +164,1302 @@ function PushPrompt() {
|
|
|
164
164
|
return null;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
// src/components/InstallGate/InstallGate.tsx
|
|
168
|
+
import { useEffect as useEffect4, useRef } from "react";
|
|
169
|
+
|
|
170
|
+
// src/hooks/useInstallPrompt.ts
|
|
171
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useState as useState3 } from "react";
|
|
172
|
+
var IOS_RE = /iPad|iPhone|iPod/;
|
|
173
|
+
var IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;
|
|
174
|
+
var ANDROID_RE = /Android/;
|
|
175
|
+
var IN_APP_RE = /Instagram|FBAN|FBAV|BytedanceWebview|TikTok|Line\/|Twitter|Snapchat|Pinterest|LinkedIn|WhatsApp|MicroMessenger|Telegram/i;
|
|
176
|
+
var PERMANENT_DISMISS_REPROMPT_DAYS = 14;
|
|
177
|
+
var SESSION_SKIPS_BEFORE_PERMANENT_OPTION = 2;
|
|
178
|
+
var storageKey = {
|
|
179
|
+
sessionSkip: (slug) => `install:${slug}:session-skip`,
|
|
180
|
+
dismissedAt: (slug) => `install:${slug}:dismissed-at`,
|
|
181
|
+
installedAt: (slug) => `install:${slug}:installed-at`,
|
|
182
|
+
skipCount: (slug) => `install:${slug}:skip-count`
|
|
183
|
+
};
|
|
184
|
+
function detectPlatform(ua) {
|
|
185
|
+
if (IN_APP_RE.test(ua)) return "in-app";
|
|
186
|
+
const isIOS = IOS_RE.test(ua);
|
|
187
|
+
if (isIOS) {
|
|
188
|
+
const isSafari = /Safari/.test(ua) && !IOS_NON_SAFARI_RE.test(ua);
|
|
189
|
+
return isSafari ? "ios-safari" : "ios-other";
|
|
190
|
+
}
|
|
191
|
+
if (ANDROID_RE.test(ua)) return "android";
|
|
192
|
+
return "desktop";
|
|
193
|
+
}
|
|
194
|
+
function detectIOSBrowser(ua) {
|
|
195
|
+
if (!IOS_RE.test(ua)) return null;
|
|
196
|
+
if (/CriOS/.test(ua)) return "chrome";
|
|
197
|
+
if (/FxiOS/.test(ua)) return "firefox";
|
|
198
|
+
if (/EdgiOS/.test(ua)) return "edge";
|
|
199
|
+
if (/Safari/.test(ua)) return "safari";
|
|
200
|
+
return "other";
|
|
201
|
+
}
|
|
202
|
+
function detectAndroidBrowser(ua) {
|
|
203
|
+
if (!ANDROID_RE.test(ua)) return null;
|
|
204
|
+
if (/EdgA/.test(ua)) return "edge";
|
|
205
|
+
if (/OPR|OPT/.test(ua)) return "opera";
|
|
206
|
+
if (/SamsungBrowser/.test(ua)) return "samsung";
|
|
207
|
+
if (/Firefox/.test(ua)) return "firefox";
|
|
208
|
+
if (/Chrome/.test(ua)) return "chrome";
|
|
209
|
+
return "other";
|
|
210
|
+
}
|
|
211
|
+
function detectInAppApp(ua) {
|
|
212
|
+
if (!IN_APP_RE.test(ua)) return null;
|
|
213
|
+
if (/Instagram/i.test(ua)) return "instagram";
|
|
214
|
+
if (/FBAN|FBAV/.test(ua)) return "facebook";
|
|
215
|
+
if (/BytedanceWebview|TikTok/i.test(ua)) return "tiktok";
|
|
216
|
+
if (/WhatsApp/i.test(ua)) return "whatsapp";
|
|
217
|
+
if (/Twitter/i.test(ua)) return "twitter";
|
|
218
|
+
if (/LinkedIn/i.test(ua)) return "linkedin";
|
|
219
|
+
if (/Telegram/i.test(ua)) return "telegram";
|
|
220
|
+
if (/Line\//i.test(ua)) return "line";
|
|
221
|
+
if (/Snapchat/i.test(ua)) return "snapchat";
|
|
222
|
+
if (/Pinterest/i.test(ua)) return "pinterest";
|
|
223
|
+
if (/MicroMessenger/i.test(ua)) return "wechat";
|
|
224
|
+
return "other";
|
|
225
|
+
}
|
|
226
|
+
function detectStandalone() {
|
|
227
|
+
if (typeof window === "undefined" || typeof navigator === "undefined") {
|
|
228
|
+
return { installed: false, source: null };
|
|
229
|
+
}
|
|
230
|
+
const mm = window.matchMedia?.("(display-mode: standalone)");
|
|
231
|
+
if (mm?.matches) return { installed: true, source: "match_media" };
|
|
232
|
+
const fs = window.matchMedia?.("(display-mode: fullscreen)");
|
|
233
|
+
if (fs?.matches) return { installed: true, source: "match_media" };
|
|
234
|
+
if (navigator.standalone === true) return { installed: true, source: "navigator_standalone" };
|
|
235
|
+
return { installed: false, source: null };
|
|
236
|
+
}
|
|
237
|
+
function track(event, props) {
|
|
238
|
+
if (typeof window === "undefined") return;
|
|
239
|
+
window.posthog?.capture?.(event, props);
|
|
240
|
+
}
|
|
241
|
+
function pickVariant(state) {
|
|
242
|
+
if (state.isInstalled) return "none";
|
|
243
|
+
switch (state.platform) {
|
|
244
|
+
case "android":
|
|
245
|
+
return state.isInstallable ? "android-native" : "android-manual";
|
|
246
|
+
case "ios-safari":
|
|
247
|
+
return "ios-safari";
|
|
248
|
+
case "ios-other":
|
|
249
|
+
return "ios-other";
|
|
250
|
+
case "in-app":
|
|
251
|
+
return "in-app";
|
|
252
|
+
case "desktop":
|
|
253
|
+
return state.isInstallable ? "desktop" : "none";
|
|
254
|
+
default:
|
|
255
|
+
return "none";
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function safeStorage() {
|
|
259
|
+
if (typeof localStorage === "undefined") return null;
|
|
260
|
+
try {
|
|
261
|
+
localStorage.setItem("__install_probe", "1");
|
|
262
|
+
localStorage.removeItem("__install_probe");
|
|
263
|
+
return localStorage;
|
|
264
|
+
} catch {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function readPermanentDismiss(slug) {
|
|
269
|
+
const storage = safeStorage();
|
|
270
|
+
if (!storage) return { dismissed: false, dismissedAt: null };
|
|
271
|
+
const raw = storage.getItem(storageKey.dismissedAt(slug));
|
|
272
|
+
if (!raw) return { dismissed: false, dismissedAt: null };
|
|
273
|
+
const parsed = Date.parse(raw);
|
|
274
|
+
if (Number.isNaN(parsed)) return { dismissed: false, dismissedAt: null };
|
|
275
|
+
const daysAgo = (Date.now() - parsed) / (1e3 * 60 * 60 * 24);
|
|
276
|
+
return { dismissed: daysAgo < PERMANENT_DISMISS_REPROMPT_DAYS, dismissedAt: raw };
|
|
277
|
+
}
|
|
278
|
+
function readInstalledMarker(slug) {
|
|
279
|
+
const storage = safeStorage();
|
|
280
|
+
if (!storage) return false;
|
|
281
|
+
return storage.getItem(storageKey.installedAt(slug)) !== null;
|
|
282
|
+
}
|
|
283
|
+
function readSkipCount(slug) {
|
|
284
|
+
const storage = safeStorage();
|
|
285
|
+
if (!storage) return 0;
|
|
286
|
+
const raw = storage.getItem(storageKey.skipCount(slug));
|
|
287
|
+
const n = raw ? Number.parseInt(raw, 10) : 0;
|
|
288
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
289
|
+
}
|
|
290
|
+
function readSessionSkip(slug) {
|
|
291
|
+
if (typeof sessionStorage === "undefined") return false;
|
|
292
|
+
try {
|
|
293
|
+
return sessionStorage.getItem(storageKey.sessionSkip(slug)) === "true";
|
|
294
|
+
} catch {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function useInstallPrompt(slug) {
|
|
299
|
+
const ua = typeof navigator !== "undefined" && typeof navigator.userAgent === "string" ? navigator.userAgent : "";
|
|
300
|
+
const platform = detectPlatform(ua);
|
|
301
|
+
const iosBrowser = detectIOSBrowser(ua);
|
|
302
|
+
const androidBrowser = detectAndroidBrowser(ua);
|
|
303
|
+
const inAppApp = detectInAppApp(ua);
|
|
304
|
+
const [isInstallable, setIsInstallable] = useState3(() => {
|
|
305
|
+
if (typeof window === "undefined") return false;
|
|
306
|
+
return window.__pwaInstallPrompt != null;
|
|
307
|
+
});
|
|
308
|
+
const [isInstalled, setIsInstalled] = useState3(() => {
|
|
309
|
+
const { installed } = detectStandalone();
|
|
310
|
+
return installed || readInstalledMarker(slug);
|
|
311
|
+
});
|
|
312
|
+
const [isDismissedSession, setIsDismissedSession] = useState3(() => readSessionSkip(slug));
|
|
313
|
+
const [isDismissedPermanent, setIsDismissedPermanent] = useState3(() => readPermanentDismiss(slug).dismissed);
|
|
314
|
+
const [skipCount, setSkipCount] = useState3(() => readSkipCount(slug));
|
|
315
|
+
useEffect3(() => {
|
|
316
|
+
if (typeof window === "undefined") return;
|
|
317
|
+
if (window.__pwaInstallPrompt) {
|
|
318
|
+
setIsInstallable(true);
|
|
319
|
+
}
|
|
320
|
+
const onPrompt = (e) => {
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
window.__pwaInstallPrompt = e;
|
|
323
|
+
setIsInstallable(true);
|
|
324
|
+
};
|
|
325
|
+
const onInstalled = () => {
|
|
326
|
+
setIsInstalled(true);
|
|
327
|
+
setIsInstallable(false);
|
|
328
|
+
window.__pwaInstallPrompt = null;
|
|
329
|
+
const storage = safeStorage();
|
|
330
|
+
if (storage) storage.setItem(storageKey.installedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
331
|
+
};
|
|
332
|
+
window.addEventListener("beforeinstallprompt", onPrompt);
|
|
333
|
+
window.addEventListener("appinstalled", onInstalled);
|
|
334
|
+
return () => {
|
|
335
|
+
window.removeEventListener("beforeinstallprompt", onPrompt);
|
|
336
|
+
window.removeEventListener("appinstalled", onInstalled);
|
|
337
|
+
};
|
|
338
|
+
}, [slug]);
|
|
339
|
+
useEffect3(() => {
|
|
340
|
+
if (typeof window === "undefined") return;
|
|
341
|
+
const mq = window.matchMedia?.("(display-mode: standalone)");
|
|
342
|
+
if (!mq) return;
|
|
343
|
+
const handler = (e) => {
|
|
344
|
+
if (e.matches) {
|
|
345
|
+
setIsInstalled(true);
|
|
346
|
+
track("pwa_install_standalone_detected", { slug, source: "match_media" });
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
mq.addEventListener?.("change", handler);
|
|
350
|
+
return () => mq.removeEventListener?.("change", handler);
|
|
351
|
+
}, [slug]);
|
|
352
|
+
const variant = pickVariant({
|
|
353
|
+
platform,
|
|
354
|
+
iosBrowser,
|
|
355
|
+
androidBrowser,
|
|
356
|
+
inAppApp,
|
|
357
|
+
isInstallable,
|
|
358
|
+
isInstalled,
|
|
359
|
+
isDismissedSession,
|
|
360
|
+
isDismissedPermanent,
|
|
361
|
+
skipCount
|
|
362
|
+
});
|
|
363
|
+
const promptInstall = useCallback2(async () => {
|
|
364
|
+
if (typeof window === "undefined") return false;
|
|
365
|
+
const prompt = window.__pwaInstallPrompt;
|
|
366
|
+
if (!prompt) return false;
|
|
367
|
+
track("pwa_install_prompt_clicked", { slug });
|
|
368
|
+
try {
|
|
369
|
+
await prompt.prompt();
|
|
370
|
+
const { outcome } = await prompt.userChoice;
|
|
371
|
+
track("pwa_install_prompt_outcome", { slug, outcome });
|
|
372
|
+
if (outcome === "accepted") {
|
|
373
|
+
setIsInstalled(true);
|
|
374
|
+
setIsInstallable(false);
|
|
375
|
+
window.__pwaInstallPrompt = null;
|
|
376
|
+
const storage = safeStorage();
|
|
377
|
+
if (storage) storage.setItem(storageKey.installedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
} catch {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
}, [slug]);
|
|
385
|
+
const dismissSession = useCallback2(() => {
|
|
386
|
+
if (typeof sessionStorage !== "undefined") {
|
|
387
|
+
try {
|
|
388
|
+
sessionStorage.setItem(storageKey.sessionSkip(slug), "true");
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
const storage = safeStorage();
|
|
393
|
+
const newCount = skipCount + 1;
|
|
394
|
+
if (storage) storage.setItem(storageKey.skipCount(slug), String(newCount));
|
|
395
|
+
setSkipCount(newCount);
|
|
396
|
+
setIsDismissedSession(true);
|
|
397
|
+
track("pwa_install_session_skip", { slug, platform, skip_count: newCount });
|
|
398
|
+
}, [slug, skipCount, platform]);
|
|
399
|
+
const dismissPermanent = useCallback2(() => {
|
|
400
|
+
const storage = safeStorage();
|
|
401
|
+
if (storage) storage.setItem(storageKey.dismissedAt(slug), (/* @__PURE__ */ new Date()).toISOString());
|
|
402
|
+
setIsDismissedPermanent(true);
|
|
403
|
+
track("pwa_install_permanent_dismiss", { slug, platform, prior_skip_count: skipCount });
|
|
404
|
+
}, [slug, platform, skipCount]);
|
|
405
|
+
const showIOSOtherHelp = useCallback2(() => {
|
|
406
|
+
track("pwa_install_ios_other_help_shown", { slug });
|
|
407
|
+
}, [slug]);
|
|
408
|
+
const copyLink = useCallback2(async () => {
|
|
409
|
+
if (typeof navigator === "undefined" || typeof location === "undefined") return;
|
|
410
|
+
try {
|
|
411
|
+
await navigator.clipboard?.writeText?.(location.href);
|
|
412
|
+
} catch {
|
|
413
|
+
}
|
|
414
|
+
}, []);
|
|
415
|
+
const reset = useCallback2(() => {
|
|
416
|
+
const storage = safeStorage();
|
|
417
|
+
if (storage) {
|
|
418
|
+
storage.removeItem(storageKey.dismissedAt(slug));
|
|
419
|
+
storage.removeItem(storageKey.installedAt(slug));
|
|
420
|
+
storage.removeItem(storageKey.skipCount(slug));
|
|
421
|
+
}
|
|
422
|
+
if (typeof sessionStorage !== "undefined") {
|
|
423
|
+
try {
|
|
424
|
+
sessionStorage.removeItem(storageKey.sessionSkip(slug));
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
setIsDismissedSession(false);
|
|
429
|
+
setIsDismissedPermanent(false);
|
|
430
|
+
setSkipCount(0);
|
|
431
|
+
}, [slug]);
|
|
432
|
+
return {
|
|
433
|
+
platform,
|
|
434
|
+
iosBrowser,
|
|
435
|
+
androidBrowser,
|
|
436
|
+
inAppApp,
|
|
437
|
+
isInstallable,
|
|
438
|
+
isInstalled,
|
|
439
|
+
isDismissedSession,
|
|
440
|
+
isDismissedPermanent,
|
|
441
|
+
skipCount,
|
|
442
|
+
variant,
|
|
443
|
+
promptInstall,
|
|
444
|
+
dismissSession,
|
|
445
|
+
dismissPermanent,
|
|
446
|
+
showIOSOtherHelp,
|
|
447
|
+
copyLink,
|
|
448
|
+
reset
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function shouldBlockInstall(state, now = Date.now()) {
|
|
452
|
+
if (state.isInstalled) return false;
|
|
453
|
+
if (state.variant === "none") return false;
|
|
454
|
+
if (state.isDismissedSession) return false;
|
|
455
|
+
if (state.isDismissedPermanent) {
|
|
456
|
+
void now;
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
if (state.platform === "desktop" && !state.isInstallable) return false;
|
|
460
|
+
if (state.platform === "unknown") return false;
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
function shouldShowPermanentOption(state) {
|
|
464
|
+
return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/components/InstallGate/copy.ts
|
|
468
|
+
var INSTALL_COPY = {
|
|
469
|
+
android: {
|
|
470
|
+
native: {
|
|
471
|
+
title: "Instale no seu celular",
|
|
472
|
+
subtitle: "Acesso r\xE1pido, sem precisar do navegador",
|
|
473
|
+
cta: "Baixar",
|
|
474
|
+
skip: "Continuar no navegador",
|
|
475
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
476
|
+
},
|
|
477
|
+
manual: {
|
|
478
|
+
title: "Instale em 2 toques",
|
|
479
|
+
subtitle: 'Toque no menu do navegador e escolha "Instalar aplicativo"',
|
|
480
|
+
step1: "Toque no menu do navegador",
|
|
481
|
+
step2: 'Escolha "Instalar aplicativo"',
|
|
482
|
+
cta: "Entendi",
|
|
483
|
+
skip: "Continuar no navegador",
|
|
484
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
iosSafari: {
|
|
488
|
+
title: "Adicione \xE0 sua Tela de In\xEDcio",
|
|
489
|
+
subtitle: "Siga os 3 passos",
|
|
490
|
+
step1: {
|
|
491
|
+
title: "Toque em Compartilhar",
|
|
492
|
+
subtitle: "Na barra inferior do Safari"
|
|
493
|
+
},
|
|
494
|
+
step2: {
|
|
495
|
+
title: 'Role e toque em "Adicionar \xE0 Tela de In\xEDcio"',
|
|
496
|
+
iconLabel: "Adicionar \xE0 Tela de In\xEDcio"
|
|
497
|
+
},
|
|
498
|
+
step3: {
|
|
499
|
+
title: 'Toque em "Adicionar" pra confirmar',
|
|
500
|
+
buttonLabel: "Adicionar"
|
|
501
|
+
},
|
|
502
|
+
skip: "Continuar no Safari",
|
|
503
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
504
|
+
},
|
|
505
|
+
iosOther: {
|
|
506
|
+
title: "Abra no Safari pra instalar",
|
|
507
|
+
subtitle: "No Chrome/Firefox/Edge do iPhone n\xE3o d\xE1 pra instalar PWA. Abra o link no Safari.",
|
|
508
|
+
ctaPrimary: "Abrir no Safari",
|
|
509
|
+
ctaSecondary: "Copiar link",
|
|
510
|
+
copiedToast: "Link copiado. Cole no Safari.",
|
|
511
|
+
skip: "Continuar mesmo assim",
|
|
512
|
+
skipPermanent: "N\xE3o me pergunte mais",
|
|
513
|
+
help: {
|
|
514
|
+
step1: {
|
|
515
|
+
title: "Toque em \u22EF ou no bot\xE3o compartilhar",
|
|
516
|
+
subtitle: "Na barra inferior ou superior do navegador"
|
|
517
|
+
},
|
|
518
|
+
step2: {
|
|
519
|
+
title: 'Escolha "Abrir no Safari"',
|
|
520
|
+
subtitle: "O app vai abrir direto no Safari"
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
inApp: {
|
|
525
|
+
instagram: {
|
|
526
|
+
title: "Pra instalar, abra fora do Instagram",
|
|
527
|
+
step1: "Toque em \u22EF (canto superior direito)",
|
|
528
|
+
step2: 'Escolha "Abrir no navegador externo"'
|
|
529
|
+
},
|
|
530
|
+
facebook: {
|
|
531
|
+
title: "Pra instalar, abra fora do Facebook",
|
|
532
|
+
step1: "Toque em \u22EE",
|
|
533
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
534
|
+
},
|
|
535
|
+
tiktok: {
|
|
536
|
+
title: "Pra instalar, abra fora do TikTok",
|
|
537
|
+
step1: "Toque em \u22EF",
|
|
538
|
+
step2: 'Escolha "Abrir no Safari" (iOS) ou "Abrir no Chrome" (Android)'
|
|
539
|
+
},
|
|
540
|
+
whatsapp: {
|
|
541
|
+
title: "Pra instalar, abra fora do WhatsApp",
|
|
542
|
+
step1: "Toque longo no link",
|
|
543
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
544
|
+
},
|
|
545
|
+
twitter: {
|
|
546
|
+
title: "Pra instalar, abra fora do Twitter",
|
|
547
|
+
step1: "Toque em \u22EF",
|
|
548
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
549
|
+
},
|
|
550
|
+
linkedin: {
|
|
551
|
+
title: "Pra instalar, abra fora do LinkedIn",
|
|
552
|
+
step1: "Toque em \u22EF",
|
|
553
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
554
|
+
},
|
|
555
|
+
telegram: {
|
|
556
|
+
title: "Pra instalar, abra fora do Telegram",
|
|
557
|
+
step1: "Toque em \u22EE",
|
|
558
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
559
|
+
},
|
|
560
|
+
line: {
|
|
561
|
+
title: "Pra instalar, abra fora do LINE",
|
|
562
|
+
step1: "Toque em \u22EF",
|
|
563
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
564
|
+
},
|
|
565
|
+
snapchat: {
|
|
566
|
+
title: "Pra instalar, abra fora do Snapchat",
|
|
567
|
+
step1: "Mantenha pressionado o link",
|
|
568
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
569
|
+
},
|
|
570
|
+
pinterest: {
|
|
571
|
+
title: "Pra instalar, abra fora do Pinterest",
|
|
572
|
+
step1: "Toque em \u22EF",
|
|
573
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
574
|
+
},
|
|
575
|
+
wechat: {
|
|
576
|
+
title: "Pra instalar, abra fora do WeChat",
|
|
577
|
+
step1: "Toque em \u22EF",
|
|
578
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
579
|
+
},
|
|
580
|
+
other: {
|
|
581
|
+
title: "Abra no navegador do celular",
|
|
582
|
+
step1: "Toque no menu do app atual",
|
|
583
|
+
step2: 'Escolha "Abrir no Chrome" ou "Abrir no Safari"'
|
|
584
|
+
},
|
|
585
|
+
copy: "Copiar link",
|
|
586
|
+
copiedToast: "Link copiado. Cole no Chrome/Safari.",
|
|
587
|
+
skip: "Continuar aqui mesmo",
|
|
588
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
589
|
+
},
|
|
590
|
+
desktop: {
|
|
591
|
+
title: "Instale no computador",
|
|
592
|
+
subtitle: "Acesso r\xE1pido",
|
|
593
|
+
cta: "Baixar",
|
|
594
|
+
close: "Fechar"
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/components/InstallGate/InstallSplash.tsx
|
|
599
|
+
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
600
|
+
function InstallSplash({ children, title, subtitle }) {
|
|
601
|
+
const { name, theme } = useTemplateConfig();
|
|
602
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
603
|
+
return /* @__PURE__ */ jsx7(
|
|
604
|
+
"div",
|
|
605
|
+
{
|
|
606
|
+
role: "dialog",
|
|
607
|
+
"aria-modal": "true",
|
|
608
|
+
"aria-labelledby": "install-splash-title",
|
|
609
|
+
"aria-describedby": subtitle ? "install-splash-subtitle" : void 0,
|
|
610
|
+
style: overlayStyle,
|
|
611
|
+
children: /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
|
|
612
|
+
/* @__PURE__ */ jsx7("div", { style: { display: "flex", justifyContent: "center", marginBottom: 16 }, children: iconUrl ? /* @__PURE__ */ jsx7(
|
|
613
|
+
"img",
|
|
614
|
+
{
|
|
615
|
+
src: iconUrl,
|
|
616
|
+
alt: `\xCDcone de ${name}`,
|
|
617
|
+
style: { width: 80, height: 80, borderRadius: 20, objectFit: "cover" }
|
|
618
|
+
}
|
|
619
|
+
) : /* @__PURE__ */ jsx7(
|
|
620
|
+
"div",
|
|
621
|
+
{
|
|
622
|
+
style: {
|
|
623
|
+
width: 80,
|
|
624
|
+
height: 80,
|
|
625
|
+
borderRadius: 20,
|
|
626
|
+
background: "var(--hook-color-primary)",
|
|
627
|
+
color: "#fff",
|
|
628
|
+
display: "flex",
|
|
629
|
+
alignItems: "center",
|
|
630
|
+
justifyContent: "center",
|
|
631
|
+
fontSize: 36,
|
|
632
|
+
fontWeight: 700
|
|
633
|
+
},
|
|
634
|
+
children: name.charAt(0).toUpperCase()
|
|
635
|
+
}
|
|
636
|
+
) }),
|
|
637
|
+
/* @__PURE__ */ jsx7("h1", { id: "install-splash-title", style: titleStyle, children: title }),
|
|
638
|
+
subtitle && /* @__PURE__ */ jsx7("p", { id: "install-splash-subtitle", style: subtitleStyle, children: subtitle }),
|
|
639
|
+
/* @__PURE__ */ jsx7("div", { style: { marginTop: 24 }, children }),
|
|
640
|
+
/* @__PURE__ */ jsx7("p", { style: footerStyle, children: "por Hook" })
|
|
641
|
+
] })
|
|
642
|
+
}
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
var primaryButtonStyle = {
|
|
646
|
+
width: "100%",
|
|
647
|
+
padding: "14px 20px",
|
|
648
|
+
background: "var(--hook-color-primary)",
|
|
649
|
+
color: "#fff",
|
|
650
|
+
border: "none",
|
|
651
|
+
borderRadius: 999,
|
|
652
|
+
fontSize: 17,
|
|
653
|
+
fontWeight: 600,
|
|
654
|
+
cursor: "pointer",
|
|
655
|
+
marginBottom: 12
|
|
656
|
+
};
|
|
657
|
+
var secondaryButtonStyle = {
|
|
658
|
+
width: "100%",
|
|
659
|
+
padding: "12px 20px",
|
|
660
|
+
background: "transparent",
|
|
661
|
+
color: "var(--hook-color-primary)",
|
|
662
|
+
border: "1px solid var(--hook-color-primary)",
|
|
663
|
+
borderRadius: 999,
|
|
664
|
+
fontSize: 15,
|
|
665
|
+
fontWeight: 500,
|
|
666
|
+
cursor: "pointer",
|
|
667
|
+
marginBottom: 12
|
|
668
|
+
};
|
|
669
|
+
var skipLinkStyle = {
|
|
670
|
+
display: "block",
|
|
671
|
+
width: "100%",
|
|
672
|
+
padding: "10px",
|
|
673
|
+
marginTop: 8,
|
|
674
|
+
background: "transparent",
|
|
675
|
+
color: "#555",
|
|
676
|
+
border: "none",
|
|
677
|
+
fontSize: 14,
|
|
678
|
+
textDecoration: "underline",
|
|
679
|
+
cursor: "pointer",
|
|
680
|
+
textAlign: "center"
|
|
681
|
+
};
|
|
682
|
+
var skipPermanentLinkStyle = {
|
|
683
|
+
...skipLinkStyle,
|
|
684
|
+
color: "#999",
|
|
685
|
+
fontSize: 13,
|
|
686
|
+
marginTop: 4
|
|
687
|
+
};
|
|
688
|
+
var overlayStyle = {
|
|
689
|
+
position: "fixed",
|
|
690
|
+
inset: 0,
|
|
691
|
+
background: "var(--hook-color-background, #fafafa)",
|
|
692
|
+
zIndex: 1e4,
|
|
693
|
+
display: "flex",
|
|
694
|
+
alignItems: "center",
|
|
695
|
+
justifyContent: "center",
|
|
696
|
+
padding: 20,
|
|
697
|
+
overflow: "auto"
|
|
698
|
+
};
|
|
699
|
+
var cardStyle = {
|
|
700
|
+
width: "100%",
|
|
701
|
+
maxWidth: 420,
|
|
702
|
+
padding: 24,
|
|
703
|
+
textAlign: "center"
|
|
704
|
+
};
|
|
705
|
+
var titleStyle = {
|
|
706
|
+
fontSize: 24,
|
|
707
|
+
fontWeight: 700,
|
|
708
|
+
lineHeight: 1.2,
|
|
709
|
+
margin: "0 0 8px 0",
|
|
710
|
+
color: "#111"
|
|
711
|
+
};
|
|
712
|
+
var subtitleStyle = {
|
|
713
|
+
fontSize: 15,
|
|
714
|
+
lineHeight: 1.4,
|
|
715
|
+
color: "#555",
|
|
716
|
+
margin: 0
|
|
717
|
+
};
|
|
718
|
+
var footerStyle = {
|
|
719
|
+
fontSize: 11,
|
|
720
|
+
color: "#aaa",
|
|
721
|
+
marginTop: 32,
|
|
722
|
+
letterSpacing: 0.5
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/components/InstallGate/icons.tsx
|
|
726
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
727
|
+
var defaultSvgProps = (size) => ({
|
|
728
|
+
width: size,
|
|
729
|
+
height: size,
|
|
730
|
+
viewBox: "0 0 24 24",
|
|
731
|
+
fill: "none",
|
|
732
|
+
stroke: "currentColor",
|
|
733
|
+
strokeWidth: 2,
|
|
734
|
+
strokeLinecap: "round",
|
|
735
|
+
strokeLinejoin: "round"
|
|
736
|
+
});
|
|
737
|
+
function ShareIconIOS({ size = 24, style, className }) {
|
|
738
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
739
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 2L12 15" }),
|
|
740
|
+
/* @__PURE__ */ jsx8("path", { d: "M8 6L12 2L16 6" }),
|
|
741
|
+
/* @__PURE__ */ jsx8("path", { d: "M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9" })
|
|
742
|
+
] });
|
|
743
|
+
}
|
|
744
|
+
function MenuDotsVerticalIcon({ size = 24, style, className }) {
|
|
745
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
746
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "5", r: "1.5" }),
|
|
747
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
748
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "19", r: "1.5" })
|
|
749
|
+
] });
|
|
750
|
+
}
|
|
751
|
+
function MenuDotsHorizontalIcon({ size = 24, style, className }) {
|
|
752
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
753
|
+
/* @__PURE__ */ jsx8("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
754
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
755
|
+
/* @__PURE__ */ jsx8("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
756
|
+
] });
|
|
757
|
+
}
|
|
758
|
+
function SquarePlusIcon({ size = 24, style, className }) {
|
|
759
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
760
|
+
/* @__PURE__ */ jsx8("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
761
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 8v8" }),
|
|
762
|
+
/* @__PURE__ */ jsx8("path", { d: "M8 12h8" })
|
|
763
|
+
] });
|
|
764
|
+
}
|
|
765
|
+
function DownloadIcon({ size = 24, style, className }) {
|
|
766
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
767
|
+
/* @__PURE__ */ jsx8("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" }),
|
|
768
|
+
/* @__PURE__ */ jsx8("polyline", { points: "7 10 12 15 17 10" }),
|
|
769
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
770
|
+
] });
|
|
771
|
+
}
|
|
772
|
+
function ExternalLinkIcon({ size = 24, style, className }) {
|
|
773
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
774
|
+
/* @__PURE__ */ jsx8("path", { d: "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" }),
|
|
775
|
+
/* @__PURE__ */ jsx8("polyline", { points: "15 3 21 3 21 9" }),
|
|
776
|
+
/* @__PURE__ */ jsx8("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
777
|
+
] });
|
|
778
|
+
}
|
|
779
|
+
function XIcon({ size = 20, style, className }) {
|
|
780
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
781
|
+
/* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
782
|
+
/* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
783
|
+
] });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// src/components/InstallGate/variants/AndroidNativeVariant.tsx
|
|
787
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
788
|
+
function AndroidNativeVariant({
|
|
789
|
+
state,
|
|
790
|
+
actions
|
|
791
|
+
}) {
|
|
792
|
+
const copy = INSTALL_COPY.android.native;
|
|
793
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
794
|
+
return /* @__PURE__ */ jsxs3(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
795
|
+
/* @__PURE__ */ jsxs3(
|
|
796
|
+
"button",
|
|
797
|
+
{
|
|
798
|
+
"data-testid": "install-prompt-cta-android-native",
|
|
799
|
+
type: "button",
|
|
800
|
+
onClick: () => void actions.promptInstall(),
|
|
801
|
+
style: { ...primaryButtonStyle, display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8 },
|
|
802
|
+
children: [
|
|
803
|
+
/* @__PURE__ */ jsx9(DownloadIcon, { size: 18 }),
|
|
804
|
+
copy.cta
|
|
805
|
+
]
|
|
806
|
+
}
|
|
807
|
+
),
|
|
808
|
+
/* @__PURE__ */ jsx9(
|
|
809
|
+
"button",
|
|
810
|
+
{
|
|
811
|
+
"data-testid": "install-prompt-skip-session",
|
|
812
|
+
type: "button",
|
|
813
|
+
onClick: actions.dismissSession,
|
|
814
|
+
style: skipLinkStyle,
|
|
815
|
+
children: copy.skip
|
|
816
|
+
}
|
|
817
|
+
),
|
|
818
|
+
showPermanent && /* @__PURE__ */ jsx9(
|
|
819
|
+
"button",
|
|
820
|
+
{
|
|
821
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
822
|
+
type: "button",
|
|
823
|
+
onClick: actions.dismissPermanent,
|
|
824
|
+
style: skipPermanentLinkStyle,
|
|
825
|
+
children: copy.skipPermanent
|
|
826
|
+
}
|
|
827
|
+
)
|
|
828
|
+
] });
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// src/components/InstallGate/variants/AndroidManualVariant.tsx
|
|
832
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
833
|
+
function AndroidManualVariant({
|
|
834
|
+
state,
|
|
835
|
+
actions
|
|
836
|
+
}) {
|
|
837
|
+
const copy = INSTALL_COPY.android.manual;
|
|
838
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
839
|
+
return /* @__PURE__ */ jsxs4(InstallSplash, { title: copy.title, children: [
|
|
840
|
+
/* @__PURE__ */ jsx10(Step, { n: 1, icon: /* @__PURE__ */ jsx10(MenuDotsVerticalIcon, { size: 20 }), children: copy.step1 }),
|
|
841
|
+
/* @__PURE__ */ jsx10(Step, { n: 2, icon: /* @__PURE__ */ jsx10(DownloadIcon, { size: 18 }), children: copy.step2 }),
|
|
842
|
+
/* @__PURE__ */ jsx10(
|
|
843
|
+
"button",
|
|
844
|
+
{
|
|
845
|
+
"data-testid": "install-prompt-cta-android-manual",
|
|
846
|
+
type: "button",
|
|
847
|
+
onClick: actions.dismissSession,
|
|
848
|
+
style: primaryButtonStyle,
|
|
849
|
+
children: copy.cta
|
|
850
|
+
}
|
|
851
|
+
),
|
|
852
|
+
/* @__PURE__ */ jsx10(
|
|
853
|
+
"button",
|
|
854
|
+
{
|
|
855
|
+
"data-testid": "install-prompt-skip-session",
|
|
856
|
+
type: "button",
|
|
857
|
+
onClick: actions.dismissSession,
|
|
858
|
+
style: skipLinkStyle,
|
|
859
|
+
children: copy.skip
|
|
860
|
+
}
|
|
861
|
+
),
|
|
862
|
+
showPermanent && /* @__PURE__ */ jsx10(
|
|
863
|
+
"button",
|
|
864
|
+
{
|
|
865
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
866
|
+
type: "button",
|
|
867
|
+
onClick: actions.dismissPermanent,
|
|
868
|
+
style: skipPermanentLinkStyle,
|
|
869
|
+
children: copy.skipPermanent
|
|
870
|
+
}
|
|
871
|
+
)
|
|
872
|
+
] });
|
|
873
|
+
}
|
|
874
|
+
function Step({ n, icon, children }) {
|
|
875
|
+
return /* @__PURE__ */ jsxs4(
|
|
876
|
+
"div",
|
|
877
|
+
{
|
|
878
|
+
style: {
|
|
879
|
+
display: "flex",
|
|
880
|
+
alignItems: "center",
|
|
881
|
+
gap: 12,
|
|
882
|
+
padding: "12px 14px",
|
|
883
|
+
background: "#f5f5f7",
|
|
884
|
+
borderRadius: 12,
|
|
885
|
+
marginBottom: 10,
|
|
886
|
+
textAlign: "left"
|
|
887
|
+
},
|
|
888
|
+
children: [
|
|
889
|
+
/* @__PURE__ */ jsx10(
|
|
890
|
+
"div",
|
|
891
|
+
{
|
|
892
|
+
style: {
|
|
893
|
+
width: 28,
|
|
894
|
+
height: 28,
|
|
895
|
+
borderRadius: "50%",
|
|
896
|
+
background: "var(--hook-color-primary)",
|
|
897
|
+
color: "#fff",
|
|
898
|
+
display: "flex",
|
|
899
|
+
alignItems: "center",
|
|
900
|
+
justifyContent: "center",
|
|
901
|
+
fontSize: 14,
|
|
902
|
+
fontWeight: 700,
|
|
903
|
+
flexShrink: 0
|
|
904
|
+
},
|
|
905
|
+
children: n
|
|
906
|
+
}
|
|
907
|
+
),
|
|
908
|
+
/* @__PURE__ */ jsx10("div", { style: { flex: 1, fontSize: 15, color: "#333" }, children }),
|
|
909
|
+
/* @__PURE__ */ jsx10("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
910
|
+
]
|
|
911
|
+
}
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// src/components/InstallGate/Step.tsx
|
|
916
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
917
|
+
function Step2({
|
|
918
|
+
n,
|
|
919
|
+
title,
|
|
920
|
+
subtitle,
|
|
921
|
+
visual
|
|
922
|
+
}) {
|
|
923
|
+
return /* @__PURE__ */ jsxs5(
|
|
924
|
+
"div",
|
|
925
|
+
{
|
|
926
|
+
style: {
|
|
927
|
+
display: "flex",
|
|
928
|
+
alignItems: "flex-start",
|
|
929
|
+
gap: 12,
|
|
930
|
+
marginBottom: 16,
|
|
931
|
+
textAlign: "left"
|
|
932
|
+
},
|
|
933
|
+
children: [
|
|
934
|
+
/* @__PURE__ */ jsx11(
|
|
935
|
+
"div",
|
|
936
|
+
{
|
|
937
|
+
style: {
|
|
938
|
+
width: 32,
|
|
939
|
+
height: 32,
|
|
940
|
+
borderRadius: 10,
|
|
941
|
+
background: "var(--hook-color-primary)",
|
|
942
|
+
color: "#fff",
|
|
943
|
+
display: "flex",
|
|
944
|
+
alignItems: "center",
|
|
945
|
+
justifyContent: "center",
|
|
946
|
+
fontSize: 15,
|
|
947
|
+
fontWeight: 700,
|
|
948
|
+
flexShrink: 0
|
|
949
|
+
},
|
|
950
|
+
children: n
|
|
951
|
+
}
|
|
952
|
+
),
|
|
953
|
+
/* @__PURE__ */ jsxs5("div", { style: { flex: 1 }, children: [
|
|
954
|
+
/* @__PURE__ */ jsx11("p", { style: { margin: 0, fontSize: 15, fontWeight: 500, color: "#111", lineHeight: 1.3 }, children: title }),
|
|
955
|
+
subtitle && /* @__PURE__ */ jsx11("p", { style: { margin: "4px 0 0 0", fontSize: 13, color: "#777" }, children: subtitle }),
|
|
956
|
+
visual
|
|
957
|
+
] })
|
|
958
|
+
]
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// src/components/InstallGate/variants/IOSafariVariant.tsx
|
|
964
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
965
|
+
function IOSafariVariant({
|
|
966
|
+
state,
|
|
967
|
+
actions
|
|
968
|
+
}) {
|
|
969
|
+
const copy = INSTALL_COPY.iosSafari;
|
|
970
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
971
|
+
return /* @__PURE__ */ jsxs6(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
972
|
+
/* @__PURE__ */ jsx12(
|
|
973
|
+
Step2,
|
|
974
|
+
{
|
|
975
|
+
n: 1,
|
|
976
|
+
title: copy.step1.title,
|
|
977
|
+
subtitle: copy.step1.subtitle,
|
|
978
|
+
visual: /* @__PURE__ */ jsx12(
|
|
979
|
+
"div",
|
|
980
|
+
{
|
|
981
|
+
style: {
|
|
982
|
+
display: "flex",
|
|
983
|
+
justifyContent: "center",
|
|
984
|
+
alignItems: "center",
|
|
985
|
+
background: "#f5f5f7",
|
|
986
|
+
borderRadius: 12,
|
|
987
|
+
padding: "12px 0",
|
|
988
|
+
marginTop: 8
|
|
989
|
+
},
|
|
990
|
+
children: /* @__PURE__ */ jsx12(ShareIconIOS, { size: 32, style: { color: "var(--hook-color-primary)" } })
|
|
991
|
+
}
|
|
992
|
+
)
|
|
993
|
+
}
|
|
994
|
+
),
|
|
995
|
+
/* @__PURE__ */ jsx12(
|
|
996
|
+
Step2,
|
|
997
|
+
{
|
|
998
|
+
n: 2,
|
|
999
|
+
title: copy.step2.title,
|
|
1000
|
+
visual: /* @__PURE__ */ jsxs6(
|
|
1001
|
+
"div",
|
|
1002
|
+
{
|
|
1003
|
+
style: {
|
|
1004
|
+
display: "flex",
|
|
1005
|
+
alignItems: "center",
|
|
1006
|
+
gap: 10,
|
|
1007
|
+
background: "#f5f5f7",
|
|
1008
|
+
borderRadius: 12,
|
|
1009
|
+
padding: "12px 14px",
|
|
1010
|
+
marginTop: 8
|
|
1011
|
+
},
|
|
1012
|
+
children: [
|
|
1013
|
+
/* @__PURE__ */ jsx12(SquarePlusIcon, { size: 22, style: { color: "#555" } }),
|
|
1014
|
+
/* @__PURE__ */ jsx12("span", { style: { fontSize: 14, color: "#333" }, children: copy.step2.iconLabel })
|
|
1015
|
+
]
|
|
1016
|
+
}
|
|
1017
|
+
)
|
|
1018
|
+
}
|
|
1019
|
+
),
|
|
1020
|
+
/* @__PURE__ */ jsx12(
|
|
1021
|
+
Step2,
|
|
1022
|
+
{
|
|
1023
|
+
n: 3,
|
|
1024
|
+
title: copy.step3.title,
|
|
1025
|
+
visual: /* @__PURE__ */ jsx12(
|
|
1026
|
+
"div",
|
|
1027
|
+
{
|
|
1028
|
+
style: {
|
|
1029
|
+
display: "flex",
|
|
1030
|
+
justifyContent: "flex-end",
|
|
1031
|
+
background: "#f5f5f7",
|
|
1032
|
+
borderRadius: 12,
|
|
1033
|
+
padding: "10px 14px",
|
|
1034
|
+
marginTop: 8
|
|
1035
|
+
},
|
|
1036
|
+
children: /* @__PURE__ */ jsx12(
|
|
1037
|
+
"span",
|
|
1038
|
+
{
|
|
1039
|
+
style: {
|
|
1040
|
+
color: "var(--hook-color-primary)",
|
|
1041
|
+
fontSize: 15,
|
|
1042
|
+
fontWeight: 600
|
|
1043
|
+
},
|
|
1044
|
+
children: copy.step3.buttonLabel
|
|
1045
|
+
}
|
|
1046
|
+
)
|
|
1047
|
+
}
|
|
1048
|
+
)
|
|
1049
|
+
}
|
|
1050
|
+
),
|
|
1051
|
+
/* @__PURE__ */ jsx12(
|
|
1052
|
+
"button",
|
|
1053
|
+
{
|
|
1054
|
+
"data-testid": "install-prompt-skip-session",
|
|
1055
|
+
type: "button",
|
|
1056
|
+
onClick: actions.dismissSession,
|
|
1057
|
+
style: { ...skipLinkStyle, marginTop: 16 },
|
|
1058
|
+
children: copy.skip
|
|
1059
|
+
}
|
|
1060
|
+
),
|
|
1061
|
+
showPermanent && /* @__PURE__ */ jsx12(
|
|
1062
|
+
"button",
|
|
1063
|
+
{
|
|
1064
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1065
|
+
type: "button",
|
|
1066
|
+
onClick: actions.dismissPermanent,
|
|
1067
|
+
style: skipPermanentLinkStyle,
|
|
1068
|
+
children: copy.skipPermanent
|
|
1069
|
+
}
|
|
1070
|
+
)
|
|
1071
|
+
] });
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/components/InstallGate/variants/IOSOtherVariant.tsx
|
|
1075
|
+
import { useState as useState4 } from "react";
|
|
1076
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1077
|
+
function IOSOtherVariant({
|
|
1078
|
+
state,
|
|
1079
|
+
actions
|
|
1080
|
+
}) {
|
|
1081
|
+
const copy = INSTALL_COPY.iosOther;
|
|
1082
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1083
|
+
const [copied, setCopied] = useState4(false);
|
|
1084
|
+
const [helpOpen, setHelpOpen] = useState4(false);
|
|
1085
|
+
const handleCopy = async () => {
|
|
1086
|
+
await actions.copyLink();
|
|
1087
|
+
setCopied(true);
|
|
1088
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1089
|
+
};
|
|
1090
|
+
const handleShowHelp = () => {
|
|
1091
|
+
if (!helpOpen) actions.showIOSOtherHelp();
|
|
1092
|
+
setHelpOpen(true);
|
|
1093
|
+
};
|
|
1094
|
+
return /* @__PURE__ */ jsxs7(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
1095
|
+
/* @__PURE__ */ jsx13(
|
|
1096
|
+
"button",
|
|
1097
|
+
{
|
|
1098
|
+
"data-testid": "install-prompt-cta-ios-other-primary",
|
|
1099
|
+
type: "button",
|
|
1100
|
+
onClick: handleShowHelp,
|
|
1101
|
+
"aria-expanded": helpOpen,
|
|
1102
|
+
style: primaryButtonStyle,
|
|
1103
|
+
children: copy.ctaPrimary
|
|
1104
|
+
}
|
|
1105
|
+
),
|
|
1106
|
+
/* @__PURE__ */ jsx13(
|
|
1107
|
+
"button",
|
|
1108
|
+
{
|
|
1109
|
+
"data-testid": "install-prompt-cta-ios-other-secondary",
|
|
1110
|
+
type: "button",
|
|
1111
|
+
onClick: () => void handleCopy(),
|
|
1112
|
+
style: secondaryButtonStyle,
|
|
1113
|
+
children: copied ? copy.copiedToast : copy.ctaSecondary
|
|
1114
|
+
}
|
|
1115
|
+
),
|
|
1116
|
+
helpOpen && /* @__PURE__ */ jsxs7(
|
|
1117
|
+
"div",
|
|
1118
|
+
{
|
|
1119
|
+
"data-testid": "install-prompt-ios-other-help",
|
|
1120
|
+
style: { marginTop: 20, textAlign: "left" },
|
|
1121
|
+
children: [
|
|
1122
|
+
/* @__PURE__ */ jsx13(
|
|
1123
|
+
Step2,
|
|
1124
|
+
{
|
|
1125
|
+
n: 1,
|
|
1126
|
+
title: copy.help.step1.title,
|
|
1127
|
+
subtitle: copy.help.step1.subtitle,
|
|
1128
|
+
visual: /* @__PURE__ */ jsx13(
|
|
1129
|
+
"div",
|
|
1130
|
+
{
|
|
1131
|
+
style: {
|
|
1132
|
+
display: "flex",
|
|
1133
|
+
justifyContent: "center",
|
|
1134
|
+
alignItems: "center",
|
|
1135
|
+
background: "#f5f5f7",
|
|
1136
|
+
borderRadius: 12,
|
|
1137
|
+
padding: "12px 0",
|
|
1138
|
+
marginTop: 8
|
|
1139
|
+
},
|
|
1140
|
+
children: /* @__PURE__ */ jsx13(
|
|
1141
|
+
MenuDotsHorizontalIcon,
|
|
1142
|
+
{
|
|
1143
|
+
size: 28,
|
|
1144
|
+
style: { color: "var(--hook-color-primary)" }
|
|
1145
|
+
}
|
|
1146
|
+
)
|
|
1147
|
+
}
|
|
1148
|
+
)
|
|
1149
|
+
}
|
|
1150
|
+
),
|
|
1151
|
+
/* @__PURE__ */ jsx13(
|
|
1152
|
+
Step2,
|
|
1153
|
+
{
|
|
1154
|
+
n: 2,
|
|
1155
|
+
title: copy.help.step2.title,
|
|
1156
|
+
subtitle: copy.help.step2.subtitle,
|
|
1157
|
+
visual: /* @__PURE__ */ jsxs7(
|
|
1158
|
+
"div",
|
|
1159
|
+
{
|
|
1160
|
+
style: {
|
|
1161
|
+
display: "flex",
|
|
1162
|
+
alignItems: "center",
|
|
1163
|
+
gap: 10,
|
|
1164
|
+
background: "#f5f5f7",
|
|
1165
|
+
borderRadius: 12,
|
|
1166
|
+
padding: "12px 14px",
|
|
1167
|
+
marginTop: 8
|
|
1168
|
+
},
|
|
1169
|
+
children: [
|
|
1170
|
+
/* @__PURE__ */ jsx13(ExternalLinkIcon, { size: 22, style: { color: "#555" } }),
|
|
1171
|
+
/* @__PURE__ */ jsx13("span", { style: { fontSize: 14, color: "#333" }, children: "Abrir no Safari" })
|
|
1172
|
+
]
|
|
1173
|
+
}
|
|
1174
|
+
)
|
|
1175
|
+
}
|
|
1176
|
+
)
|
|
1177
|
+
]
|
|
1178
|
+
}
|
|
1179
|
+
),
|
|
1180
|
+
/* @__PURE__ */ jsx13(
|
|
1181
|
+
"button",
|
|
1182
|
+
{
|
|
1183
|
+
"data-testid": "install-prompt-skip-session",
|
|
1184
|
+
type: "button",
|
|
1185
|
+
onClick: actions.dismissSession,
|
|
1186
|
+
style: skipLinkStyle,
|
|
1187
|
+
children: copy.skip
|
|
1188
|
+
}
|
|
1189
|
+
),
|
|
1190
|
+
showPermanent && /* @__PURE__ */ jsx13(
|
|
1191
|
+
"button",
|
|
1192
|
+
{
|
|
1193
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1194
|
+
type: "button",
|
|
1195
|
+
onClick: actions.dismissPermanent,
|
|
1196
|
+
style: skipPermanentLinkStyle,
|
|
1197
|
+
children: copy.skipPermanent
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
] });
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
// src/components/InstallGate/variants/InAppBrowserVariant.tsx
|
|
1204
|
+
import { useState as useState5 } from "react";
|
|
1205
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1206
|
+
function InAppBrowserVariant({
|
|
1207
|
+
state,
|
|
1208
|
+
actions
|
|
1209
|
+
}) {
|
|
1210
|
+
const app = state.inAppApp ?? "other";
|
|
1211
|
+
const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
|
|
1212
|
+
const copy = INSTALL_COPY.inApp;
|
|
1213
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1214
|
+
const [copied, setCopied] = useState5(false);
|
|
1215
|
+
const handleCopy = async () => {
|
|
1216
|
+
await actions.copyLink();
|
|
1217
|
+
setCopied(true);
|
|
1218
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1219
|
+
};
|
|
1220
|
+
const DotsIcon = app === "facebook" || app === "telegram" ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;
|
|
1221
|
+
return /* @__PURE__ */ jsxs8(InstallSplash, { title: appCopy.title, children: [
|
|
1222
|
+
/* @__PURE__ */ jsx14(Step3, { n: 1, icon: /* @__PURE__ */ jsx14(DotsIcon, { size: 20 }), children: appCopy.step1 }),
|
|
1223
|
+
/* @__PURE__ */ jsx14(Step3, { n: 2, icon: /* @__PURE__ */ jsx14(ExternalLinkIcon, { size: 18 }), children: appCopy.step2 }),
|
|
1224
|
+
/* @__PURE__ */ jsx14(
|
|
1225
|
+
"button",
|
|
1226
|
+
{
|
|
1227
|
+
"data-testid": "install-prompt-cta-inapp-copy",
|
|
1228
|
+
type: "button",
|
|
1229
|
+
onClick: () => void handleCopy(),
|
|
1230
|
+
style: { ...primaryButtonStyle, marginTop: 8 },
|
|
1231
|
+
children: copied ? copy.copiedToast : copy.copy
|
|
1232
|
+
}
|
|
1233
|
+
),
|
|
1234
|
+
/* @__PURE__ */ jsx14(
|
|
1235
|
+
"button",
|
|
1236
|
+
{
|
|
1237
|
+
"data-testid": "install-prompt-skip-session",
|
|
1238
|
+
type: "button",
|
|
1239
|
+
onClick: actions.dismissSession,
|
|
1240
|
+
style: skipLinkStyle,
|
|
1241
|
+
children: copy.skip
|
|
1242
|
+
}
|
|
1243
|
+
),
|
|
1244
|
+
showPermanent && /* @__PURE__ */ jsx14(
|
|
1245
|
+
"button",
|
|
1246
|
+
{
|
|
1247
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1248
|
+
type: "button",
|
|
1249
|
+
onClick: actions.dismissPermanent,
|
|
1250
|
+
style: skipPermanentLinkStyle,
|
|
1251
|
+
children: copy.skipPermanent
|
|
1252
|
+
}
|
|
1253
|
+
)
|
|
1254
|
+
] });
|
|
1255
|
+
}
|
|
1256
|
+
function Step3({
|
|
1257
|
+
n,
|
|
1258
|
+
icon,
|
|
1259
|
+
children
|
|
1260
|
+
}) {
|
|
1261
|
+
return /* @__PURE__ */ jsxs8(
|
|
1262
|
+
"div",
|
|
1263
|
+
{
|
|
1264
|
+
style: {
|
|
1265
|
+
display: "flex",
|
|
1266
|
+
alignItems: "center",
|
|
1267
|
+
gap: 12,
|
|
1268
|
+
padding: "12px 14px",
|
|
1269
|
+
background: "#f5f5f7",
|
|
1270
|
+
borderRadius: 12,
|
|
1271
|
+
marginBottom: 10,
|
|
1272
|
+
textAlign: "left"
|
|
1273
|
+
},
|
|
1274
|
+
children: [
|
|
1275
|
+
/* @__PURE__ */ jsx14(
|
|
1276
|
+
"div",
|
|
1277
|
+
{
|
|
1278
|
+
style: {
|
|
1279
|
+
width: 28,
|
|
1280
|
+
height: 28,
|
|
1281
|
+
borderRadius: "50%",
|
|
1282
|
+
background: "var(--hook-color-primary)",
|
|
1283
|
+
color: "#fff",
|
|
1284
|
+
display: "flex",
|
|
1285
|
+
alignItems: "center",
|
|
1286
|
+
justifyContent: "center",
|
|
1287
|
+
fontSize: 14,
|
|
1288
|
+
fontWeight: 700,
|
|
1289
|
+
flexShrink: 0
|
|
1290
|
+
},
|
|
1291
|
+
children: n
|
|
1292
|
+
}
|
|
1293
|
+
),
|
|
1294
|
+
/* @__PURE__ */ jsx14("div", { style: { flex: 1, fontSize: 14, color: "#333" }, children }),
|
|
1295
|
+
/* @__PURE__ */ jsx14("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
1296
|
+
]
|
|
1297
|
+
}
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// src/components/InstallGate/variants/DesktopVariant.tsx
|
|
1302
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1303
|
+
function DesktopVariant({
|
|
1304
|
+
state,
|
|
1305
|
+
actions
|
|
1306
|
+
}) {
|
|
1307
|
+
const { name, theme } = useTemplateConfig();
|
|
1308
|
+
const copy = INSTALL_COPY.desktop;
|
|
1309
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
1310
|
+
if (!state.isInstallable) return null;
|
|
1311
|
+
return /* @__PURE__ */ jsxs9(
|
|
1312
|
+
"div",
|
|
1313
|
+
{
|
|
1314
|
+
role: "complementary",
|
|
1315
|
+
"aria-label": copy.title,
|
|
1316
|
+
style: bannerStyle,
|
|
1317
|
+
children: [
|
|
1318
|
+
iconUrl ? /* @__PURE__ */ jsx15(
|
|
1319
|
+
"img",
|
|
1320
|
+
{
|
|
1321
|
+
src: iconUrl,
|
|
1322
|
+
alt: "",
|
|
1323
|
+
style: { width: 40, height: 40, borderRadius: 10, objectFit: "cover", flexShrink: 0 }
|
|
1324
|
+
}
|
|
1325
|
+
) : /* @__PURE__ */ jsx15(
|
|
1326
|
+
"div",
|
|
1327
|
+
{
|
|
1328
|
+
style: {
|
|
1329
|
+
width: 40,
|
|
1330
|
+
height: 40,
|
|
1331
|
+
borderRadius: 10,
|
|
1332
|
+
background: "var(--hook-color-primary)",
|
|
1333
|
+
color: "#fff",
|
|
1334
|
+
display: "flex",
|
|
1335
|
+
alignItems: "center",
|
|
1336
|
+
justifyContent: "center",
|
|
1337
|
+
fontSize: 18,
|
|
1338
|
+
fontWeight: 700,
|
|
1339
|
+
flexShrink: 0
|
|
1340
|
+
},
|
|
1341
|
+
children: name.charAt(0).toUpperCase()
|
|
1342
|
+
}
|
|
1343
|
+
),
|
|
1344
|
+
/* @__PURE__ */ jsxs9("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
1345
|
+
/* @__PURE__ */ jsx15("div", { style: { fontSize: 14, fontWeight: 600, color: "#111" }, children: copy.title }),
|
|
1346
|
+
/* @__PURE__ */ jsx15("div", { style: { fontSize: 12, color: "#666" }, children: copy.subtitle })
|
|
1347
|
+
] }),
|
|
1348
|
+
/* @__PURE__ */ jsxs9(
|
|
1349
|
+
"button",
|
|
1350
|
+
{
|
|
1351
|
+
"data-testid": "install-prompt-cta-desktop",
|
|
1352
|
+
type: "button",
|
|
1353
|
+
onClick: () => void actions.promptInstall(),
|
|
1354
|
+
style: {
|
|
1355
|
+
padding: "8px 14px",
|
|
1356
|
+
background: "var(--hook-color-primary)",
|
|
1357
|
+
color: "#fff",
|
|
1358
|
+
border: "none",
|
|
1359
|
+
borderRadius: 999,
|
|
1360
|
+
fontSize: 13,
|
|
1361
|
+
fontWeight: 600,
|
|
1362
|
+
cursor: "pointer",
|
|
1363
|
+
display: "inline-flex",
|
|
1364
|
+
alignItems: "center",
|
|
1365
|
+
gap: 6,
|
|
1366
|
+
flexShrink: 0
|
|
1367
|
+
},
|
|
1368
|
+
children: [
|
|
1369
|
+
/* @__PURE__ */ jsx15(DownloadIcon, { size: 14 }),
|
|
1370
|
+
copy.cta
|
|
1371
|
+
]
|
|
1372
|
+
}
|
|
1373
|
+
),
|
|
1374
|
+
/* @__PURE__ */ jsx15(
|
|
1375
|
+
"button",
|
|
1376
|
+
{
|
|
1377
|
+
"data-testid": "install-prompt-desktop-close",
|
|
1378
|
+
type: "button",
|
|
1379
|
+
onClick: actions.dismissPermanent,
|
|
1380
|
+
"aria-label": copy.close,
|
|
1381
|
+
style: {
|
|
1382
|
+
background: "transparent",
|
|
1383
|
+
border: "none",
|
|
1384
|
+
cursor: "pointer",
|
|
1385
|
+
color: "#888",
|
|
1386
|
+
padding: 4,
|
|
1387
|
+
flexShrink: 0
|
|
1388
|
+
},
|
|
1389
|
+
children: /* @__PURE__ */ jsx15(XIcon, { size: 16 })
|
|
1390
|
+
}
|
|
1391
|
+
)
|
|
1392
|
+
]
|
|
1393
|
+
}
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
var bannerStyle = {
|
|
1397
|
+
position: "fixed",
|
|
1398
|
+
bottom: 24,
|
|
1399
|
+
right: 24,
|
|
1400
|
+
zIndex: 1e4,
|
|
1401
|
+
display: "flex",
|
|
1402
|
+
alignItems: "center",
|
|
1403
|
+
gap: 12,
|
|
1404
|
+
padding: "12px 16px",
|
|
1405
|
+
background: "#fff",
|
|
1406
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
1407
|
+
borderRadius: 16,
|
|
1408
|
+
boxShadow: "0 10px 30px rgba(0,0,0,0.12)",
|
|
1409
|
+
maxWidth: 400
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1412
|
+
// src/components/InstallGate/InstallGate.tsx
|
|
1413
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1414
|
+
function InstallGate({ children }) {
|
|
1415
|
+
const { slug, features_enabled } = useTemplateConfig();
|
|
1416
|
+
const enabled = features_enabled.includes("install_prompt");
|
|
1417
|
+
const installState = useInstallPrompt(slug);
|
|
1418
|
+
const shouldBlock = enabled && shouldBlockInstall(installState);
|
|
1419
|
+
const trackedRef = useRef(null);
|
|
1420
|
+
useEffect4(() => {
|
|
1421
|
+
if (!shouldBlock) return;
|
|
1422
|
+
if (typeof window === "undefined") return;
|
|
1423
|
+
const variantKey = `${slug}:${installState.variant}`;
|
|
1424
|
+
if (trackedRef.current === variantKey) return;
|
|
1425
|
+
trackedRef.current = variantKey;
|
|
1426
|
+
window.posthog?.capture?.("pwa_install_splash_shown", {
|
|
1427
|
+
slug,
|
|
1428
|
+
platform: installState.platform,
|
|
1429
|
+
browser: installState.iosBrowser ?? installState.androidBrowser ?? null,
|
|
1430
|
+
in_app_app: installState.inAppApp,
|
|
1431
|
+
variant: installState.variant
|
|
1432
|
+
});
|
|
1433
|
+
}, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);
|
|
1434
|
+
if (!enabled) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1435
|
+
if (installState.isInstalled) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1436
|
+
if (installState.variant === "desktop") {
|
|
1437
|
+
return /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1438
|
+
children,
|
|
1439
|
+
/* @__PURE__ */ jsx16(DesktopVariant, { state: installState, actions: installState })
|
|
1440
|
+
] });
|
|
1441
|
+
}
|
|
1442
|
+
if (!shouldBlock) return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1443
|
+
switch (installState.variant) {
|
|
1444
|
+
case "android-native":
|
|
1445
|
+
return /* @__PURE__ */ jsx16(AndroidNativeVariant, { state: installState, actions: installState });
|
|
1446
|
+
case "android-manual":
|
|
1447
|
+
return /* @__PURE__ */ jsx16(AndroidManualVariant, { state: installState, actions: installState });
|
|
1448
|
+
case "ios-safari":
|
|
1449
|
+
return /* @__PURE__ */ jsx16(IOSafariVariant, { state: installState, actions: installState });
|
|
1450
|
+
case "ios-other":
|
|
1451
|
+
return /* @__PURE__ */ jsx16(IOSOtherVariant, { state: installState, actions: installState });
|
|
1452
|
+
case "in-app":
|
|
1453
|
+
return /* @__PURE__ */ jsx16(InAppBrowserVariant, { state: installState, actions: installState });
|
|
1454
|
+
case "none":
|
|
1455
|
+
default:
|
|
1456
|
+
return /* @__PURE__ */ jsx16(Fragment4, { children });
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
167
1460
|
// src/defaults/ErrorBoundary.tsx
|
|
168
1461
|
import { Component } from "react";
|
|
169
|
-
import { Fragment as
|
|
1462
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
170
1463
|
var ErrorBoundary = class extends Component {
|
|
171
1464
|
state = { error: null };
|
|
172
1465
|
static getDerivedStateFromError(error) {
|
|
@@ -177,17 +1470,17 @@ var ErrorBoundary = class extends Component {
|
|
|
177
1470
|
}
|
|
178
1471
|
render() {
|
|
179
1472
|
if (this.state.error) {
|
|
180
|
-
return this.props.fallback ?? /* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
/* @__PURE__ */
|
|
1473
|
+
return this.props.fallback ?? /* @__PURE__ */ jsxs11("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
1474
|
+
/* @__PURE__ */ jsx17("h2", { children: "Algo deu errado" }),
|
|
1475
|
+
/* @__PURE__ */ jsx17("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
183
1476
|
] });
|
|
184
1477
|
}
|
|
185
|
-
return /* @__PURE__ */
|
|
1478
|
+
return /* @__PURE__ */ jsx17(Fragment5, { children: this.props.children });
|
|
186
1479
|
}
|
|
187
1480
|
};
|
|
188
1481
|
|
|
189
1482
|
// src/hooks/useLoginForm.ts
|
|
190
|
-
import { useCallback as
|
|
1483
|
+
import { useCallback as useCallback3, useMemo as useMemo2, useState as useState6 } from "react";
|
|
191
1484
|
import { useHook as useHook4 } from "@hook-sdk/sdk";
|
|
192
1485
|
|
|
193
1486
|
// src/errors.ts
|
|
@@ -224,10 +1517,10 @@ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
224
1517
|
var MIN_PASSWORD = 8;
|
|
225
1518
|
function useLoginForm() {
|
|
226
1519
|
const { auth } = useHook4();
|
|
227
|
-
const [email, setEmail] =
|
|
228
|
-
const [password, setPassword] =
|
|
229
|
-
const [submitting, setSubmitting] =
|
|
230
|
-
const [error, setError] =
|
|
1520
|
+
const [email, setEmail] = useState6("");
|
|
1521
|
+
const [password, setPassword] = useState6("");
|
|
1522
|
+
const [submitting, setSubmitting] = useState6(false);
|
|
1523
|
+
const [error, setError] = useState6(null);
|
|
231
1524
|
const emailError = useMemo2(() => {
|
|
232
1525
|
if (email.length === 0) return null;
|
|
233
1526
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
@@ -239,7 +1532,7 @@ function useLoginForm() {
|
|
|
239
1532
|
return null;
|
|
240
1533
|
}, [password]);
|
|
241
1534
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
|
|
242
|
-
const submit =
|
|
1535
|
+
const submit = useCallback3(async () => {
|
|
243
1536
|
if (!canSubmit) return false;
|
|
244
1537
|
setSubmitting(true);
|
|
245
1538
|
setError(null);
|
|
@@ -269,13 +1562,13 @@ function useLoginForm() {
|
|
|
269
1562
|
}
|
|
270
1563
|
|
|
271
1564
|
// src/internal/GoogleSignInButton.tsx
|
|
272
|
-
import { jsx as
|
|
1565
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
273
1566
|
function GoogleSignInButton({
|
|
274
1567
|
onClick,
|
|
275
1568
|
testId = "oauth-google",
|
|
276
1569
|
label = "Continuar com Google"
|
|
277
1570
|
}) {
|
|
278
|
-
return /* @__PURE__ */
|
|
1571
|
+
return /* @__PURE__ */ jsxs12(
|
|
279
1572
|
"button",
|
|
280
1573
|
{
|
|
281
1574
|
"data-testid": testId,
|
|
@@ -298,36 +1591,36 @@ function GoogleSignInButton({
|
|
|
298
1591
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
299
1592
|
},
|
|
300
1593
|
children: [
|
|
301
|
-
/* @__PURE__ */
|
|
1594
|
+
/* @__PURE__ */ jsx18(GoogleGlyph, {}),
|
|
302
1595
|
label
|
|
303
1596
|
]
|
|
304
1597
|
}
|
|
305
1598
|
);
|
|
306
1599
|
}
|
|
307
1600
|
function GoogleGlyph() {
|
|
308
|
-
return /* @__PURE__ */
|
|
309
|
-
/* @__PURE__ */
|
|
1601
|
+
return /* @__PURE__ */ jsxs12("svg", { width: "18", height: "18", viewBox: "0 0 18 18", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
|
|
1602
|
+
/* @__PURE__ */ jsx18(
|
|
310
1603
|
"path",
|
|
311
1604
|
{
|
|
312
1605
|
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",
|
|
313
1606
|
fill: "#4285F4"
|
|
314
1607
|
}
|
|
315
1608
|
),
|
|
316
|
-
/* @__PURE__ */
|
|
1609
|
+
/* @__PURE__ */ jsx18(
|
|
317
1610
|
"path",
|
|
318
1611
|
{
|
|
319
1612
|
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",
|
|
320
1613
|
fill: "#34A853"
|
|
321
1614
|
}
|
|
322
1615
|
),
|
|
323
|
-
/* @__PURE__ */
|
|
1616
|
+
/* @__PURE__ */ jsx18(
|
|
324
1617
|
"path",
|
|
325
1618
|
{
|
|
326
1619
|
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",
|
|
327
1620
|
fill: "#FBBC05"
|
|
328
1621
|
}
|
|
329
1622
|
),
|
|
330
|
-
/* @__PURE__ */
|
|
1623
|
+
/* @__PURE__ */ jsx18(
|
|
331
1624
|
"path",
|
|
332
1625
|
{
|
|
333
1626
|
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",
|
|
@@ -338,8 +1631,8 @@ function GoogleGlyph() {
|
|
|
338
1631
|
}
|
|
339
1632
|
|
|
340
1633
|
// src/internal/OAuthErrorBanner.tsx
|
|
341
|
-
import { useEffect as
|
|
342
|
-
import { jsx as
|
|
1634
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
1635
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
343
1636
|
var ERROR_MESSAGES = {
|
|
344
1637
|
invalid_state: "Sess\xE3o expirou, tente de novo.",
|
|
345
1638
|
access_denied: "Voc\xEA cancelou o login com Google.",
|
|
@@ -359,13 +1652,13 @@ function stripErrorFromUrl() {
|
|
|
359
1652
|
window.history.replaceState({}, "", url.toString());
|
|
360
1653
|
}
|
|
361
1654
|
function OAuthErrorBanner() {
|
|
362
|
-
const [code, setCode] =
|
|
363
|
-
|
|
1655
|
+
const [code, setCode] = useState7(() => readErrorCode());
|
|
1656
|
+
useEffect5(() => {
|
|
364
1657
|
if (code !== null) stripErrorFromUrl();
|
|
365
1658
|
}, [code]);
|
|
366
1659
|
if (!code) return null;
|
|
367
1660
|
const message = ERROR_MESSAGES[code] ?? "N\xE3o conseguimos conectar ao Google. Tente de novo.";
|
|
368
|
-
return /* @__PURE__ */
|
|
1661
|
+
return /* @__PURE__ */ jsxs13(
|
|
369
1662
|
"div",
|
|
370
1663
|
{
|
|
371
1664
|
role: "alert",
|
|
@@ -380,7 +1673,7 @@ function OAuthErrorBanner() {
|
|
|
380
1673
|
},
|
|
381
1674
|
children: [
|
|
382
1675
|
message,
|
|
383
|
-
/* @__PURE__ */
|
|
1676
|
+
/* @__PURE__ */ jsx19(
|
|
384
1677
|
"button",
|
|
385
1678
|
{
|
|
386
1679
|
type: "button",
|
|
@@ -405,16 +1698,16 @@ function OAuthErrorBanner() {
|
|
|
405
1698
|
}
|
|
406
1699
|
|
|
407
1700
|
// src/defaults/DefaultLoginScreen.tsx
|
|
408
|
-
import { jsx as
|
|
1701
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
409
1702
|
function DefaultLoginScreen({ onNavigate }) {
|
|
410
1703
|
const { name } = useTemplateConfig();
|
|
411
1704
|
const f = useLoginForm();
|
|
412
|
-
return /* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
414
|
-
/* @__PURE__ */
|
|
415
|
-
/* @__PURE__ */
|
|
416
|
-
/* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
1705
|
+
return /* @__PURE__ */ jsxs14("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1706
|
+
/* @__PURE__ */ jsx20("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1707
|
+
/* @__PURE__ */ jsx20("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Entre na sua conta" }),
|
|
1708
|
+
/* @__PURE__ */ jsx20(OAuthErrorBanner, {}),
|
|
1709
|
+
/* @__PURE__ */ jsx20(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "login-oauth-google" }),
|
|
1710
|
+
/* @__PURE__ */ jsxs14(
|
|
418
1711
|
"div",
|
|
419
1712
|
{
|
|
420
1713
|
"aria-hidden": "true",
|
|
@@ -427,19 +1720,19 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
427
1720
|
fontSize: 12
|
|
428
1721
|
},
|
|
429
1722
|
children: [
|
|
430
|
-
/* @__PURE__ */
|
|
1723
|
+
/* @__PURE__ */ jsx20("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
431
1724
|
"ou",
|
|
432
|
-
/* @__PURE__ */
|
|
1725
|
+
/* @__PURE__ */ jsx20("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
433
1726
|
]
|
|
434
1727
|
}
|
|
435
1728
|
),
|
|
436
|
-
/* @__PURE__ */
|
|
1729
|
+
/* @__PURE__ */ jsxs14("form", { onSubmit: (e) => {
|
|
437
1730
|
e.preventDefault();
|
|
438
1731
|
void f.submit();
|
|
439
1732
|
}, children: [
|
|
440
|
-
/* @__PURE__ */
|
|
1733
|
+
/* @__PURE__ */ jsxs14("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
441
1734
|
"E-mail",
|
|
442
|
-
/* @__PURE__ */
|
|
1735
|
+
/* @__PURE__ */ jsx20(
|
|
443
1736
|
"input",
|
|
444
1737
|
{
|
|
445
1738
|
"data-testid": "login-email",
|
|
@@ -449,11 +1742,11 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
449
1742
|
style: { display: "block", width: "100%" }
|
|
450
1743
|
}
|
|
451
1744
|
),
|
|
452
|
-
f.emailError && /* @__PURE__ */
|
|
1745
|
+
f.emailError && /* @__PURE__ */ jsx20("small", { style: { color: "#c00" }, children: f.emailError })
|
|
453
1746
|
] }),
|
|
454
|
-
/* @__PURE__ */
|
|
1747
|
+
/* @__PURE__ */ jsxs14("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
455
1748
|
"Senha",
|
|
456
|
-
/* @__PURE__ */
|
|
1749
|
+
/* @__PURE__ */ jsx20(
|
|
457
1750
|
"input",
|
|
458
1751
|
{
|
|
459
1752
|
"data-testid": "login-password",
|
|
@@ -463,10 +1756,10 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
463
1756
|
style: { display: "block", width: "100%" }
|
|
464
1757
|
}
|
|
465
1758
|
),
|
|
466
|
-
f.passwordError && /* @__PURE__ */
|
|
1759
|
+
f.passwordError && /* @__PURE__ */ jsx20("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
467
1760
|
] }),
|
|
468
|
-
f.error && /* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
1761
|
+
f.error && /* @__PURE__ */ jsx20("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1762
|
+
/* @__PURE__ */ jsx20(
|
|
470
1763
|
"button",
|
|
471
1764
|
{
|
|
472
1765
|
"data-testid": "login-submit",
|
|
@@ -485,25 +1778,25 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
485
1778
|
}
|
|
486
1779
|
)
|
|
487
1780
|
] }),
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
490
|
-
/* @__PURE__ */
|
|
1781
|
+
/* @__PURE__ */ jsxs14("div", { style: { marginTop: 16, display: "flex", justifyContent: "space-between" }, children: [
|
|
1782
|
+
/* @__PURE__ */ jsx20("button", { "data-testid": "login-goto-signup", type: "button", onClick: () => onNavigate("signup"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Criar conta" }),
|
|
1783
|
+
/* @__PURE__ */ jsx20("button", { "data-testid": "login-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Esqueci senha" })
|
|
491
1784
|
] })
|
|
492
1785
|
] });
|
|
493
1786
|
}
|
|
494
1787
|
|
|
495
1788
|
// src/hooks/useSignupForm.ts
|
|
496
|
-
import { useCallback as
|
|
1789
|
+
import { useCallback as useCallback4, useMemo as useMemo3, useState as useState8 } from "react";
|
|
497
1790
|
import { useHook as useHook5 } from "@hook-sdk/sdk";
|
|
498
1791
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
499
1792
|
var MIN_PASSWORD2 = 8;
|
|
500
1793
|
function useSignupForm() {
|
|
501
1794
|
const { auth } = useHook5();
|
|
502
|
-
const [name, setName] =
|
|
503
|
-
const [email, setEmail] =
|
|
504
|
-
const [password, setPassword] =
|
|
505
|
-
const [submitting, setSubmitting] =
|
|
506
|
-
const [error, setError] =
|
|
1795
|
+
const [name, setName] = useState8("");
|
|
1796
|
+
const [email, setEmail] = useState8("");
|
|
1797
|
+
const [password, setPassword] = useState8("");
|
|
1798
|
+
const [submitting, setSubmitting] = useState8(false);
|
|
1799
|
+
const [error, setError] = useState8(null);
|
|
507
1800
|
const nameError = useMemo3(() => {
|
|
508
1801
|
if (name.length === 0) return null;
|
|
509
1802
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
@@ -520,7 +1813,7 @@ function useSignupForm() {
|
|
|
520
1813
|
return null;
|
|
521
1814
|
}, [password]);
|
|
522
1815
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
|
|
523
|
-
const submit =
|
|
1816
|
+
const submit = useCallback4(async () => {
|
|
524
1817
|
if (!canSubmit) return false;
|
|
525
1818
|
setSubmitting(true);
|
|
526
1819
|
setError(null);
|
|
@@ -553,16 +1846,16 @@ function useSignupForm() {
|
|
|
553
1846
|
}
|
|
554
1847
|
|
|
555
1848
|
// src/defaults/DefaultSignupScreen.tsx
|
|
556
|
-
import { jsx as
|
|
1849
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
557
1850
|
function DefaultSignupScreen({ onNavigate }) {
|
|
558
1851
|
const { name } = useTemplateConfig();
|
|
559
1852
|
const f = useSignupForm();
|
|
560
|
-
return /* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
564
|
-
/* @__PURE__ */
|
|
565
|
-
/* @__PURE__ */
|
|
1853
|
+
return /* @__PURE__ */ jsxs15("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1854
|
+
/* @__PURE__ */ jsx21("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1855
|
+
/* @__PURE__ */ jsx21("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Criar sua conta" }),
|
|
1856
|
+
/* @__PURE__ */ jsx21(OAuthErrorBanner, {}),
|
|
1857
|
+
/* @__PURE__ */ jsx21(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "signup-oauth-google" }),
|
|
1858
|
+
/* @__PURE__ */ jsxs15(
|
|
566
1859
|
"div",
|
|
567
1860
|
{
|
|
568
1861
|
"aria-hidden": "true",
|
|
@@ -575,55 +1868,55 @@ function DefaultSignupScreen({ onNavigate }) {
|
|
|
575
1868
|
fontSize: 12
|
|
576
1869
|
},
|
|
577
1870
|
children: [
|
|
578
|
-
/* @__PURE__ */
|
|
1871
|
+
/* @__PURE__ */ jsx21("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
579
1872
|
"ou",
|
|
580
|
-
/* @__PURE__ */
|
|
1873
|
+
/* @__PURE__ */ jsx21("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
581
1874
|
]
|
|
582
1875
|
}
|
|
583
1876
|
),
|
|
584
|
-
/* @__PURE__ */
|
|
1877
|
+
/* @__PURE__ */ jsxs15("form", { onSubmit: (e) => {
|
|
585
1878
|
e.preventDefault();
|
|
586
1879
|
void f.submit();
|
|
587
1880
|
}, children: [
|
|
588
|
-
/* @__PURE__ */
|
|
1881
|
+
/* @__PURE__ */ jsxs15("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
589
1882
|
"Nome",
|
|
590
|
-
/* @__PURE__ */
|
|
591
|
-
f.nameError && /* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx21("input", { "data-testid": "signup-name", value: f.name, onChange: (e) => f.setName(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1884
|
+
f.nameError && /* @__PURE__ */ jsx21("small", { style: { color: "#c00" }, children: f.nameError })
|
|
592
1885
|
] }),
|
|
593
|
-
/* @__PURE__ */
|
|
1886
|
+
/* @__PURE__ */ jsxs15("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
594
1887
|
"E-mail",
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
f.emailError && /* @__PURE__ */
|
|
1888
|
+
/* @__PURE__ */ jsx21("input", { "data-testid": "signup-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1889
|
+
f.emailError && /* @__PURE__ */ jsx21("small", { style: { color: "#c00" }, children: f.emailError })
|
|
597
1890
|
] }),
|
|
598
|
-
/* @__PURE__ */
|
|
1891
|
+
/* @__PURE__ */ jsxs15("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
599
1892
|
"Senha",
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
f.passwordError && /* @__PURE__ */
|
|
1893
|
+
/* @__PURE__ */ jsx21("input", { "data-testid": "signup-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1894
|
+
f.passwordError && /* @__PURE__ */ jsx21("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
602
1895
|
] }),
|
|
603
|
-
f.error && /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
1896
|
+
f.error && /* @__PURE__ */ jsx21("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1897
|
+
/* @__PURE__ */ jsx21("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" })
|
|
605
1898
|
] }),
|
|
606
|
-
/* @__PURE__ */
|
|
1899
|
+
/* @__PURE__ */ jsx21("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx21("button", { "data-testid": "signup-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "J\xE1 tem conta? Entre" }) })
|
|
607
1900
|
] });
|
|
608
1901
|
}
|
|
609
1902
|
|
|
610
1903
|
// src/hooks/useForgotForm.ts
|
|
611
|
-
import { useCallback as
|
|
1904
|
+
import { useCallback as useCallback5, useMemo as useMemo4, useState as useState9 } from "react";
|
|
612
1905
|
import { useHook as useHook6 } from "@hook-sdk/sdk";
|
|
613
1906
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
614
1907
|
function useForgotForm() {
|
|
615
1908
|
const { auth } = useHook6();
|
|
616
|
-
const [email, setEmail] =
|
|
617
|
-
const [submitting, setSubmitting] =
|
|
618
|
-
const [sent, setSent] =
|
|
619
|
-
const [error, setError] =
|
|
1909
|
+
const [email, setEmail] = useState9("");
|
|
1910
|
+
const [submitting, setSubmitting] = useState9(false);
|
|
1911
|
+
const [sent, setSent] = useState9(false);
|
|
1912
|
+
const [error, setError] = useState9(null);
|
|
620
1913
|
const emailError = useMemo4(() => {
|
|
621
1914
|
if (email.length === 0) return null;
|
|
622
1915
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
623
1916
|
return null;
|
|
624
1917
|
}, [email]);
|
|
625
1918
|
const canSubmit = email.length > 0 && emailError === null && !submitting;
|
|
626
|
-
const submit =
|
|
1919
|
+
const submit = useCallback5(async () => {
|
|
627
1920
|
if (!canSubmit) return false;
|
|
628
1921
|
setSubmitting(true);
|
|
629
1922
|
setError(null);
|
|
@@ -651,49 +1944,49 @@ function useForgotForm() {
|
|
|
651
1944
|
}
|
|
652
1945
|
|
|
653
1946
|
// src/defaults/DefaultForgotScreen.tsx
|
|
654
|
-
import { jsx as
|
|
1947
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
655
1948
|
function DefaultForgotScreen({ onNavigate }) {
|
|
656
1949
|
const { name } = useTemplateConfig();
|
|
657
1950
|
const f = useForgotForm();
|
|
658
1951
|
if (f.sent) {
|
|
659
|
-
return /* @__PURE__ */
|
|
660
|
-
/* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
1952
|
+
return /* @__PURE__ */ jsxs16("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
1953
|
+
/* @__PURE__ */ jsx22("h1", { children: "Verifique seu e-mail" }),
|
|
1954
|
+
/* @__PURE__ */ jsx22("p", { style: { opacity: 0.7 }, children: "Enviamos um link pra redefinir sua senha." }),
|
|
1955
|
+
/* @__PURE__ */ jsx22("button", { "data-testid": "forgot-back-login", type: "button", onClick: () => onNavigate("login"), children: "Voltar pro login" })
|
|
663
1956
|
] });
|
|
664
1957
|
}
|
|
665
|
-
return /* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
668
|
-
/* @__PURE__ */
|
|
1958
|
+
return /* @__PURE__ */ jsxs16("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1959
|
+
/* @__PURE__ */ jsx22("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1960
|
+
/* @__PURE__ */ jsx22("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Redefinir senha" }),
|
|
1961
|
+
/* @__PURE__ */ jsxs16("form", { onSubmit: (e) => {
|
|
669
1962
|
e.preventDefault();
|
|
670
1963
|
void f.submit();
|
|
671
1964
|
}, children: [
|
|
672
|
-
/* @__PURE__ */
|
|
1965
|
+
/* @__PURE__ */ jsxs16("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
673
1966
|
"E-mail",
|
|
674
|
-
/* @__PURE__ */
|
|
675
|
-
f.emailError && /* @__PURE__ */
|
|
1967
|
+
/* @__PURE__ */ jsx22("input", { "data-testid": "forgot-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1968
|
+
f.emailError && /* @__PURE__ */ jsx22("small", { style: { color: "#c00" }, children: f.emailError })
|
|
676
1969
|
] }),
|
|
677
|
-
f.error && /* @__PURE__ */
|
|
678
|
-
/* @__PURE__ */
|
|
1970
|
+
f.error && /* @__PURE__ */ jsx22("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1971
|
+
/* @__PURE__ */ jsx22("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" })
|
|
679
1972
|
] }),
|
|
680
|
-
/* @__PURE__ */
|
|
1973
|
+
/* @__PURE__ */ jsx22("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx22("button", { "data-testid": "forgot-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Voltar pro login" }) })
|
|
681
1974
|
] });
|
|
682
1975
|
}
|
|
683
1976
|
|
|
684
1977
|
// src/hooks/useResetForm.ts
|
|
685
|
-
import { useCallback as
|
|
1978
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo5, useState as useState10 } from "react";
|
|
686
1979
|
import { useHook as useHook7 } from "@hook-sdk/sdk";
|
|
687
1980
|
var MIN_PASSWORD3 = 12;
|
|
688
1981
|
function useResetForm() {
|
|
689
1982
|
const { auth } = useHook7();
|
|
690
|
-
const [token, setToken] =
|
|
691
|
-
const [password, setPassword] =
|
|
692
|
-
const [confirm, setConfirm] =
|
|
693
|
-
const [submitting, setSubmitting] =
|
|
694
|
-
const [done, setDone] =
|
|
695
|
-
const [error, setError] =
|
|
696
|
-
|
|
1983
|
+
const [token, setToken] = useState10(null);
|
|
1984
|
+
const [password, setPassword] = useState10("");
|
|
1985
|
+
const [confirm, setConfirm] = useState10("");
|
|
1986
|
+
const [submitting, setSubmitting] = useState10(false);
|
|
1987
|
+
const [done, setDone] = useState10(false);
|
|
1988
|
+
const [error, setError] = useState10(null);
|
|
1989
|
+
useEffect6(() => {
|
|
697
1990
|
if (typeof window === "undefined") return;
|
|
698
1991
|
const params = new URLSearchParams(window.location.search);
|
|
699
1992
|
const t = params.get("token");
|
|
@@ -710,7 +2003,7 @@ function useResetForm() {
|
|
|
710
2003
|
return null;
|
|
711
2004
|
}, [confirm, password]);
|
|
712
2005
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && passwordError === null && confirmError === null && !submitting && !done;
|
|
713
|
-
const submit =
|
|
2006
|
+
const submit = useCallback6(async () => {
|
|
714
2007
|
if (!canSubmit || token === null) return;
|
|
715
2008
|
setSubmitting(true);
|
|
716
2009
|
setError(null);
|
|
@@ -746,67 +2039,67 @@ function useResetForm() {
|
|
|
746
2039
|
}
|
|
747
2040
|
|
|
748
2041
|
// src/defaults/DefaultResetScreen.tsx
|
|
749
|
-
import { jsx as
|
|
2042
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
750
2043
|
function DefaultResetScreen({ onNavigate }) {
|
|
751
2044
|
const { name } = useTemplateConfig();
|
|
752
2045
|
const f = useResetForm();
|
|
753
2046
|
if (f.done) {
|
|
754
|
-
return /* @__PURE__ */
|
|
755
|
-
/* @__PURE__ */
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
2047
|
+
return /* @__PURE__ */ jsxs17("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
2048
|
+
/* @__PURE__ */ jsx23("h1", { children: "Senha alterada" }),
|
|
2049
|
+
/* @__PURE__ */ jsx23("p", { style: { opacity: 0.7 }, children: "Agora \xE9 s\xF3 fazer login com a nova senha." }),
|
|
2050
|
+
/* @__PURE__ */ jsx23("button", { "data-testid": "reset-back-login", type: "button", onClick: () => onNavigate("login"), children: "Ir pro login" })
|
|
758
2051
|
] });
|
|
759
2052
|
}
|
|
760
2053
|
if (f.token === null) {
|
|
761
|
-
return /* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
764
|
-
/* @__PURE__ */
|
|
2054
|
+
return /* @__PURE__ */ jsxs17("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
2055
|
+
/* @__PURE__ */ jsx23("h1", { children: "Link inv\xE1lido" }),
|
|
2056
|
+
/* @__PURE__ */ jsx23("p", { style: { opacity: 0.7 }, children: "Pe\xE7a um novo link de reset." }),
|
|
2057
|
+
/* @__PURE__ */ jsx23("button", { "data-testid": "reset-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), children: "Pedir novo link" })
|
|
765
2058
|
] });
|
|
766
2059
|
}
|
|
767
|
-
return /* @__PURE__ */
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
2060
|
+
return /* @__PURE__ */ jsxs17("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
2061
|
+
/* @__PURE__ */ jsx23("h1", { style: { marginBottom: 8 }, children: name }),
|
|
2062
|
+
/* @__PURE__ */ jsx23("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Escolha uma nova senha" }),
|
|
2063
|
+
/* @__PURE__ */ jsxs17("form", { onSubmit: (e) => {
|
|
771
2064
|
e.preventDefault();
|
|
772
2065
|
void f.submit();
|
|
773
2066
|
}, children: [
|
|
774
|
-
/* @__PURE__ */
|
|
2067
|
+
/* @__PURE__ */ jsxs17("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
775
2068
|
"Nova senha",
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
f.passwordError && /* @__PURE__ */
|
|
2069
|
+
/* @__PURE__ */ jsx23("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" }),
|
|
2070
|
+
f.passwordError && /* @__PURE__ */ jsx23("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
778
2071
|
] }),
|
|
779
|
-
/* @__PURE__ */
|
|
2072
|
+
/* @__PURE__ */ jsxs17("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
780
2073
|
"Confirmar senha",
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
f.confirmError && /* @__PURE__ */
|
|
2074
|
+
/* @__PURE__ */ jsx23("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" }),
|
|
2075
|
+
f.confirmError && /* @__PURE__ */ jsx23("small", { style: { color: "#c00" }, children: f.confirmError })
|
|
783
2076
|
] }),
|
|
784
|
-
f.error && /* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
2077
|
+
f.error && /* @__PURE__ */ jsx23("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
2078
|
+
/* @__PURE__ */ jsx23("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" })
|
|
786
2079
|
] })
|
|
787
2080
|
] });
|
|
788
2081
|
}
|
|
789
2082
|
|
|
790
2083
|
// src/defaults/DefaultPaywall.tsx
|
|
791
|
-
import { useState as
|
|
792
|
-
import { jsx as
|
|
2084
|
+
import { useState as useState11 } from "react";
|
|
2085
|
+
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
793
2086
|
function DefaultPaywall() {
|
|
794
2087
|
const config = useTemplateConfig();
|
|
795
2088
|
const { checkout, opening, error } = usePaywallState();
|
|
796
2089
|
const p = config.subscription.paywall_config;
|
|
797
|
-
const [cpf, setCpf] =
|
|
2090
|
+
const [cpf, setCpf] = useState11("");
|
|
798
2091
|
const cpfDigits = cpf.replace(/\D/g, "");
|
|
799
2092
|
const canCheckout = cpfDigits.length === 11 && !opening;
|
|
800
|
-
return /* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
p.subtitle && /* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
/* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
2093
|
+
return /* @__PURE__ */ jsxs18("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
|
|
2094
|
+
/* @__PURE__ */ jsx24("h1", { style: { marginBottom: 8 }, children: p.title }),
|
|
2095
|
+
p.subtitle && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
|
|
2096
|
+
/* @__PURE__ */ jsx24("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", marginBottom: 24 }, children: p.benefits.map((b) => /* @__PURE__ */ jsxs18("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
|
|
2097
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
|
|
2098
|
+
/* @__PURE__ */ jsx24("span", { children: b })
|
|
806
2099
|
] }, b)) }),
|
|
807
|
-
/* @__PURE__ */
|
|
808
|
-
/* @__PURE__ */
|
|
809
|
-
/* @__PURE__ */
|
|
2100
|
+
/* @__PURE__ */ jsxs18("div", { style: { textAlign: "left", marginBottom: 16 }, children: [
|
|
2101
|
+
/* @__PURE__ */ jsx24("label", { style: { display: "block", fontSize: 14, opacity: 0.7, marginBottom: 4 }, children: "Seu CPF (pra emiss\xE3o de recibo)" }),
|
|
2102
|
+
/* @__PURE__ */ jsx24(
|
|
810
2103
|
"input",
|
|
811
2104
|
{
|
|
812
2105
|
"data-testid": "paywall-cpf",
|
|
@@ -819,8 +2112,8 @@ function DefaultPaywall() {
|
|
|
819
2112
|
}
|
|
820
2113
|
)
|
|
821
2114
|
] }),
|
|
822
|
-
error && /* @__PURE__ */
|
|
823
|
-
/* @__PURE__ */
|
|
2115
|
+
error && /* @__PURE__ */ jsx24("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: error.message }),
|
|
2116
|
+
/* @__PURE__ */ jsx24(
|
|
824
2117
|
"button",
|
|
825
2118
|
{
|
|
826
2119
|
"data-testid": "paywall-cta",
|
|
@@ -841,21 +2134,21 @@ function DefaultPaywall() {
|
|
|
841
2134
|
children: opening ? "Abrindo..." : p.cta
|
|
842
2135
|
}
|
|
843
2136
|
),
|
|
844
|
-
p.priceHint && /* @__PURE__ */
|
|
845
|
-
p.footerNote && /* @__PURE__ */
|
|
2137
|
+
p.priceHint && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.6, marginTop: 12 }, children: p.priceHint }),
|
|
2138
|
+
p.footerNote && /* @__PURE__ */ jsx24("p", { style: { opacity: 0.5, marginTop: 16, fontSize: 12 }, children: p.footerNote })
|
|
846
2139
|
] });
|
|
847
2140
|
}
|
|
848
2141
|
|
|
849
2142
|
// src/AppRoot.tsx
|
|
850
|
-
import { Fragment as
|
|
2143
|
+
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
851
2144
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
852
2145
|
function PaymentReturnHandler({ children }) {
|
|
853
2146
|
const { subscription } = useHook8();
|
|
854
|
-
const subRef =
|
|
2147
|
+
const subRef = useRef2(subscription);
|
|
855
2148
|
subRef.current = subscription;
|
|
856
|
-
const runIdRef =
|
|
857
|
-
const [state, setState] =
|
|
858
|
-
const runPoll =
|
|
2149
|
+
const runIdRef = useRef2(0);
|
|
2150
|
+
const [state, setState] = useState12("idle");
|
|
2151
|
+
const runPoll = useCallback7(() => {
|
|
859
2152
|
const runId = ++runIdRef.current;
|
|
860
2153
|
setState("confirming");
|
|
861
2154
|
let attempts = 0;
|
|
@@ -884,7 +2177,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
884
2177
|
};
|
|
885
2178
|
void tick();
|
|
886
2179
|
}, []);
|
|
887
|
-
|
|
2180
|
+
useEffect7(() => {
|
|
888
2181
|
if (typeof window === "undefined") return;
|
|
889
2182
|
const url = new URL(window.location.href);
|
|
890
2183
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -894,20 +2187,20 @@ function PaymentReturnHandler({ children }) {
|
|
|
894
2187
|
};
|
|
895
2188
|
}, [runPoll]);
|
|
896
2189
|
if (state === "confirming") {
|
|
897
|
-
return /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsx25(
|
|
898
2191
|
"div",
|
|
899
2192
|
{
|
|
900
2193
|
role: "status",
|
|
901
2194
|
"aria-live": "polite",
|
|
902
|
-
style:
|
|
2195
|
+
style: overlayStyle2,
|
|
903
2196
|
children: "Confirmando pagamento\u2026"
|
|
904
2197
|
}
|
|
905
2198
|
);
|
|
906
2199
|
}
|
|
907
2200
|
if (state === "waiting") {
|
|
908
|
-
return /* @__PURE__ */
|
|
909
|
-
/* @__PURE__ */
|
|
910
|
-
/* @__PURE__ */
|
|
2201
|
+
return /* @__PURE__ */ jsx25("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs19("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2202
|
+
/* @__PURE__ */ jsx25("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2203
|
+
/* @__PURE__ */ jsx25(
|
|
911
2204
|
"button",
|
|
912
2205
|
{
|
|
913
2206
|
type: "button",
|
|
@@ -918,9 +2211,9 @@ function PaymentReturnHandler({ children }) {
|
|
|
918
2211
|
)
|
|
919
2212
|
] }) });
|
|
920
2213
|
}
|
|
921
|
-
return /* @__PURE__ */
|
|
2214
|
+
return /* @__PURE__ */ jsx25(Fragment6, { children });
|
|
922
2215
|
}
|
|
923
|
-
var
|
|
2216
|
+
var overlayStyle2 = {
|
|
924
2217
|
position: "fixed",
|
|
925
2218
|
inset: 0,
|
|
926
2219
|
display: "flex",
|
|
@@ -951,14 +2244,14 @@ function AppRoot({
|
|
|
951
2244
|
Reset = DefaultResetScreen,
|
|
952
2245
|
Paywall = DefaultPaywall
|
|
953
2246
|
}) {
|
|
954
|
-
return /* @__PURE__ */
|
|
2247
|
+
return /* @__PURE__ */ jsx25(PaymentReturnHandler, { children: /* @__PURE__ */ jsx25(TemplateConfigProvider, { config, children: /* @__PURE__ */ jsx25(ErrorBoundary, { children: /* @__PURE__ */ jsx25(ThemeProvider, { children: /* @__PURE__ */ jsx25(InstallGate, { children: /* @__PURE__ */ jsx25(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ jsx25(PersistedKeysPrefetch, { children: /* @__PURE__ */ jsxs19(SubscriptionGate, { Paywall, children: [
|
|
955
2248
|
children,
|
|
956
|
-
/* @__PURE__ */
|
|
957
|
-
] }) }) }) }) }) }) });
|
|
2249
|
+
/* @__PURE__ */ jsx25(PushPrompt, {})
|
|
2250
|
+
] }) }) }) }) }) }) }) });
|
|
958
2251
|
}
|
|
959
2252
|
|
|
960
2253
|
// src/hooks/usePush.ts
|
|
961
|
-
import { useCallback as
|
|
2254
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useState as useState13 } from "react";
|
|
962
2255
|
import { useHook as useHook9 } from "@hook-sdk/sdk";
|
|
963
2256
|
function detectIosNeedsInstall() {
|
|
964
2257
|
if (typeof navigator === "undefined" || typeof window === "undefined") return false;
|
|
@@ -986,11 +2279,11 @@ function deriveState(push) {
|
|
|
986
2279
|
}
|
|
987
2280
|
function usePush() {
|
|
988
2281
|
const { push } = useHook9();
|
|
989
|
-
const [state, setState] =
|
|
990
|
-
|
|
2282
|
+
const [state, setState] = useState13(() => deriveState(push));
|
|
2283
|
+
useEffect8(() => {
|
|
991
2284
|
setState(deriveState(push));
|
|
992
2285
|
}, [push]);
|
|
993
|
-
const subscribe =
|
|
2286
|
+
const subscribe = useCallback8(async () => {
|
|
994
2287
|
try {
|
|
995
2288
|
await push.subscribe();
|
|
996
2289
|
setState({ kind: "subscribed" });
|
|
@@ -1002,7 +2295,7 @@ function usePush() {
|
|
|
1002
2295
|
throw e;
|
|
1003
2296
|
}
|
|
1004
2297
|
}, [push]);
|
|
1005
|
-
const unsubscribe =
|
|
2298
|
+
const unsubscribe = useCallback8(async () => {
|
|
1006
2299
|
try {
|
|
1007
2300
|
await push.unsubscribe();
|
|
1008
2301
|
setState({ kind: "prompt" });
|
|
@@ -1015,31 +2308,31 @@ function usePush() {
|
|
|
1015
2308
|
}
|
|
1016
2309
|
|
|
1017
2310
|
// src/components/PushPrompt.tsx
|
|
1018
|
-
import { jsx as
|
|
2311
|
+
import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1019
2312
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
1020
2313
|
const { state, subscribe } = usePush();
|
|
1021
2314
|
if (state.kind === "subscribed") return null;
|
|
1022
2315
|
if (state.kind === "ios_needs_install") {
|
|
1023
|
-
return /* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */
|
|
2316
|
+
return /* @__PURE__ */ jsxs20("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2317
|
+
/* @__PURE__ */ jsx26("h3", { children: texts.iosInstallTitle }),
|
|
2318
|
+
/* @__PURE__ */ jsx26("p", { children: texts.iosInstallBody }),
|
|
2319
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx26("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
1027
2320
|
] });
|
|
1028
2321
|
}
|
|
1029
2322
|
if (state.kind === "denied") {
|
|
1030
|
-
return /* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
2323
|
+
return /* @__PURE__ */ jsxs20("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
|
|
2324
|
+
/* @__PURE__ */ jsx26("h3", { children: texts.deniedTitle }),
|
|
2325
|
+
/* @__PURE__ */ jsx26("p", { children: texts.deniedBody })
|
|
1033
2326
|
] });
|
|
1034
2327
|
}
|
|
1035
2328
|
if (state.kind === "unsupported") {
|
|
1036
|
-
return /* @__PURE__ */
|
|
2329
|
+
return /* @__PURE__ */ jsx26("div", { className, role: "region", children: /* @__PURE__ */ jsx26("p", { children: texts.unsupportedBody }) });
|
|
1037
2330
|
}
|
|
1038
2331
|
if (state.kind === "error") {
|
|
1039
|
-
return /* @__PURE__ */
|
|
2332
|
+
return /* @__PURE__ */ jsx26("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx26("p", { children: state.message }) });
|
|
1040
2333
|
}
|
|
1041
|
-
return /* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
2334
|
+
return /* @__PURE__ */ jsxs20("div", { className, role: "region", children: [
|
|
2335
|
+
/* @__PURE__ */ jsx26(
|
|
1043
2336
|
"button",
|
|
1044
2337
|
{
|
|
1045
2338
|
type: "button",
|
|
@@ -1053,27 +2346,27 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
1053
2346
|
children: texts.cta
|
|
1054
2347
|
}
|
|
1055
2348
|
),
|
|
1056
|
-
onDeclined && /* @__PURE__ */
|
|
2349
|
+
onDeclined && /* @__PURE__ */ jsx26("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
1057
2350
|
] });
|
|
1058
2351
|
}
|
|
1059
2352
|
|
|
1060
2353
|
// src/defaults/EmptyState.tsx
|
|
1061
|
-
import { jsx as
|
|
2354
|
+
import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1062
2355
|
function EmptyState({ title, description, action }) {
|
|
1063
|
-
return /* @__PURE__ */
|
|
1064
|
-
/* @__PURE__ */
|
|
1065
|
-
description && /* @__PURE__ */
|
|
1066
|
-
action && /* @__PURE__ */
|
|
2356
|
+
return /* @__PURE__ */ jsxs21("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2357
|
+
/* @__PURE__ */ jsx27("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2358
|
+
description && /* @__PURE__ */ jsx27("p", { style: { opacity: 0.7 }, children: description }),
|
|
2359
|
+
action && /* @__PURE__ */ jsx27("div", { style: { marginTop: 16 }, children: action })
|
|
1067
2360
|
] });
|
|
1068
2361
|
}
|
|
1069
2362
|
|
|
1070
2363
|
// src/hooks/useAuthPrimitives.ts
|
|
1071
|
-
import { useEffect as
|
|
2364
|
+
import { useEffect as useEffect9 } from "react";
|
|
1072
2365
|
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
1073
2366
|
var warned = false;
|
|
1074
2367
|
function useAuthPrimitives() {
|
|
1075
2368
|
const { auth } = useHook10();
|
|
1076
|
-
|
|
2369
|
+
useEffect9(() => {
|
|
1077
2370
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
1078
2371
|
warned = true;
|
|
1079
2372
|
console.warn(
|
|
@@ -1104,14 +2397,14 @@ function useSubscription() {
|
|
|
1104
2397
|
}
|
|
1105
2398
|
|
|
1106
2399
|
// src/hooks/useReminders.ts
|
|
1107
|
-
import { useCallback as
|
|
2400
|
+
import { useCallback as useCallback9, useEffect as useEffect10, useState as useState14 } from "react";
|
|
1108
2401
|
import { useHook as useHook12 } from "@hook-sdk/sdk";
|
|
1109
2402
|
function useReminders() {
|
|
1110
2403
|
const { push } = useHook12();
|
|
1111
2404
|
const r = push.reminders;
|
|
1112
|
-
const [reminders, setReminders] =
|
|
1113
|
-
const [loading, setLoading] =
|
|
1114
|
-
const reload =
|
|
2405
|
+
const [reminders, setReminders] = useState14([]);
|
|
2406
|
+
const [loading, setLoading] = useState14(true);
|
|
2407
|
+
const reload = useCallback9(async () => {
|
|
1115
2408
|
setLoading(true);
|
|
1116
2409
|
try {
|
|
1117
2410
|
const next = await r.list();
|
|
@@ -1120,38 +2413,38 @@ function useReminders() {
|
|
|
1120
2413
|
setLoading(false);
|
|
1121
2414
|
}
|
|
1122
2415
|
}, [r]);
|
|
1123
|
-
|
|
2416
|
+
useEffect10(() => {
|
|
1124
2417
|
void reload();
|
|
1125
2418
|
}, [reload]);
|
|
1126
|
-
const setReminder =
|
|
2419
|
+
const setReminder = useCallback9(async (input) => {
|
|
1127
2420
|
await r.set(input);
|
|
1128
2421
|
await reload();
|
|
1129
2422
|
}, [r, reload]);
|
|
1130
|
-
const deleteReminder =
|
|
2423
|
+
const deleteReminder = useCallback9(async (slot) => {
|
|
1131
2424
|
await r.delete(slot);
|
|
1132
2425
|
await reload();
|
|
1133
2426
|
}, [r, reload]);
|
|
1134
|
-
const schedule =
|
|
2427
|
+
const schedule = useCallback9(async (items) => {
|
|
1135
2428
|
return r.schedule(items);
|
|
1136
2429
|
}, [r]);
|
|
1137
|
-
const setFallbacks =
|
|
2430
|
+
const setFallbacks = useCallback9(async (items) => {
|
|
1138
2431
|
return r.setFallbacks(items);
|
|
1139
2432
|
}, [r]);
|
|
1140
2433
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
1141
2434
|
}
|
|
1142
2435
|
|
|
1143
2436
|
// src/hooks/useToast.ts
|
|
1144
|
-
import { useCallback as
|
|
2437
|
+
import { useCallback as useCallback10, useState as useState15 } from "react";
|
|
1145
2438
|
function useToast() {
|
|
1146
|
-
const [items, setItems] =
|
|
1147
|
-
const show =
|
|
2439
|
+
const [items, setItems] = useState15([]);
|
|
2440
|
+
const show = useCallback10((message, kind = "info") => {
|
|
1148
2441
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1149
2442
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
1150
2443
|
setTimeout(() => {
|
|
1151
2444
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1152
2445
|
}, 4e3);
|
|
1153
2446
|
}, []);
|
|
1154
|
-
const dismiss =
|
|
2447
|
+
const dismiss = useCallback10((id) => {
|
|
1155
2448
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1156
2449
|
}, []);
|
|
1157
2450
|
return { items, show, dismiss };
|
|
@@ -1165,11 +2458,21 @@ export {
|
|
|
1165
2458
|
DefaultSignupScreen,
|
|
1166
2459
|
EmptyState,
|
|
1167
2460
|
ErrorBoundary,
|
|
2461
|
+
InstallGate,
|
|
2462
|
+
InstallSplash,
|
|
1168
2463
|
LoadingState,
|
|
1169
2464
|
PushPrompt2 as PushPrompt,
|
|
2465
|
+
detectAndroidBrowser,
|
|
2466
|
+
detectIOSBrowser,
|
|
2467
|
+
detectInAppApp,
|
|
2468
|
+
detectPlatform,
|
|
2469
|
+
detectStandalone,
|
|
2470
|
+
shouldBlockInstall,
|
|
2471
|
+
shouldShowPermanentOption,
|
|
1170
2472
|
useAuth,
|
|
1171
2473
|
useAuthPrimitives,
|
|
1172
2474
|
useForgotForm,
|
|
2475
|
+
useInstallPrompt,
|
|
1173
2476
|
useLoginForm,
|
|
1174
2477
|
usePaywallState,
|
|
1175
2478
|
usePush,
|