@marcwelti/mw-core 0.5.3 → 0.6.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.
@@ -14,4 +14,28 @@ interface AuthDialogProps {
14
14
  }
15
15
  declare function AuthDialog({ open, onOpenChange, onSuccess, sessionEndpoint, defaultMode, }: AuthDialogProps): react_jsx_runtime.JSX.Element;
16
16
 
17
- export { AuthDialog, type AuthDialogProps };
17
+ interface AccountSettingsUser {
18
+ uid: string;
19
+ email?: string;
20
+ displayName?: string;
21
+ emailVerified?: boolean;
22
+ }
23
+ interface AccountSettingsProps {
24
+ /** Current user data */
25
+ user: AccountSettingsUser | null;
26
+ /** Firebase user object for provider checks */
27
+ firebaseUser?: any;
28
+ /** Called when user updates email */
29
+ onUpdateEmail?: (newEmail: string, password: string) => Promise<void>;
30
+ /** Called when user updates password */
31
+ onUpdatePassword?: (currentPassword: string, newPassword: string) => Promise<void>;
32
+ /** Called when user deletes account */
33
+ onDeleteAccount?: (password?: string) => Promise<boolean | void>;
34
+ /** Called to refresh user data */
35
+ onRefreshUser?: () => Promise<void>;
36
+ /** Session endpoint for logout */
37
+ logoutEndpoint?: string;
38
+ }
39
+ declare function AccountSettings({ user, firebaseUser, onUpdateEmail, onUpdatePassword, onDeleteAccount, onRefreshUser, logoutEndpoint, }: AccountSettingsProps): react_jsx_runtime.JSX.Element;
40
+
41
+ export { AccountSettings, type AccountSettingsProps, type AccountSettingsUser, AuthDialog, type AuthDialogProps };
@@ -14,4 +14,28 @@ interface AuthDialogProps {
14
14
  }
15
15
  declare function AuthDialog({ open, onOpenChange, onSuccess, sessionEndpoint, defaultMode, }: AuthDialogProps): react_jsx_runtime.JSX.Element;
16
16
 
17
- export { AuthDialog, type AuthDialogProps };
17
+ interface AccountSettingsUser {
18
+ uid: string;
19
+ email?: string;
20
+ displayName?: string;
21
+ emailVerified?: boolean;
22
+ }
23
+ interface AccountSettingsProps {
24
+ /** Current user data */
25
+ user: AccountSettingsUser | null;
26
+ /** Firebase user object for provider checks */
27
+ firebaseUser?: any;
28
+ /** Called when user updates email */
29
+ onUpdateEmail?: (newEmail: string, password: string) => Promise<void>;
30
+ /** Called when user updates password */
31
+ onUpdatePassword?: (currentPassword: string, newPassword: string) => Promise<void>;
32
+ /** Called when user deletes account */
33
+ onDeleteAccount?: (password?: string) => Promise<boolean | void>;
34
+ /** Called to refresh user data */
35
+ onRefreshUser?: () => Promise<void>;
36
+ /** Session endpoint for logout */
37
+ logoutEndpoint?: string;
38
+ }
39
+ declare function AccountSettings({ user, firebaseUser, onUpdateEmail, onUpdatePassword, onDeleteAccount, onRefreshUser, logoutEndpoint, }: AccountSettingsProps): react_jsx_runtime.JSX.Element;
40
+
41
+ export { AccountSettings, type AccountSettingsProps, type AccountSettingsUser, AuthDialog, type AuthDialogProps };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React = require('react');
4
+ var React2 = require('react');
5
5
  var auth = require('firebase/auth');
6
6
  var app = require('firebase/app');
7
7
  var firestore = require('firebase/firestore');
@@ -27,7 +27,7 @@ function _interopNamespace(e) {
27
27
  return Object.freeze(n);
28
28
  }
29
29
 
30
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
30
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
31
31
 
32
32
  // src/components/AuthDialog.tsx
