@insforge/react 1.0.3 → 1.0.5-dev.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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { ConditionalProps, ForgotPassword, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordProps, SignIn, SignInButton, SignInButtonProps, SignInProps, SignOutButton, SignOutButtonProps, SignUp, SignUpButton, SignUpButtonProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, VerifyEmail, VerifyEmailProps } from './components.cjs';
1
+ export { ConditionalProps, ForgotPassword, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordProps, SignIn, SignInButton, SignInButtonProps, SignInProps, SignOutButton, SignOutButtonProps, SignUp, SignUpButton, SignUpButtonProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, UserProfileModal, UserProfileModalProps, VerifyEmail, VerifyEmailProps } from './components.cjs';
2
2
  export { ForgotPasswordForm, ForgotPasswordFormProps, ResetPasswordForm, ResetPasswordFormProps, SignInForm, SignInFormProps, SignUpForm, SignUpFormProps, VerifyEmailStatus, VerifyEmailStatusProps } from './forms.cjs';
3
3
  export { AuthBranding, AuthContainer, AuthContainerProps, AuthDivider, AuthDividerProps, AuthEmailVerificationStep, AuthErrorBanner, AuthErrorBannerProps, AuthFormField, AuthFormFieldProps, AuthHeader, AuthHeaderProps, AuthLink, AuthLinkProps, AuthOAuthButton, AuthOAuthButtonProps, AuthOAuthProviders, AuthOAuthProvidersProps, AuthPasswordField, AuthPasswordFieldProps, AuthPasswordStrengthIndicator, AuthPasswordStrengthIndicatorProps, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthSubmitButtonProps, AuthVerificationCodeInput, AuthVerificationCodeInputProps } from './atoms.cjs';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -10,7 +10,6 @@ export { checkPasswordStrength, createPasswordSchema, emailSchema, passwordSchem
10
10
  import { OAuthProviderConfig } from './types.cjs';
11
11
  export { AuthConfig, EmailVerificationMethod } from './types.cjs';
12
12
  export { BrowserNavigationAdapter, NavigationAdapter, NavigationProvider, NavigationProviderProps, useNavigationAdapter, useSearchParams } from './navigation.cjs';
13
- import '@insforge/sdk';
14
13
  import '@insforge/shared-schemas';
15
14
  import 'zod';
16
15
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { ConditionalProps, ForgotPassword, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordProps, SignIn, SignInButton, SignInButtonProps, SignInProps, SignOutButton, SignOutButtonProps, SignUp, SignUpButton, SignUpButtonProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, VerifyEmail, VerifyEmailProps } from './components.js';
1
+ export { ConditionalProps, ForgotPassword, ForgotPasswordProps, Protect, ProtectProps, ResetPassword, ResetPasswordProps, SignIn, SignInButton, SignInButtonProps, SignInProps, SignOutButton, SignOutButtonProps, SignUp, SignUpButton, SignUpButtonProps, SignUpProps, SignedIn, SignedOut, UserButton, UserButtonProps, UserProfileModal, UserProfileModalProps, VerifyEmail, VerifyEmailProps } from './components.js';
2
2
  export { ForgotPasswordForm, ForgotPasswordFormProps, ResetPasswordForm, ResetPasswordFormProps, SignInForm, SignInFormProps, SignUpForm, SignUpFormProps, VerifyEmailStatus, VerifyEmailStatusProps } from './forms.js';
3
3
  export { AuthBranding, AuthContainer, AuthContainerProps, AuthDivider, AuthDividerProps, AuthEmailVerificationStep, AuthErrorBanner, AuthErrorBannerProps, AuthFormField, AuthFormFieldProps, AuthHeader, AuthHeaderProps, AuthLink, AuthLinkProps, AuthOAuthButton, AuthOAuthButtonProps, AuthOAuthProviders, AuthOAuthProvidersProps, AuthPasswordField, AuthPasswordFieldProps, AuthPasswordStrengthIndicator, AuthPasswordStrengthIndicatorProps, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthSubmitButtonProps, AuthVerificationCodeInput, AuthVerificationCodeInputProps } from './atoms.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -10,7 +10,6 @@ export { checkPasswordStrength, createPasswordSchema, emailSchema, passwordSchem
10
10
  import { OAuthProviderConfig } from './types.js';
11
11
  export { AuthConfig, EmailVerificationMethod } from './types.js';
12
12
  export { BrowserNavigationAdapter, NavigationAdapter, NavigationProvider, NavigationProviderProps, useNavigationAdapter, useSearchParams } from './navigation.js';
13
- import '@insforge/sdk';
14
13
  import '@insforge/shared-schemas';
15
14
  import 'zod';
16
15
 
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import { createContext, forwardRef, useContext, useState, useMemo, useEffect, us
17
17
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
18
  import { createClient } from '@insforge/sdk';
19
19
  import { InsforgeContext } from '@insforge/shared/react';
20
- import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, LogOut } from 'lucide-react';
20
+ import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, X, User, LogOut } from 'lucide-react';
21
21
  import { z } from 'zod';
