@hook-sdk/template 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1442 -206
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +1423 -197
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.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,1225 @@ 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 redirectToSafari = useCallback2(() => {
|
|
406
|
+
if (typeof location === "undefined") return;
|
|
407
|
+
track("pwa_install_redirect_to_safari", { slug });
|
|
408
|
+
const url = `safari-https://${location.host}${location.pathname}${location.search}${location.hash}`;
|
|
409
|
+
try {
|
|
410
|
+
window.location.href = url;
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
}, [slug]);
|
|
414
|
+
const copyLink = useCallback2(async () => {
|
|
415
|
+
if (typeof navigator === "undefined" || typeof location === "undefined") return;
|
|
416
|
+
try {
|
|
417
|
+
await navigator.clipboard?.writeText?.(location.href);
|
|
418
|
+
} catch {
|
|
419
|
+
}
|
|
420
|
+
}, []);
|
|
421
|
+
const reset = useCallback2(() => {
|
|
422
|
+
const storage = safeStorage();
|
|
423
|
+
if (storage) {
|
|
424
|
+
storage.removeItem(storageKey.dismissedAt(slug));
|
|
425
|
+
storage.removeItem(storageKey.installedAt(slug));
|
|
426
|
+
storage.removeItem(storageKey.skipCount(slug));
|
|
427
|
+
}
|
|
428
|
+
if (typeof sessionStorage !== "undefined") {
|
|
429
|
+
try {
|
|
430
|
+
sessionStorage.removeItem(storageKey.sessionSkip(slug));
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
setIsDismissedSession(false);
|
|
435
|
+
setIsDismissedPermanent(false);
|
|
436
|
+
setSkipCount(0);
|
|
437
|
+
}, [slug]);
|
|
438
|
+
return {
|
|
439
|
+
platform,
|
|
440
|
+
iosBrowser,
|
|
441
|
+
androidBrowser,
|
|
442
|
+
inAppApp,
|
|
443
|
+
isInstallable,
|
|
444
|
+
isInstalled,
|
|
445
|
+
isDismissedSession,
|
|
446
|
+
isDismissedPermanent,
|
|
447
|
+
skipCount,
|
|
448
|
+
variant,
|
|
449
|
+
promptInstall,
|
|
450
|
+
dismissSession,
|
|
451
|
+
dismissPermanent,
|
|
452
|
+
redirectToSafari,
|
|
453
|
+
copyLink,
|
|
454
|
+
reset
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function shouldBlockInstall(state, now = Date.now()) {
|
|
458
|
+
if (state.isInstalled) return false;
|
|
459
|
+
if (state.variant === "none") return false;
|
|
460
|
+
if (state.isDismissedSession) return false;
|
|
461
|
+
if (state.isDismissedPermanent) {
|
|
462
|
+
void now;
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
if (state.platform === "desktop" && !state.isInstallable) return false;
|
|
466
|
+
if (state.platform === "unknown") return false;
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
function shouldShowPermanentOption(state) {
|
|
470
|
+
return state.skipCount >= SESSION_SKIPS_BEFORE_PERMANENT_OPTION;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// src/components/InstallGate/copy.ts
|
|
474
|
+
var INSTALL_COPY = {
|
|
475
|
+
android: {
|
|
476
|
+
native: {
|
|
477
|
+
title: "Instale no seu celular",
|
|
478
|
+
subtitle: "Acesso r\xE1pido, sem precisar do navegador",
|
|
479
|
+
cta: "Baixar",
|
|
480
|
+
skip: "Continuar no navegador",
|
|
481
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
482
|
+
},
|
|
483
|
+
manual: {
|
|
484
|
+
title: "Instale em 2 toques",
|
|
485
|
+
subtitle: 'Toque no menu do navegador e escolha "Instalar aplicativo"',
|
|
486
|
+
step1: "Toque no menu do navegador",
|
|
487
|
+
step2: 'Escolha "Instalar aplicativo"',
|
|
488
|
+
cta: "Entendi",
|
|
489
|
+
skip: "Continuar no navegador",
|
|
490
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
iosSafari: {
|
|
494
|
+
title: "Adicione \xE0 sua Tela de In\xEDcio",
|
|
495
|
+
subtitle: "Siga os 3 passos",
|
|
496
|
+
step1: {
|
|
497
|
+
title: "Toque em Compartilhar",
|
|
498
|
+
subtitle: "Na barra inferior do Safari"
|
|
499
|
+
},
|
|
500
|
+
step2: {
|
|
501
|
+
title: 'Role e toque em "Adicionar \xE0 Tela de In\xEDcio"',
|
|
502
|
+
iconLabel: "Adicionar \xE0 Tela de In\xEDcio"
|
|
503
|
+
},
|
|
504
|
+
step3: {
|
|
505
|
+
title: 'Toque em "Adicionar" pra confirmar',
|
|
506
|
+
buttonLabel: "Adicionar"
|
|
507
|
+
},
|
|
508
|
+
skip: "Continuar no Safari",
|
|
509
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
510
|
+
},
|
|
511
|
+
iosOther: {
|
|
512
|
+
title: "Abra no Safari pra instalar",
|
|
513
|
+
subtitle: "No Chrome/Firefox/Edge do iPhone n\xE3o d\xE1 pra instalar PWA. Abra o link no Safari.",
|
|
514
|
+
ctaPrimary: "Abrir no Safari",
|
|
515
|
+
ctaSecondary: "Copiar link",
|
|
516
|
+
copiedToast: "Link copiado. Cole no Safari.",
|
|
517
|
+
skip: "Continuar mesmo assim",
|
|
518
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
519
|
+
},
|
|
520
|
+
inApp: {
|
|
521
|
+
instagram: {
|
|
522
|
+
title: "Pra instalar, abra fora do Instagram",
|
|
523
|
+
step1: "Toque em \u22EF (canto superior direito)",
|
|
524
|
+
step2: 'Escolha "Abrir no navegador externo"'
|
|
525
|
+
},
|
|
526
|
+
facebook: {
|
|
527
|
+
title: "Pra instalar, abra fora do Facebook",
|
|
528
|
+
step1: "Toque em \u22EE",
|
|
529
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
530
|
+
},
|
|
531
|
+
tiktok: {
|
|
532
|
+
title: "Pra instalar, abra fora do TikTok",
|
|
533
|
+
step1: "Toque em \u22EF",
|
|
534
|
+
step2: 'Escolha "Abrir no Safari" (iOS) ou "Abrir no Chrome" (Android)'
|
|
535
|
+
},
|
|
536
|
+
whatsapp: {
|
|
537
|
+
title: "Pra instalar, abra fora do WhatsApp",
|
|
538
|
+
step1: "Toque longo no link",
|
|
539
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
540
|
+
},
|
|
541
|
+
twitter: {
|
|
542
|
+
title: "Pra instalar, abra fora do Twitter",
|
|
543
|
+
step1: "Toque em \u22EF",
|
|
544
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
545
|
+
},
|
|
546
|
+
linkedin: {
|
|
547
|
+
title: "Pra instalar, abra fora do LinkedIn",
|
|
548
|
+
step1: "Toque em \u22EF",
|
|
549
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
550
|
+
},
|
|
551
|
+
telegram: {
|
|
552
|
+
title: "Pra instalar, abra fora do Telegram",
|
|
553
|
+
step1: "Toque em \u22EE",
|
|
554
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
555
|
+
},
|
|
556
|
+
line: {
|
|
557
|
+
title: "Pra instalar, abra fora do LINE",
|
|
558
|
+
step1: "Toque em \u22EF",
|
|
559
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
560
|
+
},
|
|
561
|
+
snapchat: {
|
|
562
|
+
title: "Pra instalar, abra fora do Snapchat",
|
|
563
|
+
step1: "Mantenha pressionado o link",
|
|
564
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
565
|
+
},
|
|
566
|
+
pinterest: {
|
|
567
|
+
title: "Pra instalar, abra fora do Pinterest",
|
|
568
|
+
step1: "Toque em \u22EF",
|
|
569
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
570
|
+
},
|
|
571
|
+
wechat: {
|
|
572
|
+
title: "Pra instalar, abra fora do WeChat",
|
|
573
|
+
step1: "Toque em \u22EF",
|
|
574
|
+
step2: 'Escolha "Abrir no navegador"'
|
|
575
|
+
},
|
|
576
|
+
other: {
|
|
577
|
+
title: "Abra no navegador do celular",
|
|
578
|
+
step1: "Toque no menu do app atual",
|
|
579
|
+
step2: 'Escolha "Abrir no Chrome" ou "Abrir no Safari"'
|
|
580
|
+
},
|
|
581
|
+
copy: "Copiar link",
|
|
582
|
+
copiedToast: "Link copiado. Cole no Chrome/Safari.",
|
|
583
|
+
skip: "Continuar aqui mesmo",
|
|
584
|
+
skipPermanent: "N\xE3o me pergunte mais"
|
|
585
|
+
},
|
|
586
|
+
desktop: {
|
|
587
|
+
title: "Instale no computador",
|
|
588
|
+
subtitle: "Acesso r\xE1pido",
|
|
589
|
+
cta: "Baixar",
|
|
590
|
+
close: "Fechar"
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
// src/components/InstallGate/InstallSplash.tsx
|
|
595
|
+
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
596
|
+
function InstallSplash({ children, title, subtitle }) {
|
|
597
|
+
const { name, theme } = useTemplateConfig();
|
|
598
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
599
|
+
return /* @__PURE__ */ jsx7(
|
|
600
|
+
"div",
|
|
601
|
+
{
|
|
602
|
+
role: "dialog",
|
|
603
|
+
"aria-modal": "true",
|
|
604
|
+
"aria-labelledby": "install-splash-title",
|
|
605
|
+
"aria-describedby": subtitle ? "install-splash-subtitle" : void 0,
|
|
606
|
+
style: overlayStyle,
|
|
607
|
+
children: /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
|
|
608
|
+
/* @__PURE__ */ jsx7("div", { style: { display: "flex", justifyContent: "center", marginBottom: 16 }, children: iconUrl ? /* @__PURE__ */ jsx7(
|
|
609
|
+
"img",
|
|
610
|
+
{
|
|
611
|
+
src: iconUrl,
|
|
612
|
+
alt: `\xCDcone de ${name}`,
|
|
613
|
+
style: { width: 80, height: 80, borderRadius: 20, objectFit: "cover" }
|
|
614
|
+
}
|
|
615
|
+
) : /* @__PURE__ */ jsx7(
|
|
616
|
+
"div",
|
|
617
|
+
{
|
|
618
|
+
style: {
|
|
619
|
+
width: 80,
|
|
620
|
+
height: 80,
|
|
621
|
+
borderRadius: 20,
|
|
622
|
+
background: "var(--hook-color-primary)",
|
|
623
|
+
color: "#fff",
|
|
624
|
+
display: "flex",
|
|
625
|
+
alignItems: "center",
|
|
626
|
+
justifyContent: "center",
|
|
627
|
+
fontSize: 36,
|
|
628
|
+
fontWeight: 700
|
|
629
|
+
},
|
|
630
|
+
children: name.charAt(0).toUpperCase()
|
|
631
|
+
}
|
|
632
|
+
) }),
|
|
633
|
+
/* @__PURE__ */ jsx7("h1", { id: "install-splash-title", style: titleStyle, children: title }),
|
|
634
|
+
subtitle && /* @__PURE__ */ jsx7("p", { id: "install-splash-subtitle", style: subtitleStyle, children: subtitle }),
|
|
635
|
+
/* @__PURE__ */ jsx7("div", { style: { marginTop: 24 }, children }),
|
|
636
|
+
/* @__PURE__ */ jsx7("p", { style: footerStyle, children: "por Hook" })
|
|
637
|
+
] })
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
var primaryButtonStyle = {
|
|
642
|
+
width: "100%",
|
|
643
|
+
padding: "14px 20px",
|
|
644
|
+
background: "var(--hook-color-primary)",
|
|
645
|
+
color: "#fff",
|
|
646
|
+
border: "none",
|
|
647
|
+
borderRadius: 999,
|
|
648
|
+
fontSize: 17,
|
|
649
|
+
fontWeight: 600,
|
|
650
|
+
cursor: "pointer",
|
|
651
|
+
marginBottom: 12
|
|
652
|
+
};
|
|
653
|
+
var secondaryButtonStyle = {
|
|
654
|
+
width: "100%",
|
|
655
|
+
padding: "12px 20px",
|
|
656
|
+
background: "transparent",
|
|
657
|
+
color: "var(--hook-color-primary)",
|
|
658
|
+
border: "1px solid var(--hook-color-primary)",
|
|
659
|
+
borderRadius: 999,
|
|
660
|
+
fontSize: 15,
|
|
661
|
+
fontWeight: 500,
|
|
662
|
+
cursor: "pointer",
|
|
663
|
+
marginBottom: 12
|
|
664
|
+
};
|
|
665
|
+
var skipLinkStyle = {
|
|
666
|
+
display: "block",
|
|
667
|
+
width: "100%",
|
|
668
|
+
padding: "10px",
|
|
669
|
+
marginTop: 8,
|
|
670
|
+
background: "transparent",
|
|
671
|
+
color: "#555",
|
|
672
|
+
border: "none",
|
|
673
|
+
fontSize: 14,
|
|
674
|
+
textDecoration: "underline",
|
|
675
|
+
cursor: "pointer",
|
|
676
|
+
textAlign: "center"
|
|
677
|
+
};
|
|
678
|
+
var skipPermanentLinkStyle = {
|
|
679
|
+
...skipLinkStyle,
|
|
680
|
+
color: "#999",
|
|
681
|
+
fontSize: 13,
|
|
682
|
+
marginTop: 4
|
|
683
|
+
};
|
|
684
|
+
var overlayStyle = {
|
|
685
|
+
position: "fixed",
|
|
686
|
+
inset: 0,
|
|
687
|
+
background: "var(--hook-color-background, #fafafa)",
|
|
688
|
+
zIndex: 1e4,
|
|
689
|
+
display: "flex",
|
|
690
|
+
alignItems: "center",
|
|
691
|
+
justifyContent: "center",
|
|
692
|
+
padding: 20,
|
|
693
|
+
overflow: "auto"
|
|
694
|
+
};
|
|
695
|
+
var cardStyle = {
|
|
696
|
+
width: "100%",
|
|
697
|
+
maxWidth: 420,
|
|
698
|
+
padding: 24,
|
|
699
|
+
textAlign: "center"
|
|
700
|
+
};
|
|
701
|
+
var titleStyle = {
|
|
702
|
+
fontSize: 24,
|
|
703
|
+
fontWeight: 700,
|
|
704
|
+
lineHeight: 1.2,
|
|
705
|
+
margin: "0 0 8px 0",
|
|
706
|
+
color: "#111"
|
|
707
|
+
};
|
|
708
|
+
var subtitleStyle = {
|
|
709
|
+
fontSize: 15,
|
|
710
|
+
lineHeight: 1.4,
|
|
711
|
+
color: "#555",
|
|
712
|
+
margin: 0
|
|
713
|
+
};
|
|
714
|
+
var footerStyle = {
|
|
715
|
+
fontSize: 11,
|
|
716
|
+
color: "#aaa",
|
|
717
|
+
marginTop: 32,
|
|
718
|
+
letterSpacing: 0.5
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
// src/components/InstallGate/icons.tsx
|
|
722
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
723
|
+
var defaultSvgProps = (size) => ({
|
|
724
|
+
width: size,
|
|
725
|
+
height: size,
|
|
726
|
+
viewBox: "0 0 24 24",
|
|
727
|
+
fill: "none",
|
|
728
|
+
stroke: "currentColor",
|
|
729
|
+
strokeWidth: 2,
|
|
730
|
+
strokeLinecap: "round",
|
|
731
|
+
strokeLinejoin: "round"
|
|
732
|
+
});
|
|
733
|
+
function ShareIconIOS({ size = 24, style, className }) {
|
|
734
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
735
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 2L12 15" }),
|
|
736
|
+
/* @__PURE__ */ jsx8("path", { d: "M8 6L12 2L16 6" }),
|
|
737
|
+
/* @__PURE__ */ jsx8("path", { d: "M4 11v9a2 2 0 002 2h12a2 2 0 002-2v-9" })
|
|
738
|
+
] });
|
|
739
|
+
}
|
|
740
|
+
function MenuDotsVerticalIcon({ size = 24, style, className }) {
|
|
741
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
742
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "5", r: "1.5" }),
|
|
743
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
744
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "19", r: "1.5" })
|
|
745
|
+
] });
|
|
746
|
+
}
|
|
747
|
+
function MenuDotsHorizontalIcon({ size = 24, style, className }) {
|
|
748
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
749
|
+
/* @__PURE__ */ jsx8("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
750
|
+
/* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
751
|
+
/* @__PURE__ */ jsx8("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
752
|
+
] });
|
|
753
|
+
}
|
|
754
|
+
function SquarePlusIcon({ size = 24, style, className }) {
|
|
755
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
756
|
+
/* @__PURE__ */ jsx8("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
757
|
+
/* @__PURE__ */ jsx8("path", { d: "M12 8v8" }),
|
|
758
|
+
/* @__PURE__ */ jsx8("path", { d: "M8 12h8" })
|
|
759
|
+
] });
|
|
760
|
+
}
|
|
761
|
+
function DownloadIcon({ size = 24, style, className }) {
|
|
762
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
763
|
+
/* @__PURE__ */ jsx8("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4" }),
|
|
764
|
+
/* @__PURE__ */ jsx8("polyline", { points: "7 10 12 15 17 10" }),
|
|
765
|
+
/* @__PURE__ */ jsx8("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
|
|
766
|
+
] });
|
|
767
|
+
}
|
|
768
|
+
function ExternalLinkIcon({ size = 24, style, className }) {
|
|
769
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
770
|
+
/* @__PURE__ */ jsx8("path", { d: "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" }),
|
|
771
|
+
/* @__PURE__ */ jsx8("polyline", { points: "15 3 21 3 21 9" }),
|
|
772
|
+
/* @__PURE__ */ jsx8("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
773
|
+
] });
|
|
774
|
+
}
|
|
775
|
+
function XIcon({ size = 20, style, className }) {
|
|
776
|
+
return /* @__PURE__ */ jsxs2("svg", { ...defaultSvgProps(size), style, className, "aria-hidden": "true", children: [
|
|
777
|
+
/* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
778
|
+
/* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
779
|
+
] });
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// src/components/InstallGate/variants/AndroidNativeVariant.tsx
|
|
783
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
784
|
+
function AndroidNativeVariant({
|
|
785
|
+
state,
|
|
786
|
+
actions
|
|
787
|
+
}) {
|
|
788
|
+
const copy = INSTALL_COPY.android.native;
|
|
789
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
790
|
+
return /* @__PURE__ */ jsxs3(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
791
|
+
/* @__PURE__ */ jsxs3(
|
|
792
|
+
"button",
|
|
793
|
+
{
|
|
794
|
+
"data-testid": "install-prompt-cta-android-native",
|
|
795
|
+
type: "button",
|
|
796
|
+
onClick: () => void actions.promptInstall(),
|
|
797
|
+
style: { ...primaryButtonStyle, display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8 },
|
|
798
|
+
children: [
|
|
799
|
+
/* @__PURE__ */ jsx9(DownloadIcon, { size: 18 }),
|
|
800
|
+
copy.cta
|
|
801
|
+
]
|
|
802
|
+
}
|
|
803
|
+
),
|
|
804
|
+
/* @__PURE__ */ jsx9(
|
|
805
|
+
"button",
|
|
806
|
+
{
|
|
807
|
+
"data-testid": "install-prompt-skip-session",
|
|
808
|
+
type: "button",
|
|
809
|
+
onClick: actions.dismissSession,
|
|
810
|
+
style: skipLinkStyle,
|
|
811
|
+
children: copy.skip
|
|
812
|
+
}
|
|
813
|
+
),
|
|
814
|
+
showPermanent && /* @__PURE__ */ jsx9(
|
|
815
|
+
"button",
|
|
816
|
+
{
|
|
817
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
818
|
+
type: "button",
|
|
819
|
+
onClick: actions.dismissPermanent,
|
|
820
|
+
style: skipPermanentLinkStyle,
|
|
821
|
+
children: copy.skipPermanent
|
|
822
|
+
}
|
|
823
|
+
)
|
|
824
|
+
] });
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/components/InstallGate/variants/AndroidManualVariant.tsx
|
|
828
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
829
|
+
function AndroidManualVariant({
|
|
830
|
+
state,
|
|
831
|
+
actions
|
|
832
|
+
}) {
|
|
833
|
+
const copy = INSTALL_COPY.android.manual;
|
|
834
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
835
|
+
return /* @__PURE__ */ jsxs4(InstallSplash, { title: copy.title, children: [
|
|
836
|
+
/* @__PURE__ */ jsx10(Step, { n: 1, icon: /* @__PURE__ */ jsx10(MenuDotsVerticalIcon, { size: 20 }), children: copy.step1 }),
|
|
837
|
+
/* @__PURE__ */ jsx10(Step, { n: 2, icon: /* @__PURE__ */ jsx10(DownloadIcon, { size: 18 }), children: copy.step2 }),
|
|
838
|
+
/* @__PURE__ */ jsx10(
|
|
839
|
+
"button",
|
|
840
|
+
{
|
|
841
|
+
"data-testid": "install-prompt-cta-android-manual",
|
|
842
|
+
type: "button",
|
|
843
|
+
onClick: actions.dismissSession,
|
|
844
|
+
style: primaryButtonStyle,
|
|
845
|
+
children: copy.cta
|
|
846
|
+
}
|
|
847
|
+
),
|
|
848
|
+
/* @__PURE__ */ jsx10(
|
|
849
|
+
"button",
|
|
850
|
+
{
|
|
851
|
+
"data-testid": "install-prompt-skip-session",
|
|
852
|
+
type: "button",
|
|
853
|
+
onClick: actions.dismissSession,
|
|
854
|
+
style: skipLinkStyle,
|
|
855
|
+
children: copy.skip
|
|
856
|
+
}
|
|
857
|
+
),
|
|
858
|
+
showPermanent && /* @__PURE__ */ jsx10(
|
|
859
|
+
"button",
|
|
860
|
+
{
|
|
861
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
862
|
+
type: "button",
|
|
863
|
+
onClick: actions.dismissPermanent,
|
|
864
|
+
style: skipPermanentLinkStyle,
|
|
865
|
+
children: copy.skipPermanent
|
|
866
|
+
}
|
|
867
|
+
)
|
|
868
|
+
] });
|
|
869
|
+
}
|
|
870
|
+
function Step({ n, icon, children }) {
|
|
871
|
+
return /* @__PURE__ */ jsxs4(
|
|
872
|
+
"div",
|
|
873
|
+
{
|
|
874
|
+
style: {
|
|
875
|
+
display: "flex",
|
|
876
|
+
alignItems: "center",
|
|
877
|
+
gap: 12,
|
|
878
|
+
padding: "12px 14px",
|
|
879
|
+
background: "#f5f5f7",
|
|
880
|
+
borderRadius: 12,
|
|
881
|
+
marginBottom: 10,
|
|
882
|
+
textAlign: "left"
|
|
883
|
+
},
|
|
884
|
+
children: [
|
|
885
|
+
/* @__PURE__ */ jsx10(
|
|
886
|
+
"div",
|
|
887
|
+
{
|
|
888
|
+
style: {
|
|
889
|
+
width: 28,
|
|
890
|
+
height: 28,
|
|
891
|
+
borderRadius: "50%",
|
|
892
|
+
background: "var(--hook-color-primary)",
|
|
893
|
+
color: "#fff",
|
|
894
|
+
display: "flex",
|
|
895
|
+
alignItems: "center",
|
|
896
|
+
justifyContent: "center",
|
|
897
|
+
fontSize: 14,
|
|
898
|
+
fontWeight: 700,
|
|
899
|
+
flexShrink: 0
|
|
900
|
+
},
|
|
901
|
+
children: n
|
|
902
|
+
}
|
|
903
|
+
),
|
|
904
|
+
/* @__PURE__ */ jsx10("div", { style: { flex: 1, fontSize: 15, color: "#333" }, children }),
|
|
905
|
+
/* @__PURE__ */ jsx10("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
906
|
+
]
|
|
907
|
+
}
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// src/components/InstallGate/variants/IOSafariVariant.tsx
|
|
912
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
913
|
+
function IOSafariVariant({
|
|
914
|
+
state,
|
|
915
|
+
actions
|
|
916
|
+
}) {
|
|
917
|
+
const copy = INSTALL_COPY.iosSafari;
|
|
918
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
919
|
+
return /* @__PURE__ */ jsxs5(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
920
|
+
/* @__PURE__ */ jsx11(
|
|
921
|
+
Step2,
|
|
922
|
+
{
|
|
923
|
+
n: 1,
|
|
924
|
+
title: copy.step1.title,
|
|
925
|
+
subtitle: copy.step1.subtitle,
|
|
926
|
+
visual: /* @__PURE__ */ jsx11(
|
|
927
|
+
"div",
|
|
928
|
+
{
|
|
929
|
+
style: {
|
|
930
|
+
display: "flex",
|
|
931
|
+
justifyContent: "center",
|
|
932
|
+
alignItems: "center",
|
|
933
|
+
background: "#f5f5f7",
|
|
934
|
+
borderRadius: 12,
|
|
935
|
+
padding: "12px 0",
|
|
936
|
+
marginTop: 8
|
|
937
|
+
},
|
|
938
|
+
children: /* @__PURE__ */ jsx11(ShareIconIOS, { size: 32, style: { color: "var(--hook-color-primary)" } })
|
|
939
|
+
}
|
|
940
|
+
)
|
|
941
|
+
}
|
|
942
|
+
),
|
|
943
|
+
/* @__PURE__ */ jsx11(
|
|
944
|
+
Step2,
|
|
945
|
+
{
|
|
946
|
+
n: 2,
|
|
947
|
+
title: copy.step2.title,
|
|
948
|
+
visual: /* @__PURE__ */ jsxs5(
|
|
949
|
+
"div",
|
|
950
|
+
{
|
|
951
|
+
style: {
|
|
952
|
+
display: "flex",
|
|
953
|
+
alignItems: "center",
|
|
954
|
+
gap: 10,
|
|
955
|
+
background: "#f5f5f7",
|
|
956
|
+
borderRadius: 12,
|
|
957
|
+
padding: "12px 14px",
|
|
958
|
+
marginTop: 8
|
|
959
|
+
},
|
|
960
|
+
children: [
|
|
961
|
+
/* @__PURE__ */ jsx11(SquarePlusIcon, { size: 22, style: { color: "#555" } }),
|
|
962
|
+
/* @__PURE__ */ jsx11("span", { style: { fontSize: 14, color: "#333" }, children: copy.step2.iconLabel })
|
|
963
|
+
]
|
|
964
|
+
}
|
|
965
|
+
)
|
|
966
|
+
}
|
|
967
|
+
),
|
|
968
|
+
/* @__PURE__ */ jsx11(
|
|
969
|
+
Step2,
|
|
970
|
+
{
|
|
971
|
+
n: 3,
|
|
972
|
+
title: copy.step3.title,
|
|
973
|
+
visual: /* @__PURE__ */ jsx11(
|
|
974
|
+
"div",
|
|
975
|
+
{
|
|
976
|
+
style: {
|
|
977
|
+
display: "flex",
|
|
978
|
+
justifyContent: "flex-end",
|
|
979
|
+
background: "#f5f5f7",
|
|
980
|
+
borderRadius: 12,
|
|
981
|
+
padding: "10px 14px",
|
|
982
|
+
marginTop: 8
|
|
983
|
+
},
|
|
984
|
+
children: /* @__PURE__ */ jsx11(
|
|
985
|
+
"span",
|
|
986
|
+
{
|
|
987
|
+
style: {
|
|
988
|
+
color: "var(--hook-color-primary)",
|
|
989
|
+
fontSize: 15,
|
|
990
|
+
fontWeight: 600
|
|
991
|
+
},
|
|
992
|
+
children: copy.step3.buttonLabel
|
|
993
|
+
}
|
|
994
|
+
)
|
|
995
|
+
}
|
|
996
|
+
)
|
|
997
|
+
}
|
|
998
|
+
),
|
|
999
|
+
/* @__PURE__ */ jsx11(
|
|
1000
|
+
"button",
|
|
1001
|
+
{
|
|
1002
|
+
"data-testid": "install-prompt-skip-session",
|
|
1003
|
+
type: "button",
|
|
1004
|
+
onClick: actions.dismissSession,
|
|
1005
|
+
style: { ...skipLinkStyle, marginTop: 16 },
|
|
1006
|
+
children: copy.skip
|
|
1007
|
+
}
|
|
1008
|
+
),
|
|
1009
|
+
showPermanent && /* @__PURE__ */ jsx11(
|
|
1010
|
+
"button",
|
|
1011
|
+
{
|
|
1012
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1013
|
+
type: "button",
|
|
1014
|
+
onClick: actions.dismissPermanent,
|
|
1015
|
+
style: skipPermanentLinkStyle,
|
|
1016
|
+
children: copy.skipPermanent
|
|
1017
|
+
}
|
|
1018
|
+
)
|
|
1019
|
+
] });
|
|
1020
|
+
}
|
|
1021
|
+
function Step2({
|
|
1022
|
+
n,
|
|
1023
|
+
title,
|
|
1024
|
+
subtitle,
|
|
1025
|
+
visual
|
|
1026
|
+
}) {
|
|
1027
|
+
return /* @__PURE__ */ jsxs5(
|
|
1028
|
+
"div",
|
|
1029
|
+
{
|
|
1030
|
+
style: {
|
|
1031
|
+
display: "flex",
|
|
1032
|
+
alignItems: "flex-start",
|
|
1033
|
+
gap: 12,
|
|
1034
|
+
marginBottom: 16,
|
|
1035
|
+
textAlign: "left"
|
|
1036
|
+
},
|
|
1037
|
+
children: [
|
|
1038
|
+
/* @__PURE__ */ jsx11(
|
|
1039
|
+
"div",
|
|
1040
|
+
{
|
|
1041
|
+
style: {
|
|
1042
|
+
width: 32,
|
|
1043
|
+
height: 32,
|
|
1044
|
+
borderRadius: 10,
|
|
1045
|
+
background: "var(--hook-color-primary)",
|
|
1046
|
+
color: "#fff",
|
|
1047
|
+
display: "flex",
|
|
1048
|
+
alignItems: "center",
|
|
1049
|
+
justifyContent: "center",
|
|
1050
|
+
fontSize: 15,
|
|
1051
|
+
fontWeight: 700,
|
|
1052
|
+
flexShrink: 0
|
|
1053
|
+
},
|
|
1054
|
+
children: n
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
/* @__PURE__ */ jsxs5("div", { style: { flex: 1 }, children: [
|
|
1058
|
+
/* @__PURE__ */ jsx11("p", { style: { margin: 0, fontSize: 15, fontWeight: 500, color: "#111", lineHeight: 1.3 }, children: title }),
|
|
1059
|
+
subtitle && /* @__PURE__ */ jsx11("p", { style: { margin: "4px 0 0 0", fontSize: 13, color: "#777" }, children: subtitle }),
|
|
1060
|
+
visual
|
|
1061
|
+
] })
|
|
1062
|
+
]
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/components/InstallGate/variants/IOSOtherVariant.tsx
|
|
1068
|
+
import { useState as useState4 } from "react";
|
|
1069
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1070
|
+
function IOSOtherVariant({
|
|
1071
|
+
state,
|
|
1072
|
+
actions
|
|
1073
|
+
}) {
|
|
1074
|
+
const copy = INSTALL_COPY.iosOther;
|
|
1075
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1076
|
+
const [copied, setCopied] = useState4(false);
|
|
1077
|
+
const handleCopy = async () => {
|
|
1078
|
+
await actions.copyLink();
|
|
1079
|
+
setCopied(true);
|
|
1080
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1081
|
+
};
|
|
1082
|
+
return /* @__PURE__ */ jsxs6(InstallSplash, { title: copy.title, subtitle: copy.subtitle, children: [
|
|
1083
|
+
/* @__PURE__ */ jsx12(
|
|
1084
|
+
"button",
|
|
1085
|
+
{
|
|
1086
|
+
"data-testid": "install-prompt-cta-ios-other-primary",
|
|
1087
|
+
type: "button",
|
|
1088
|
+
onClick: actions.redirectToSafari,
|
|
1089
|
+
style: primaryButtonStyle,
|
|
1090
|
+
children: copy.ctaPrimary
|
|
1091
|
+
}
|
|
1092
|
+
),
|
|
1093
|
+
/* @__PURE__ */ jsx12(
|
|
1094
|
+
"button",
|
|
1095
|
+
{
|
|
1096
|
+
"data-testid": "install-prompt-cta-ios-other-secondary",
|
|
1097
|
+
type: "button",
|
|
1098
|
+
onClick: () => void handleCopy(),
|
|
1099
|
+
style: secondaryButtonStyle,
|
|
1100
|
+
children: copied ? copy.copiedToast : copy.ctaSecondary
|
|
1101
|
+
}
|
|
1102
|
+
),
|
|
1103
|
+
/* @__PURE__ */ jsx12(
|
|
1104
|
+
"button",
|
|
1105
|
+
{
|
|
1106
|
+
"data-testid": "install-prompt-skip-session",
|
|
1107
|
+
type: "button",
|
|
1108
|
+
onClick: actions.dismissSession,
|
|
1109
|
+
style: skipLinkStyle,
|
|
1110
|
+
children: copy.skip
|
|
1111
|
+
}
|
|
1112
|
+
),
|
|
1113
|
+
showPermanent && /* @__PURE__ */ jsx12(
|
|
1114
|
+
"button",
|
|
1115
|
+
{
|
|
1116
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1117
|
+
type: "button",
|
|
1118
|
+
onClick: actions.dismissPermanent,
|
|
1119
|
+
style: skipPermanentLinkStyle,
|
|
1120
|
+
children: copy.skipPermanent
|
|
1121
|
+
}
|
|
1122
|
+
)
|
|
1123
|
+
] });
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/components/InstallGate/variants/InAppBrowserVariant.tsx
|
|
1127
|
+
import { useState as useState5 } from "react";
|
|
1128
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1129
|
+
function InAppBrowserVariant({
|
|
1130
|
+
state,
|
|
1131
|
+
actions
|
|
1132
|
+
}) {
|
|
1133
|
+
const app = state.inAppApp ?? "other";
|
|
1134
|
+
const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
|
|
1135
|
+
const copy = INSTALL_COPY.inApp;
|
|
1136
|
+
const showPermanent = shouldShowPermanentOption(state);
|
|
1137
|
+
const [copied, setCopied] = useState5(false);
|
|
1138
|
+
const handleCopy = async () => {
|
|
1139
|
+
await actions.copyLink();
|
|
1140
|
+
setCopied(true);
|
|
1141
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1142
|
+
};
|
|
1143
|
+
const DotsIcon = app === "facebook" || app === "telegram" ? MenuDotsVerticalIcon : MenuDotsHorizontalIcon;
|
|
1144
|
+
return /* @__PURE__ */ jsxs7(InstallSplash, { title: appCopy.title, children: [
|
|
1145
|
+
/* @__PURE__ */ jsx13(Step3, { n: 1, icon: /* @__PURE__ */ jsx13(DotsIcon, { size: 20 }), children: appCopy.step1 }),
|
|
1146
|
+
/* @__PURE__ */ jsx13(Step3, { n: 2, icon: /* @__PURE__ */ jsx13(ExternalLinkIcon, { size: 18 }), children: appCopy.step2 }),
|
|
1147
|
+
/* @__PURE__ */ jsx13(
|
|
1148
|
+
"button",
|
|
1149
|
+
{
|
|
1150
|
+
"data-testid": "install-prompt-cta-inapp-copy",
|
|
1151
|
+
type: "button",
|
|
1152
|
+
onClick: () => void handleCopy(),
|
|
1153
|
+
style: { ...primaryButtonStyle, marginTop: 8 },
|
|
1154
|
+
children: copied ? copy.copiedToast : copy.copy
|
|
1155
|
+
}
|
|
1156
|
+
),
|
|
1157
|
+
/* @__PURE__ */ jsx13(
|
|
1158
|
+
"button",
|
|
1159
|
+
{
|
|
1160
|
+
"data-testid": "install-prompt-skip-session",
|
|
1161
|
+
type: "button",
|
|
1162
|
+
onClick: actions.dismissSession,
|
|
1163
|
+
style: skipLinkStyle,
|
|
1164
|
+
children: copy.skip
|
|
1165
|
+
}
|
|
1166
|
+
),
|
|
1167
|
+
showPermanent && /* @__PURE__ */ jsx13(
|
|
1168
|
+
"button",
|
|
1169
|
+
{
|
|
1170
|
+
"data-testid": "install-prompt-skip-permanent",
|
|
1171
|
+
type: "button",
|
|
1172
|
+
onClick: actions.dismissPermanent,
|
|
1173
|
+
style: skipPermanentLinkStyle,
|
|
1174
|
+
children: copy.skipPermanent
|
|
1175
|
+
}
|
|
1176
|
+
)
|
|
1177
|
+
] });
|
|
1178
|
+
}
|
|
1179
|
+
function Step3({
|
|
1180
|
+
n,
|
|
1181
|
+
icon,
|
|
1182
|
+
children
|
|
1183
|
+
}) {
|
|
1184
|
+
return /* @__PURE__ */ jsxs7(
|
|
1185
|
+
"div",
|
|
1186
|
+
{
|
|
1187
|
+
style: {
|
|
1188
|
+
display: "flex",
|
|
1189
|
+
alignItems: "center",
|
|
1190
|
+
gap: 12,
|
|
1191
|
+
padding: "12px 14px",
|
|
1192
|
+
background: "#f5f5f7",
|
|
1193
|
+
borderRadius: 12,
|
|
1194
|
+
marginBottom: 10,
|
|
1195
|
+
textAlign: "left"
|
|
1196
|
+
},
|
|
1197
|
+
children: [
|
|
1198
|
+
/* @__PURE__ */ jsx13(
|
|
1199
|
+
"div",
|
|
1200
|
+
{
|
|
1201
|
+
style: {
|
|
1202
|
+
width: 28,
|
|
1203
|
+
height: 28,
|
|
1204
|
+
borderRadius: "50%",
|
|
1205
|
+
background: "var(--hook-color-primary)",
|
|
1206
|
+
color: "#fff",
|
|
1207
|
+
display: "flex",
|
|
1208
|
+
alignItems: "center",
|
|
1209
|
+
justifyContent: "center",
|
|
1210
|
+
fontSize: 14,
|
|
1211
|
+
fontWeight: 700,
|
|
1212
|
+
flexShrink: 0
|
|
1213
|
+
},
|
|
1214
|
+
children: n
|
|
1215
|
+
}
|
|
1216
|
+
),
|
|
1217
|
+
/* @__PURE__ */ jsx13("div", { style: { flex: 1, fontSize: 14, color: "#333" }, children }),
|
|
1218
|
+
/* @__PURE__ */ jsx13("div", { style: { color: "#888", flexShrink: 0 }, children: icon })
|
|
1219
|
+
]
|
|
1220
|
+
}
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// src/components/InstallGate/variants/DesktopVariant.tsx
|
|
1225
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1226
|
+
function DesktopVariant({
|
|
1227
|
+
state,
|
|
1228
|
+
actions
|
|
1229
|
+
}) {
|
|
1230
|
+
const { name, theme } = useTemplateConfig();
|
|
1231
|
+
const copy = INSTALL_COPY.desktop;
|
|
1232
|
+
const iconUrl = theme.icon_url || theme.logo_url || null;
|
|
1233
|
+
if (!state.isInstallable) return null;
|
|
1234
|
+
return /* @__PURE__ */ jsxs8(
|
|
1235
|
+
"div",
|
|
1236
|
+
{
|
|
1237
|
+
role: "complementary",
|
|
1238
|
+
"aria-label": copy.title,
|
|
1239
|
+
style: bannerStyle,
|
|
1240
|
+
children: [
|
|
1241
|
+
iconUrl ? /* @__PURE__ */ jsx14(
|
|
1242
|
+
"img",
|
|
1243
|
+
{
|
|
1244
|
+
src: iconUrl,
|
|
1245
|
+
alt: "",
|
|
1246
|
+
style: { width: 40, height: 40, borderRadius: 10, objectFit: "cover", flexShrink: 0 }
|
|
1247
|
+
}
|
|
1248
|
+
) : /* @__PURE__ */ jsx14(
|
|
1249
|
+
"div",
|
|
1250
|
+
{
|
|
1251
|
+
style: {
|
|
1252
|
+
width: 40,
|
|
1253
|
+
height: 40,
|
|
1254
|
+
borderRadius: 10,
|
|
1255
|
+
background: "var(--hook-color-primary)",
|
|
1256
|
+
color: "#fff",
|
|
1257
|
+
display: "flex",
|
|
1258
|
+
alignItems: "center",
|
|
1259
|
+
justifyContent: "center",
|
|
1260
|
+
fontSize: 18,
|
|
1261
|
+
fontWeight: 700,
|
|
1262
|
+
flexShrink: 0
|
|
1263
|
+
},
|
|
1264
|
+
children: name.charAt(0).toUpperCase()
|
|
1265
|
+
}
|
|
1266
|
+
),
|
|
1267
|
+
/* @__PURE__ */ jsxs8("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
1268
|
+
/* @__PURE__ */ jsx14("div", { style: { fontSize: 14, fontWeight: 600, color: "#111" }, children: copy.title }),
|
|
1269
|
+
/* @__PURE__ */ jsx14("div", { style: { fontSize: 12, color: "#666" }, children: copy.subtitle })
|
|
1270
|
+
] }),
|
|
1271
|
+
/* @__PURE__ */ jsxs8(
|
|
1272
|
+
"button",
|
|
1273
|
+
{
|
|
1274
|
+
"data-testid": "install-prompt-cta-desktop",
|
|
1275
|
+
type: "button",
|
|
1276
|
+
onClick: () => void actions.promptInstall(),
|
|
1277
|
+
style: {
|
|
1278
|
+
padding: "8px 14px",
|
|
1279
|
+
background: "var(--hook-color-primary)",
|
|
1280
|
+
color: "#fff",
|
|
1281
|
+
border: "none",
|
|
1282
|
+
borderRadius: 999,
|
|
1283
|
+
fontSize: 13,
|
|
1284
|
+
fontWeight: 600,
|
|
1285
|
+
cursor: "pointer",
|
|
1286
|
+
display: "inline-flex",
|
|
1287
|
+
alignItems: "center",
|
|
1288
|
+
gap: 6,
|
|
1289
|
+
flexShrink: 0
|
|
1290
|
+
},
|
|
1291
|
+
children: [
|
|
1292
|
+
/* @__PURE__ */ jsx14(DownloadIcon, { size: 14 }),
|
|
1293
|
+
copy.cta
|
|
1294
|
+
]
|
|
1295
|
+
}
|
|
1296
|
+
),
|
|
1297
|
+
/* @__PURE__ */ jsx14(
|
|
1298
|
+
"button",
|
|
1299
|
+
{
|
|
1300
|
+
"data-testid": "install-prompt-desktop-close",
|
|
1301
|
+
type: "button",
|
|
1302
|
+
onClick: actions.dismissPermanent,
|
|
1303
|
+
"aria-label": copy.close,
|
|
1304
|
+
style: {
|
|
1305
|
+
background: "transparent",
|
|
1306
|
+
border: "none",
|
|
1307
|
+
cursor: "pointer",
|
|
1308
|
+
color: "#888",
|
|
1309
|
+
padding: 4,
|
|
1310
|
+
flexShrink: 0
|
|
1311
|
+
},
|
|
1312
|
+
children: /* @__PURE__ */ jsx14(XIcon, { size: 16 })
|
|
1313
|
+
}
|
|
1314
|
+
)
|
|
1315
|
+
]
|
|
1316
|
+
}
|
|
1317
|
+
);
|
|
1318
|
+
}
|
|
1319
|
+
var bannerStyle = {
|
|
1320
|
+
position: "fixed",
|
|
1321
|
+
bottom: 24,
|
|
1322
|
+
right: 24,
|
|
1323
|
+
zIndex: 1e4,
|
|
1324
|
+
display: "flex",
|
|
1325
|
+
alignItems: "center",
|
|
1326
|
+
gap: 12,
|
|
1327
|
+
padding: "12px 16px",
|
|
1328
|
+
background: "#fff",
|
|
1329
|
+
border: "1px solid rgba(0,0,0,0.08)",
|
|
1330
|
+
borderRadius: 16,
|
|
1331
|
+
boxShadow: "0 10px 30px rgba(0,0,0,0.12)",
|
|
1332
|
+
maxWidth: 400
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
// src/components/InstallGate/InstallGate.tsx
|
|
1336
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1337
|
+
function InstallGate({ children }) {
|
|
1338
|
+
const { slug, features_enabled } = useTemplateConfig();
|
|
1339
|
+
const enabled = features_enabled.includes("install_prompt");
|
|
1340
|
+
const installState = useInstallPrompt(slug);
|
|
1341
|
+
const shouldBlock = enabled && shouldBlockInstall(installState);
|
|
1342
|
+
const trackedRef = useRef(null);
|
|
1343
|
+
useEffect4(() => {
|
|
1344
|
+
if (!shouldBlock) return;
|
|
1345
|
+
if (typeof window === "undefined") return;
|
|
1346
|
+
const variantKey = `${slug}:${installState.variant}`;
|
|
1347
|
+
if (trackedRef.current === variantKey) return;
|
|
1348
|
+
trackedRef.current = variantKey;
|
|
1349
|
+
window.posthog?.capture?.("pwa_install_splash_shown", {
|
|
1350
|
+
slug,
|
|
1351
|
+
platform: installState.platform,
|
|
1352
|
+
browser: installState.iosBrowser ?? installState.androidBrowser ?? null,
|
|
1353
|
+
in_app_app: installState.inAppApp,
|
|
1354
|
+
variant: installState.variant
|
|
1355
|
+
});
|
|
1356
|
+
}, [shouldBlock, slug, installState.variant, installState.platform, installState.iosBrowser, installState.androidBrowser, installState.inAppApp]);
|
|
1357
|
+
if (!enabled) return /* @__PURE__ */ jsx15(Fragment4, { children });
|
|
1358
|
+
if (installState.isInstalled) return /* @__PURE__ */ jsx15(Fragment4, { children });
|
|
1359
|
+
if (installState.variant === "desktop") {
|
|
1360
|
+
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1361
|
+
children,
|
|
1362
|
+
/* @__PURE__ */ jsx15(DesktopVariant, { state: installState, actions: installState })
|
|
1363
|
+
] });
|
|
1364
|
+
}
|
|
1365
|
+
if (!shouldBlock) return /* @__PURE__ */ jsx15(Fragment4, { children });
|
|
1366
|
+
switch (installState.variant) {
|
|
1367
|
+
case "android-native":
|
|
1368
|
+
return /* @__PURE__ */ jsx15(AndroidNativeVariant, { state: installState, actions: installState });
|
|
1369
|
+
case "android-manual":
|
|
1370
|
+
return /* @__PURE__ */ jsx15(AndroidManualVariant, { state: installState, actions: installState });
|
|
1371
|
+
case "ios-safari":
|
|
1372
|
+
return /* @__PURE__ */ jsx15(IOSafariVariant, { state: installState, actions: installState });
|
|
1373
|
+
case "ios-other":
|
|
1374
|
+
return /* @__PURE__ */ jsx15(IOSOtherVariant, { state: installState, actions: installState });
|
|
1375
|
+
case "in-app":
|
|
1376
|
+
return /* @__PURE__ */ jsx15(InAppBrowserVariant, { state: installState, actions: installState });
|
|
1377
|
+
case "none":
|
|
1378
|
+
default:
|
|
1379
|
+
return /* @__PURE__ */ jsx15(Fragment4, { children });
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
|
|
167
1383
|
// src/defaults/ErrorBoundary.tsx
|
|
168
1384
|
import { Component } from "react";
|
|
169
|
-
import { Fragment as
|
|
1385
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
170
1386
|
var ErrorBoundary = class extends Component {
|
|
171
1387
|
state = { error: null };
|
|
172
1388
|
static getDerivedStateFromError(error) {
|
|
@@ -177,17 +1393,17 @@ var ErrorBoundary = class extends Component {
|
|
|
177
1393
|
}
|
|
178
1394
|
render() {
|
|
179
1395
|
if (this.state.error) {
|
|
180
|
-
return this.props.fallback ?? /* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
/* @__PURE__ */
|
|
1396
|
+
return this.props.fallback ?? /* @__PURE__ */ jsxs10("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
|
|
1397
|
+
/* @__PURE__ */ jsx16("h2", { children: "Algo deu errado" }),
|
|
1398
|
+
/* @__PURE__ */ jsx16("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
|
|
183
1399
|
] });
|
|
184
1400
|
}
|
|
185
|
-
return /* @__PURE__ */
|
|
1401
|
+
return /* @__PURE__ */ jsx16(Fragment5, { children: this.props.children });
|
|
186
1402
|
}
|
|
187
1403
|
};
|
|
188
1404
|
|
|
189
1405
|
// src/hooks/useLoginForm.ts
|
|
190
|
-
import { useCallback as
|
|
1406
|
+
import { useCallback as useCallback3, useMemo as useMemo2, useState as useState6 } from "react";
|
|
191
1407
|
import { useHook as useHook4 } from "@hook-sdk/sdk";
|
|
192
1408
|
|
|
193
1409
|
// src/errors.ts
|
|
@@ -224,10 +1440,10 @@ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
224
1440
|
var MIN_PASSWORD = 8;
|
|
225
1441
|
function useLoginForm() {
|
|
226
1442
|
const { auth } = useHook4();
|
|
227
|
-
const [email, setEmail] =
|
|
228
|
-
const [password, setPassword] =
|
|
229
|
-
const [submitting, setSubmitting] =
|
|
230
|
-
const [error, setError] =
|
|
1443
|
+
const [email, setEmail] = useState6("");
|
|
1444
|
+
const [password, setPassword] = useState6("");
|
|
1445
|
+
const [submitting, setSubmitting] = useState6(false);
|
|
1446
|
+
const [error, setError] = useState6(null);
|
|
231
1447
|
const emailError = useMemo2(() => {
|
|
232
1448
|
if (email.length === 0) return null;
|
|
233
1449
|
if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
@@ -239,7 +1455,7 @@ function useLoginForm() {
|
|
|
239
1455
|
return null;
|
|
240
1456
|
}, [password]);
|
|
241
1457
|
const canSubmit = email.length > 0 && password.length >= MIN_PASSWORD && emailError === null && passwordError === null && !submitting;
|
|
242
|
-
const submit =
|
|
1458
|
+
const submit = useCallback3(async () => {
|
|
243
1459
|
if (!canSubmit) return false;
|
|
244
1460
|
setSubmitting(true);
|
|
245
1461
|
setError(null);
|
|
@@ -269,13 +1485,13 @@ function useLoginForm() {
|
|
|
269
1485
|
}
|
|
270
1486
|
|
|
271
1487
|
// src/internal/GoogleSignInButton.tsx
|
|
272
|
-
import { jsx as
|
|
1488
|
+
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
273
1489
|
function GoogleSignInButton({
|
|
274
1490
|
onClick,
|
|
275
1491
|
testId = "oauth-google",
|
|
276
1492
|
label = "Continuar com Google"
|
|
277
1493
|
}) {
|
|
278
|
-
return /* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ jsxs11(
|
|
279
1495
|
"button",
|
|
280
1496
|
{
|
|
281
1497
|
"data-testid": testId,
|
|
@@ -298,36 +1514,36 @@ function GoogleSignInButton({
|
|
|
298
1514
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
299
1515
|
},
|
|
300
1516
|
children: [
|
|
301
|
-
/* @__PURE__ */
|
|
1517
|
+
/* @__PURE__ */ jsx17(GoogleGlyph, {}),
|
|
302
1518
|
label
|
|
303
1519
|
]
|
|
304
1520
|
}
|
|
305
1521
|
);
|
|
306
1522
|
}
|
|
307
1523
|
function GoogleGlyph() {
|
|
308
|
-
return /* @__PURE__ */
|
|
309
|
-
/* @__PURE__ */
|
|
1524
|
+
return /* @__PURE__ */ jsxs11("svg", { width: "18", height: "18", viewBox: "0 0 18 18", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
|
|
1525
|
+
/* @__PURE__ */ jsx17(
|
|
310
1526
|
"path",
|
|
311
1527
|
{
|
|
312
1528
|
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
1529
|
fill: "#4285F4"
|
|
314
1530
|
}
|
|
315
1531
|
),
|
|
316
|
-
/* @__PURE__ */
|
|
1532
|
+
/* @__PURE__ */ jsx17(
|
|
317
1533
|
"path",
|
|
318
1534
|
{
|
|
319
1535
|
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
1536
|
fill: "#34A853"
|
|
321
1537
|
}
|
|
322
1538
|
),
|
|
323
|
-
/* @__PURE__ */
|
|
1539
|
+
/* @__PURE__ */ jsx17(
|
|
324
1540
|
"path",
|
|
325
1541
|
{
|
|
326
1542
|
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
1543
|
fill: "#FBBC05"
|
|
328
1544
|
}
|
|
329
1545
|
),
|
|
330
|
-
/* @__PURE__ */
|
|
1546
|
+
/* @__PURE__ */ jsx17(
|
|
331
1547
|
"path",
|
|
332
1548
|
{
|
|
333
1549
|
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 +1554,8 @@ function GoogleGlyph() {
|
|
|
338
1554
|
}
|
|
339
1555
|
|
|
340
1556
|
// src/internal/OAuthErrorBanner.tsx
|
|
341
|
-
import { useEffect as
|
|
342
|
-
import { jsx as
|
|
1557
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
1558
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
343
1559
|
var ERROR_MESSAGES = {
|
|
344
1560
|
invalid_state: "Sess\xE3o expirou, tente de novo.",
|
|
345
1561
|
access_denied: "Voc\xEA cancelou o login com Google.",
|
|
@@ -359,13 +1575,13 @@ function stripErrorFromUrl() {
|
|
|
359
1575
|
window.history.replaceState({}, "", url.toString());
|
|
360
1576
|
}
|
|
361
1577
|
function OAuthErrorBanner() {
|
|
362
|
-
const [code, setCode] =
|
|
363
|
-
|
|
1578
|
+
const [code, setCode] = useState7(() => readErrorCode());
|
|
1579
|
+
useEffect5(() => {
|
|
364
1580
|
if (code !== null) stripErrorFromUrl();
|
|
365
1581
|
}, [code]);
|
|
366
1582
|
if (!code) return null;
|
|
367
1583
|
const message = ERROR_MESSAGES[code] ?? "N\xE3o conseguimos conectar ao Google. Tente de novo.";
|
|
368
|
-
return /* @__PURE__ */
|
|
1584
|
+
return /* @__PURE__ */ jsxs12(
|
|
369
1585
|
"div",
|
|
370
1586
|
{
|
|
371
1587
|
role: "alert",
|
|
@@ -380,7 +1596,7 @@ function OAuthErrorBanner() {
|
|
|
380
1596
|
},
|
|
381
1597
|
children: [
|
|
382
1598
|
message,
|
|
383
|
-
/* @__PURE__ */
|
|
1599
|
+
/* @__PURE__ */ jsx18(
|
|
384
1600
|
"button",
|
|
385
1601
|
{
|
|
386
1602
|
type: "button",
|
|
@@ -405,16 +1621,16 @@ function OAuthErrorBanner() {
|
|
|
405
1621
|
}
|
|
406
1622
|
|
|
407
1623
|
// src/defaults/DefaultLoginScreen.tsx
|
|
408
|
-
import { jsx as
|
|
1624
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
409
1625
|
function DefaultLoginScreen({ onNavigate }) {
|
|
410
1626
|
const { name } = useTemplateConfig();
|
|
411
1627
|
const f = useLoginForm();
|
|
412
|
-
return /* @__PURE__ */
|
|
413
|
-
/* @__PURE__ */
|
|
414
|
-
/* @__PURE__ */
|
|
415
|
-
/* @__PURE__ */
|
|
416
|
-
/* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
1628
|
+
return /* @__PURE__ */ jsxs13("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1629
|
+
/* @__PURE__ */ jsx19("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1630
|
+
/* @__PURE__ */ jsx19("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Entre na sua conta" }),
|
|
1631
|
+
/* @__PURE__ */ jsx19(OAuthErrorBanner, {}),
|
|
1632
|
+
/* @__PURE__ */ jsx19(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "login-oauth-google" }),
|
|
1633
|
+
/* @__PURE__ */ jsxs13(
|
|
418
1634
|
"div",
|
|
419
1635
|
{
|
|
420
1636
|
"aria-hidden": "true",
|
|
@@ -427,19 +1643,19 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
427
1643
|
fontSize: 12
|
|
428
1644
|
},
|
|
429
1645
|
children: [
|
|
430
|
-
/* @__PURE__ */
|
|
1646
|
+
/* @__PURE__ */ jsx19("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
431
1647
|
"ou",
|
|
432
|
-
/* @__PURE__ */
|
|
1648
|
+
/* @__PURE__ */ jsx19("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
433
1649
|
]
|
|
434
1650
|
}
|
|
435
1651
|
),
|
|
436
|
-
/* @__PURE__ */
|
|
1652
|
+
/* @__PURE__ */ jsxs13("form", { onSubmit: (e) => {
|
|
437
1653
|
e.preventDefault();
|
|
438
1654
|
void f.submit();
|
|
439
1655
|
}, children: [
|
|
440
|
-
/* @__PURE__ */
|
|
1656
|
+
/* @__PURE__ */ jsxs13("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
441
1657
|
"E-mail",
|
|
442
|
-
/* @__PURE__ */
|
|
1658
|
+
/* @__PURE__ */ jsx19(
|
|
443
1659
|
"input",
|
|
444
1660
|
{
|
|
445
1661
|
"data-testid": "login-email",
|
|
@@ -449,11 +1665,11 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
449
1665
|
style: { display: "block", width: "100%" }
|
|
450
1666
|
}
|
|
451
1667
|
),
|
|
452
|
-
f.emailError && /* @__PURE__ */
|
|
1668
|
+
f.emailError && /* @__PURE__ */ jsx19("small", { style: { color: "#c00" }, children: f.emailError })
|
|
453
1669
|
] }),
|
|
454
|
-
/* @__PURE__ */
|
|
1670
|
+
/* @__PURE__ */ jsxs13("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
455
1671
|
"Senha",
|
|
456
|
-
/* @__PURE__ */
|
|
1672
|
+
/* @__PURE__ */ jsx19(
|
|
457
1673
|
"input",
|
|
458
1674
|
{
|
|
459
1675
|
"data-testid": "login-password",
|
|
@@ -463,10 +1679,10 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
463
1679
|
style: { display: "block", width: "100%" }
|
|
464
1680
|
}
|
|
465
1681
|
),
|
|
466
|
-
f.passwordError && /* @__PURE__ */
|
|
1682
|
+
f.passwordError && /* @__PURE__ */ jsx19("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
467
1683
|
] }),
|
|
468
|
-
f.error && /* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
1684
|
+
f.error && /* @__PURE__ */ jsx19("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1685
|
+
/* @__PURE__ */ jsx19(
|
|
470
1686
|
"button",
|
|
471
1687
|
{
|
|
472
1688
|
"data-testid": "login-submit",
|
|
@@ -485,25 +1701,25 @@ function DefaultLoginScreen({ onNavigate }) {
|
|
|
485
1701
|
}
|
|
486
1702
|
)
|
|
487
1703
|
] }),
|
|
488
|
-
/* @__PURE__ */
|
|
489
|
-
/* @__PURE__ */
|
|
490
|
-
/* @__PURE__ */
|
|
1704
|
+
/* @__PURE__ */ jsxs13("div", { style: { marginTop: 16, display: "flex", justifyContent: "space-between" }, children: [
|
|
1705
|
+
/* @__PURE__ */ jsx19("button", { "data-testid": "login-goto-signup", type: "button", onClick: () => onNavigate("signup"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Criar conta" }),
|
|
1706
|
+
/* @__PURE__ */ jsx19("button", { "data-testid": "login-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Esqueci senha" })
|
|
491
1707
|
] })
|
|
492
1708
|
] });
|
|
493
1709
|
}
|
|
494
1710
|
|
|
495
1711
|
// src/hooks/useSignupForm.ts
|
|
496
|
-
import { useCallback as
|
|
1712
|
+
import { useCallback as useCallback4, useMemo as useMemo3, useState as useState8 } from "react";
|
|
497
1713
|
import { useHook as useHook5 } from "@hook-sdk/sdk";
|
|
498
1714
|
var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
499
1715
|
var MIN_PASSWORD2 = 8;
|
|
500
1716
|
function useSignupForm() {
|
|
501
1717
|
const { auth } = useHook5();
|
|
502
|
-
const [name, setName] =
|
|
503
|
-
const [email, setEmail] =
|
|
504
|
-
const [password, setPassword] =
|
|
505
|
-
const [submitting, setSubmitting] =
|
|
506
|
-
const [error, setError] =
|
|
1718
|
+
const [name, setName] = useState8("");
|
|
1719
|
+
const [email, setEmail] = useState8("");
|
|
1720
|
+
const [password, setPassword] = useState8("");
|
|
1721
|
+
const [submitting, setSubmitting] = useState8(false);
|
|
1722
|
+
const [error, setError] = useState8(null);
|
|
507
1723
|
const nameError = useMemo3(() => {
|
|
508
1724
|
if (name.length === 0) return null;
|
|
509
1725
|
if (name.trim().length < 2) return "Nome muito curto.";
|
|
@@ -520,7 +1736,7 @@ function useSignupForm() {
|
|
|
520
1736
|
return null;
|
|
521
1737
|
}, [password]);
|
|
522
1738
|
const canSubmit = name.trim().length >= 2 && email.length > 0 && password.length >= MIN_PASSWORD2 && nameError === null && emailError === null && passwordError === null && !submitting;
|
|
523
|
-
const submit =
|
|
1739
|
+
const submit = useCallback4(async () => {
|
|
524
1740
|
if (!canSubmit) return false;
|
|
525
1741
|
setSubmitting(true);
|
|
526
1742
|
setError(null);
|
|
@@ -553,16 +1769,16 @@ function useSignupForm() {
|
|
|
553
1769
|
}
|
|
554
1770
|
|
|
555
1771
|
// src/defaults/DefaultSignupScreen.tsx
|
|
556
|
-
import { jsx as
|
|
1772
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
557
1773
|
function DefaultSignupScreen({ onNavigate }) {
|
|
558
1774
|
const { name } = useTemplateConfig();
|
|
559
1775
|
const f = useSignupForm();
|
|
560
|
-
return /* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
564
|
-
/* @__PURE__ */
|
|
565
|
-
/* @__PURE__ */
|
|
1776
|
+
return /* @__PURE__ */ jsxs14("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1777
|
+
/* @__PURE__ */ jsx20("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1778
|
+
/* @__PURE__ */ jsx20("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Criar sua conta" }),
|
|
1779
|
+
/* @__PURE__ */ jsx20(OAuthErrorBanner, {}),
|
|
1780
|
+
/* @__PURE__ */ jsx20(GoogleSignInButton, { onClick: f.loginWithGoogle, testId: "signup-oauth-google" }),
|
|
1781
|
+
/* @__PURE__ */ jsxs14(
|
|
566
1782
|
"div",
|
|
567
1783
|
{
|
|
568
1784
|
"aria-hidden": "true",
|
|
@@ -575,55 +1791,55 @@ function DefaultSignupScreen({ onNavigate }) {
|
|
|
575
1791
|
fontSize: 12
|
|
576
1792
|
},
|
|
577
1793
|
children: [
|
|
578
|
-
/* @__PURE__ */
|
|
1794
|
+
/* @__PURE__ */ jsx20("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } }),
|
|
579
1795
|
"ou",
|
|
580
|
-
/* @__PURE__ */
|
|
1796
|
+
/* @__PURE__ */ jsx20("span", { style: { flex: 1, height: 1, background: "rgba(0,0,0,0.1)" } })
|
|
581
1797
|
]
|
|
582
1798
|
}
|
|
583
1799
|
),
|
|
584
|
-
/* @__PURE__ */
|
|
1800
|
+
/* @__PURE__ */ jsxs14("form", { onSubmit: (e) => {
|
|
585
1801
|
e.preventDefault();
|
|
586
1802
|
void f.submit();
|
|
587
1803
|
}, children: [
|
|
588
|
-
/* @__PURE__ */
|
|
1804
|
+
/* @__PURE__ */ jsxs14("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
589
1805
|
"Nome",
|
|
590
|
-
/* @__PURE__ */
|
|
591
|
-
f.nameError && /* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsx20("input", { "data-testid": "signup-name", value: f.name, onChange: (e) => f.setName(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1807
|
+
f.nameError && /* @__PURE__ */ jsx20("small", { style: { color: "#c00" }, children: f.nameError })
|
|
592
1808
|
] }),
|
|
593
|
-
/* @__PURE__ */
|
|
1809
|
+
/* @__PURE__ */ jsxs14("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
594
1810
|
"E-mail",
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
f.emailError && /* @__PURE__ */
|
|
1811
|
+
/* @__PURE__ */ jsx20("input", { "data-testid": "signup-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1812
|
+
f.emailError && /* @__PURE__ */ jsx20("small", { style: { color: "#c00" }, children: f.emailError })
|
|
597
1813
|
] }),
|
|
598
|
-
/* @__PURE__ */
|
|
1814
|
+
/* @__PURE__ */ jsxs14("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
599
1815
|
"Senha",
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
f.passwordError && /* @__PURE__ */
|
|
1816
|
+
/* @__PURE__ */ jsx20("input", { "data-testid": "signup-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1817
|
+
f.passwordError && /* @__PURE__ */ jsx20("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
602
1818
|
] }),
|
|
603
|
-
f.error && /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
1819
|
+
f.error && /* @__PURE__ */ jsx20("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1820
|
+
/* @__PURE__ */ jsx20("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
1821
|
] }),
|
|
606
|
-
/* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsx20("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx20("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
1823
|
] });
|
|
608
1824
|
}
|
|
609
1825
|
|
|
610
1826
|
// src/hooks/useForgotForm.ts
|
|
611
|
-
import { useCallback as
|
|
1827
|
+
import { useCallback as useCallback5, useMemo as useMemo4, useState as useState9 } from "react";
|
|
612
1828
|
import { useHook as useHook6 } from "@hook-sdk/sdk";
|
|
613
1829
|
var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
614
1830
|
function useForgotForm() {
|
|
615
1831
|
const { auth } = useHook6();
|
|
616
|
-
const [email, setEmail] =
|
|
617
|
-
const [submitting, setSubmitting] =
|
|
618
|
-
const [sent, setSent] =
|
|
619
|
-
const [error, setError] =
|
|
1832
|
+
const [email, setEmail] = useState9("");
|
|
1833
|
+
const [submitting, setSubmitting] = useState9(false);
|
|
1834
|
+
const [sent, setSent] = useState9(false);
|
|
1835
|
+
const [error, setError] = useState9(null);
|
|
620
1836
|
const emailError = useMemo4(() => {
|
|
621
1837
|
if (email.length === 0) return null;
|
|
622
1838
|
if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
|
|
623
1839
|
return null;
|
|
624
1840
|
}, [email]);
|
|
625
1841
|
const canSubmit = email.length > 0 && emailError === null && !submitting;
|
|
626
|
-
const submit =
|
|
1842
|
+
const submit = useCallback5(async () => {
|
|
627
1843
|
if (!canSubmit) return false;
|
|
628
1844
|
setSubmitting(true);
|
|
629
1845
|
setError(null);
|
|
@@ -651,49 +1867,49 @@ function useForgotForm() {
|
|
|
651
1867
|
}
|
|
652
1868
|
|
|
653
1869
|
// src/defaults/DefaultForgotScreen.tsx
|
|
654
|
-
import { jsx as
|
|
1870
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
655
1871
|
function DefaultForgotScreen({ onNavigate }) {
|
|
656
1872
|
const { name } = useTemplateConfig();
|
|
657
1873
|
const f = useForgotForm();
|
|
658
1874
|
if (f.sent) {
|
|
659
|
-
return /* @__PURE__ */
|
|
660
|
-
/* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
1875
|
+
return /* @__PURE__ */ jsxs15("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
1876
|
+
/* @__PURE__ */ jsx21("h1", { children: "Verifique seu e-mail" }),
|
|
1877
|
+
/* @__PURE__ */ jsx21("p", { style: { opacity: 0.7 }, children: "Enviamos um link pra redefinir sua senha." }),
|
|
1878
|
+
/* @__PURE__ */ jsx21("button", { "data-testid": "forgot-back-login", type: "button", onClick: () => onNavigate("login"), children: "Voltar pro login" })
|
|
663
1879
|
] });
|
|
664
1880
|
}
|
|
665
|
-
return /* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
668
|
-
/* @__PURE__ */
|
|
1881
|
+
return /* @__PURE__ */ jsxs15("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1882
|
+
/* @__PURE__ */ jsx21("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1883
|
+
/* @__PURE__ */ jsx21("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Redefinir senha" }),
|
|
1884
|
+
/* @__PURE__ */ jsxs15("form", { onSubmit: (e) => {
|
|
669
1885
|
e.preventDefault();
|
|
670
1886
|
void f.submit();
|
|
671
1887
|
}, children: [
|
|
672
|
-
/* @__PURE__ */
|
|
1888
|
+
/* @__PURE__ */ jsxs15("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
673
1889
|
"E-mail",
|
|
674
|
-
/* @__PURE__ */
|
|
675
|
-
f.emailError && /* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsx21("input", { "data-testid": "forgot-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
|
|
1891
|
+
f.emailError && /* @__PURE__ */ jsx21("small", { style: { color: "#c00" }, children: f.emailError })
|
|
676
1892
|
] }),
|
|
677
|
-
f.error && /* @__PURE__ */
|
|
678
|
-
/* @__PURE__ */
|
|
1893
|
+
f.error && /* @__PURE__ */ jsx21("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
1894
|
+
/* @__PURE__ */ jsx21("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
1895
|
] }),
|
|
680
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsx21("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx21("button", { "data-testid": "forgot-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Voltar pro login" }) })
|
|
681
1897
|
] });
|
|
682
1898
|
}
|
|
683
1899
|
|
|
684
1900
|
// src/hooks/useResetForm.ts
|
|
685
|
-
import { useCallback as
|
|
1901
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo5, useState as useState10 } from "react";
|
|
686
1902
|
import { useHook as useHook7 } from "@hook-sdk/sdk";
|
|
687
1903
|
var MIN_PASSWORD3 = 12;
|
|
688
1904
|
function useResetForm() {
|
|
689
1905
|
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
|
-
|
|
1906
|
+
const [token, setToken] = useState10(null);
|
|
1907
|
+
const [password, setPassword] = useState10("");
|
|
1908
|
+
const [confirm, setConfirm] = useState10("");
|
|
1909
|
+
const [submitting, setSubmitting] = useState10(false);
|
|
1910
|
+
const [done, setDone] = useState10(false);
|
|
1911
|
+
const [error, setError] = useState10(null);
|
|
1912
|
+
useEffect6(() => {
|
|
697
1913
|
if (typeof window === "undefined") return;
|
|
698
1914
|
const params = new URLSearchParams(window.location.search);
|
|
699
1915
|
const t = params.get("token");
|
|
@@ -710,7 +1926,7 @@ function useResetForm() {
|
|
|
710
1926
|
return null;
|
|
711
1927
|
}, [confirm, password]);
|
|
712
1928
|
const canSubmit = token !== null && password.length >= MIN_PASSWORD3 && confirm === password && passwordError === null && confirmError === null && !submitting && !done;
|
|
713
|
-
const submit =
|
|
1929
|
+
const submit = useCallback6(async () => {
|
|
714
1930
|
if (!canSubmit || token === null) return;
|
|
715
1931
|
setSubmitting(true);
|
|
716
1932
|
setError(null);
|
|
@@ -746,67 +1962,67 @@ function useResetForm() {
|
|
|
746
1962
|
}
|
|
747
1963
|
|
|
748
1964
|
// src/defaults/DefaultResetScreen.tsx
|
|
749
|
-
import { jsx as
|
|
1965
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
750
1966
|
function DefaultResetScreen({ onNavigate }) {
|
|
751
1967
|
const { name } = useTemplateConfig();
|
|
752
1968
|
const f = useResetForm();
|
|
753
1969
|
if (f.done) {
|
|
754
|
-
return /* @__PURE__ */
|
|
755
|
-
/* @__PURE__ */
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
1970
|
+
return /* @__PURE__ */ jsxs16("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
1971
|
+
/* @__PURE__ */ jsx22("h1", { children: "Senha alterada" }),
|
|
1972
|
+
/* @__PURE__ */ jsx22("p", { style: { opacity: 0.7 }, children: "Agora \xE9 s\xF3 fazer login com a nova senha." }),
|
|
1973
|
+
/* @__PURE__ */ jsx22("button", { "data-testid": "reset-back-login", type: "button", onClick: () => onNavigate("login"), children: "Ir pro login" })
|
|
758
1974
|
] });
|
|
759
1975
|
}
|
|
760
1976
|
if (f.token === null) {
|
|
761
|
-
return /* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
764
|
-
/* @__PURE__ */
|
|
1977
|
+
return /* @__PURE__ */ jsxs16("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
|
|
1978
|
+
/* @__PURE__ */ jsx22("h1", { children: "Link inv\xE1lido" }),
|
|
1979
|
+
/* @__PURE__ */ jsx22("p", { style: { opacity: 0.7 }, children: "Pe\xE7a um novo link de reset." }),
|
|
1980
|
+
/* @__PURE__ */ jsx22("button", { "data-testid": "reset-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), children: "Pedir novo link" })
|
|
765
1981
|
] });
|
|
766
1982
|
}
|
|
767
|
-
return /* @__PURE__ */
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
1983
|
+
return /* @__PURE__ */ jsxs16("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
|
|
1984
|
+
/* @__PURE__ */ jsx22("h1", { style: { marginBottom: 8 }, children: name }),
|
|
1985
|
+
/* @__PURE__ */ jsx22("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Escolha uma nova senha" }),
|
|
1986
|
+
/* @__PURE__ */ jsxs16("form", { onSubmit: (e) => {
|
|
771
1987
|
e.preventDefault();
|
|
772
1988
|
void f.submit();
|
|
773
1989
|
}, children: [
|
|
774
|
-
/* @__PURE__ */
|
|
1990
|
+
/* @__PURE__ */ jsxs16("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
775
1991
|
"Nova senha",
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
f.passwordError && /* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx22("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" }),
|
|
1993
|
+
f.passwordError && /* @__PURE__ */ jsx22("small", { style: { color: "#c00" }, children: f.passwordError })
|
|
778
1994
|
] }),
|
|
779
|
-
/* @__PURE__ */
|
|
1995
|
+
/* @__PURE__ */ jsxs16("label", { style: { display: "block", marginBottom: 12 }, children: [
|
|
780
1996
|
"Confirmar senha",
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
f.confirmError && /* @__PURE__ */
|
|
1997
|
+
/* @__PURE__ */ jsx22("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" }),
|
|
1998
|
+
f.confirmError && /* @__PURE__ */ jsx22("small", { style: { color: "#c00" }, children: f.confirmError })
|
|
783
1999
|
] }),
|
|
784
|
-
f.error && /* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
2000
|
+
f.error && /* @__PURE__ */ jsx22("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
|
|
2001
|
+
/* @__PURE__ */ jsx22("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
2002
|
] })
|
|
787
2003
|
] });
|
|
788
2004
|
}
|
|
789
2005
|
|
|
790
2006
|
// src/defaults/DefaultPaywall.tsx
|
|
791
|
-
import { useState as
|
|
792
|
-
import { jsx as
|
|
2007
|
+
import { useState as useState11 } from "react";
|
|
2008
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
793
2009
|
function DefaultPaywall() {
|
|
794
2010
|
const config = useTemplateConfig();
|
|
795
2011
|
const { checkout, opening, error } = usePaywallState();
|
|
796
2012
|
const p = config.subscription.paywall_config;
|
|
797
|
-
const [cpf, setCpf] =
|
|
2013
|
+
const [cpf, setCpf] = useState11("");
|
|
798
2014
|
const cpfDigits = cpf.replace(/\D/g, "");
|
|
799
2015
|
const canCheckout = cpfDigits.length === 11 && !opening;
|
|
800
|
-
return /* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
p.subtitle && /* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
/* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
2016
|
+
return /* @__PURE__ */ jsxs17("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
|
|
2017
|
+
/* @__PURE__ */ jsx23("h1", { style: { marginBottom: 8 }, children: p.title }),
|
|
2018
|
+
p.subtitle && /* @__PURE__ */ jsx23("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
|
|
2019
|
+
/* @__PURE__ */ jsx23("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", marginBottom: 24 }, children: p.benefits.map((b) => /* @__PURE__ */ jsxs17("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
|
|
2020
|
+
/* @__PURE__ */ jsx23("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
|
|
2021
|
+
/* @__PURE__ */ jsx23("span", { children: b })
|
|
806
2022
|
] }, b)) }),
|
|
807
|
-
/* @__PURE__ */
|
|
808
|
-
/* @__PURE__ */
|
|
809
|
-
/* @__PURE__ */
|
|
2023
|
+
/* @__PURE__ */ jsxs17("div", { style: { textAlign: "left", marginBottom: 16 }, children: [
|
|
2024
|
+
/* @__PURE__ */ jsx23("label", { style: { display: "block", fontSize: 14, opacity: 0.7, marginBottom: 4 }, children: "Seu CPF (pra emiss\xE3o de recibo)" }),
|
|
2025
|
+
/* @__PURE__ */ jsx23(
|
|
810
2026
|
"input",
|
|
811
2027
|
{
|
|
812
2028
|
"data-testid": "paywall-cpf",
|
|
@@ -819,8 +2035,8 @@ function DefaultPaywall() {
|
|
|
819
2035
|
}
|
|
820
2036
|
)
|
|
821
2037
|
] }),
|
|
822
|
-
error && /* @__PURE__ */
|
|
823
|
-
/* @__PURE__ */
|
|
2038
|
+
error && /* @__PURE__ */ jsx23("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: error.message }),
|
|
2039
|
+
/* @__PURE__ */ jsx23(
|
|
824
2040
|
"button",
|
|
825
2041
|
{
|
|
826
2042
|
"data-testid": "paywall-cta",
|
|
@@ -841,21 +2057,21 @@ function DefaultPaywall() {
|
|
|
841
2057
|
children: opening ? "Abrindo..." : p.cta
|
|
842
2058
|
}
|
|
843
2059
|
),
|
|
844
|
-
p.priceHint && /* @__PURE__ */
|
|
845
|
-
p.footerNote && /* @__PURE__ */
|
|
2060
|
+
p.priceHint && /* @__PURE__ */ jsx23("p", { style: { opacity: 0.6, marginTop: 12 }, children: p.priceHint }),
|
|
2061
|
+
p.footerNote && /* @__PURE__ */ jsx23("p", { style: { opacity: 0.5, marginTop: 16, fontSize: 12 }, children: p.footerNote })
|
|
846
2062
|
] });
|
|
847
2063
|
}
|
|
848
2064
|
|
|
849
2065
|
// src/AppRoot.tsx
|
|
850
|
-
import { Fragment as
|
|
2066
|
+
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
851
2067
|
var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
|
|
852
2068
|
function PaymentReturnHandler({ children }) {
|
|
853
2069
|
const { subscription } = useHook8();
|
|
854
|
-
const subRef =
|
|
2070
|
+
const subRef = useRef2(subscription);
|
|
855
2071
|
subRef.current = subscription;
|
|
856
|
-
const runIdRef =
|
|
857
|
-
const [state, setState] =
|
|
858
|
-
const runPoll =
|
|
2072
|
+
const runIdRef = useRef2(0);
|
|
2073
|
+
const [state, setState] = useState12("idle");
|
|
2074
|
+
const runPoll = useCallback7(() => {
|
|
859
2075
|
const runId = ++runIdRef.current;
|
|
860
2076
|
setState("confirming");
|
|
861
2077
|
let attempts = 0;
|
|
@@ -884,7 +2100,7 @@ function PaymentReturnHandler({ children }) {
|
|
|
884
2100
|
};
|
|
885
2101
|
void tick();
|
|
886
2102
|
}, []);
|
|
887
|
-
|
|
2103
|
+
useEffect7(() => {
|
|
888
2104
|
if (typeof window === "undefined") return;
|
|
889
2105
|
const url = new URL(window.location.href);
|
|
890
2106
|
if (url.searchParams.get("paymentReturn") !== "1") return;
|
|
@@ -894,20 +2110,20 @@ function PaymentReturnHandler({ children }) {
|
|
|
894
2110
|
};
|
|
895
2111
|
}, [runPoll]);
|
|
896
2112
|
if (state === "confirming") {
|
|
897
|
-
return /* @__PURE__ */
|
|
2113
|
+
return /* @__PURE__ */ jsx24(
|
|
898
2114
|
"div",
|
|
899
2115
|
{
|
|
900
2116
|
role: "status",
|
|
901
2117
|
"aria-live": "polite",
|
|
902
|
-
style:
|
|
2118
|
+
style: overlayStyle2,
|
|
903
2119
|
children: "Confirmando pagamento\u2026"
|
|
904
2120
|
}
|
|
905
2121
|
);
|
|
906
2122
|
}
|
|
907
2123
|
if (state === "waiting") {
|
|
908
|
-
return /* @__PURE__ */
|
|
909
|
-
/* @__PURE__ */
|
|
910
|
-
/* @__PURE__ */
|
|
2124
|
+
return /* @__PURE__ */ jsx24("div", { role: "status", "aria-live": "polite", style: overlayStyle2, children: /* @__PURE__ */ jsxs18("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
|
|
2125
|
+
/* @__PURE__ */ jsx24("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
|
|
2126
|
+
/* @__PURE__ */ jsx24(
|
|
911
2127
|
"button",
|
|
912
2128
|
{
|
|
913
2129
|
type: "button",
|
|
@@ -918,9 +2134,9 @@ function PaymentReturnHandler({ children }) {
|
|
|
918
2134
|
)
|
|
919
2135
|
] }) });
|
|
920
2136
|
}
|
|
921
|
-
return /* @__PURE__ */
|
|
2137
|
+
return /* @__PURE__ */ jsx24(Fragment6, { children });
|
|
922
2138
|
}
|
|
923
|
-
var
|
|
2139
|
+
var overlayStyle2 = {
|
|
924
2140
|
position: "fixed",
|
|
925
2141
|
inset: 0,
|
|
926
2142
|
display: "flex",
|
|
@@ -951,14 +2167,14 @@ function AppRoot({
|
|
|
951
2167
|
Reset = DefaultResetScreen,
|
|
952
2168
|
Paywall = DefaultPaywall
|
|
953
2169
|
}) {
|
|
954
|
-
return /* @__PURE__ */
|
|
2170
|
+
return /* @__PURE__ */ jsx24(PaymentReturnHandler, { children: /* @__PURE__ */ jsx24(TemplateConfigProvider, { config, children: /* @__PURE__ */ jsx24(ErrorBoundary, { children: /* @__PURE__ */ jsx24(ThemeProvider, { children: /* @__PURE__ */ jsx24(InstallGate, { children: /* @__PURE__ */ jsx24(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ jsx24(PersistedKeysPrefetch, { children: /* @__PURE__ */ jsxs18(SubscriptionGate, { Paywall, children: [
|
|
955
2171
|
children,
|
|
956
|
-
/* @__PURE__ */
|
|
957
|
-
] }) }) }) }) }) }) });
|
|
2172
|
+
/* @__PURE__ */ jsx24(PushPrompt, {})
|
|
2173
|
+
] }) }) }) }) }) }) }) });
|
|
958
2174
|
}
|
|
959
2175
|
|
|
960
2176
|
// src/hooks/usePush.ts
|
|
961
|
-
import { useCallback as
|
|
2177
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useState as useState13 } from "react";
|
|
962
2178
|
import { useHook as useHook9 } from "@hook-sdk/sdk";
|
|
963
2179
|
function detectIosNeedsInstall() {
|
|
964
2180
|
if (typeof navigator === "undefined" || typeof window === "undefined") return false;
|
|
@@ -986,11 +2202,11 @@ function deriveState(push) {
|
|
|
986
2202
|
}
|
|
987
2203
|
function usePush() {
|
|
988
2204
|
const { push } = useHook9();
|
|
989
|
-
const [state, setState] =
|
|
990
|
-
|
|
2205
|
+
const [state, setState] = useState13(() => deriveState(push));
|
|
2206
|
+
useEffect8(() => {
|
|
991
2207
|
setState(deriveState(push));
|
|
992
2208
|
}, [push]);
|
|
993
|
-
const subscribe =
|
|
2209
|
+
const subscribe = useCallback8(async () => {
|
|
994
2210
|
try {
|
|
995
2211
|
await push.subscribe();
|
|
996
2212
|
setState({ kind: "subscribed" });
|
|
@@ -1002,7 +2218,7 @@ function usePush() {
|
|
|
1002
2218
|
throw e;
|
|
1003
2219
|
}
|
|
1004
2220
|
}, [push]);
|
|
1005
|
-
const unsubscribe =
|
|
2221
|
+
const unsubscribe = useCallback8(async () => {
|
|
1006
2222
|
try {
|
|
1007
2223
|
await push.unsubscribe();
|
|
1008
2224
|
setState({ kind: "prompt" });
|
|
@@ -1015,31 +2231,31 @@ function usePush() {
|
|
|
1015
2231
|
}
|
|
1016
2232
|
|
|
1017
2233
|
// src/components/PushPrompt.tsx
|
|
1018
|
-
import { jsx as
|
|
2234
|
+
import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1019
2235
|
function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
|
|
1020
2236
|
const { state, subscribe } = usePush();
|
|
1021
2237
|
if (state.kind === "subscribed") return null;
|
|
1022
2238
|
if (state.kind === "ios_needs_install") {
|
|
1023
|
-
return /* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */
|
|
2239
|
+
return /* @__PURE__ */ jsxs19("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
|
|
2240
|
+
/* @__PURE__ */ jsx25("h3", { children: texts.iosInstallTitle }),
|
|
2241
|
+
/* @__PURE__ */ jsx25("p", { children: texts.iosInstallBody }),
|
|
2242
|
+
onInstallRequested && texts.iosInstallCta && /* @__PURE__ */ jsx25("button", { onClick: onInstallRequested, children: texts.iosInstallCta })
|
|
1027
2243
|
] });
|
|
1028
2244
|
}
|
|
1029
2245
|
if (state.kind === "denied") {
|
|
1030
|
-
return /* @__PURE__ */
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
2246
|
+
return /* @__PURE__ */ jsxs19("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
|
|
2247
|
+
/* @__PURE__ */ jsx25("h3", { children: texts.deniedTitle }),
|
|
2248
|
+
/* @__PURE__ */ jsx25("p", { children: texts.deniedBody })
|
|
1033
2249
|
] });
|
|
1034
2250
|
}
|
|
1035
2251
|
if (state.kind === "unsupported") {
|
|
1036
|
-
return /* @__PURE__ */
|
|
2252
|
+
return /* @__PURE__ */ jsx25("div", { className, role: "region", children: /* @__PURE__ */ jsx25("p", { children: texts.unsupportedBody }) });
|
|
1037
2253
|
}
|
|
1038
2254
|
if (state.kind === "error") {
|
|
1039
|
-
return /* @__PURE__ */
|
|
2255
|
+
return /* @__PURE__ */ jsx25("div", { className, role: "region", "aria-label": "error", children: /* @__PURE__ */ jsx25("p", { children: state.message }) });
|
|
1040
2256
|
}
|
|
1041
|
-
return /* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
2257
|
+
return /* @__PURE__ */ jsxs19("div", { className, role: "region", children: [
|
|
2258
|
+
/* @__PURE__ */ jsx25(
|
|
1043
2259
|
"button",
|
|
1044
2260
|
{
|
|
1045
2261
|
type: "button",
|
|
@@ -1053,27 +2269,27 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
|
|
|
1053
2269
|
children: texts.cta
|
|
1054
2270
|
}
|
|
1055
2271
|
),
|
|
1056
|
-
onDeclined && /* @__PURE__ */
|
|
2272
|
+
onDeclined && /* @__PURE__ */ jsx25("button", { type: "button", onClick: onDeclined, children: texts.declineCta })
|
|
1057
2273
|
] });
|
|
1058
2274
|
}
|
|
1059
2275
|
|
|
1060
2276
|
// src/defaults/EmptyState.tsx
|
|
1061
|
-
import { jsx as
|
|
2277
|
+
import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1062
2278
|
function EmptyState({ title, description, action }) {
|
|
1063
|
-
return /* @__PURE__ */
|
|
1064
|
-
/* @__PURE__ */
|
|
1065
|
-
description && /* @__PURE__ */
|
|
1066
|
-
action && /* @__PURE__ */
|
|
2279
|
+
return /* @__PURE__ */ jsxs20("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
|
|
2280
|
+
/* @__PURE__ */ jsx26("h2", { style: { marginBottom: 8 }, children: title }),
|
|
2281
|
+
description && /* @__PURE__ */ jsx26("p", { style: { opacity: 0.7 }, children: description }),
|
|
2282
|
+
action && /* @__PURE__ */ jsx26("div", { style: { marginTop: 16 }, children: action })
|
|
1067
2283
|
] });
|
|
1068
2284
|
}
|
|
1069
2285
|
|
|
1070
2286
|
// src/hooks/useAuthPrimitives.ts
|
|
1071
|
-
import { useEffect as
|
|
2287
|
+
import { useEffect as useEffect9 } from "react";
|
|
1072
2288
|
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
1073
2289
|
var warned = false;
|
|
1074
2290
|
function useAuthPrimitives() {
|
|
1075
2291
|
const { auth } = useHook10();
|
|
1076
|
-
|
|
2292
|
+
useEffect9(() => {
|
|
1077
2293
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
1078
2294
|
warned = true;
|
|
1079
2295
|
console.warn(
|
|
@@ -1104,14 +2320,14 @@ function useSubscription() {
|
|
|
1104
2320
|
}
|
|
1105
2321
|
|
|
1106
2322
|
// src/hooks/useReminders.ts
|
|
1107
|
-
import { useCallback as
|
|
2323
|
+
import { useCallback as useCallback9, useEffect as useEffect10, useState as useState14 } from "react";
|
|
1108
2324
|
import { useHook as useHook12 } from "@hook-sdk/sdk";
|
|
1109
2325
|
function useReminders() {
|
|
1110
2326
|
const { push } = useHook12();
|
|
1111
2327
|
const r = push.reminders;
|
|
1112
|
-
const [reminders, setReminders] =
|
|
1113
|
-
const [loading, setLoading] =
|
|
1114
|
-
const reload =
|
|
2328
|
+
const [reminders, setReminders] = useState14([]);
|
|
2329
|
+
const [loading, setLoading] = useState14(true);
|
|
2330
|
+
const reload = useCallback9(async () => {
|
|
1115
2331
|
setLoading(true);
|
|
1116
2332
|
try {
|
|
1117
2333
|
const next = await r.list();
|
|
@@ -1120,38 +2336,38 @@ function useReminders() {
|
|
|
1120
2336
|
setLoading(false);
|
|
1121
2337
|
}
|
|
1122
2338
|
}, [r]);
|
|
1123
|
-
|
|
2339
|
+
useEffect10(() => {
|
|
1124
2340
|
void reload();
|
|
1125
2341
|
}, [reload]);
|
|
1126
|
-
const setReminder =
|
|
2342
|
+
const setReminder = useCallback9(async (input) => {
|
|
1127
2343
|
await r.set(input);
|
|
1128
2344
|
await reload();
|
|
1129
2345
|
}, [r, reload]);
|
|
1130
|
-
const deleteReminder =
|
|
2346
|
+
const deleteReminder = useCallback9(async (slot) => {
|
|
1131
2347
|
await r.delete(slot);
|
|
1132
2348
|
await reload();
|
|
1133
2349
|
}, [r, reload]);
|
|
1134
|
-
const schedule =
|
|
2350
|
+
const schedule = useCallback9(async (items) => {
|
|
1135
2351
|
return r.schedule(items);
|
|
1136
2352
|
}, [r]);
|
|
1137
|
-
const setFallbacks =
|
|
2353
|
+
const setFallbacks = useCallback9(async (items) => {
|
|
1138
2354
|
return r.setFallbacks(items);
|
|
1139
2355
|
}, [r]);
|
|
1140
2356
|
return { reminders, loading, setReminder, deleteReminder, schedule, setFallbacks };
|
|
1141
2357
|
}
|
|
1142
2358
|
|
|
1143
2359
|
// src/hooks/useToast.ts
|
|
1144
|
-
import { useCallback as
|
|
2360
|
+
import { useCallback as useCallback10, useState as useState15 } from "react";
|
|
1145
2361
|
function useToast() {
|
|
1146
|
-
const [items, setItems] =
|
|
1147
|
-
const show =
|
|
2362
|
+
const [items, setItems] = useState15([]);
|
|
2363
|
+
const show = useCallback10((message, kind = "info") => {
|
|
1148
2364
|
const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1149
2365
|
setItems((prev) => [...prev, { id, message, kind }]);
|
|
1150
2366
|
setTimeout(() => {
|
|
1151
2367
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1152
2368
|
}, 4e3);
|
|
1153
2369
|
}, []);
|
|
1154
|
-
const dismiss =
|
|
2370
|
+
const dismiss = useCallback10((id) => {
|
|
1155
2371
|
setItems((prev) => prev.filter((t) => t.id !== id));
|
|
1156
2372
|
}, []);
|
|
1157
2373
|
return { items, show, dismiss };
|
|
@@ -1165,11 +2381,21 @@ export {
|
|
|
1165
2381
|
DefaultSignupScreen,
|
|
1166
2382
|
EmptyState,
|
|
1167
2383
|
ErrorBoundary,
|
|
2384
|
+
InstallGate,
|
|
2385
|
+
InstallSplash,
|
|
1168
2386
|
LoadingState,
|
|
1169
2387
|
PushPrompt2 as PushPrompt,
|
|
2388
|
+
detectAndroidBrowser,
|
|
2389
|
+
detectIOSBrowser,
|
|
2390
|
+
detectInAppApp,
|
|
2391
|
+
detectPlatform,
|
|
2392
|
+
detectStandalone,
|
|
2393
|
+
shouldBlockInstall,
|
|
2394
|
+
shouldShowPermanentOption,
|
|
1170
2395
|
useAuth,
|
|
1171
2396
|
useAuthPrimitives,
|
|
1172
2397
|
useForgotForm,
|
|
2398
|
+
useInstallPrompt,
|
|
1173
2399
|
useLoginForm,
|
|
1174
2400
|
usePaywallState,
|
|
1175
2401
|
usePush,
|