@insforge/react 1.0.4 → 1.0.5-dev.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/atoms.cjs +0 -1
- package/dist/atoms.cjs.map +1 -1
- package/dist/atoms.js +0 -1
- package/dist/atoms.js.map +1 -1
- package/dist/components.cjs +411 -14
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +18 -2
- package/dist/components.d.ts +18 -2
- package/dist/components.js +412 -16
- package/dist/components.js.map +1 -1
- package/dist/forms.cjs +0 -1
- package/dist/forms.cjs.map +1 -1
- package/dist/forms.js +0 -1
- package/dist/forms.js.map +1 -1
- package/dist/hooks.cjs +0 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +0 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +435 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +436 -54
- package/dist/index.js.map +1 -1
- package/package.json +114 -114
package/dist/components.d.cts
CHANGED
|
@@ -163,13 +163,29 @@ declare function VerifyEmail({ token, onSuccess, onError, ...uiProps }: VerifyEm
|
|
|
163
163
|
interface UserButtonProps {
|
|
164
164
|
afterSignOutUrl?: string;
|
|
165
165
|
mode?: 'detailed' | 'simple';
|
|
166
|
+
/** Whether to show the Profile menu item (default: true) */
|
|
167
|
+
showProfile?: boolean;
|
|
168
|
+
/** Callback when profile update fails */
|
|
169
|
+
onProfileError?: (error: string) => void;
|
|
166
170
|
}
|
|
167
171
|
/**
|
|
168
172
|
* User profile button with dropdown menu and sign-out functionality.
|
|
169
173
|
*
|
|
170
174
|
* Styles are powered by Emotion CSS-in-JS to prevent FOUC in SSR environments.
|
|
171
175
|
*/
|
|
172
|
-
declare function UserButton({ afterSignOutUrl, mode }: UserButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
176
|
+
declare function UserButton({ afterSignOutUrl, mode, showProfile, onProfileError, }: UserButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
177
|
+
|
|
178
|
+
interface UserProfileModalProps {
|
|
179
|
+
/** Called when the modal is closed */
|
|
180
|
+
onClose: () => void;
|
|
181
|
+
/** Called when an error occurs */
|
|
182
|
+
onError?: (error: string) => void;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* User profile modal component.
|
|
186
|
+
* Displays user profile information with edit capability for allowed fields.
|
|
187
|
+
*/
|
|
188
|
+
declare function UserProfileModal({ onClose, onError }: UserProfileModalProps): react_jsx_runtime.JSX.Element | null;
|
|
173
189
|
|
|
174
190
|
interface ProtectProps {
|
|
175
191
|
children: ReactNode;
|
|
@@ -341,4 +357,4 @@ interface SignOutButtonProps {
|
|
|
341
357
|
*/
|
|
342
358
|
declare function SignOutButton({ children, className, afterSignOutUrl }: SignOutButtonProps): react_jsx_runtime.JSX.Element;
|
|
343
359
|
|
|
344
|
-
export { type ConditionalProps$1 as ConditionalProps, ForgotPassword, type ForgotPasswordProps, Protect, type ProtectProps, ResetPassword, type ResetPasswordProps, SignIn, SignInButton, type SignInButtonProps, type SignInProps, SignOutButton, type SignOutButtonProps, SignUp, SignUpButton, type SignUpButtonProps, type SignUpProps, SignedIn, SignedOut, UserButton, type UserButtonProps, VerifyEmail, type VerifyEmailProps };
|
|
360
|
+
export { type ConditionalProps$1 as ConditionalProps, ForgotPassword, type ForgotPasswordProps, Protect, type ProtectProps, ResetPassword, type ResetPasswordProps, SignIn, SignInButton, type SignInButtonProps, type SignInProps, SignOutButton, type SignOutButtonProps, SignUp, SignUpButton, type SignUpButtonProps, type SignUpProps, SignedIn, SignedOut, UserButton, type UserButtonProps, UserProfileModal, type UserProfileModalProps, VerifyEmail, type VerifyEmailProps };
|
package/dist/components.d.ts
CHANGED
|
@@ -163,13 +163,29 @@ declare function VerifyEmail({ token, onSuccess, onError, ...uiProps }: VerifyEm
|
|
|
163
163
|
interface UserButtonProps {
|
|
164
164
|
afterSignOutUrl?: string;
|
|
165
165
|
mode?: 'detailed' | 'simple';
|
|
166
|
+
/** Whether to show the Profile menu item (default: true) */
|
|
167
|
+
showProfile?: boolean;
|
|
168
|
+
/** Callback when profile update fails */
|
|
169
|
+
onProfileError?: (error: string) => void;
|
|
166
170
|
}
|
|
167
171
|
/**
|
|
168
172
|
* User profile button with dropdown menu and sign-out functionality.
|
|
169
173
|
*
|
|
170
174
|
* Styles are powered by Emotion CSS-in-JS to prevent FOUC in SSR environments.
|
|
171
175
|
*/
|
|
172
|
-
declare function UserButton({ afterSignOutUrl, mode }: UserButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
176
|
+
declare function UserButton({ afterSignOutUrl, mode, showProfile, onProfileError, }: UserButtonProps): react_jsx_runtime.JSX.Element | null;
|
|
177
|
+
|
|
178
|
+
interface UserProfileModalProps {
|
|
179
|
+
/** Called when the modal is closed */
|
|
180
|
+
onClose: () => void;
|
|
181
|
+
/** Called when an error occurs */
|
|
182
|
+
onError?: (error: string) => void;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* User profile modal component.
|
|
186
|
+
* Displays user profile information with edit capability for allowed fields.
|
|
187
|
+
*/
|
|
188
|
+
declare function UserProfileModal({ onClose, onError }: UserProfileModalProps): react_jsx_runtime.JSX.Element | null;
|
|
173
189
|
|
|
174
190
|
interface ProtectProps {
|
|
175
191
|
children: ReactNode;
|
|
@@ -341,4 +357,4 @@ interface SignOutButtonProps {
|
|
|
341
357
|
*/
|
|
342
358
|
declare function SignOutButton({ children, className, afterSignOutUrl }: SignOutButtonProps): react_jsx_runtime.JSX.Element;
|
|
343
359
|
|
|
344
|
-
export { type ConditionalProps$1 as ConditionalProps, ForgotPassword, type ForgotPasswordProps, Protect, type ProtectProps, ResetPassword, type ResetPasswordProps, SignIn, SignInButton, type SignInButtonProps, type SignInProps, SignOutButton, type SignOutButtonProps, SignUp, SignUpButton, type SignUpButtonProps, type SignUpProps, SignedIn, SignedOut, UserButton, type UserButtonProps, VerifyEmail, type VerifyEmailProps };
|
|
360
|
+
export { type ConditionalProps$1 as ConditionalProps, ForgotPassword, type ForgotPasswordProps, Protect, type ProtectProps, ResetPassword, type ResetPasswordProps, SignIn, SignInButton, type SignInButtonProps, type SignInProps, SignOutButton, type SignOutButtonProps, SignUp, SignUpButton, type SignUpButtonProps, type SignUpProps, SignedIn, SignedOut, UserButton, type UserButtonProps, UserProfileModal, type UserProfileModalProps, VerifyEmail, type VerifyEmailProps };
|
package/dist/components.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
2
|
import { createContext, forwardRef, useContext, useState, useMemo, useRef, useEffect, useCallback, isValidElement, cloneElement } from 'react';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import '@insforge/sdk';
|
|
5
4
|
import { InsforgeContext } from '@insforge/shared/react';
|
|
6
|
-
import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, LogOut } from 'lucide-react';
|
|
5
|
+
import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, X, User, LogOut } from 'lucide-react';
|
|
7
6
|
import { z } from 'zod';
|
|
8
7
|
|
|
9
8
|
var __create = Object.create;
|
|
@@ -211,7 +210,7 @@ var require_react_is_development = __commonJS({
|
|
|
211
210
|
var ContextProvider = REACT_PROVIDER_TYPE;
|
|
212
211
|
var Element = REACT_ELEMENT_TYPE;
|
|
213
212
|
var ForwardRef = REACT_FORWARD_REF_TYPE;
|
|
214
|
-
var
|
|
213
|
+
var Fragment10 = REACT_FRAGMENT_TYPE;
|
|
215
214
|
var Lazy = REACT_LAZY_TYPE;
|
|
216
215
|
var Memo = REACT_MEMO_TYPE;
|
|
217
216
|
var Portal = REACT_PORTAL_TYPE;
|
|
@@ -270,7 +269,7 @@ var require_react_is_development = __commonJS({
|
|
|
270
269
|
exports$1.ContextProvider = ContextProvider;
|
|
271
270
|
exports$1.Element = Element;
|
|
272
271
|
exports$1.ForwardRef = ForwardRef;
|
|
273
|
-
exports$1.Fragment =
|
|
272
|
+
exports$1.Fragment = Fragment10;
|
|
274
273
|
exports$1.Lazy = Lazy;
|
|
275
274
|
exports$1.Memo = Memo;
|
|
276
275
|
exports$1.Portal = Portal;
|
|
@@ -2127,6 +2126,8 @@ var theme = {
|
|
|
2127
2126
|
sm: "0.875rem",
|
|
2128
2127
|
// 14px
|
|
2129
2128
|
base: "1rem",
|
|
2129
|
+
// 16px
|
|
2130
|
+
lg: "1.125rem",
|
|
2130
2131
|
// 20px
|
|
2131
2132
|
"2xl": "1.5rem"
|
|
2132
2133
|
// 24px
|
|
@@ -2158,6 +2159,10 @@ var theme = {
|
|
|
2158
2159
|
base: "200ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
2159
2160
|
},
|
|
2160
2161
|
sizes: {
|
|
2162
|
+
input: {
|
|
2163
|
+
height: "2.5rem"
|
|
2164
|
+
// 40px
|
|
2165
|
+
},
|
|
2161
2166
|
button: {
|
|
2162
2167
|
height: "2.5rem",
|
|
2163
2168
|
// 40px for submit
|
|
@@ -4673,9 +4678,384 @@ var UserButtonMenuItemIcon = styled.div`
|
|
|
4673
4678
|
height: 100%;
|
|
4674
4679
|
}
|
|
4675
4680
|
`;
|
|
4676
|
-
|
|
4681
|
+
var ProfileModalOverlay = styled.div`
|
|
4682
|
+
position: fixed;
|
|
4683
|
+
inset: 0;
|
|
4684
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
4685
|
+
display: flex;
|
|
4686
|
+
align-items: center;
|
|
4687
|
+
justify-content: center;
|
|
4688
|
+
z-index: 100;
|
|
4689
|
+
padding: ${theme.spacing[4]};
|
|
4690
|
+
`;
|
|
4691
|
+
var ProfileModalContainer = styled.div`
|
|
4692
|
+
background-color: ${theme.colors.bgWhite};
|
|
4693
|
+
border-radius: ${theme.radius.xl};
|
|
4694
|
+
box-shadow: ${theme.shadow.lg};
|
|
4695
|
+
width: 100%;
|
|
4696
|
+
max-width: 400px;
|
|
4697
|
+
max-height: 90vh;
|
|
4698
|
+
overflow: hidden;
|
|
4699
|
+
display: flex;
|
|
4700
|
+
flex-direction: column;
|
|
4701
|
+
font-family: ${theme.fontFamily.base};
|
|
4702
|
+
`;
|
|
4703
|
+
var ProfileModalHeader = styled.div`
|
|
4704
|
+
display: flex;
|
|
4705
|
+
align-items: center;
|
|
4706
|
+
justify-content: space-between;
|
|
4707
|
+
padding: ${theme.spacing[4]} ${theme.spacing[6]};
|
|
4708
|
+
border-bottom: 1px solid ${theme.colors.border};
|
|
4709
|
+
`;
|
|
4710
|
+
var ProfileModalTitle = styled.h2`
|
|
4711
|
+
font-size: ${theme.fontSize.lg};
|
|
4712
|
+
font-weight: ${theme.fontWeight.semibold};
|
|
4713
|
+
color: ${theme.colors.text};
|
|
4714
|
+
margin: 0;
|
|
4715
|
+
`;
|
|
4716
|
+
var ProfileModalCloseButton = styled.button`
|
|
4717
|
+
display: flex;
|
|
4718
|
+
align-items: center;
|
|
4719
|
+
justify-content: center;
|
|
4720
|
+
width: 2rem;
|
|
4721
|
+
height: 2rem;
|
|
4722
|
+
border-radius: ${theme.radius.md};
|
|
4723
|
+
background: none;
|
|
4724
|
+
border: none;
|
|
4725
|
+
cursor: pointer;
|
|
4726
|
+
color: ${theme.colors.textSecondary};
|
|
4727
|
+
transition: all ${theme.transition.fast};
|
|
4728
|
+
|
|
4729
|
+
&:hover {
|
|
4730
|
+
background-color: ${theme.colors.bgLight};
|
|
4731
|
+
color: ${theme.colors.text};
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4734
|
+
svg {
|
|
4735
|
+
width: 1.25rem;
|
|
4736
|
+
height: 1.25rem;
|
|
4737
|
+
}
|
|
4738
|
+
`;
|
|
4739
|
+
var ProfileModalBody = styled.div`
|
|
4740
|
+
padding: ${theme.spacing[6]};
|
|
4741
|
+
overflow-y: auto;
|
|
4742
|
+
flex: 1;
|
|
4743
|
+
`;
|
|
4744
|
+
var ProfileAvatarSection = styled.div`
|
|
4745
|
+
display: flex;
|
|
4746
|
+
flex-direction: column;
|
|
4747
|
+
align-items: center;
|
|
4748
|
+
margin-bottom: ${theme.spacing[6]};
|
|
4749
|
+
`;
|
|
4750
|
+
var ProfileAvatar = styled.div`
|
|
4751
|
+
width: 5rem;
|
|
4752
|
+
height: 5rem;
|
|
4753
|
+
border-radius: ${theme.radius.full};
|
|
4754
|
+
background-color: ${theme.colors.primary};
|
|
4755
|
+
color: ${theme.colors.bgWhite};
|
|
4756
|
+
display: flex;
|
|
4757
|
+
align-items: center;
|
|
4758
|
+
justify-content: center;
|
|
4759
|
+
font-weight: ${theme.fontWeight.semibold};
|
|
4760
|
+
font-size: ${theme.fontSize["2xl"]};
|
|
4761
|
+
overflow: hidden;
|
|
4762
|
+
`;
|
|
4763
|
+
var ProfileAvatarImage = styled.img`
|
|
4764
|
+
width: 100%;
|
|
4765
|
+
height: 100%;
|
|
4766
|
+
object-fit: cover;
|
|
4767
|
+
`;
|
|
4768
|
+
var ProfileFieldsContainer = styled.div`
|
|
4769
|
+
display: flex;
|
|
4770
|
+
flex-direction: column;
|
|
4771
|
+
gap: ${theme.spacing[4]};
|
|
4772
|
+
`;
|
|
4773
|
+
var ProfileField = styled.div`
|
|
4774
|
+
display: flex;
|
|
4775
|
+
flex-direction: column;
|
|
4776
|
+
gap: ${theme.spacing[1]};
|
|
4777
|
+
`;
|
|
4778
|
+
var ProfileFieldLabel = styled.label`
|
|
4779
|
+
font-size: ${theme.fontSize.sm};
|
|
4780
|
+
font-weight: ${theme.fontWeight.medium};
|
|
4781
|
+
color: ${theme.colors.textSecondary};
|
|
4782
|
+
text-transform: capitalize;
|
|
4783
|
+
`;
|
|
4784
|
+
var ProfileFieldValue = styled.div`
|
|
4785
|
+
font-size: ${theme.fontSize.base};
|
|
4786
|
+
color: ${theme.colors.text};
|
|
4787
|
+
padding: ${theme.spacing[2]} 0;
|
|
4788
|
+
word-break: break-word;
|
|
4789
|
+
`;
|
|
4790
|
+
var ProfileFieldInput = styled.input`
|
|
4791
|
+
width: 100%;
|
|
4792
|
+
height: ${theme.sizes.input.height};
|
|
4793
|
+
padding: 0 ${theme.spacing[3]};
|
|
4794
|
+
border: 1px solid ${theme.colors.border};
|
|
4795
|
+
border-radius: ${theme.radius.md};
|
|
4796
|
+
font-size: ${theme.fontSize.base};
|
|
4797
|
+
font-family: ${theme.fontFamily.base};
|
|
4798
|
+
color: ${theme.colors.text};
|
|
4799
|
+
background-color: ${theme.colors.bgWhite};
|
|
4800
|
+
transition: border-color ${theme.transition.fast};
|
|
4801
|
+
|
|
4802
|
+
&:focus {
|
|
4803
|
+
outline: none;
|
|
4804
|
+
border-color: ${theme.colors.borderFocus};
|
|
4805
|
+
}
|
|
4806
|
+
|
|
4807
|
+
&:disabled {
|
|
4808
|
+
background-color: ${theme.colors.bgLight};
|
|
4809
|
+
color: ${theme.colors.textSecondary};
|
|
4810
|
+
cursor: not-allowed;
|
|
4811
|
+
}
|
|
4812
|
+
`;
|
|
4813
|
+
var ProfileModalFooter = styled.div`
|
|
4814
|
+
display: flex;
|
|
4815
|
+
align-items: center;
|
|
4816
|
+
justify-content: flex-end;
|
|
4817
|
+
gap: ${theme.spacing[3]};
|
|
4818
|
+
padding: ${theme.spacing[4]} ${theme.spacing[6]};
|
|
4819
|
+
border-top: 1px solid ${theme.colors.border};
|
|
4820
|
+
`;
|
|
4821
|
+
var ProfileButton = styled.button`
|
|
4822
|
+
display: flex;
|
|
4823
|
+
align-items: center;
|
|
4824
|
+
justify-content: center;
|
|
4825
|
+
gap: ${theme.spacing[2]};
|
|
4826
|
+
height: ${theme.sizes.button.height};
|
|
4827
|
+
padding: 0 ${theme.spacing[4]};
|
|
4828
|
+
border-radius: ${theme.radius.md};
|
|
4829
|
+
font-size: ${theme.fontSize.sm};
|
|
4830
|
+
font-weight: ${theme.fontWeight.medium};
|
|
4831
|
+
font-family: ${theme.fontFamily.base};
|
|
4832
|
+
cursor: pointer;
|
|
4833
|
+
transition: all ${theme.transition.fast};
|
|
4834
|
+
|
|
4835
|
+
${(props) => props.$primary ? `
|
|
4836
|
+
background-color: ${theme.colors.primary};
|
|
4837
|
+
color: ${theme.colors.bgWhite};
|
|
4838
|
+
border: none;
|
|
4839
|
+
|
|
4840
|
+
&:hover:not(:disabled) {
|
|
4841
|
+
background-color: ${theme.colors.primaryHover};
|
|
4842
|
+
}
|
|
4843
|
+
|
|
4844
|
+
&:disabled {
|
|
4845
|
+
opacity: 0.5;
|
|
4846
|
+
cursor: not-allowed;
|
|
4847
|
+
}
|
|
4848
|
+
` : `
|
|
4849
|
+
background-color: ${theme.colors.bgWhite};
|
|
4850
|
+
color: ${theme.colors.text};
|
|
4851
|
+
border: 1px solid ${theme.colors.border};
|
|
4852
|
+
|
|
4853
|
+
&:hover:not(:disabled) {
|
|
4854
|
+
background-color: ${theme.colors.bgLight};
|
|
4855
|
+
}
|
|
4856
|
+
|
|
4857
|
+
&:disabled {
|
|
4858
|
+
opacity: 0.5;
|
|
4859
|
+
cursor: not-allowed;
|
|
4860
|
+
}
|
|
4861
|
+
`}
|
|
4862
|
+
`;
|
|
4863
|
+
var ProfileSpinner = styled.div`
|
|
4864
|
+
width: 1rem;
|
|
4865
|
+
height: 1rem;
|
|
4866
|
+
border: 2px solid transparent;
|
|
4867
|
+
border-top-color: currentColor;
|
|
4868
|
+
border-radius: ${theme.radius.full};
|
|
4869
|
+
animation: spin 0.6s linear infinite;
|
|
4870
|
+
|
|
4871
|
+
@keyframes spin {
|
|
4872
|
+
to {
|
|
4873
|
+
transform: rotate(360deg);
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4876
|
+
`;
|
|
4877
|
+
var READ_ONLY_FIELDS = ["id", "email", "avatar_url", "created_at", "updated_at"];
|
|
4878
|
+
var HIDDEN_FIELDS = ["id"];
|
|
4879
|
+
function formatFieldLabel(key) {
|
|
4880
|
+
return key.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
|
|
4881
|
+
}
|
|
4882
|
+
function UserProfileModal({ onClose, onError }) {
|
|
4883
|
+
const { user, updateUser, isLoaded } = useInsforge();
|
|
4884
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
4885
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
4886
|
+
const [imageError, setImageError] = useState(false);
|
|
4887
|
+
const [formData, setFormData] = useState({});
|
|
4888
|
+
useEffect(() => {
|
|
4889
|
+
if (user) {
|
|
4890
|
+
const initialData = {
|
|
4891
|
+
name: user.profile?.name || ""
|
|
4892
|
+
};
|
|
4893
|
+
if (user.profile) {
|
|
4894
|
+
Object.entries(user.profile).forEach(([key, value]) => {
|
|
4895
|
+
if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
|
|
4896
|
+
initialData[key] = value;
|
|
4897
|
+
}
|
|
4898
|
+
});
|
|
4899
|
+
}
|
|
4900
|
+
setFormData(initialData);
|
|
4901
|
+
}
|
|
4902
|
+
}, [user]);
|
|
4903
|
+
useEffect(() => {
|
|
4904
|
+
setImageError(false);
|
|
4905
|
+
const avatarUrl = user?.profile?.avatar_url;
|
|
4906
|
+
if (!avatarUrl) {
|
|
4907
|
+
return;
|
|
4908
|
+
}
|
|
4909
|
+
const checkImageUrl = async () => {
|
|
4910
|
+
try {
|
|
4911
|
+
const response = await fetch(avatarUrl, {
|
|
4912
|
+
method: "HEAD",
|
|
4913
|
+
cache: "no-cache"
|
|
4914
|
+
});
|
|
4915
|
+
if (!response.ok) {
|
|
4916
|
+
setImageError(true);
|
|
4917
|
+
}
|
|
4918
|
+
} catch {
|
|
4919
|
+
setImageError(true);
|
|
4920
|
+
}
|
|
4921
|
+
};
|
|
4922
|
+
void checkImageUrl();
|
|
4923
|
+
}, [user?.profile?.avatar_url]);
|
|
4924
|
+
const handleFieldChange = useCallback((key, value) => {
|
|
4925
|
+
setFormData((prev2) => ({
|
|
4926
|
+
...prev2,
|
|
4927
|
+
[key]: value
|
|
4928
|
+
}));
|
|
4929
|
+
}, []);
|
|
4930
|
+
const handleSave = useCallback(async () => {
|
|
4931
|
+
if (!user) return;
|
|
4932
|
+
setIsSaving(true);
|
|
4933
|
+
try {
|
|
4934
|
+
const { name, ...dynamicFields } = formData;
|
|
4935
|
+
const updateData = {
|
|
4936
|
+
profile: {
|
|
4937
|
+
name
|
|
4938
|
+
}
|
|
4939
|
+
};
|
|
4940
|
+
if (Object.keys(dynamicFields).length > 0) {
|
|
4941
|
+
updateData.profile = dynamicFields;
|
|
4942
|
+
}
|
|
4943
|
+
const result = await updateUser(updateData);
|
|
4944
|
+
if (result?.error) {
|
|
4945
|
+
onError?.(result.error);
|
|
4946
|
+
} else {
|
|
4947
|
+
setIsEditing(false);
|
|
4948
|
+
}
|
|
4949
|
+
} catch (error) {
|
|
4950
|
+
onError?.(error instanceof Error ? error.message : "Failed to update profile");
|
|
4951
|
+
} finally {
|
|
4952
|
+
setIsSaving(false);
|
|
4953
|
+
}
|
|
4954
|
+
}, [user, formData, updateUser, onError]);
|
|
4955
|
+
const handleCancel = useCallback(() => {
|
|
4956
|
+
if (user) {
|
|
4957
|
+
const resetData = {
|
|
4958
|
+
name: user.profile?.name || ""
|
|
4959
|
+
};
|
|
4960
|
+
if (user.profile) {
|
|
4961
|
+
Object.entries(user.profile).forEach(([key, value]) => {
|
|
4962
|
+
if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
|
|
4963
|
+
resetData[key] = value;
|
|
4964
|
+
}
|
|
4965
|
+
});
|
|
4966
|
+
}
|
|
4967
|
+
setFormData(resetData);
|
|
4968
|
+
}
|
|
4969
|
+
setIsEditing(false);
|
|
4970
|
+
}, [user]);
|
|
4971
|
+
const handleOverlayClick = useCallback(
|
|
4972
|
+
(e) => {
|
|
4973
|
+
if (e.target === e.currentTarget) {
|
|
4974
|
+
onClose();
|
|
4975
|
+
}
|
|
4976
|
+
},
|
|
4977
|
+
[onClose]
|
|
4978
|
+
);
|
|
4979
|
+
useEffect(() => {
|
|
4980
|
+
const handleEscape = (e) => {
|
|
4981
|
+
if (e.key === "Escape") {
|
|
4982
|
+
if (isEditing) {
|
|
4983
|
+
handleCancel();
|
|
4984
|
+
} else {
|
|
4985
|
+
onClose();
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
};
|
|
4989
|
+
document.addEventListener("keydown", handleEscape);
|
|
4990
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
4991
|
+
}, [isEditing, handleCancel, onClose]);
|
|
4992
|
+
if (!isLoaded || !user) {
|
|
4993
|
+
return null;
|
|
4994
|
+
}
|
|
4995
|
+
const initials = user.profile?.name ? user.profile.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
|
|
4996
|
+
const fields = [];
|
|
4997
|
+
fields.push({ key: "email", value: user.email, readOnly: true });
|
|
4998
|
+
fields.push({
|
|
4999
|
+
key: "name",
|
|
5000
|
+
value: isEditing ? formData.name || "" : user.profile?.name || "",
|
|
5001
|
+
readOnly: false
|
|
5002
|
+
});
|
|
5003
|
+
if (user.profile) {
|
|
5004
|
+
Object.entries(user.profile).forEach(([key, value]) => {
|
|
5005
|
+
if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
|
|
5006
|
+
fields.push({
|
|
5007
|
+
key,
|
|
5008
|
+
value: isEditing ? formData[key] ?? value : value,
|
|
5009
|
+
readOnly: READ_ONLY_FIELDS.includes(key)
|
|
5010
|
+
});
|
|
5011
|
+
}
|
|
5012
|
+
});
|
|
5013
|
+
}
|
|
5014
|
+
return /* @__PURE__ */ jsx(ProfileModalOverlay, { onClick: handleOverlayClick, children: /* @__PURE__ */ jsxs(ProfileModalContainer, { onClick: (e) => e.stopPropagation(), children: [
|
|
5015
|
+
/* @__PURE__ */ jsxs(ProfileModalHeader, { children: [
|
|
5016
|
+
/* @__PURE__ */ jsx(ProfileModalTitle, { children: "Profile" }),
|
|
5017
|
+
/* @__PURE__ */ jsx(ProfileModalCloseButton, { onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(X, {}) })
|
|
5018
|
+
] }),
|
|
5019
|
+
/* @__PURE__ */ jsxs(ProfileModalBody, { children: [
|
|
5020
|
+
/* @__PURE__ */ jsx(ProfileAvatarSection, { children: /* @__PURE__ */ jsx(ProfileAvatar, { children: user.profile?.avatar_url && !imageError ? /* @__PURE__ */ jsx(
|
|
5021
|
+
ProfileAvatarImage,
|
|
5022
|
+
{
|
|
5023
|
+
src: user.profile.avatar_url,
|
|
5024
|
+
alt: user.profile?.name || user.email,
|
|
5025
|
+
onError: () => setImageError(true)
|
|
5026
|
+
}
|
|
5027
|
+
) : initials }) }),
|
|
5028
|
+
/* @__PURE__ */ jsx(ProfileFieldsContainer, { children: fields.map(({ key, value, readOnly }) => /* @__PURE__ */ jsxs(ProfileField, { children: [
|
|
5029
|
+
/* @__PURE__ */ jsx(ProfileFieldLabel, { children: formatFieldLabel(key) }),
|
|
5030
|
+
isEditing && !readOnly ? /* @__PURE__ */ jsx(
|
|
5031
|
+
ProfileFieldInput,
|
|
5032
|
+
{
|
|
5033
|
+
type: "text",
|
|
5034
|
+
value: formData[key] ?? value,
|
|
5035
|
+
onChange: (e) => handleFieldChange(key, e.target.value),
|
|
5036
|
+
disabled: isSaving
|
|
5037
|
+
}
|
|
5038
|
+
) : /* @__PURE__ */ jsx(ProfileFieldValue, { children: value || "-" })
|
|
5039
|
+
] }, key)) })
|
|
5040
|
+
] }),
|
|
5041
|
+
/* @__PURE__ */ jsx(ProfileModalFooter, { children: isEditing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5042
|
+
/* @__PURE__ */ jsx(ProfileButton, { onClick: handleCancel, disabled: isSaving, children: "Cancel" }),
|
|
5043
|
+
/* @__PURE__ */ jsxs(ProfileButton, { $primary: true, onClick: () => void handleSave(), disabled: isSaving, children: [
|
|
5044
|
+
isSaving && /* @__PURE__ */ jsx(ProfileSpinner, {}),
|
|
5045
|
+
isSaving ? "Saving..." : "Save"
|
|
5046
|
+
] })
|
|
5047
|
+
] }) : /* @__PURE__ */ jsx(ProfileButton, { $primary: true, onClick: () => setIsEditing(true), children: "Edit Profile" }) })
|
|
5048
|
+
] }) });
|
|
5049
|
+
}
|
|
5050
|
+
function UserButton({
|
|
5051
|
+
afterSignOutUrl = "/",
|
|
5052
|
+
mode = "simple",
|
|
5053
|
+
showProfile = true,
|
|
5054
|
+
onProfileError
|
|
5055
|
+
}) {
|
|
4677
5056
|
const { user } = useInsforge();
|
|
4678
5057
|
const [isOpen, setIsOpen] = useState(false);
|
|
5058
|
+
const [showProfileModal, setShowProfileModal] = useState(false);
|
|
4679
5059
|
const [imageError, setImageError] = useState(false);
|
|
4680
5060
|
const [openUpward, setOpenUpward] = useState(false);
|
|
4681
5061
|
const [horizontalOffset, setHorizontalOffset] = useState(0);
|
|
@@ -4683,7 +5063,7 @@ function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
|
|
|
4683
5063
|
const menuRef = useRef(null);
|
|
4684
5064
|
useEffect(() => {
|
|
4685
5065
|
setImageError(false);
|
|
4686
|
-
const avatarUrl = user?.
|
|
5066
|
+
const avatarUrl = user?.profile?.avatar_url;
|
|
4687
5067
|
if (!avatarUrl) {
|
|
4688
5068
|
return;
|
|
4689
5069
|
}
|
|
@@ -4704,7 +5084,7 @@ function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
|
|
|
4704
5084
|
}
|
|
4705
5085
|
};
|
|
4706
5086
|
void checkImageUrl();
|
|
4707
|
-
}, [user?.
|
|
5087
|
+
}, [user?.profile?.avatar_url]);
|
|
4708
5088
|
useEffect(() => {
|
|
4709
5089
|
if (isOpen && dropdownRef.current) {
|
|
4710
5090
|
const buttonRect = dropdownRef.current.getBoundingClientRect();
|
|
@@ -4748,7 +5128,7 @@ function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
|
|
|
4748
5128
|
if (!user) {
|
|
4749
5129
|
return null;
|
|
4750
5130
|
}
|
|
4751
|
-
const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
|
|
5131
|
+
const initials = user.profile?.name ? user.profile.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
|
|
4752
5132
|
return /* @__PURE__ */ jsxs(UserButtonContainer, { ref: dropdownRef, children: [
|
|
4753
5133
|
/* @__PURE__ */ jsxs(
|
|
4754
5134
|
UserButtonButton,
|
|
@@ -4758,25 +5138,41 @@ function UserButton({ afterSignOutUrl = "/", mode = "simple" }) {
|
|
|
4758
5138
|
"aria-expanded": isOpen,
|
|
4759
5139
|
"aria-haspopup": "true",
|
|
4760
5140
|
children: [
|
|
4761
|
-
/* @__PURE__ */ jsx(UserButtonAvatar, { children: user.
|
|
5141
|
+
/* @__PURE__ */ jsx(UserButtonAvatar, { children: user.profile?.avatar_url && !imageError ? /* @__PURE__ */ jsx(
|
|
4762
5142
|
UserButtonAvatarImage,
|
|
4763
5143
|
{
|
|
4764
|
-
src: user.
|
|
5144
|
+
src: user.profile.avatar_url,
|
|
4765
5145
|
alt: user.email,
|
|
4766
5146
|
onError: () => setImageError(true)
|
|
4767
5147
|
}
|
|
4768
5148
|
) : /* @__PURE__ */ jsx(UserButtonAvatarInitials, { children: initials }) }),
|
|
4769
5149
|
mode === "detailed" && /* @__PURE__ */ jsxs(UserButtonInfo, { children: [
|
|
4770
|
-
user.name && /* @__PURE__ */ jsx(UserButtonName, { children: user.name }),
|
|
5150
|
+
user.profile?.name && /* @__PURE__ */ jsx(UserButtonName, { children: user.profile.name }),
|
|
4771
5151
|
/* @__PURE__ */ jsx(UserButtonEmail, { children: user.email })
|
|
4772
5152
|
] })
|
|
4773
5153
|
]
|
|
4774
5154
|
}
|
|
4775
5155
|
),
|
|
4776
|
-
isOpen && /* @__PURE__ */
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
5156
|
+
isOpen && /* @__PURE__ */ jsxs(UserButtonMenu, { ref: menuRef, $openUpward: openUpward, $horizontalOffset: horizontalOffset, children: [
|
|
5157
|
+
showProfile && /* @__PURE__ */ jsxs(
|
|
5158
|
+
UserButtonMenuItem,
|
|
5159
|
+
{
|
|
5160
|
+
onClick: () => {
|
|
5161
|
+
setShowProfileModal(true);
|
|
5162
|
+
setIsOpen(false);
|
|
5163
|
+
},
|
|
5164
|
+
children: [
|
|
5165
|
+
/* @__PURE__ */ jsx(UserButtonMenuItemIcon, { children: /* @__PURE__ */ jsx(User, {}) }),
|
|
5166
|
+
"Profile"
|
|
5167
|
+
]
|
|
5168
|
+
}
|
|
5169
|
+
),
|
|
5170
|
+
/* @__PURE__ */ jsx(SignOutButton, { afterSignOutUrl, children: /* @__PURE__ */ jsxs(UserButtonMenuItem, { $signout: true, onClick: () => setIsOpen(false), children: [
|
|
5171
|
+
/* @__PURE__ */ jsx(UserButtonMenuItemIcon, { children: /* @__PURE__ */ jsx(LogOut, {}) }),
|
|
5172
|
+
"Sign out"
|
|
5173
|
+
] }) })
|
|
5174
|
+
] }),
|
|
5175
|
+
showProfileModal && /* @__PURE__ */ jsx(UserProfileModal, { onClose: () => setShowProfileModal(false), onError: onProfileError })
|
|
4780
5176
|
] });
|
|
4781
5177
|
}
|
|
4782
5178
|
function Protect({
|
|
@@ -4895,6 +5291,6 @@ react-is/cjs/react-is.development.js:
|
|
|
4895
5291
|
*)
|
|
4896
5292
|
*/
|
|
4897
5293
|
|
|
4898
|
-
export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInButton, SignInForm, SignOutButton, SignUp, SignUpButton, SignUpForm, SignedIn, SignedOut, UserButton, VerifyEmail, VerifyEmailStatus };
|
|
5294
|
+
export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthResetPasswordVerificationStep, AuthSubmitButton, AuthVerificationCodeInput, ForgotPassword, ForgotPasswordForm, Protect, ResetPassword, ResetPasswordForm, SignIn, SignInButton, SignInForm, SignOutButton, SignUp, SignUpButton, SignUpForm, SignedIn, SignedOut, UserButton, UserProfileModal, VerifyEmail, VerifyEmailStatus };
|
|
4899
5295
|
//# sourceMappingURL=components.js.map
|
|
4900
5296
|
//# sourceMappingURL=components.js.map
|