@getmicdrop/svelte-components 5.16.2 → 5.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calendar/AboutShow/AboutShow.svelte +19 -4
- package/dist/calendar/AboutShow/AboutShow.svelte.d.ts +2 -0
- package/dist/calendar/AboutShow/AboutShow.svelte.d.ts.map +1 -1
- package/dist/calendar/FAQs/FAQs.svelte +3 -1
- package/dist/calendar/FAQs/FAQs.svelte.d.ts +2 -0
- package/dist/calendar/FAQs/FAQs.svelte.d.ts.map +1 -1
- package/dist/calendar/OrderSummary/OrderSummary.svelte +64 -34
- package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts +2 -0
- package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts.map +1 -1
- package/dist/components/Layout/Stack.spec.js +1 -1
- package/dist/datetime/__tests__/format.test.js +1 -1
- package/dist/datetime/__tests__/parse.test.js +1 -1
- package/dist/datetime/__tests__/timezone.test.js +1 -1
- package/dist/datetime/parse.js +1 -1
- package/dist/datetime/timezone.d.ts.map +1 -1
- package/dist/datetime/timezone.js +1 -2
- package/dist/forms/createFormStore.svelte.d.ts +1 -1
- package/dist/forms/createFormStore.svelte.d.ts.map +1 -1
- package/dist/forms/createFormStore.svelte.js +0 -1
- package/dist/recipes/CropImage/CropImage.svelte +33 -11
- package/dist/recipes/CropImage/CropImage.svelte.d.ts +15 -3
- package/dist/recipes/CropImage/CropImage.svelte.d.ts.map +1 -1
- package/dist/recipes/ImageUploader/ImageUploader.svelte +34 -11
- package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts +17 -9
- package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts.map +1 -1
- package/dist/recipes/SuperLogin/SuperLogin.spec.js +21 -21
- package/dist/recipes/SuperLogin/SuperLogin.svelte +143 -77
- package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts +2 -0
- package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +19 -19
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +5 -8
- package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.d.ts.map +1 -1
- package/dist/services/EventService.d.ts +1 -1
- package/dist/services/EventService.d.ts.map +1 -1
- package/dist/services/EventService.js +6 -2
- package/dist/services/EventService.spec.js +1 -1
- package/dist/services/ShowService.js +11 -10
- package/dist/services/ShowService.spec.js +11 -11
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +24 -27
- package/dist/telemetry.server.js +6 -6
- package/dist/telemetry.server.spec.js +3 -4
- package/dist/telemetry.spec.js +3 -4
- package/dist/utils/apiConfig.js +12 -15
- package/dist/utils/apiConfig.spec.js +2 -2
- package/package.json +37 -41
|
@@ -12,6 +12,75 @@
|
|
|
12
12
|
import Checkbox from "../../primitives/Checkbox/Checkbox.svelte";
|
|
13
13
|
import { typography } from '../../tokens/typography';
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Default labels for all user-visible strings in SuperLogin.
|
|
17
|
+
* Consumers can override any string via the `labels` prop.
|
|
18
|
+
*/
|
|
19
|
+
const defaultLabels = {
|
|
20
|
+
// Login view
|
|
21
|
+
welcomeTitle: (name) => name ? `Welcome, ${name}!` : 'Welcome!',
|
|
22
|
+
signInDescription: (portal) => `Sign in to access your ${portal}.`,
|
|
23
|
+
welcomeBackTitle: (name) => `Welcome back, ${name}`,
|
|
24
|
+
notYouButton: (name) => `Not ${name}?`,
|
|
25
|
+
logInTitle: 'Log in',
|
|
26
|
+
emailLabel: 'Email',
|
|
27
|
+
passwordLabel: 'Password',
|
|
28
|
+
forgotPassword: 'Forgot your password?',
|
|
29
|
+
rememberMe: 'Remember me on this device',
|
|
30
|
+
logInButton: 'Log in',
|
|
31
|
+
or: 'OR',
|
|
32
|
+
sendMeLoginLink: 'Send me a login link',
|
|
33
|
+
|
|
34
|
+
// Account selection view
|
|
35
|
+
selectAccountTitle: 'Select account',
|
|
36
|
+
multipleAccountsDescription: (email) => `You have multiple accounts associated with ${email}. Select one to continue.`,
|
|
37
|
+
loginDifferentEmail: 'Log in with a different email',
|
|
38
|
+
performerFallback: 'Performer',
|
|
39
|
+
|
|
40
|
+
// Setup view
|
|
41
|
+
setupTitle: (name) => name ? `Welcome, ${name}` : 'Set up your account',
|
|
42
|
+
setupDescription: 'Create a password to finish setting up your account.',
|
|
43
|
+
createPasswordLabel: 'Create password',
|
|
44
|
+
completeSetupButton: 'Complete setup',
|
|
45
|
+
tosAgreement: 'By setting up your account, you agree to Micdrop\'s',
|
|
46
|
+
termsOfService: 'terms of service',
|
|
47
|
+
|
|
48
|
+
// Reset password view
|
|
49
|
+
resetTitle: 'Reset your password',
|
|
50
|
+
resetDescription: 'Enter the email address associated with your account and we\'ll send you a link to reset your password.',
|
|
51
|
+
sendResetLink: 'Send reset link',
|
|
52
|
+
returnToLogIn: 'Return to log in',
|
|
53
|
+
|
|
54
|
+
// Login link view
|
|
55
|
+
loginLinkTitle: 'Send a login link',
|
|
56
|
+
loginLinkDescription: 'Enter the email address associated with your account and we\'ll send you a link to sign in.',
|
|
57
|
+
sendLoginLink: 'Send login link',
|
|
58
|
+
|
|
59
|
+
// Success view
|
|
60
|
+
checkEmailTitle: 'Check your email',
|
|
61
|
+
resentMessage: (type, email) => `We've resent ${type === 'reset' ? 'password reset instructions' : 'a login link'} to ${email} if it is an email on file.`,
|
|
62
|
+
resentFollowUp: 'Please check again. If you still haven\'t received an email,',
|
|
63
|
+
tryDifferentEmail: 'try a different email',
|
|
64
|
+
successMessage: (type, email) => `Thanks! If ${email} matches an email we have on file, then we've sent you an email containing further instructions for ${type === 'reset' ? 'resetting your password' : 'signing in'}.`,
|
|
65
|
+
noEmailReceived: 'If you haven\'t received an email in 5 minutes, check your spam,',
|
|
66
|
+
resend: 'resend',
|
|
67
|
+
returnToSignIn: 'Return to sign in',
|
|
68
|
+
|
|
69
|
+
// Error messages
|
|
70
|
+
linkNoLongerValid: 'This link is no longer valid or has already been used.',
|
|
71
|
+
invalidExpiredLink: 'Invalid or expired link.',
|
|
72
|
+
unableToValidateLink: 'Unable to validate link. Please try again later.',
|
|
73
|
+
invalidEmailAddress: (email) => `Invalid email address: ${email}`,
|
|
74
|
+
incorrectCredentials: 'Incorrect email or password',
|
|
75
|
+
loginFailed: 'Login failed. Please try again.',
|
|
76
|
+
networkError: 'Unable to connect. Please check your internet connection.',
|
|
77
|
+
passwordRequirements: 'Password must be at least 8 characters and include at least 2 of: uppercase, lowercase, numbers, or symbols.',
|
|
78
|
+
setupNetworkError: 'Network error. Please try again.',
|
|
79
|
+
|
|
80
|
+
// TOS checkout (OrderSummary reuse)
|
|
81
|
+
placeOrderTos: 'By selecting Place order, I agree to the',
|
|
82
|
+
};
|
|
83
|
+
|
|
15
84
|
/**
|
|
16
85
|
* @typedef {Object} Account
|
|
17
86
|
* @property {string} type - Account type (e.g., 'owner', 'performer')
|
|
@@ -67,8 +136,12 @@
|
|
|
67
136
|
showDarkModeToggle = true,
|
|
68
137
|
/** @type {string} URL search params for setup detection */
|
|
69
138
|
searchParams = "",
|
|
139
|
+
/** @type {Partial<typeof defaultLabels>} Override any user-visible string */
|
|
140
|
+
labels: userLabels = {},
|
|
70
141
|
} = $props();
|
|
71
142
|
|
|
143
|
+
let labels = $derived({ ...defaultLabels, ...userLabels });
|
|
144
|
+
|
|
72
145
|
// Parse search params
|
|
73
146
|
let parsedParams = $derived.by(() => {
|
|
74
147
|
if (typeof window === 'undefined') return { setup: null, email: null };
|
|
@@ -156,8 +229,7 @@
|
|
|
156
229
|
} else if (currentScore !== -1 && currentScore < 2) {
|
|
157
230
|
errors = {
|
|
158
231
|
...errors,
|
|
159
|
-
password:
|
|
160
|
-
"Password must be at least 8 characters and include at least 2 of: uppercase, lowercase, numbers, or symbols.",
|
|
232
|
+
password: labels.passwordRequirements,
|
|
161
233
|
};
|
|
162
234
|
showErrors = true;
|
|
163
235
|
} else if (currentScore >= 2) {
|
|
@@ -241,7 +313,7 @@
|
|
|
241
313
|
isLoading = true;
|
|
242
314
|
try {
|
|
243
315
|
const response = await fetch(
|
|
244
|
-
`${apiBaseUrl}/api/
|
|
316
|
+
`${apiBaseUrl}/api/v2/auth/first-time/${encodeURIComponent(emailVal)}`,
|
|
245
317
|
);
|
|
246
318
|
if (response.ok) {
|
|
247
319
|
const data = await response.json();
|
|
@@ -252,19 +324,19 @@
|
|
|
252
324
|
view = "setup";
|
|
253
325
|
} else {
|
|
254
326
|
errors = {
|
|
255
|
-
email:
|
|
327
|
+
email: labels.linkNoLongerValid,
|
|
256
328
|
};
|
|
257
329
|
showErrors = true;
|
|
258
330
|
triggerShake();
|
|
259
331
|
}
|
|
260
332
|
} else {
|
|
261
|
-
errors = { email:
|
|
333
|
+
errors = { email: labels.invalidExpiredLink };
|
|
262
334
|
showErrors = true;
|
|
263
335
|
triggerShake();
|
|
264
336
|
}
|
|
265
337
|
} catch (e) {
|
|
266
338
|
console.error(e);
|
|
267
|
-
errors = { email:
|
|
339
|
+
errors = { email: labels.unableToValidateLink };
|
|
268
340
|
showErrors = true;
|
|
269
341
|
triggerShake();
|
|
270
342
|
} finally {
|
|
@@ -285,13 +357,13 @@
|
|
|
285
357
|
// Validate email format
|
|
286
358
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
287
359
|
if (!emailRegex.test(emailValue)) {
|
|
288
|
-
errors = { email:
|
|
360
|
+
errors = { email: typeof labels.invalidEmailAddress === 'function' ? labels.invalidEmailAddress(emailValue) : labels.invalidEmailAddress };
|
|
289
361
|
triggerShake();
|
|
290
362
|
isLoading = false;
|
|
291
363
|
return;
|
|
292
364
|
}
|
|
293
365
|
try {
|
|
294
|
-
const response = await fetch(`${apiBaseUrl}/api/
|
|
366
|
+
const response = await fetch(`${apiBaseUrl}/api/v2/auth/login`, {
|
|
295
367
|
method: "POST",
|
|
296
368
|
headers: {
|
|
297
369
|
"Content-Type": "application/json",
|
|
@@ -341,10 +413,10 @@
|
|
|
341
413
|
}
|
|
342
414
|
|
|
343
415
|
if (response.status === 401) {
|
|
344
|
-
errors = { password:
|
|
416
|
+
errors = { password: labels.incorrectCredentials };
|
|
345
417
|
} else {
|
|
346
418
|
errors = {
|
|
347
|
-
password: errorData.message ||
|
|
419
|
+
password: errorData.message || labels.loginFailed,
|
|
348
420
|
};
|
|
349
421
|
}
|
|
350
422
|
triggerShake();
|
|
@@ -353,10 +425,10 @@
|
|
|
353
425
|
console.error("Login Error:", error);
|
|
354
426
|
if (error.message === "Network Error" || error.name === "TypeError") {
|
|
355
427
|
errors = {
|
|
356
|
-
password:
|
|
428
|
+
password: labels.networkError,
|
|
357
429
|
};
|
|
358
430
|
} else {
|
|
359
|
-
errors = { password:
|
|
431
|
+
errors = { password: labels.incorrectCredentials };
|
|
360
432
|
}
|
|
361
433
|
triggerShake();
|
|
362
434
|
isLoading = false;
|
|
@@ -369,7 +441,7 @@
|
|
|
369
441
|
const passwordValue = password;
|
|
370
442
|
|
|
371
443
|
try {
|
|
372
|
-
const response = await fetch(`${apiBaseUrl}/api/
|
|
444
|
+
const response = await fetch(`${apiBaseUrl}/api/v2/auth/first-time`, {
|
|
373
445
|
method: "POST",
|
|
374
446
|
headers: {
|
|
375
447
|
"Content-Type": "application/json",
|
|
@@ -399,14 +471,14 @@
|
|
|
399
471
|
errors = {
|
|
400
472
|
password:
|
|
401
473
|
errorData.error ||
|
|
402
|
-
|
|
474
|
+
labels.passwordRequirements,
|
|
403
475
|
};
|
|
404
476
|
showErrors = true;
|
|
405
477
|
triggerShake();
|
|
406
478
|
}
|
|
407
479
|
} catch (error) {
|
|
408
480
|
console.error("Error setting up account:", error);
|
|
409
|
-
errors = { password:
|
|
481
|
+
errors = { password: labels.setupNetworkError };
|
|
410
482
|
showErrors = true;
|
|
411
483
|
triggerShake();
|
|
412
484
|
} finally {
|
|
@@ -423,13 +495,13 @@
|
|
|
423
495
|
// Validate email format
|
|
424
496
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
425
497
|
if (!emailRegex.test(emailValue)) {
|
|
426
|
-
errors = { email:
|
|
498
|
+
errors = { email: typeof labels.invalidEmailAddress === 'function' ? labels.invalidEmailAddress(emailValue) : labels.invalidEmailAddress };
|
|
427
499
|
triggerShake();
|
|
428
500
|
isLoading = false;
|
|
429
501
|
return false;
|
|
430
502
|
}
|
|
431
503
|
|
|
432
|
-
const apiCall = fetch(`${apiBaseUrl}/api/
|
|
504
|
+
const apiCall = fetch(`${apiBaseUrl}/api/v2/auth/reset-password`, {
|
|
433
505
|
method: "POST",
|
|
434
506
|
headers: { "Content-Type": "application/json" },
|
|
435
507
|
body: JSON.stringify({ email: emailValue.toLowerCase() }),
|
|
@@ -467,13 +539,13 @@
|
|
|
467
539
|
// Validate email format
|
|
468
540
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
469
541
|
if (!emailRegex.test(emailValue)) {
|
|
470
|
-
errors = { email:
|
|
542
|
+
errors = { email: typeof labels.invalidEmailAddress === 'function' ? labels.invalidEmailAddress(emailValue) : labels.invalidEmailAddress };
|
|
471
543
|
triggerShake();
|
|
472
544
|
isLoading = false;
|
|
473
545
|
return false;
|
|
474
546
|
}
|
|
475
547
|
|
|
476
|
-
const apiCall = fetch(`${apiBaseUrl}/api/
|
|
548
|
+
const apiCall = fetch(`${apiBaseUrl}/api/v2/auth/passwordless`, {
|
|
477
549
|
method: "POST",
|
|
478
550
|
headers: { "Content-Type": "application/json" },
|
|
479
551
|
body: JSON.stringify({
|
|
@@ -585,7 +657,7 @@
|
|
|
585
657
|
|
|
586
658
|
const first = profile.firstName || account.firstName || account.name || "";
|
|
587
659
|
const lastName = profile.lastName || account.lastName || "";
|
|
588
|
-
return `${first} ${lastName}`.trim() ||
|
|
660
|
+
return `${first} ${lastName}`.trim() || labels.performerFallback;
|
|
589
661
|
}
|
|
590
662
|
|
|
591
663
|
function triggerShake() {
|
|
@@ -635,22 +707,22 @@
|
|
|
635
707
|
{#if isFirstTime}
|
|
636
708
|
<div>
|
|
637
709
|
<h2 class={typography.h1}>
|
|
638
|
-
|
|
710
|
+
{typeof labels.welcomeTitle === 'function' ? labels.welcomeTitle(firstName) : labels.welcomeTitle}
|
|
639
711
|
</h2>
|
|
640
712
|
<p class={`${typography.smMuted} mt-2`}>
|
|
641
|
-
|
|
713
|
+
{typeof labels.signInDescription === 'function' ? labels.signInDescription(portalType) : labels.signInDescription}
|
|
642
714
|
</p>
|
|
643
715
|
</div>
|
|
644
716
|
{:else if !showEmailInput && rememberedUser?.firstName}
|
|
645
717
|
<h2 class={typography.h1}>
|
|
646
|
-
|
|
718
|
+
{typeof labels.welcomeBackTitle === 'function' ? labels.welcomeBackTitle(rememberedUser.firstName) : labels.welcomeBackTitle}
|
|
647
719
|
</h2>
|
|
648
720
|
<Button variant="link" class="text-gray-500 hover:text-blue-600" onclick={handleNotMe}>
|
|
649
|
-
|
|
721
|
+
{typeof labels.notYouButton === 'function' ? labels.notYouButton(rememberedUser.firstName) : labels.notYouButton}
|
|
650
722
|
</Button>
|
|
651
723
|
{:else}
|
|
652
724
|
<h2 class={typography.h1}>
|
|
653
|
-
|
|
725
|
+
{labels.logInTitle}
|
|
654
726
|
</h2>
|
|
655
727
|
{/if}
|
|
656
728
|
</div>
|
|
@@ -666,7 +738,7 @@
|
|
|
666
738
|
<label
|
|
667
739
|
for="email"
|
|
668
740
|
class={`${typography.label} block mb-2`}
|
|
669
|
-
>
|
|
741
|
+
>{labels.emailLabel}</label>
|
|
670
742
|
<Input
|
|
671
743
|
id="email"
|
|
672
744
|
placeholder=""
|
|
@@ -700,7 +772,7 @@
|
|
|
700
772
|
<label
|
|
701
773
|
for="password"
|
|
702
774
|
class={`${typography.label} block`}
|
|
703
|
-
>
|
|
775
|
+
>{labels.passwordLabel}</label>
|
|
704
776
|
<!-- Placeholder to maintain layout - actual button is after input for tab order -->
|
|
705
777
|
<span class="forgot-password-placeholder"></span>
|
|
706
778
|
</div>
|
|
@@ -713,7 +785,7 @@
|
|
|
713
785
|
/>
|
|
714
786
|
<!-- Forgot password button: after input in DOM for correct tab order, positioned visually in label row -->
|
|
715
787
|
<Button variant="link" type="button" class="forgot-password-btn" onclick={() => { view = "reset"; }}>
|
|
716
|
-
|
|
788
|
+
{labels.forgotPassword}
|
|
717
789
|
</Button>
|
|
718
790
|
</div>
|
|
719
791
|
</div>
|
|
@@ -740,7 +812,7 @@
|
|
|
740
812
|
<Checkbox
|
|
741
813
|
bind:checked={rememberMe}
|
|
742
814
|
id="remember-me"
|
|
743
|
-
>
|
|
815
|
+
>{labels.rememberMe}</Checkbox>
|
|
744
816
|
</div>
|
|
745
817
|
</div>
|
|
746
818
|
|
|
@@ -751,7 +823,7 @@
|
|
|
751
823
|
loading={isLoading}
|
|
752
824
|
disabled={!isFormValid}
|
|
753
825
|
>
|
|
754
|
-
|
|
826
|
+
{labels.logInButton}
|
|
755
827
|
</Button>
|
|
756
828
|
|
|
757
829
|
<div class="relative">
|
|
@@ -762,7 +834,7 @@
|
|
|
762
834
|
</div>
|
|
763
835
|
<div class="relative flex justify-center text-sm">
|
|
764
836
|
<span class={`px-2 bg-white dark:bg-gray-800 ${typography.textMuted}`}
|
|
765
|
-
>
|
|
837
|
+
>{labels.or}</span
|
|
766
838
|
>
|
|
767
839
|
</div>
|
|
768
840
|
</div>
|
|
@@ -775,7 +847,7 @@
|
|
|
775
847
|
view = "login-link";
|
|
776
848
|
}}
|
|
777
849
|
>
|
|
778
|
-
|
|
850
|
+
{labels.sendMeLoginLink}
|
|
779
851
|
</Button>
|
|
780
852
|
</div>
|
|
781
853
|
</form>
|
|
@@ -784,13 +856,14 @@
|
|
|
784
856
|
<div in:fade={{ duration: 200 }} class="space-y-6">
|
|
785
857
|
<div class="space-y-2">
|
|
786
858
|
<h2 class={typography.h1}>
|
|
787
|
-
|
|
859
|
+
{labels.selectAccountTitle}
|
|
788
860
|
</h2>
|
|
789
861
|
<p class={typography.smMuted}>
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
862
|
+
{#if true}
|
|
863
|
+
{@const message = typeof labels.multipleAccountsDescription === 'function' ? labels.multipleAccountsDescription(email) : labels.multipleAccountsDescription}
|
|
864
|
+
{@const parts = message.split(email)}
|
|
865
|
+
{parts[0]}<span class={typography.sm}>{email}</span>{parts[1] || ''}
|
|
866
|
+
{/if}
|
|
794
867
|
</p>
|
|
795
868
|
</div>
|
|
796
869
|
|
|
@@ -850,7 +923,7 @@
|
|
|
850
923
|
|
|
851
924
|
<div class="pt-4 border-t border-gray-300 dark:border-gray-600">
|
|
852
925
|
<Button variant="ghost" size="full" class="text-gray-500 dark:text-gray-400" onclick={handleReturnToSignIn}>
|
|
853
|
-
|
|
926
|
+
{labels.loginDifferentEmail}
|
|
854
927
|
</Button>
|
|
855
928
|
</div>
|
|
856
929
|
</div>
|
|
@@ -858,10 +931,10 @@
|
|
|
858
931
|
<div in:fade={{ duration: 200 }} class="space-y-6">
|
|
859
932
|
<div class="space-y-2">
|
|
860
933
|
<h2 class={typography.h1}>
|
|
861
|
-
{
|
|
934
|
+
{typeof labels.setupTitle === 'function' ? labels.setupTitle(setupFirstName) : labels.setupTitle}
|
|
862
935
|
</h2>
|
|
863
936
|
<p class={typography.smMuted}>
|
|
864
|
-
|
|
937
|
+
{labels.setupDescription}
|
|
865
938
|
</p>
|
|
866
939
|
</div>
|
|
867
940
|
|
|
@@ -876,7 +949,7 @@
|
|
|
876
949
|
<label
|
|
877
950
|
for="setup-password"
|
|
878
951
|
class={`${typography.label} block`}
|
|
879
|
-
>
|
|
952
|
+
>{labels.createPasswordLabel}</label>
|
|
880
953
|
{#if strengthText}
|
|
881
954
|
<span
|
|
882
955
|
class="text-xs font-medium {strengthTextColor} transition-opacity duration-300"
|
|
@@ -921,16 +994,16 @@
|
|
|
921
994
|
loading={isLoading}
|
|
922
995
|
disabled={!isSetupValid}
|
|
923
996
|
>
|
|
924
|
-
|
|
997
|
+
{labels.completeSetupButton}
|
|
925
998
|
</Button>
|
|
926
999
|
|
|
927
1000
|
<div class="text-center">
|
|
928
1001
|
<p class={typography.xsMuted}>
|
|
929
|
-
|
|
1002
|
+
{labels.tosAgreement} <a
|
|
930
1003
|
href={tosUrl}
|
|
931
1004
|
target="_blank"
|
|
932
1005
|
rel="noopener noreferrer"
|
|
933
|
-
class="text-blue-600 hover:underline dark:text-blue-400">
|
|
1006
|
+
class="text-blue-600 hover:underline dark:text-blue-400">{labels.termsOfService}</a
|
|
934
1007
|
>.
|
|
935
1008
|
</p>
|
|
936
1009
|
</div>
|
|
@@ -941,11 +1014,10 @@
|
|
|
941
1014
|
<div in:fade={{ duration: 200 }} class="space-y-6">
|
|
942
1015
|
<div class="space-y-2">
|
|
943
1016
|
<h2 class={typography.h1}>
|
|
944
|
-
|
|
1017
|
+
{labels.resetTitle}
|
|
945
1018
|
</h2>
|
|
946
1019
|
<p class={typography.smMuted}>
|
|
947
|
-
|
|
948
|
-
send you a link to reset your password.
|
|
1020
|
+
{labels.resetDescription}
|
|
949
1021
|
</p>
|
|
950
1022
|
</div>
|
|
951
1023
|
|
|
@@ -959,7 +1031,7 @@
|
|
|
959
1031
|
<label
|
|
960
1032
|
for="reset-email"
|
|
961
1033
|
class={`${typography.label} block mb-2`}
|
|
962
|
-
>
|
|
1034
|
+
>{labels.emailLabel}</label>
|
|
963
1035
|
<Input
|
|
964
1036
|
id="reset-email"
|
|
965
1037
|
placeholder=""
|
|
@@ -991,12 +1063,12 @@
|
|
|
991
1063
|
loading={isLoading}
|
|
992
1064
|
disabled={!email}
|
|
993
1065
|
>
|
|
994
|
-
|
|
1066
|
+
{labels.sendResetLink}
|
|
995
1067
|
</Button>
|
|
996
1068
|
|
|
997
1069
|
<div class="text-center">
|
|
998
1070
|
<Button variant="link" onclick={handleReturnToSignIn}>
|
|
999
|
-
|
|
1071
|
+
{labels.returnToLogIn}
|
|
1000
1072
|
</Button>
|
|
1001
1073
|
</div>
|
|
1002
1074
|
</div>
|
|
@@ -1006,11 +1078,10 @@
|
|
|
1006
1078
|
<div in:fade={{ duration: 200 }} class="space-y-6">
|
|
1007
1079
|
<div class="space-y-2">
|
|
1008
1080
|
<h2 class={typography.h1}>
|
|
1009
|
-
|
|
1081
|
+
{labels.loginLinkTitle}
|
|
1010
1082
|
</h2>
|
|
1011
1083
|
<p class={typography.smMuted}>
|
|
1012
|
-
|
|
1013
|
-
send you a link to sign in.
|
|
1084
|
+
{labels.loginLinkDescription}
|
|
1014
1085
|
</p>
|
|
1015
1086
|
</div>
|
|
1016
1087
|
|
|
@@ -1024,7 +1095,7 @@
|
|
|
1024
1095
|
<label
|
|
1025
1096
|
for="login-link-email"
|
|
1026
1097
|
class={`${typography.label} block mb-2`}
|
|
1027
|
-
>
|
|
1098
|
+
>{labels.emailLabel}</label>
|
|
1028
1099
|
<Input
|
|
1029
1100
|
id="login-link-email"
|
|
1030
1101
|
placeholder=""
|
|
@@ -1068,12 +1139,12 @@
|
|
|
1068
1139
|
loading={isLoading}
|
|
1069
1140
|
disabled={!email}
|
|
1070
1141
|
>
|
|
1071
|
-
|
|
1142
|
+
{labels.sendLoginLink}
|
|
1072
1143
|
</Button>
|
|
1073
1144
|
|
|
1074
1145
|
<div class="text-center">
|
|
1075
1146
|
<Button variant="link" onclick={handleReturnToSignIn}>
|
|
1076
|
-
|
|
1147
|
+
{labels.returnToLogIn}
|
|
1077
1148
|
</Button>
|
|
1078
1149
|
</div>
|
|
1079
1150
|
</div>
|
|
@@ -1083,45 +1154,40 @@
|
|
|
1083
1154
|
<div in:fade={{ duration: 200 }} class="space-y-6 text-center">
|
|
1084
1155
|
<div class="space-y-4">
|
|
1085
1156
|
<h2 class={typography.h1}>
|
|
1086
|
-
|
|
1157
|
+
{labels.checkEmailTitle}
|
|
1087
1158
|
</h2>
|
|
1088
1159
|
{#if isResendSuccess}
|
|
1089
1160
|
<p class={`${typography.smMuted} leading-relaxed text-left`}>
|
|
1090
|
-
|
|
1091
|
-
?
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
> if it is an email on file.
|
|
1161
|
+
{#if true}
|
|
1162
|
+
{@const message = typeof labels.resentMessage === 'function' ? labels.resentMessage(successType, successEmail) : labels.resentMessage}
|
|
1163
|
+
{@const parts = message.split(successEmail)}
|
|
1164
|
+
{parts[0]}<span class={typography.sm}>{successEmail}</span>{parts[1] || ''}
|
|
1165
|
+
{/if}
|
|
1096
1166
|
</p>
|
|
1097
1167
|
<p class={`${typography.smMuted} leading-relaxed text-left`}>
|
|
1098
|
-
|
|
1168
|
+
{labels.resentFollowUp} <Button
|
|
1099
1169
|
variant="link"
|
|
1100
1170
|
onclick={handleTryDifferentEmail}
|
|
1101
|
-
>
|
|
1171
|
+
>{labels.tryDifferentEmail}</Button>.
|
|
1102
1172
|
</p>
|
|
1103
1173
|
{:else}
|
|
1104
1174
|
<p class={`${typography.smMuted} leading-relaxed text-left`}>
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
containing further instructions for {successType === "reset"
|
|
1111
|
-
? "resetting your password"
|
|
1112
|
-
: "signing in"}.
|
|
1175
|
+
{#if true}
|
|
1176
|
+
{@const message = typeof labels.successMessage === 'function' ? labels.successMessage(successType, successEmail) : labels.successMessage}
|
|
1177
|
+
{@const parts = message.split(successEmail)}
|
|
1178
|
+
{parts[0]}<span class={typography.sm}>{successEmail}</span>{parts[1] || ''}
|
|
1179
|
+
{/if}
|
|
1113
1180
|
</p>
|
|
1114
1181
|
<p class={`${typography.smMuted} leading-relaxed text-left`}>
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
<Button variant="link" onclick={handleTryDifferentEmail}>try a different email</Button>.
|
|
1182
|
+
{labels.noEmailReceived} <Button variant="link" onclick={handleResend}>{labels.resend}</Button>, or
|
|
1183
|
+
<Button variant="link" onclick={handleTryDifferentEmail}>{labels.tryDifferentEmail}</Button>.
|
|
1118
1184
|
</p>
|
|
1119
1185
|
{/if}
|
|
1120
1186
|
</div>
|
|
1121
1187
|
|
|
1122
1188
|
<div class="pt-2">
|
|
1123
1189
|
<Button variant="link" onclick={handleReturnToSignIn}>
|
|
1124
|
-
|
|
1190
|
+
{labels.returnToSignIn}
|
|
1125
1191
|
</Button>
|
|
1126
1192
|
</div>
|
|
1127
1193
|
</div>
|
|
@@ -21,6 +21,7 @@ declare const SuperLogin: import("svelte").Component<{
|
|
|
21
21
|
onExternalNavigate?: Function;
|
|
22
22
|
showDarkModeToggle?: boolean;
|
|
23
23
|
searchParams?: string;
|
|
24
|
+
labels?: Record<string, any>;
|
|
24
25
|
}, {}, "">;
|
|
25
26
|
type $$ComponentProps = {
|
|
26
27
|
apiBaseUrl?: string;
|
|
@@ -40,5 +41,6 @@ type $$ComponentProps = {
|
|
|
40
41
|
onExternalNavigate?: Function;
|
|
41
42
|
showDarkModeToggle?: boolean;
|
|
42
43
|
searchParams?: string;
|
|
44
|
+
labels?: Record<string, any>;
|
|
43
45
|
};
|
|
44
46
|
//# sourceMappingURL=SuperLogin.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuperLogin.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/SuperLogin/SuperLogin.svelte.js"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"SuperLogin.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/SuperLogin/SuperLogin.svelte.js"],"names":[],"mappings":";;;;;AAgjCA;iBAz7BkC,MAAM;cAAY,MAAM;cAAY,MAAM;kBAAgB,MAAM;kBAAgB,OAAO;gBAAc,MAAM;gBAAc,MAAM;iBAAe,MAAM;0BAAwB,MAAM;wBAAsB,MAAM;aAAW,MAAM;;;;;yBAAoI,OAAO;mBAAiB,MAAM;aAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;WAy7BxY;wBAz7BtC;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,WAAW;IAAC,eAAe,CAAC,WAAW;IAAC,UAAU,CAAC,WAAW;IAAC,kBAAkB,CAAC,WAAW;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE"}
|
|
@@ -4,27 +4,27 @@ import { expect, describe, test, vi, beforeEach, afterEach } from 'vitest';
|
|
|
4
4
|
import PlaceAutocomplete from './PlaceAutocomplete.svelte';
|
|
5
5
|
|
|
6
6
|
// Mock Google Maps API
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
// vi.hoisted ensures these are available when vi.mock is hoisted
|
|
8
|
+
const { mockAutocompleteSuggestion, MockAutocompleteSessionToken, mockSetOptions, mockImportLibrary } = vi.hoisted(() => {
|
|
9
|
+
class _MockAutocompleteSessionToken {}
|
|
10
|
+
const _mockAutocompleteSuggestion = {
|
|
11
|
+
fetchAutocompleteSuggestions: vi.fn(),
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
mockAutocompleteSuggestion: _mockAutocompleteSuggestion,
|
|
15
|
+
MockAutocompleteSessionToken: _MockAutocompleteSessionToken,
|
|
16
|
+
mockSetOptions: vi.fn(),
|
|
17
|
+
mockImportLibrary: vi.fn().mockResolvedValue({
|
|
18
|
+
AutocompleteSessionToken: _MockAutocompleteSessionToken,
|
|
19
|
+
AutocompleteSuggestion: _mockAutocompleteSuggestion,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
20
23
|
|
|
21
|
-
// Mock the Google Maps Loader -
|
|
24
|
+
// Mock the Google Maps Loader - v2 uses functional API
|
|
22
25
|
vi.mock('@googlemaps/js-api-loader', () => ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.importLibrary = mockLoader.importLibrary;
|
|
26
|
-
}
|
|
27
|
-
},
|
|
26
|
+
setOptions: mockSetOptions,
|
|
27
|
+
importLibrary: mockImportLibrary,
|
|
28
28
|
}));
|
|
29
29
|
|
|
30
30
|
// Mock config
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { SearchOutline } from "../../../primitives/Icons";
|
|
3
|
-
import
|
|
3
|
+
import { setOptions, importLibrary } from '@googlemaps/js-api-loader';
|
|
4
4
|
import { PUBLIC_GOOGLE_MAPS_API_KEY } from '../../../config.js';
|
|
5
5
|
import { typography } from '../../../tokens/typography';
|
|
6
6
|
import { bloom } from '../../../utils/transitions.js';
|
|
7
|
-
const { Loader } = GMaps;
|
|
8
7
|
/** Google Places API address component */ interface AddressComponent { longText: string; shortText: string; types: string[]; } /** Google Places API response data */ interface PlaceData { formattedAddress?: string; addressComponents?: AddressComponent[]; text?: string; [key: string]: unknown; } /** Google Places autocomplete suggestion */ interface AutocompleteSuggestion { placePrediction: { types: string[]; text: { toString(): string }; toPlace(): PlaceObject; }; } /** Google Places place object */ interface PlaceObject { fetchFields(options: { fields: string[] }): Promise<void>; toJSON(): PlaceData; } /** Google Places API interface */ interface PlacesApiInterface { AutocompleteSessionToken: new () => AutocompleteSessionToken; AutocompleteSuggestion: { fetchAutocompleteSuggestions(request: AutocompleteRequest): Promise<{ suggestions: AutocompleteSuggestion[] }>; }; } /** Google Places autocomplete session token */ interface AutocompleteSessionToken {} /** Autocomplete request parameters */ interface AutocompleteRequest { input: string; language: string; region: string; sessionToken: AutocompleteSessionToken | string; } /** Search result item */ interface SearchResult { to_place: PlaceObject; text: string; originalText?: string; }
|
|
9
8
|
|
|
10
9
|
interface Props {
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
let title = $state('');
|
|
44
43
|
let results = $state<SearchResult[]>([]);
|
|
45
44
|
let token: AutocompleteSessionToken | undefined;
|
|
46
|
-
let loader: GMaps.Loader;
|
|
47
45
|
let placesApi: Partial<PlacesApiInterface> = {};
|
|
48
46
|
|
|
49
47
|
let request = $state<{
|
|
@@ -243,14 +241,13 @@
|
|
|
243
241
|
}
|
|
244
242
|
|
|
245
243
|
try {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
libraries: ['places'],
|
|
244
|
+
setOptions({
|
|
245
|
+
key: PUBLIC_GOOGLE_MAPS_API_KEY,
|
|
246
|
+
v: 'weekly',
|
|
250
247
|
});
|
|
251
248
|
|
|
252
249
|
const { AutocompleteSessionToken, AutocompleteSuggestion } =
|
|
253
|
-
await
|
|
250
|
+
await importLibrary('places');
|
|
254
251
|
placesApi.AutocompleteSessionToken = AutocompleteSessionToken;
|
|
255
252
|
placesApi.AutocompleteSuggestion = AutocompleteSuggestion;
|
|
256
253
|
token = new placesApi.AutocompleteSessionToken!();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaceAutocomplete.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.ts"],"names":[],"mappings":"AASA,0CAA0C,CAAE,UAAU,gBAAgB;IAAM,QAAQ,EAAE,MAAM,CAAC;IAAI,SAAS,EAAE,MAAM,CAAC;IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;CAAG;AACzI,sCAAsC,CAAE,UAAU,SAAS;IAAM,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAI,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAAI,IAAI,CAAC,EAAE,MAAM,CAAC;IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAAG;AAMrL,UAAU,KAAK;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"PlaceAutocomplete.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.ts"],"names":[],"mappings":"AASA,0CAA0C,CAAE,UAAU,gBAAgB;IAAM,QAAQ,EAAE,MAAM,CAAC;IAAI,SAAS,EAAE,MAAM,CAAC;IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;CAAG;AACzI,sCAAsC,CAAE,UAAU,SAAS;IAAM,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAI,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAAI,IAAI,CAAC,EAAE,MAAM,CAAC;IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAAG;AAMrL,UAAU,KAAK;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA8SH,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function fetchEventsFromAPI(): Promise<any>;
|
|
1
|
+
export function fetchEventsFromAPI(venueId: any): Promise<any>;
|
|
2
2
|
export function fetchEventsForMonth(year: any, month: any): Promise<any>;
|
|
3
3
|
export function fetchEventsForWeek(date: any): Promise<any>;
|
|
4
4
|
export function fetchEventsForDay(date: any): Promise<any>;
|