22
22
 
23
23
  var __create = Object.create;
@@ -225,7 +225,7 @@ var require_react_is_development = __commonJS({
225
225
  var ContextProvider = REACT_PROVIDER_TYPE;
226
226
  var Element = REACT_ELEMENT_TYPE;
227
227
  var ForwardRef = REACT_FORWARD_REF_TYPE;
228
- var Fragment9 = REACT_FRAGMENT_TYPE;
228
+ var Fragment10 = REACT_FRAGMENT_TYPE;
229
229
  var Lazy = REACT_LAZY_TYPE;
230
230
  var Memo = REACT_MEMO_TYPE;
231
231
  var Portal = REACT_PORTAL_TYPE;
@@ -284,7 +284,7 @@ var require_react_is_development = __commonJS({
284
284
  exports$1.ContextProvider = ContextProvider;
285
285
  exports$1.Element = Element;
286
286
  exports$1.ForwardRef = ForwardRef;
287
- exports$1.Fragment = Fragment9;
287
+ exports$1.Fragment = Fragment10;
288
288
  exports$1.Lazy = Lazy;
289
289
  exports$1.Memo = Memo;
290
290
  exports$1.Portal = Portal;
@@ -568,11 +568,14 @@ var InsforgeManager = class _InsforgeManager {
568
568
  const userResult = await this.sdk.auth.getCurrentUser();
569
569
  if (userResult.data) {
570
570
  const profile = userResult.data.user.profile;
571
+ const { name, avatar_url, ...dynamicFields } = profile || {};
571
572
  const userData = {
572
573
  id: userResult.data.user.id,
573
574
  email: userResult.data.user.email,
574
- name: profile?.name || "",
575
- avatarUrl: profile?.avatar_url || ""
575
+ name: name || "",
576
+ avatarUrl: avatar_url || "",
577
+ // Store additional dynamic fields
578
+ profile: Object.keys(dynamicFields).length > 0 ? dynamicFields : void 0
576
579
  };
577
580
  this.user = userData;
578
581
  if (this.config.onAuthChange) {
@@ -609,11 +612,14 @@ var InsforgeManager = class _InsforgeManager {
609
612
  const userResult = await this.sdk.auth.getCurrentUser();
610
613
  if (userResult.data) {
611
614
  const profile = userResult.data.user.profile;
615
+ const { name, avatar_url, ...dynamicFields } = profile || {};
612
616
  const userData = {
613
617
  id: userResult.data.user.id,
614
618
  email: userResult.data.user.email,
615
- name: profile?.name || "",
616
- avatarUrl: profile?.avatar_url || ""
619
+ name: name || "",
620
+ avatarUrl: avatar_url || "",
621
+ // Store additional dynamic fields
622
+ profile: Object.keys(dynamicFields).length > 0 ? dynamicFields : void 0
617
623
  };
618
624
  this.user = userData;
619
625
  this.notifyListeners();
@@ -714,27 +720,32 @@ var InsforgeManager = class _InsforgeManager {
714
720
  if (!this.user) {
715
721
  return { error: "No user signed in" };
716
722
  }
717
- const profileUpdate = {
718
- name: data.name,
719
- avatar_url: data.avatarUrl
720
- };
723
+ const profileUpdate = {};
724
+ if (data.name !== void 0) {
725
+ profileUpdate.name = data.name;
726
+ }
727
+ if (data.avatarUrl !== void 0) {
728
+ profileUpdate.avatar_url = data.avatarUrl;
729
+ }
730
+ if (data.profile) {
731
+ Object.assign(profileUpdate, data.profile);
732
+ }
721
733
  const result = await this.sdk.auth.setProfile(profileUpdate);
722
734
  if (result.data) {
723
- const userResult = await this.sdk.auth.getCurrentUser();
724
- if (userResult.data) {
725
- const profile = userResult.data.user.profile;
726
- const updatedUser = {
727
- id: userResult.data.user.id,
728
- email: userResult.data.user.email,
729
- name: profile?.name || "",
730
- avatarUrl: profile?.avatar_url || ""
731
- };
732
- this.user = updatedUser;
733
- if (this.config.onAuthChange) {
734
- this.config.onAuthChange(updatedUser);
735
- }
736
- this.notifyListeners();
735
+ const updatedUser = {
736
+ id: this.user.id,
737
+ email: this.user.email,
738
+ // Use sent value if provided, otherwise keep existing
739
+ name: profileUpdate.name !== void 0 ? profileUpdate.name : this.user.name || "",
740
+ avatarUrl: profileUpdate.avatar_url !== void 0 ? profileUpdate.avatar_url : this.user.avatarUrl || "",
741
+ // Merge existing profile with new dynamic fields
742
+ profile: data.profile ? { ...this.user.profile, ...data.profile } : this.user.profile
743
+ };
744
+ this.user = updatedUser;
745
+ if (this.config.onAuthChange) {
746
+ this.config.onAuthChange(updatedUser);
737
747
  }
748
+ this.notifyListeners();
738
749
  return null;
739
750
  }
740
751
  const error = result.error;
@@ -5097,11 +5108,7 @@ function VerifyEmail({ token: token2, onSuccess, onError, ...uiProps }) {
5097
5108
  }
5098
5109
  setStatus("success");
5099
5110
  if (onSuccess) {
5100
- onSuccess({
5101
- accessToken: result.accessToken,
5102
- user: result.user,
5103
- redirectTo: result.redirectTo
5104
- });
5111
+ onSuccess(result);
5105
5112
  }
5106
5113
  } catch (err) {
5107
5114
  const errorMessage = err instanceof Error ? err.message : "Email verification failed";
@@ -5261,9 +5268,382 @@ var UserButtonMenuItemIcon = styled.div`
5261
5268
  height: 100%;
5262
5269
  }
5263
5270
  `;
5264
- function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
5271
+ var ProfileModalOverlay = styled.div`
5272
+ position: fixed;
5273
+ inset: 0;
5274
+ background-color: rgba(0, 0, 0, 0.5);
5275
+ display: flex;
5276
+ align-items: center;
5277
+ justify-content: center;
5278
+ z-index: 100;
5279
+ padding: ${theme.spacing[4]};
5280
+ `;
5281
+ var ProfileModalContainer = styled.div`
5282
+ background-color: ${theme.colors.bgWhite};
5283
+ border-radius: ${theme.radius.xl};
5284
+ box-shadow: ${theme.shadow.lg};
5285
+ width: 100%;
5286
+ max-width: 400px;
5287
+ max-height: 90vh;
5288
+ overflow: hidden;
5289
+ display: flex;
5290
+ flex-direction: column;
5291
+ font-family: ${theme.fontFamily.base};
5292
+ `;
5293
+ var ProfileModalHeader = styled.div`
5294
+ display: flex;
5295
+ align-items: center;
5296
+ justify-content: space-between;
5297
+ padding: ${theme.spacing[4]} ${theme.spacing[6]};
5298
+ border-bottom: 1px solid ${theme.colors.border};
5299
+ `;
5300
+ var ProfileModalTitle = styled.h2`
5301
+ font-size: ${theme.fontSize.lg};
5302
+ font-weight: ${theme.fontWeight.semibold};
5303
+ color: ${theme.colors.text};
5304
+ margin: 0;
5305
+ `;
5306
+ var ProfileModalCloseButton = styled.button`
5307
+ display: flex;
5308
+ align-items: center;
5309
+ justify-content: center;
5310
+ width: 2rem;
5311
+ height: 2rem;
5312
+ border-radius: ${theme.radius.md};
5313
+ background: none;
5314
+ border: none;
5315
+ cursor: pointer;
5316
+ color: ${theme.colors.textSecondary};
5317
+ transition: all ${theme.transition.fast};
5318
+
5319
+ &:hover {
5320
+ background-color: ${theme.colors.bgLight};
5321
+ color: ${theme.colors.text};
5322
+ }
5323
+
5324
+ svg {
5325
+ width: 1.25rem;
5326
+ height: 1.25rem;
5327
+ }
5328
+ `;
5329
+ var ProfileModalBody = styled.div`
5330
+ padding: ${theme.spacing[6]};
5331
+ overflow-y: auto;
5332
+ flex: 1;
5333
+ `;
5334
+ var ProfileAvatarSection = styled.div`
5335
+ display: flex;
5336
+ flex-direction: column;
5337
+ align-items: center;
5338
+ margin-bottom: ${theme.spacing[6]};
5339
+ `;
5340
+ var ProfileAvatar = styled.div`
5341
+ width: 5rem;
5342
+ height: 5rem;
5343
+ border-radius: ${theme.radius.full};
5344
+ background-color: ${theme.colors.primary};
5345
+ color: ${theme.colors.bgWhite};
5346
+ display: flex;
5347
+ align-items: center;
5348
+ justify-content: center;
5349
+ font-weight: ${theme.fontWeight.semibold};
5350
+ font-size: ${theme.fontSize["2xl"]};
5351
+ overflow: hidden;
5352
+ `;
5353
+ var ProfileAvatarImage = styled.img`
5354
+ width: 100%;
5355
+ height: 100%;
5356
+ object-fit: cover;
5357
+ `;
5358
+ var ProfileFieldsContainer = styled.div`
5359
+ display: flex;
5360
+ flex-direction: column;
5361
+ gap: ${theme.spacing[4]};
5362
+ `;
5363
+ var ProfileField = styled.div`
5364
+ display: flex;
5365
+ flex-direction: column;
5366
+ gap: ${theme.spacing[1]};
5367
+ `;
5368
+ var ProfileFieldLabel = styled.label`
5369
+ font-size: ${theme.fontSize.sm};
5370
+ font-weight: ${theme.fontWeight.medium};
5371
+ color: ${theme.colors.textSecondary};
5372
+ text-transform: capitalize;
5373
+ `;
5374
+ var ProfileFieldValue = styled.div`
5375
+ font-size: ${theme.fontSize.base};
5376
+ color: ${theme.colors.text};
5377
+ padding: ${theme.spacing[2]} 0;
5378
+ word-break: break-word;
5379
+ `;
5380
+ var ProfileFieldInput = styled.input`
5381
+ width: 100%;
5382
+ height: ${theme.sizes.input.height};
5383
+ padding: 0 ${theme.spacing[3]};
5384
+ border: 1px solid ${theme.colors.border};
5385
+ border-radius: ${theme.radius.md};
5386
+ font-size: ${theme.fontSize.base};
5387
+ font-family: ${theme.fontFamily.base};
5388
+ color: ${theme.colors.text};
5389
+ background-color: ${theme.colors.bgWhite};
5390
+ transition: border-color ${theme.transition.fast};
5391
+
5392
+ &:focus {
5393
+ outline: none;
5394
+ border-color: ${theme.colors.borderFocus};
5395
+ }
5396
+
5397
+ &:disabled {
5398
+ background-color: ${theme.colors.bgLight};
5399
+ color: ${theme.colors.textSecondary};
5400
+ cursor: not-allowed;
5401
+ }
5402
+ `;
5403
+ var ProfileModalFooter = styled.div`
5404
+ display: flex;
5405
+ align-items: center;
5406
+ justify-content: flex-end;
5407
+ gap: ${theme.spacing[3]};
5408
+ padding: ${theme.spacing[4]} ${theme.spacing[6]};
5409
+ border-top: 1px solid ${theme.colors.border};
5410
+ `;
5411
+ var ProfileButton = styled.button`
5412
+ display: flex;
5413
+ align-items: center;
5414
+ justify-content: center;
5415
+ gap: ${theme.spacing[2]};
5416
+ height: ${theme.sizes.button.height};
5417
+ padding: 0 ${theme.spacing[4]};
5418
+ border-radius: ${theme.radius.md};
5419
+ font-size: ${theme.fontSize.sm};
5420
+ font-weight: ${theme.fontWeight.medium};
5421
+ font-family: ${theme.fontFamily.base};
5422
+ cursor: pointer;
5423
+ transition: all ${theme.transition.fast};
5424
+
5425
+ ${(props) => props.$primary ? `
5426
+ background-color: ${theme.colors.primary};
5427
+ color: ${theme.colors.bgWhite};
5428
+ border: none;
5429
+
5430
+ &:hover:not(:disabled) {
5431
+ background-color: ${theme.colors.primaryHover};
5432
+ }
5433
+
5434
+ &:disabled {
5435
+ opacity: 0.5;
5436
+ cursor: not-allowed;
5437
+ }
5438
+ ` : `
5439
+ background-color: ${theme.colors.bgWhite};
5440
+ color: ${theme.colors.text};
5441
+ border: 1px solid ${theme.colors.border};
5442
+
5443
+ &:hover:not(:disabled) {
5444
+ background-color: ${theme.colors.bgLight};
5445
+ }
5446
+
5447
+ &:disabled {
5448
+ opacity: 0.5;
5449
+ cursor: not-allowed;
5450
+ }
5451
+ `}
5452
+ `;
5453
+ var ProfileSpinner = styled.div`
5454
+ width: 1rem;
5455
+ height: 1rem;
5456
+ border: 2px solid transparent;
5457
+ border-top-color: currentColor;
5458
+ border-radius: ${theme.radius.full};
5459
+ animation: spin 0.6s linear infinite;
5460
+
5461
+ @keyframes spin {
5462
+ to {
5463
+ transform: rotate(360deg);
5464
+ }
5465
+ }
5466
+ `;
5467
+ var READ_ONLY_FIELDS = ["id", "email", "avatar_url", "created_at", "updated_at"];
5468
+ var HIDDEN_FIELDS = ["id"];
5469
+ function formatFieldLabel(key) {
5470
+ return key.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
5471
+ }
5472
+ function UserProfileModal({ onClose, onError }) {
5473
+ const { user, updateUser, isLoaded } = useInsforge();
5474
+ const [isEditing, setIsEditing] = useState(false);
5475
+ const [isSaving, setIsSaving] = useState(false);
5476
+ const [imageError, setImageError] = useState(false);
5477
+ const [formData, setFormData] = useState({});
5478
+ useEffect(() => {
5479
+ if (user) {
5480
+ const initialData = {
5481
+ name: user.name || ""
5482
+ };
5483
+ if (user.profile) {
5484
+ Object.entries(user.profile).forEach(([key, value]) => {
5485
+ if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
5486
+ initialData[key] = value;
5487
+ }
5488
+ });
5489
+ }
5490
+ setFormData(initialData);
5491
+ }
5492
+ }, [user]);
5493
+ useEffect(() => {
5494
+ setImageError(false);
5495
+ const avatarUrl = user?.avatarUrl;
5496
+ if (!avatarUrl) {
5497
+ return;
5498
+ }
5499
+ const checkImageUrl = async () => {
5500
+ try {
5501
+ const response = await fetch(avatarUrl, {
5502
+ method: "HEAD",
5503
+ cache: "no-cache"
5504
+ });
5505
+ if (!response.ok) {
5506
+ setImageError(true);
5507
+ }
5508
+ } catch {
5509
+ setImageError(true);
5510
+ }
5511
+ };
5512
+ void checkImageUrl();
5513
+ }, [user?.avatarUrl]);
5514
+ const handleFieldChange = useCallback((key, value) => {
5515
+ setFormData((prev2) => ({
5516
+ ...prev2,
5517
+ [key]: value
5518
+ }));
5519
+ }, []);
5520
+ const handleSave = useCallback(async () => {
5521
+ if (!user) return;
5522
+ setIsSaving(true);
5523
+ try {
5524
+ const { name, ...dynamicFields } = formData;
5525
+ const updateData = {
5526
+ name
5527
+ };
5528
+ if (Object.keys(dynamicFields).length > 0) {
5529
+ updateData.profile = dynamicFields;
5530
+ }
5531
+ const result = await updateUser(updateData);
5532
+ if (result?.error) {
5533
+ onError?.(result.error);
5534
+ } else {
5535
+ setIsEditing(false);
5536
+ }
5537
+ } catch (error) {
5538
+ onError?.(error instanceof Error ? error.message : "Failed to update profile");
5539
+ } finally {
5540
+ setIsSaving(false);
5541
+ }
5542
+ }, [user, formData, updateUser, onError]);
5543
+ const handleCancel = useCallback(() => {
5544
+ if (user) {
5545
+ const resetData = {
5546
+ name: user.name || ""
5547
+ };
5548
+ if (user.profile) {
5549
+ Object.entries(user.profile).forEach(([key, value]) => {
5550
+ if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
5551
+ resetData[key] = value;
5552
+ }
5553
+ });
5554
+ }
5555
+ setFormData(resetData);
5556
+ }
5557
+ setIsEditing(false);
5558
+ }, [user]);
5559
+ const handleOverlayClick = useCallback(
5560
+ (e) => {
5561
+ if (e.target === e.currentTarget) {
5562
+ onClose();
5563
+ }
5564
+ },
5565
+ [onClose]
5566
+ );
5567
+ useEffect(() => {
5568
+ const handleEscape = (e) => {
5569
+ if (e.key === "Escape") {
5570
+ if (isEditing) {
5571
+ handleCancel();
5572
+ } else {
5573
+ onClose();
5574
+ }
5575
+ }
5576
+ };
5577
+ document.addEventListener("keydown", handleEscape);
5578
+ return () => document.removeEventListener("keydown", handleEscape);
5579
+ }, [isEditing, handleCancel, onClose]);
5580
+ if (!isLoaded || !user) {
5581
+ return null;
5582
+ }
5583
+ const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
5584
+ const fields = [];
5585
+ fields.push({ key: "email", value: user.email, readOnly: true });
5586
+ fields.push({
5587
+ key: "name",
5588
+ value: isEditing ? formData.name || "" : user.name || "",
5589
+ readOnly: false
5590
+ });
5591
+ if (user.profile) {
5592
+ Object.entries(user.profile).forEach(([key, value]) => {
5593
+ if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
5594
+ fields.push({
5595
+ key,
5596
+ value: isEditing ? formData[key] ?? value : value,
5597
+ readOnly: READ_ONLY_FIELDS.includes(key)
5598
+ });
5599
+ }
5600
+ });
5601
+ }
5602
+ return /* @__PURE__ */ jsx(ProfileModalOverlay, { onClick: handleOverlayClick, children: /* @__PURE__ */ jsxs(ProfileModalContainer, { onClick: (e) => e.stopPropagation(), children: [
5603
+ /* @__PURE__ */ jsxs(ProfileModalHeader, { children: [
5604
+ /* @__PURE__ */ jsx(ProfileModalTitle, { children: "Profile" }),
5605
+ /* @__PURE__ */ jsx(ProfileModalCloseButton, { onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(X, {}) })
5606
+ ] }),
5607
+ /* @__PURE__ */ jsxs(ProfileModalBody, { children: [
5608
+ /* @__PURE__ */ jsx(ProfileAvatarSection, { children: /* @__PURE__ */ jsx(ProfileAvatar, { children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
5609
+ ProfileAvatarImage,
5610
+ {
5611
+ src: user.avatarUrl,
5612
+ alt: user.name || user.email,
5613
+ onError: () => setImageError(true)
5614
+ }
5615
+ ) : initials }) }),
5616
+ /* @__PURE__ */ jsx(ProfileFieldsContainer, { children: fields.map(({ key, value, readOnly }) => /* @__PURE__ */ jsxs(ProfileField, { children: [
5617
+ /* @__PURE__ */ jsx(ProfileFieldLabel, { children: formatFieldLabel(key) }),
5618
+ isEditing && !readOnly ? /* @__PURE__ */ jsx(
5619
+ ProfileFieldInput,
5620
+ {
5621
+ type: "text",
5622
+ value: formData[key] ?? value,
5623
+ onChange: (e) => handleFieldChange(key, e.target.value),
5624
+ disabled: isSaving
5625
+ }
5626
+ ) : /* @__PURE__ */ jsx(ProfileFieldValue, { children: value || "-" })
5627
+ ] }, key)) })
5628
+ ] }),
5629
+ /* @__PURE__ */ jsx(ProfileModalFooter, { children: isEditing ? /* @__PURE__ */ jsxs(Fragment, { children: [
5630
+ /* @__PURE__ */ jsx(ProfileButton, { onClick: handleCancel, disabled: isSaving, children: "Cancel" }),
5631
+ /* @__PURE__ */ jsxs(ProfileButton, { $primary: true, onClick: handleSave, disabled: isSaving, children: [
5632
+ isSaving && /* @__PURE__ */ jsx(ProfileSpinner, {}),
5633
+ isSaving ? "Saving..." : "Save"
5634
+ ] })
5635
+ ] }) : /* @__PURE__ */ jsx(ProfileButton, { $primary: true, onClick: () => setIsEditing(true), children: "Edit Profile" }) })
5636
+ ] }) });
5637
+ }
5638
+ function UserButton({
5639
+ afterSignOutUrl = "/",
5640
+ mode = "simple",
5641
+ showProfile = true,
5642
+ onProfileError
5643
+ }) {
5265
5644
  const { user } = useInsforge();
5266
5645
  const [isOpen, setIsOpen] = useState(false);
5646
+ const [showProfileModal, setShowProfileModal] = useState(false);
5267
5647
  const [imageError, setImageError] = useState(false);
5268
5648
  const [openUpward, setOpenUpward] = useState(false);
5269
5649
  const [horizontalOffset, setHorizontalOffset] = useState(0);
@@ -5361,10 +5741,32 @@ function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
5361
5741
  ]
5362
5742
  }
5363
5743
  ),
5364
- isOpen && /* @__PURE__ */ jsx(UserButtonMenu, { ref: menuRef, $openUpward: openUpward, $horizontalOffset: horizontalOffset, children: /* @__PURE__ */ jsx(SignOutButton, { afterSignOutUrl, children: /* @__PURE__ */ jsxs(UserButtonMenuItem, { $signout: true, onClick: () => setIsOpen(false), children: [
5365
- /* @__PURE__ */ jsx(UserButtonMenuItemIcon, { children: /* @__PURE__ */ jsx(LogOut, {}) }),
5366
- "Sign out"
5367
- ] }) }) })
5744
+ isOpen && /* @__PURE__ */ jsxs(UserButtonMenu, { ref: menuRef, $openUpward: openUpward, $horizontalOffset: horizontalOffset, children: [
5745
+ showProfile && /* @__PURE__ */ jsxs(
5746
+ UserButtonMenuItem,
5747
+ {
5748
+ onClick: () => {
5749
+ setShowProfileModal(true);
5750
+ setIsOpen(false);
5751
+ },
5752
+ children: [
5753
+ /* @__PURE__ */ jsx(UserButtonMenuItemIcon, { children: /* @__PURE__ */ jsx(User, {}) }),
5754
+ "Profile"
5755
+ ]
5756
+ }
5757
+ ),
5758
+ /* @__PURE__ */ jsx(SignOutButton, { afterSignOutUrl, children: /* @__PURE__ */ jsxs(UserButtonMenuItem, { $signout: true, onClick: () => setIsOpen(false), children: [
5759
+ /* @__PURE__ */ jsx(UserButtonMenuItemIcon, { children: /* @__PURE__ */ jsx(LogOut, {}) }),
5760
+ "Sign out"
5761
+ ] }) })
5762
+ ] }),
5763
+ showProfileModal && /* @__PURE__ */ jsx(
5764
+ UserProfileModal,
5765
+ {
5766
+ onClose: () => setShowProfileModal(false),
5767
+ onError: onProfileError
5768
+ }
5769
+ )
5368
5770
  ] });
5369
5771
  }
5370
5772
  function Protect({
@@ -5495,6 +5897,6 @@ react-is/cjs/react-is.development.js:
5495
5897
  *)
5496
5898
  */
5497
5899
 
5498
- export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, BrowserNavigationAdapter, ForgotPassword, ForgotPasswordForm, InsforgeProvider, InsforgeProviderCore, NavigationProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInButton, SignInForm, SignOutButton, SignUp, SignUpButton, SignUpForm, SignedIn, SignedOut, StyleProvider, UserButton, VerifyEmail, VerifyEmailStatus, checkPasswordStrength, createPasswordSchema, emailSchema, getAllProviderConfigs, getProviderConfig, passwordSchema, resolveAuthPath, resolveAuthUrl, theme, useAuth, useInsforge, useNavigationAdapter, usePublicAuthConfig, useSearchParams, useUser, validateEmail, validatePassword };
5900
+ export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, BrowserNavigationAdapter, ForgotPassword, ForgotPasswordForm, InsforgeProvider, InsforgeProviderCore, NavigationProvider, OAUTH_PROVIDER_CONFIG, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInButton, SignInForm, SignOutButton, SignUp, SignUpButton, SignUpForm, SignedIn, SignedOut, StyleProvider, UserButton, UserProfileModal, VerifyEmail, VerifyEmailStatus, checkPasswordStrength, createPasswordSchema, emailSchema, getAllProviderConfigs, getProviderConfig, passwordSchema, resolveAuthPath, resolveAuthUrl, theme, useAuth, useInsforge, useNavigationAdapter, usePublicAuthConfig, useSearchParams, useUser, validateEmail, validatePassword };
5499
5901
  //# sourceMappingURL=index.js.map
5500
5902
  //# sourceMappingURL=index.js.map