33
33
  function getFirebaseConfig() {
@@ -147,20 +147,20 @@ function AuthDialog({
147
147
  sessionEndpoint = "/api/auth/login",
148
148
  defaultMode = "login"
149
149
  }) {
150
- const [mode, setMode] = React__namespace.useState(defaultMode);
151
- const [email, setEmail] = React__namespace.useState("");
152
- const [password, setPassword] = React__namespace.useState("");
153
- const [confirmPassword, setConfirmPassword] = React__namespace.useState("");
154
- const [loading, setLoading] = React__namespace.useState(false);
155
- const [error, setError] = React__namespace.useState(null);
156
- const resetForm = React__namespace.useCallback(() => {
150
+ const [mode, setMode] = React2__namespace.useState(defaultMode);
151
+ const [email, setEmail] = React2__namespace.useState("");
152
+ const [password, setPassword] = React2__namespace.useState("");
153
+ const [confirmPassword, setConfirmPassword] = React2__namespace.useState("");
154
+ const [loading, setLoading] = React2__namespace.useState(false);
155
+ const [error, setError] = React2__namespace.useState(null);
156
+ const resetForm = React2__namespace.useCallback(() => {
157
157
  setEmail("");
158
158
  setPassword("");
159
159
  setConfirmPassword("");
160
160
  setError(null);
161
161
  setLoading(false);
162
162
  }, []);
163
- React__namespace.useEffect(() => {
163
+ React2__namespace.useEffect(() => {
164
164
  if (open) {
165
165
  setMode(defaultMode);
166
166
  resetForm();
@@ -327,6 +327,555 @@ function AuthDialog({
327
327
  ] }) });
328
328
  }
329
329
 
330
+ // node_modules/lucide-react/dist/esm/shared/src/utils.js
331
+ var toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
332
+ var mergeClasses = (...classes) => classes.filter((className, index, array) => {
333
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
334
+ }).join(" ").trim();
335
+
336
+ // node_modules/lucide-react/dist/esm/defaultAttributes.js
337
+ var defaultAttributes = {
338
+ xmlns: "http://www.w3.org/2000/svg",
339
+ width: 24,
340
+ height: 24,
341
+ viewBox: "0 0 24 24",
342
+ fill: "none",
343
+ stroke: "currentColor",
344
+ strokeWidth: 2,
345
+ strokeLinecap: "round",
346
+ strokeLinejoin: "round"
347
+ };
348
+
349
+ // node_modules/lucide-react/dist/esm/Icon.js
350
+ var Icon = React2.forwardRef(
351
+ ({
352
+ color = "currentColor",
353
+ size = 24,
354
+ strokeWidth = 2,
355
+ absoluteStrokeWidth,
356
+ className = "",
357
+ children,
358
+ iconNode,
359
+ ...rest
360
+ }, ref) => {
361
+ return React2.createElement(
362
+ "svg",
363
+ {
364
+ ref,
365
+ ...defaultAttributes,
366
+ width: size,
367
+ height: size,
368
+ stroke: color,
369
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
370
+ className: mergeClasses("lucide", className),
371
+ ...rest
372
+ },
373
+ [
374
+ ...iconNode.map(([tag, attrs]) => React2.createElement(tag, attrs)),
375
+ ...Array.isArray(children) ? children : [children]
376
+ ]
377
+ );
378
+ }
379
+ );
380
+
381
+ // node_modules/lucide-react/dist/esm/createLucideIcon.js
382
+ var createLucideIcon = (iconName, iconNode) => {
383
+ const Component = React2.forwardRef(
384
+ ({ className, ...props }, ref) => React2.createElement(Icon, {
385
+ ref,
386
+ iconNode,
387
+ className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),
388
+ ...props
389
+ })
390
+ );
391
+ Component.displayName = `${iconName}`;
392
+ return Component;
393
+ };
394
+
395
+ // node_modules/lucide-react/dist/esm/icons/circle-alert.js
396
+ var CircleAlert = createLucideIcon("CircleAlert", [
397
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
398
+ ["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
399
+ ["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
400
+ ]);
401
+
402
+ // node_modules/lucide-react/dist/esm/icons/circle-check-big.js
403
+ var CircleCheckBig = createLucideIcon("CircleCheckBig", [
404
+ ["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
405
+ ["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
406
+ ]);
407
+
408
+ // node_modules/lucide-react/dist/esm/icons/key-round.js
409
+ var KeyRound = createLucideIcon("KeyRound", [
410
+ [
411
+ "path",
412
+ {
413
+ d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",
414
+ key: "1s6t7t"
415
+ }
416
+ ],
417
+ ["circle", { cx: "16.5", cy: "7.5", r: ".5", fill: "currentColor", key: "w0ekpg" }]
418
+ ]);
419
+
420
+ // node_modules/lucide-react/dist/esm/icons/mail.js
421
+ var Mail = createLucideIcon("Mail", [
422
+ ["rect", { width: "20", height: "16", x: "2", y: "4", rx: "2", key: "18n3k1" }],
423
+ ["path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7", key: "1ocrg3" }]
424
+ ]);
425
+
426
+ // node_modules/lucide-react/dist/esm/icons/pen.js
427
+ var Pen = createLucideIcon("Pen", [
428
+ [
429
+ "path",
430
+ {
431
+ d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
432
+ key: "1a8usu"
433
+ }
434
+ ]
435
+ ]);
436
+
437
+ // node_modules/lucide-react/dist/esm/icons/trash-2.js
438
+ var Trash2 = createLucideIcon("Trash2", [
439
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
440
+ ["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
441
+ ["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }],
442
+ ["line", { x1: "10", x2: "10", y1: "11", y2: "17", key: "1uufr5" }],
443
+ ["line", { x1: "14", x2: "14", y1: "11", y2: "17", key: "xtxkd" }]
444
+ ]);
445
+
446
+ // node_modules/lucide-react/dist/esm/icons/triangle-alert.js
447
+ var TriangleAlert = createLucideIcon("TriangleAlert", [
448
+ [
449
+ "path",
450
+ {
451
+ d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
452
+ key: "wmoenq"
453
+ }
454
+ ],
455
+ ["path", { d: "M12 9v4", key: "juzpu7" }],
456
+ ["path", { d: "M12 17h.01", key: "p32p05" }]
457
+ ]);
458
+ function SpinnerIcon({ className }) {
459
+ return /* @__PURE__ */ jsxRuntime.jsx(
460
+ "svg",
461
+ {
462
+ className,
463
+ xmlns: "http://www.w3.org/2000/svg",
464
+ width: "24",
465
+ height: "24",
466
+ viewBox: "0 0 24 24",
467
+ fill: "none",
468
+ stroke: "currentColor",
469
+ strokeWidth: "2",
470
+ strokeLinecap: "round",
471
+ strokeLinejoin: "round",
472
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
473
+ }
474
+ );
475
+ }
476
+ var PasswordInput = React2__namespace.forwardRef((props, ref) => {
477
+ return /* @__PURE__ */ jsxRuntime.jsx(mwUi.Input, { ...props, ref, type: "password" });
478
+ });
479
+ PasswordInput.displayName = "PasswordInput";
480
+ function AccountSettings({
481
+ user,
482
+ firebaseUser,
483
+ onUpdateEmail,
484
+ onUpdatePassword,
485
+ onDeleteAccount,
486
+ onRefreshUser,
487
+ logoutEndpoint = "/api/auth/logout"
488
+ }) {
489
+ const [showEmailChange, setShowEmailChange] = React2__namespace.useState(false);
490
+ const [newEmail, setNewEmail] = React2__namespace.useState("");
491
+ const [emailPassword, setEmailPassword] = React2__namespace.useState("");
492
+ const [emailLoading, setEmailLoading] = React2__namespace.useState(false);
493
+ const [emailError, setEmailError] = React2__namespace.useState("");
494
+ const [emailSuccess, setEmailSuccess] = React2__namespace.useState(false);
495
+ const [showPasswordChange, setShowPasswordChange] = React2__namespace.useState(false);
496
+ const [currentPassword, setCurrentPassword] = React2__namespace.useState("");
497
+ const [newPassword, setNewPassword] = React2__namespace.useState("");
498
+ const [confirmPassword, setConfirmPassword] = React2__namespace.useState("");
499
+ const [passwordLoading, setPasswordLoading] = React2__namespace.useState(false);
500
+ const [passwordError, setPasswordError] = React2__namespace.useState("");
501
+ const [passwordSuccess, setPasswordSuccess] = React2__namespace.useState(false);
502
+ const [showDeleteConfirm, setShowDeleteConfirm] = React2__namespace.useState(false);
503
+ const [deletePassword, setDeletePassword] = React2__namespace.useState("");
504
+ const [deleteConfirmText, setDeleteConfirmText] = React2__namespace.useState("");
505
+ const [deleteLoading, setDeleteLoading] = React2__namespace.useState(false);
506
+ const [deleteError, setDeleteError] = React2__namespace.useState("");
507
+ const hasPasswordProvider = firebaseUser?.providerData?.some(
508
+ (p) => p.providerId === "password"
509
+ );
510
+ const hasGoogleProvider = firebaseUser?.providerData?.some(
511
+ (p) => p.providerId === "google.com"
512
+ );
513
+ const handleEmailUpdate = async (e) => {
514
+ e.preventDefault();
515
+ if (!onUpdateEmail) return;
516
+ setEmailError("");
517
+ setEmailLoading(true);
518
+ try {
519
+ await onUpdateEmail(newEmail, emailPassword);
520
+ setEmailSuccess(true);
521
+ setNewEmail("");
522
+ setEmailPassword("");
523
+ setTimeout(() => {
524
+ setShowEmailChange(false);
525
+ setEmailSuccess(false);
526
+ onRefreshUser?.();
527
+ }, 2e3);
528
+ } catch (error) {
529
+ setEmailError(error.message || "Failed to update email");
530
+ } finally {
531
+ setEmailLoading(false);
532
+ }
533
+ };
534
+ const handlePasswordUpdate = async (e) => {
535
+ e.preventDefault();
536
+ if (!onUpdatePassword) return;
537
+ if (newPassword !== confirmPassword) {
538
+ setPasswordError("Passwords do not match");
539
+ return;
540
+ }
541
+ if (newPassword.length < 8) {
542
+ setPasswordError("Password must be at least 8 characters");
543
+ return;
544
+ }
545
+ setPasswordError("");
546
+ setPasswordLoading(true);
547
+ try {
548
+ await onUpdatePassword(currentPassword, newPassword);
549
+ setPasswordSuccess(true);
550
+ setCurrentPassword("");
551
+ setNewPassword("");
552
+ setConfirmPassword("");
553
+ setTimeout(() => {
554
+ setShowPasswordChange(false);
555
+ setPasswordSuccess(false);
556
+ }, 2e3);
557
+ } catch (error) {
558
+ setPasswordError(error.message || "Failed to update password");
559
+ } finally {
560
+ setPasswordLoading(false);
561
+ }
562
+ };
563
+ const handleDeleteAccount = async () => {
564
+ if (!onDeleteAccount) return;
565
+ const needsPassword = hasPasswordProvider && !hasGoogleProvider;
566
+ const needsConfirmText = hasGoogleProvider;
567
+ if (needsPassword && !deletePassword) {
568
+ setDeleteError("Please enter your password");
569
+ return;
570
+ }
571
+ if (needsConfirmText && deleteConfirmText !== "DELETE") {
572
+ setDeleteError("Please type DELETE to confirm");
573
+ return;
574
+ }
575
+ setDeleteLoading(true);
576
+ setDeleteError("");
577
+ try {
578
+ const result = await onDeleteAccount(needsPassword ? deletePassword : void 0);
579
+ if (result === false) {
580
+ setDeleteLoading(false);
581
+ return;
582
+ }
583
+ await fetch(logoutEndpoint, { method: "POST" });
584
+ } catch (error) {
585
+ setDeleteError(error.message || "Failed to delete account");
586
+ setDeleteLoading(false);
587
+ }
588
+ };
589
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-4xl mx-auto space-y-6", children: [
590
+ /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Card, { className: "bg-card border border-border shadow-lg", children: [
591
+ /* @__PURE__ */ jsxRuntime.jsxs(mwUi.CardHeader, { children: [
592
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardTitle, { className: "text-foreground", children: "Email Address" }),
593
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardDescription, { className: "text-muted-foreground", children: "Manage your email address" })
594
+ ] }),
595
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardContent, { children: !showEmailChange ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
596
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
598
+ /* @__PURE__ */ jsxRuntime.jsx(Mail, { className: "h-5 w-5 text-brand-gold" }),
599
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: user?.email })
600
+ ] }),
601
+ hasPasswordProvider && user?.emailVerified && onUpdateEmail && /* @__PURE__ */ jsxRuntime.jsx(
602
+ mwUi.Button,
603
+ {
604
+ intent: "ghost",
605
+ size: "sm",
606
+ onClick: () => setShowEmailChange(true),
607
+ children: /* @__PURE__ */ jsxRuntime.jsx(Pen, { className: "h-4 w-4" })
608
+ }
609
+ )
610
+ ] }),
611
+ !user?.emailVerified && /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Alert, { variant: "destructive", children: [
612
+ /* @__PURE__ */ jsxRuntime.jsx(CircleAlert, { className: "h-4 w-4" }),
613
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { children: "Your email is not verified. Please check your inbox." })
614
+ ] })
615
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleEmailUpdate, className: "space-y-4", children: [
616
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
617
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "new-email", children: "New Email Address" }),
618
+ /* @__PURE__ */ jsxRuntime.jsx(
619
+ mwUi.Input,
620
+ {
621
+ id: "new-email",
622
+ type: "email",
623
+ value: newEmail,
624
+ onChange: (e) => setNewEmail(e.target.value),
625
+ required: true,
626
+ disabled: emailLoading
627
+ }
628
+ )
629
+ ] }),
630
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
631
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "email-password", children: "Current Password" }),
632
+ /* @__PURE__ */ jsxRuntime.jsx(
633
+ PasswordInput,
634
+ {
635
+ id: "email-password",
636
+ value: emailPassword,
637
+ onChange: (e) => setEmailPassword(e.target.value),
638
+ required: true,
639
+ disabled: emailLoading
640
+ }
641
+ )
642
+ ] }),
643
+ emailError && /* @__PURE__ */ jsxRuntime.jsx(mwUi.Alert, { variant: "destructive", children: /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { children: emailError }) }),
644
+ emailSuccess && /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Alert, { className: "bg-brand-gold/10 border-brand-gold/30", children: [
645
+ /* @__PURE__ */ jsxRuntime.jsx(CircleCheckBig, { className: "h-4 w-4 text-brand-gold" }),
646
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { className: "text-brand-gold", children: "Email updated! Check your new email to verify." })
647
+ ] }),
648
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
649
+ /* @__PURE__ */ jsxRuntime.jsx(
650
+ mwUi.Button,
651
+ {
652
+ type: "button",
653
+ intent: "secondary",
654
+ onClick: () => {
655
+ setShowEmailChange(false);
656
+ setEmailError("");
657
+ setNewEmail("");
658
+ setEmailPassword("");
659
+ },
660
+ disabled: emailLoading,
661
+ children: "Cancel"
662
+ }
663
+ ),
664
+ /* @__PURE__ */ jsxRuntime.jsxs(
665
+ mwUi.Button,
666
+ {
667
+ type: "submit",
668
+ disabled: emailLoading || !newEmail || !emailPassword,
669
+ children: [
670
+ emailLoading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, { className: "mr-2 h-4 w-4 animate-spin" }),
671
+ "Update Email"
672
+ ]
673
+ }
674
+ )
675
+ ] })
676
+ ] }) })
677
+ ] }),
678
+ hasPasswordProvider && onUpdatePassword && /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Card, { className: "bg-card border border-border shadow-lg", children: [
679
+ /* @__PURE__ */ jsxRuntime.jsxs(mwUi.CardHeader, { children: [
680
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardTitle, { className: "text-foreground", children: "Password" }),
681
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardDescription, { className: "text-muted-foreground", children: "Change your password" })
682
+ ] }),
683
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardContent, { children: !showPasswordChange ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
684
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
685
+ /* @__PURE__ */ jsxRuntime.jsx(KeyRound, { className: "h-5 w-5 text-brand-gold" }),
686
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" })
687
+ ] }),
688
+ /* @__PURE__ */ jsxRuntime.jsx(
689
+ mwUi.Button,
690
+ {
691
+ intent: "ghost",
692
+ size: "sm",
693
+ onClick: () => setShowPasswordChange(true),
694
+ children: /* @__PURE__ */ jsxRuntime.jsx(Pen, { className: "h-4 w-4" })
695
+ }
696
+ )
697
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handlePasswordUpdate, className: "space-y-4", children: [
698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
699
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "current-password", children: "Current Password" }),
700
+ /* @__PURE__ */ jsxRuntime.jsx(
701
+ PasswordInput,
702
+ {
703
+ id: "current-password",
704
+ value: currentPassword,
705
+ onChange: (e) => setCurrentPassword(e.target.value),
706
+ required: true,
707
+ disabled: passwordLoading
708
+ }
709
+ )
710
+ ] }),
711
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
712
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "new-password", children: "New Password" }),
713
+ /* @__PURE__ */ jsxRuntime.jsx(
714
+ PasswordInput,
715
+ {
716
+ id: "new-password",
717
+ value: newPassword,
718
+ onChange: (e) => setNewPassword(e.target.value),
719
+ required: true,
720
+ minLength: 8,
721
+ disabled: passwordLoading
722
+ }
723
+ )
724
+ ] }),
725
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
726
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "confirm-password", children: "Confirm New Password" }),
727
+ /* @__PURE__ */ jsxRuntime.jsx(
728
+ PasswordInput,
729
+ {
730
+ id: "confirm-password",
731
+ value: confirmPassword,
732
+ onChange: (e) => setConfirmPassword(e.target.value),
733
+ required: true,
734
+ disabled: passwordLoading
735
+ }
736
+ )
737
+ ] }),
738
+ passwordError && /* @__PURE__ */ jsxRuntime.jsx(mwUi.Alert, { variant: "destructive", children: /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { children: passwordError }) }),
739
+ passwordSuccess && /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Alert, { className: "bg-brand-gold/10 border-brand-gold/30", children: [
740
+ /* @__PURE__ */ jsxRuntime.jsx(CircleCheckBig, { className: "h-4 w-4 text-brand-gold" }),
741
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { className: "text-brand-gold", children: "Password updated successfully!" })
742
+ ] }),
743
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
744
+ /* @__PURE__ */ jsxRuntime.jsx(
745
+ mwUi.Button,
746
+ {
747
+ type: "button",
748
+ intent: "secondary",
749
+ onClick: () => {
750
+ setShowPasswordChange(false);
751
+ setPasswordError("");
752
+ setCurrentPassword("");
753
+ setNewPassword("");
754
+ setConfirmPassword("");
755
+ },
756
+ disabled: passwordLoading,
757
+ children: "Cancel"
758
+ }
759
+ ),
760
+ /* @__PURE__ */ jsxRuntime.jsxs(
761
+ mwUi.Button,
762
+ {
763
+ type: "submit",
764
+ disabled: passwordLoading || !currentPassword || !newPassword || !confirmPassword || newPassword !== confirmPassword,
765
+ children: [
766
+ passwordLoading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, { className: "mr-2 h-4 w-4 animate-spin" }),
767
+ "Update Password"
768
+ ]
769
+ }
770
+ )
771
+ ] })
772
+ ] }) })
773
+ ] }),
774
+ onDeleteAccount && /* @__PURE__ */ jsxRuntime.jsxs(mwUi.Card, { className: "bg-card border border-border shadow-lg", children: [
775
+ /* @__PURE__ */ jsxRuntime.jsxs(mwUi.CardHeader, { children: [
776
+ /* @__PURE__ */ jsxRuntime.jsxs(mwUi.CardTitle, { className: "text-foreground flex items-center gap-2", children: [
777
+ /* @__PURE__ */ jsxRuntime.jsx(TriangleAlert, { className: "h-5 w-5 text-red-500" }),
778
+ "Danger Zone"
779
+ ] }),
780
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardDescription, { className: "text-muted-foreground", children: "Permanently delete your account" })
781
+ ] }),
782
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.CardContent, { children: !showDeleteConfirm ? /* @__PURE__ */ jsxRuntime.jsxs(
783
+ mwUi.Button,
784
+ {
785
+ intent: "destructive",
786
+ onClick: () => setShowDeleteConfirm(true),
787
+ children: [
788
+ /* @__PURE__ */ jsxRuntime.jsx(Trash2, { className: "mr-2 h-4 w-4" }),
789
+ "Delete My Account"
790
+ ]
791
+ }
792
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
793
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Alert, { variant: "destructive", className: "bg-red-900/20 border-red-900/40", children: /* @__PURE__ */ jsxRuntime.jsxs(mwUi.AlertDescription, { children: [
794
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium mb-2", children: "\u26A0\uFE0F This action cannot be undone!" }),
795
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Your account and all associated data will be permanently deleted." })
796
+ ] }) }),
797
+ hasPasswordProvider && !hasGoogleProvider && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
798
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "delete-password", children: "Enter Your Password" }),
799
+ /* @__PURE__ */ jsxRuntime.jsx(
800
+ PasswordInput,
801
+ {
802
+ id: "delete-password",
803
+ value: deletePassword,
804
+ onChange: (e) => setDeletePassword(e.target.value),
805
+ placeholder: "Enter your password to confirm",
806
+ disabled: deleteLoading
807
+ }
808
+ )
809
+ ] }),
810
+ hasGoogleProvider && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
811
+ /* @__PURE__ */ jsxRuntime.jsx(mwUi.Label, { htmlFor: "delete-confirm", children: "Type DELETE to confirm" }),
812
+ /* @__PURE__ */ jsxRuntime.jsx(
813
+ mwUi.Input,
814
+ {
815
+ id: "delete-confirm",
816
+ value: deleteConfirmText,
817
+ onChange: (e) => setDeleteConfirmText(e.target.value),
818
+ placeholder: "DELETE",
819
+ disabled: deleteLoading
820
+ }
821
+ )
822
+ ] }),
823
+ deleteError && /* @__PURE__ */ jsxRuntime.jsx(mwUi.Alert, { variant: "destructive", children: /* @__PURE__ */ jsxRuntime.jsx(mwUi.AlertDescription, { children: deleteError }) }),
824
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
825
+ /* @__PURE__ */ jsxRuntime.jsx(
826
+ mwUi.Button,
827
+ {
828
+ intent: "secondary",
829
+ onClick: () => {
830
+ setShowDeleteConfirm(false);
831
+ setDeleteError("");
832
+ setDeletePassword("");
833
+ setDeleteConfirmText("");
834
+ },
835
+ disabled: deleteLoading,
836
+ children: "Cancel"
837
+ }
838
+ ),
839
+ /* @__PURE__ */ jsxRuntime.jsxs(
840
+ mwUi.Button,
841
+ {
842
+ intent: "destructive",
843
+ onClick: handleDeleteAccount,
844
+ disabled: deleteLoading || hasPasswordProvider && !hasGoogleProvider && !deletePassword || hasGoogleProvider && deleteConfirmText !== "DELETE",
845
+ children: [
846
+ deleteLoading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, { className: "mr-2 h-4 w-4 animate-spin" }),
847
+ "Yes, Delete My Account"
848
+ ]
849
+ }
850
+ )
851
+ ] })
852
+ ] }) })
853
+ ] })
854
+ ] });
855
+ }
856
+ /*! Bundled license information:
857
+
858
+ lucide-react/dist/esm/shared/src/utils.js:
859
+ lucide-react/dist/esm/defaultAttributes.js:
860
+ lucide-react/dist/esm/Icon.js:
861
+ lucide-react/dist/esm/createLucideIcon.js:
862
+ lucide-react/dist/esm/icons/circle-alert.js:
863
+ lucide-react/dist/esm/icons/circle-check-big.js:
864
+ lucide-react/dist/esm/icons/key-round.js:
865
+ lucide-react/dist/esm/icons/mail.js:
866
+ lucide-react/dist/esm/icons/pen.js:
867
+ lucide-react/dist/esm/icons/trash-2.js:
868
+ lucide-react/dist/esm/icons/triangle-alert.js:
869
+ lucide-react/dist/esm/lucide-react.js:
870
+ (**
871
+ * @license lucide-react v0.460.0 - ISC
872
+ *
873
+ * This source code is licensed under the ISC license.
874
+ * See the LICENSE file in the root directory of this source tree.
875
+ *)
876
+ */
877
+
878
+ exports.AccountSettings = AccountSettings;
330
879
  exports.AuthDialog = AuthDialog;
331
880
  //# sourceMappingURL=index.js.map
332
881
  //# sourceMappingURL=index.js.map