@riligar/auth-react 1.9.4 → 1.11.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.js CHANGED
@@ -8,6 +8,7 @@ var reactRouterDom = require('react-router-dom');
8
8
  var core = require('@mantine/core');
9
9
  var form = require('@mantine/form');
10
10
  var iconsReact = require('@tabler/icons-react');
11
+ var notifications = require('@mantine/notifications');
11
12
 
12
13
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
13
14
  // Config - pode ser sobrescrita pelo AuthProvider
@@ -284,6 +285,34 @@ const getApplicationInfo = async () => {
284
285
  }
285
286
  };
286
287
 
288
+ /*--- Profile Management ---------------------------*/
289
+ const updateProfile = async data => {
290
+ return await api('/auth/update-user', {
291
+ method: 'POST',
292
+ body: JSON.stringify(data)
293
+ });
294
+ };
295
+ const changePassword = async (currentPassword, newPassword, revokeOtherSessions = false) => {
296
+ return await api('/auth/change-password', {
297
+ method: 'POST',
298
+ body: JSON.stringify({
299
+ currentPassword,
300
+ newPassword,
301
+ revokeOtherSessions
302
+ })
303
+ });
304
+ };
305
+ const changeEmail = async (newEmail, callbackURL) => {
306
+ const callback = callbackURL || (typeof window !== 'undefined' ? `${window.location.origin}/auth/verify-email` : '/auth/verify-email');
307
+ return await api('/auth/change-email', {
308
+ method: 'POST',
309
+ body: JSON.stringify({
310
+ newEmail,
311
+ callbackURL: callback
312
+ })
313
+ });
314
+ };
315
+
287
316
  /* Social login redirect (ex.: Google) -----------*/
288
317
  function socialRedirect(provider, redirectTo = typeof window !== 'undefined' ? window.location.href : '/') {
289
318
  if (typeof window === 'undefined') return;
@@ -304,7 +333,10 @@ const useAuthStore = zustand.create((set, get) => ({
304
333
  verifyMagicLink: false,
305
334
  resetPassword: false,
306
335
  verifyEmail: false,
307
- resendVerification: false
336
+ resendVerification: false,
337
+ updateProfile: false,
338
+ changePassword: false,
339
+ changeEmail: false
308
340
  },
309
341
  // Application info (logo, nome, etc)
310
342
  applicationInfo: null,
@@ -671,7 +703,75 @@ const useAuthStore = zustand.create((set, get) => ({
671
703
  /* Atualizar usuário manualmente */
672
704
  setUser: user => set({
673
705
  user
674
- })
706
+ }),
707
+ /* Profile Management */
708
+ updateProfile: async data => {
709
+ const {
710
+ setLoading
711
+ } = get();
712
+ setLoading('updateProfile', true);
713
+ set({
714
+ error: null
715
+ });
716
+ try {
717
+ const result = await updateProfile(data);
718
+ // Atualiza o user no store com os novos dados
719
+ set(state => ({
720
+ user: state.user ? {
721
+ ...state.user,
722
+ ...data
723
+ } : null
724
+ }));
725
+ setLoading('updateProfile', false);
726
+ return result;
727
+ } catch (err) {
728
+ set({
729
+ error: err
730
+ });
731
+ setLoading('updateProfile', false);
732
+ throw err;
733
+ }
734
+ },
735
+ changePassword: async (currentPassword, newPassword, revokeOtherSessions = false) => {
736
+ const {
737
+ setLoading
738
+ } = get();
739
+ setLoading('changePassword', true);
740
+ set({
741
+ error: null
742
+ });
743
+ try {
744
+ const result = await changePassword(currentPassword, newPassword, revokeOtherSessions);
745
+ setLoading('changePassword', false);
746
+ return result;
747
+ } catch (err) {
748
+ set({
749
+ error: err
750
+ });
751
+ setLoading('changePassword', false);
752
+ throw err;
753
+ }
754
+ },
755
+ changeEmail: async (newEmail, callbackURL) => {
756
+ const {
757
+ setLoading
758
+ } = get();
759
+ setLoading('changeEmail', true);
760
+ set({
761
+ error: null
762
+ });
763
+ try {
764
+ const result = await changeEmail(newEmail, callbackURL);
765
+ setLoading('changeEmail', false);
766
+ return result;
767
+ } catch (err) {
768
+ set({
769
+ error: err
770
+ });
771
+ setLoading('changeEmail', false);
772
+ throw err;
773
+ }
774
+ }
675
775
  }));
676
776
 
677
777
  const AuthContext = /*#__PURE__*/react.createContext(); // só para ter o Provider em JSX
@@ -795,6 +895,21 @@ const useSession = () => useAuthStore(shallow.useShallow(s => ({
795
895
  // Loading States Hook
796
896
  const useAuthLoading = () => useAuthStore(s => s.loadingStates);
797
897
 
898
+ // Profile Management Hook (novo nome estilo Clerk)
899
+ const useUser = () => useAuthStore(shallow.useShallow(s => ({
900
+ user: s.user,
901
+ updateProfile: s.updateProfile,
902
+ changePassword: s.changePassword,
903
+ changeEmail: s.changeEmail,
904
+ loadingUpdateProfile: s.loadingStates.updateProfile,
905
+ loadingChangePassword: s.loadingStates.changePassword,
906
+ loadingChangeEmail: s.loadingStates.changeEmail,
907
+ error: s.error
908
+ })));
909
+
910
+ // Alias deprecado para backwards compatibility
911
+ const useProfile = useUser;
912
+
798
913
  // Application Logo Hook
799
914
  const useApplicationLogo = () => {
800
915
  const applicationInfo = useAuthStore(s => s.applicationInfo);
@@ -802,11 +917,11 @@ const useApplicationLogo = () => {
802
917
  return applicationInfo?.image || null;
803
918
  };
804
919
 
805
- function ProtectedRoute({
920
+ function Protect({
806
921
  fallback = /*#__PURE__*/jsxRuntime.jsx("p", {
807
922
  children: "\u231B Carregando..."
808
923
  }),
809
- redirectTo = "/login"
924
+ redirectTo = '/login'
810
925
  }) {
811
926
  const {
812
927
  user,
@@ -860,7 +975,7 @@ function AuthCard({
860
975
 
861
976
  var img = "data:image/webp;base64,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";
862
977
 
863
- function SignInForm({
978
+ function SignIn({
864
979
  // Configuração
865
980
  logo,
866
981
  // Removido default, será calculado abaixo
@@ -1028,7 +1143,7 @@ function SignInForm({
1028
1143
  });
1029
1144
  }
1030
1145
 
1031
- function SignUpForm({
1146
+ function SignUp({
1032
1147
  // Configuração
1033
1148
  logo,
1034
1149
  title = 'Criar Conta',
@@ -1162,7 +1277,7 @@ function SignUpForm({
1162
1277
  });
1163
1278
  }
1164
1279
 
1165
- function MagicLinkForm({
1280
+ function MagicLink({
1166
1281
  // Configuração
1167
1282
  logo,
1168
1283
  title = 'Login sem Senha',
@@ -1240,7 +1355,7 @@ function MagicLinkForm({
1240
1355
  });
1241
1356
  }
1242
1357
 
1243
- function MagicLinkVerify({
1358
+ function MagicLinkCallback({
1244
1359
  // Configuração
1245
1360
  logo,
1246
1361
  // Token pode ser passado diretamente ou extraído da URL
@@ -1350,7 +1465,7 @@ function MagicLinkVerify({
1350
1465
  });
1351
1466
  }
1352
1467
 
1353
- function ForgotPasswordForm({
1468
+ function ForgotPassword({
1354
1469
  // Configuração
1355
1470
  logo,
1356
1471
  title = 'Recuperar Senha',
@@ -1428,7 +1543,7 @@ function ForgotPasswordForm({
1428
1543
  });
1429
1544
  }
1430
1545
 
1431
- function ResetPasswordForm({
1546
+ function ResetPassword({
1432
1547
  // Configuração
1433
1548
  logo,
1434
1549
  title = 'Nova Senha',
@@ -1567,7 +1682,7 @@ function ResetPasswordForm({
1567
1682
  });
1568
1683
  }
1569
1684
 
1570
- function VerifyEmailCard({
1685
+ function VerifyEmail({
1571
1686
  // Configuração
1572
1687
  logo,
1573
1688
  // Token pode ser passado diretamente ou extraído da URL
@@ -1731,16 +1846,811 @@ function VerifyEmailCard({
1731
1846
  });
1732
1847
  }
1733
1848
 
1849
+ function UserProfile({
1850
+ // Controle do modal
1851
+ opened,
1852
+ onClose,
1853
+ // Callbacks
1854
+ onProfileUpdate,
1855
+ onPasswordChange,
1856
+ onEmailChange,
1857
+ onError,
1858
+ // Features toggle
1859
+ showAvatar = true,
1860
+ showName = true,
1861
+ showEmail = true,
1862
+ showPassword = true,
1863
+ // Customização
1864
+ labels = {},
1865
+ title = 'Account',
1866
+ subtitle = 'Manage your account info.',
1867
+ // Avatar config
1868
+ maxAvatarSize = 500 * 1024,
1869
+ // 500KB
1870
+
1871
+ ...modalProps
1872
+ }) {
1873
+ // Local state - which section is expanded
1874
+ const [editingSection, setEditingSection] = react.useState(null); // 'password' | 'email' | 'name' | 'avatar' | null
1875
+
1876
+ // Hook para profile
1877
+ const {
1878
+ user,
1879
+ updateProfile,
1880
+ changePassword,
1881
+ changeEmail,
1882
+ loadingUpdateProfile,
1883
+ loadingChangePassword,
1884
+ loadingChangeEmail
1885
+ } = useProfile();
1886
+
1887
+ // Password form
1888
+ const passwordForm = form.useForm({
1889
+ initialValues: {
1890
+ currentPassword: '',
1891
+ newPassword: '',
1892
+ confirmPassword: ''
1893
+ },
1894
+ validate: {
1895
+ currentPassword: v => !v ? labels.currentPasswordRequired || 'Senha atual obrigatória' : null,
1896
+ newPassword: v => {
1897
+ if (!v) return labels.newPasswordRequired || 'Nova senha obrigatória';
1898
+ if (v.length < 8) return labels.passwordMinLength || 'Mínimo 8 caracteres';
1899
+ return null;
1900
+ },
1901
+ confirmPassword: (v, values) => v !== values.newPassword ? labels.passwordMismatch || 'Senhas não coincidem' : null
1902
+ }
1903
+ });
1904
+
1905
+ // Email form
1906
+ const emailForm = form.useForm({
1907
+ initialValues: {
1908
+ newEmail: ''
1909
+ },
1910
+ validate: {
1911
+ newEmail: v => {
1912
+ if (!v) return labels.emailRequired || 'Email obrigatório';
1913
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) return labels.emailInvalid || 'Email inválido';
1914
+ return null;
1915
+ }
1916
+ }
1917
+ });
1918
+
1919
+ // Name form
1920
+ const nameForm = form.useForm({
1921
+ initialValues: {
1922
+ name: ''
1923
+ },
1924
+ validate: {
1925
+ name: v => !v ? labels.nameRequired || 'Nome obrigatório' : null
1926
+ }
1927
+ });
1928
+
1929
+ // Avatar state (base64)
1930
+ const [avatarPreview, setAvatarPreview] = react.useState(null);
1931
+ const [avatarFile, setAvatarFile] = react.useState(null);
1932
+
1933
+ // Handle file selection and convert to base64
1934
+ const handleAvatarFileChange = file => {
1935
+ if (!file) {
1936
+ setAvatarPreview(null);
1937
+ setAvatarFile(null);
1938
+ return;
1939
+ }
1940
+
1941
+ // Validate file type
1942
+ if (!file.type.startsWith('image/')) {
1943
+ notifications.notifications.show({
1944
+ title: labels.errorTitle || 'Erro',
1945
+ message: labels.avatarInvalidType || 'Por favor, selecione uma imagem válida',
1946
+ color: 'red'
1947
+ });
1948
+ return;
1949
+ }
1950
+
1951
+ // Validate file size
1952
+ if (file.size > maxAvatarSize) {
1953
+ notifications.notifications.show({
1954
+ title: labels.errorTitle || 'Erro',
1955
+ message: labels.avatarTooLarge || `Imagem muito grande. Máximo ${Math.round(maxAvatarSize / 1024)}KB.`,
1956
+ color: 'red'
1957
+ });
1958
+ return;
1959
+ }
1960
+ setAvatarFile(file);
1961
+
1962
+ // Convert to base64
1963
+ const reader = new FileReader();
1964
+ reader.onloadend = () => {
1965
+ setAvatarPreview(reader.result);
1966
+ };
1967
+ reader.readAsDataURL(file);
1968
+ };
1969
+
1970
+ // Populate forms when user data is available or section opens
1971
+ react.useEffect(() => {
1972
+ if (editingSection === 'name' && user?.name) {
1973
+ nameForm.setValues({
1974
+ name: user.name
1975
+ });
1976
+ }
1977
+ if (editingSection === 'avatar' && user?.image) {
1978
+ setAvatarPreview(user.image);
1979
+ }
1980
+ }, [editingSection, user]);
1981
+ const handleToggleSection = section => {
1982
+ if (editingSection === section) {
1983
+ setEditingSection(null);
1984
+ passwordForm.reset();
1985
+ emailForm.reset();
1986
+ nameForm.reset();
1987
+ setAvatarPreview(null);
1988
+ setAvatarFile(null);
1989
+ } else {
1990
+ setEditingSection(section);
1991
+ }
1992
+ };
1993
+ const handleChangePassword = async values => {
1994
+ try {
1995
+ await changePassword(values.currentPassword, values.newPassword);
1996
+ notifications.notifications.show({
1997
+ title: labels.successTitle || 'Sucesso',
1998
+ message: labels.passwordChanged || 'Senha alterada com sucesso',
1999
+ color: 'green'
2000
+ });
2001
+ passwordForm.reset();
2002
+ setEditingSection(null);
2003
+ onPasswordChange?.();
2004
+ } catch (error) {
2005
+ notifications.notifications.show({
2006
+ title: labels.errorTitle || 'Erro',
2007
+ message: error.message || labels.passwordChangeFailed || 'Falha ao alterar senha',
2008
+ color: 'red'
2009
+ });
2010
+ onError?.(error);
2011
+ }
2012
+ };
2013
+ const handleChangeEmail = async values => {
2014
+ try {
2015
+ await changeEmail(values.newEmail);
2016
+ notifications.notifications.show({
2017
+ title: labels.successTitle || 'Sucesso',
2018
+ message: labels.emailVerificationSent || 'Verifique seu novo email para confirmar a alteração',
2019
+ color: 'green'
2020
+ });
2021
+ emailForm.reset();
2022
+ setEditingSection(null);
2023
+ onEmailChange?.(values.newEmail);
2024
+ } catch (error) {
2025
+ notifications.notifications.show({
2026
+ title: labels.errorTitle || 'Erro',
2027
+ message: error.message || labels.emailChangeFailed || 'Falha ao alterar email',
2028
+ color: 'red'
2029
+ });
2030
+ onError?.(error);
2031
+ }
2032
+ };
2033
+ const handleChangeName = async values => {
2034
+ try {
2035
+ await updateProfile({
2036
+ name: values.name
2037
+ });
2038
+ notifications.notifications.show({
2039
+ title: labels.successTitle || 'Sucesso',
2040
+ message: labels.nameUpdated || 'Nome atualizado com sucesso',
2041
+ color: 'green'
2042
+ });
2043
+ nameForm.reset();
2044
+ setEditingSection(null);
2045
+ onProfileUpdate?.({
2046
+ name: values.name
2047
+ });
2048
+ } catch (error) {
2049
+ notifications.notifications.show({
2050
+ title: labels.errorTitle || 'Erro',
2051
+ message: error.message || labels.nameUpdateFailed || 'Falha ao atualizar nome',
2052
+ color: 'red'
2053
+ });
2054
+ onError?.(error);
2055
+ }
2056
+ };
2057
+ const handleChangeAvatar = async () => {
2058
+ if (!avatarPreview) {
2059
+ notifications.notifications.show({
2060
+ title: labels.errorTitle || 'Erro',
2061
+ message: labels.avatarRequired || 'Selecione uma imagem',
2062
+ color: 'red'
2063
+ });
2064
+ return;
2065
+ }
2066
+ try {
2067
+ await updateProfile({
2068
+ image: avatarPreview
2069
+ });
2070
+ notifications.notifications.show({
2071
+ title: labels.successTitle || 'Sucesso',
2072
+ message: labels.avatarUpdated || 'Foto de perfil atualizada com sucesso',
2073
+ color: 'green'
2074
+ });
2075
+ setAvatarPreview(null);
2076
+ setAvatarFile(null);
2077
+ setEditingSection(null);
2078
+ onProfileUpdate?.({
2079
+ image: avatarPreview
2080
+ });
2081
+ } catch (error) {
2082
+ notifications.notifications.show({
2083
+ title: labels.errorTitle || 'Erro',
2084
+ message: error.message || labels.avatarUpdateFailed || 'Falha ao atualizar foto',
2085
+ color: 'red'
2086
+ });
2087
+ onError?.(error);
2088
+ }
2089
+ };
2090
+ const handleRemoveAvatar = async () => {
2091
+ try {
2092
+ await updateProfile({
2093
+ image: ''
2094
+ });
2095
+ notifications.notifications.show({
2096
+ title: labels.successTitle || 'Sucesso',
2097
+ message: labels.avatarRemoved || 'Foto de perfil removida',
2098
+ color: 'green'
2099
+ });
2100
+ setAvatarPreview(null);
2101
+ setAvatarFile(null);
2102
+ setEditingSection(null);
2103
+ onProfileUpdate?.({
2104
+ image: ''
2105
+ });
2106
+ } catch (error) {
2107
+ notifications.notifications.show({
2108
+ title: labels.errorTitle || 'Erro',
2109
+ message: error.message || labels.avatarRemoveFailed || 'Falha ao remover foto',
2110
+ color: 'red'
2111
+ });
2112
+ onError?.(error);
2113
+ }
2114
+ };
2115
+
2116
+ // Reusable Section Header
2117
+ const SectionHeader = ({
2118
+ icon: Icon,
2119
+ sectionTitle,
2120
+ description
2121
+ }) => /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2122
+ gap: "sm",
2123
+ mb: "lg",
2124
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.ThemeIcon, {
2125
+ size: 36,
2126
+ variant: "light",
2127
+ children: /*#__PURE__*/jsxRuntime.jsx(Icon, {
2128
+ size: 18
2129
+ })
2130
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Box, {
2131
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Text, {
2132
+ fw: 600,
2133
+ size: "md",
2134
+ children: sectionTitle
2135
+ }), description && /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2136
+ size: "xs",
2137
+ c: "dimmed",
2138
+ children: description
2139
+ })]
2140
+ })]
2141
+ });
2142
+
2143
+ // Reusable Row component
2144
+ const SettingRow = ({
2145
+ label,
2146
+ children,
2147
+ action,
2148
+ actionLabel,
2149
+ onClick,
2150
+ expanded
2151
+ }) => /*#__PURE__*/jsxRuntime.jsx(core.Card, {
2152
+ p: "xs",
2153
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2154
+ justify: "space-between",
2155
+ wrap: "nowrap",
2156
+ children: [/*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2157
+ gap: "xl",
2158
+ wrap: "nowrap",
2159
+ flex: 1,
2160
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Text, {
2161
+ size: "sm",
2162
+ c: "dimmed",
2163
+ w: 100,
2164
+ style: {
2165
+ flexShrink: 0
2166
+ },
2167
+ children: label
2168
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Box, {
2169
+ flex: 1,
2170
+ children: children
2171
+ })]
2172
+ }), action && /*#__PURE__*/jsxRuntime.jsx(core.Tooltip, {
2173
+ label: actionLabel || action,
2174
+ position: "left",
2175
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Anchor, {
2176
+ size: "sm",
2177
+ fw: 500,
2178
+ onClick: onClick,
2179
+ c: expanded ? 'red' : 'blue',
2180
+ children: expanded ? labels.cancel || 'Cancel' : action
2181
+ })
2182
+ })]
2183
+ })
2184
+ });
2185
+ return /*#__PURE__*/jsxRuntime.jsxs(core.Modal, {
2186
+ opened: opened,
2187
+ onClose: onClose,
2188
+ size: 550,
2189
+ withCloseButton: true,
2190
+ radius: "lg",
2191
+ overlayProps: {
2192
+ backgroundOpacity: 0.55,
2193
+ blur: 3
2194
+ },
2195
+ title: /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2196
+ gap: "md",
2197
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.ThemeIcon, {
2198
+ size: 44,
2199
+ variant: "light",
2200
+ children: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconUserCircle, {
2201
+ size: 24
2202
+ })
2203
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Box, {
2204
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Title, {
2205
+ order: 4,
2206
+ children: title
2207
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2208
+ size: "sm",
2209
+ c: "dimmed",
2210
+ children: subtitle
2211
+ })]
2212
+ })]
2213
+ }),
2214
+ ...modalProps,
2215
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Divider, {
2216
+ mb: "md"
2217
+ }), (showAvatar || showName || showEmail) && /*#__PURE__*/jsxRuntime.jsxs(core.Box, {
2218
+ mb: "xl",
2219
+ children: [/*#__PURE__*/jsxRuntime.jsx(SectionHeader, {
2220
+ icon: iconsReact.IconUser,
2221
+ sectionTitle: labels.profileSection || 'Profile',
2222
+ description: labels.profileDescription || 'Your personal information'
2223
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2224
+ gap: "sm",
2225
+ children: [showAvatar && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
2226
+ children: [/*#__PURE__*/jsxRuntime.jsx(SettingRow, {
2227
+ label: labels.avatar || 'Avatar',
2228
+ action: labels.update || 'Update',
2229
+ actionLabel: labels.updateAvatar || 'Update your profile picture',
2230
+ onClick: () => handleToggleSection('avatar'),
2231
+ expanded: editingSection === 'avatar',
2232
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Group, {
2233
+ gap: "md",
2234
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Avatar, {
2235
+ src: user?.image,
2236
+ name: user?.name || user?.email,
2237
+ size: 48,
2238
+ radius: "xl",
2239
+ color: "initials"
2240
+ })
2241
+ })
2242
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Collapse, {
2243
+ in: editingSection === 'avatar',
2244
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Card, {
2245
+ p: "md",
2246
+ withBorder: true,
2247
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2248
+ gap: "md",
2249
+ align: "center",
2250
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
2251
+ type: "file",
2252
+ id: "avatar-upload",
2253
+ accept: "image/*",
2254
+ style: {
2255
+ display: 'none'
2256
+ },
2257
+ onChange: e => handleAvatarFileChange(e.target.files?.[0])
2258
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Tooltip, {
2259
+ label: labels.clickToChange || 'Clique para alterar',
2260
+ position: "bottom",
2261
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Box, {
2262
+ onClick: () => document.getElementById('avatar-upload')?.click(),
2263
+ style: {
2264
+ position: 'relative',
2265
+ cursor: 'pointer',
2266
+ borderRadius: '50%'
2267
+ },
2268
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Avatar, {
2269
+ src: avatarPreview || user?.image,
2270
+ name: user?.name || user?.email,
2271
+ size: 100,
2272
+ radius: 100,
2273
+ color: "initials"
2274
+ }), /*#__PURE__*/jsxRuntime.jsx(core.ThemeIcon, {
2275
+ size: 32,
2276
+ radius: "xl",
2277
+ color: "blue",
2278
+ style: {
2279
+ position: 'absolute',
2280
+ bottom: 0,
2281
+ right: 0,
2282
+ border: '2px solid var(--mantine-color-body)'
2283
+ },
2284
+ children: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconPhoto, {
2285
+ size: 16
2286
+ })
2287
+ })]
2288
+ })
2289
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2290
+ size: "xs",
2291
+ c: "dimmed",
2292
+ ta: "center",
2293
+ children: labels.avatarHint || `Máximo ${Math.round(maxAvatarSize / 1024)}KB • JPG, PNG, GIF, WebP`
2294
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2295
+ justify: "center",
2296
+ gap: "sm",
2297
+ children: [user?.image && /*#__PURE__*/jsxRuntime.jsx(core.Tooltip, {
2298
+ label: labels.removePhoto || 'Remover foto',
2299
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2300
+ variant: "light",
2301
+ color: "red",
2302
+ size: "xs",
2303
+ onClick: handleRemoveAvatar,
2304
+ loading: loadingUpdateProfile,
2305
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconTrash, {
2306
+ size: 14
2307
+ }),
2308
+ children: labels.remove || 'Remover'
2309
+ })
2310
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2311
+ variant: "default",
2312
+ size: "xs",
2313
+ onClick: () => handleToggleSection('avatar'),
2314
+ children: labels.cancel || 'Cancelar'
2315
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2316
+ size: "xs",
2317
+ loading: loadingUpdateProfile,
2318
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconCheck, {
2319
+ size: 14
2320
+ }),
2321
+ onClick: handleChangeAvatar,
2322
+ disabled: !avatarPreview || avatarPreview === user?.image,
2323
+ children: labels.save || 'Salvar'
2324
+ })]
2325
+ })]
2326
+ })
2327
+ })
2328
+ })]
2329
+ }), showName && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
2330
+ children: [/*#__PURE__*/jsxRuntime.jsx(SettingRow, {
2331
+ label: labels.name || 'Nome',
2332
+ action: labels.change || 'Change',
2333
+ actionLabel: labels.changeName || 'Change your display name',
2334
+ onClick: () => handleToggleSection('name'),
2335
+ expanded: editingSection === 'name',
2336
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2337
+ gap: "xs",
2338
+ children: [/*#__PURE__*/jsxRuntime.jsx(iconsReact.IconPencil, {
2339
+ size: 16,
2340
+ color: "var(--mantine-color-dimmed)"
2341
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2342
+ size: "sm",
2343
+ children: user?.name || labels.notDefined || 'Não definido'
2344
+ })]
2345
+ })
2346
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Collapse, {
2347
+ in: editingSection === 'name',
2348
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Card, {
2349
+ p: "md",
2350
+ withBorder: true,
2351
+ children: /*#__PURE__*/jsxRuntime.jsx("form", {
2352
+ onSubmit: nameForm.onSubmit(handleChangeName),
2353
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2354
+ gap: "sm",
2355
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.TextInput, {
2356
+ label: labels.name || 'Nome',
2357
+ placeholder: labels.namePlaceholder || 'Digite seu nome',
2358
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconUser, {
2359
+ size: 16
2360
+ }),
2361
+ ...nameForm.getInputProps('name')
2362
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2363
+ justify: "flex-end",
2364
+ gap: "sm",
2365
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Button, {
2366
+ variant: "default",
2367
+ size: "xs",
2368
+ onClick: () => handleToggleSection('name'),
2369
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconX, {
2370
+ size: 14
2371
+ }),
2372
+ children: labels.cancel || 'Cancelar'
2373
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2374
+ type: "submit",
2375
+ size: "xs",
2376
+ loading: loadingUpdateProfile,
2377
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconCheck, {
2378
+ size: 14
2379
+ }),
2380
+ children: labels.save || 'Salvar'
2381
+ })]
2382
+ })]
2383
+ })
2384
+ })
2385
+ })
2386
+ })]
2387
+ }), showEmail && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
2388
+ children: [/*#__PURE__*/jsxRuntime.jsx(SettingRow, {
2389
+ label: labels.email || 'Email',
2390
+ action: labels.change || 'Change',
2391
+ actionLabel: labels.changeEmail || 'Change your email',
2392
+ onClick: () => handleToggleSection('email'),
2393
+ expanded: editingSection === 'email',
2394
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2395
+ gap: "xs",
2396
+ children: [/*#__PURE__*/jsxRuntime.jsx(iconsReact.IconMail, {
2397
+ size: 16,
2398
+ color: "var(--mantine-color-dimmed)"
2399
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2400
+ size: "sm",
2401
+ children: user?.email || 'email@exemplo.com'
2402
+ })]
2403
+ })
2404
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Collapse, {
2405
+ in: editingSection === 'email',
2406
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Card, {
2407
+ p: "md",
2408
+ withBorder: true,
2409
+ children: /*#__PURE__*/jsxRuntime.jsx("form", {
2410
+ onSubmit: emailForm.onSubmit(handleChangeEmail),
2411
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2412
+ gap: "sm",
2413
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.TextInput, {
2414
+ label: labels.newEmail || 'Novo Email',
2415
+ placeholder: labels.newEmailPlaceholder || 'Digite o novo email',
2416
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconMail, {
2417
+ size: 16
2418
+ }),
2419
+ ...emailForm.getInputProps('newEmail')
2420
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2421
+ justify: "flex-end",
2422
+ gap: "sm",
2423
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Button, {
2424
+ variant: "default",
2425
+ size: "xs",
2426
+ onClick: () => handleToggleSection('email'),
2427
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconX, {
2428
+ size: 14
2429
+ }),
2430
+ children: labels.cancel || 'Cancelar'
2431
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2432
+ type: "submit",
2433
+ size: "xs",
2434
+ loading: loadingChangeEmail,
2435
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconCheck, {
2436
+ size: 14
2437
+ }),
2438
+ children: labels.save || 'Salvar'
2439
+ })]
2440
+ })]
2441
+ })
2442
+ })
2443
+ })
2444
+ })]
2445
+ })]
2446
+ })]
2447
+ }), showPassword && /*#__PURE__*/jsxRuntime.jsxs(core.Box, {
2448
+ mb: "md",
2449
+ children: [/*#__PURE__*/jsxRuntime.jsx(SectionHeader, {
2450
+ icon: iconsReact.IconShield,
2451
+ sectionTitle: labels.securitySection || 'Security',
2452
+ description: labels.securityDescription || 'Protect your account'
2453
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2454
+ gap: "sm",
2455
+ children: [/*#__PURE__*/jsxRuntime.jsx(SettingRow, {
2456
+ label: labels.password || 'Password',
2457
+ action: labels.change || 'Change',
2458
+ actionLabel: labels.changePassword || 'Change your password',
2459
+ onClick: () => handleToggleSection('password'),
2460
+ expanded: editingSection === 'password',
2461
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2462
+ gap: "xs",
2463
+ children: [/*#__PURE__*/jsxRuntime.jsx(iconsReact.IconKey, {
2464
+ size: 16,
2465
+ color: "var(--mantine-color-dimmed)"
2466
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
2467
+ size: "sm",
2468
+ c: "dimmed",
2469
+ children: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
2470
+ })]
2471
+ })
2472
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Collapse, {
2473
+ in: editingSection === 'password',
2474
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Card, {
2475
+ p: "md",
2476
+ withBorder: true,
2477
+ children: /*#__PURE__*/jsxRuntime.jsx("form", {
2478
+ onSubmit: passwordForm.onSubmit(handleChangePassword),
2479
+ children: /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
2480
+ gap: "sm",
2481
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.PasswordInput, {
2482
+ label: labels.currentPassword || 'Senha Atual',
2483
+ placeholder: labels.currentPasswordPlaceholder || 'Digite sua senha atual',
2484
+ ...passwordForm.getInputProps('currentPassword')
2485
+ }), /*#__PURE__*/jsxRuntime.jsx(core.PasswordInput, {
2486
+ label: labels.newPassword || 'Nova Senha',
2487
+ placeholder: labels.newPasswordPlaceholder || 'Digite a nova senha',
2488
+ description: labels.passwordDescription || 'Mínimo 8 caracteres',
2489
+ ...passwordForm.getInputProps('newPassword')
2490
+ }), /*#__PURE__*/jsxRuntime.jsx(core.PasswordInput, {
2491
+ label: labels.confirmPassword || 'Confirmar Nova Senha',
2492
+ placeholder: labels.confirmPasswordPlaceholder || 'Confirme a nova senha',
2493
+ ...passwordForm.getInputProps('confirmPassword')
2494
+ }), /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
2495
+ justify: "flex-end",
2496
+ gap: "xs",
2497
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Button, {
2498
+ variant: "default",
2499
+ size: "xs",
2500
+ onClick: () => handleToggleSection('password'),
2501
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconX, {
2502
+ size: 14
2503
+ }),
2504
+ children: labels.cancel || 'Cancelar'
2505
+ }), /*#__PURE__*/jsxRuntime.jsx(core.Button, {
2506
+ type: "submit",
2507
+ size: "xs",
2508
+ loading: loadingChangePassword,
2509
+ leftSection: /*#__PURE__*/jsxRuntime.jsx(iconsReact.IconCheck, {
2510
+ size: 14
2511
+ }),
2512
+ children: labels.save || 'Salvar'
2513
+ })]
2514
+ })]
2515
+ })
2516
+ })
2517
+ })
2518
+ })]
2519
+ })]
2520
+ })]
2521
+ });
2522
+ }
2523
+
2524
+ /**
2525
+ * Renderiza children apenas quando o usuário está autenticado
2526
+ * Equivalente ao <SignedIn> do Clerk
2527
+ */
2528
+ function SignedIn({
2529
+ children
2530
+ }) {
2531
+ const {
2532
+ user,
2533
+ loading
2534
+ } = useAuth();
2535
+ if (loading || !user) return null;
2536
+ return children;
2537
+ }
2538
+
2539
+ /**
2540
+ * Renderiza children apenas quando o usuário NÃO está autenticado
2541
+ * Equivalente ao <SignedOut> do Clerk
2542
+ */
2543
+ function SignedOut({
2544
+ children
2545
+ }) {
2546
+ const {
2547
+ user,
2548
+ loading
2549
+ } = useAuth();
2550
+ if (loading || user) return null;
2551
+ return children;
2552
+ }
2553
+
2554
+ /**
2555
+ * Renderiza children enquanto a autenticação está carregando
2556
+ * Equivalente ao <ClerkLoading> do Clerk
2557
+ */
2558
+ function AuthLoading({
2559
+ children
2560
+ }) {
2561
+ const {
2562
+ loading
2563
+ } = useAuth();
2564
+ if (!loading) return null;
2565
+ return children;
2566
+ }
2567
+
2568
+ /**
2569
+ * Renderiza children quando a autenticação terminou de carregar
2570
+ * Equivalente ao <ClerkLoaded> do Clerk
2571
+ */
2572
+ function AuthLoaded({
2573
+ children
2574
+ }) {
2575
+ const {
2576
+ loading
2577
+ } = useAuth();
2578
+ if (loading) return null;
2579
+ return children;
2580
+ }
2581
+
2582
+ function SignInButton({
2583
+ children,
2584
+ redirectTo = '/login',
2585
+ ...props
2586
+ }) {
2587
+ const navigate = reactRouterDom.useNavigate();
2588
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
2589
+ onClick: () => navigate(redirectTo),
2590
+ ...props,
2591
+ children: children || 'Sign In'
2592
+ });
2593
+ }
2594
+
2595
+ function SignUpButton({
2596
+ children,
2597
+ redirectTo = '/register',
2598
+ ...props
2599
+ }) {
2600
+ const navigate = reactRouterDom.useNavigate();
2601
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
2602
+ onClick: () => navigate(redirectTo),
2603
+ ...props,
2604
+ children: children || 'Sign Up'
2605
+ });
2606
+ }
2607
+
2608
+ function SignOutButton({
2609
+ children,
2610
+ onSignOut,
2611
+ ...props
2612
+ }) {
2613
+ const signOut = useSignOut();
2614
+ const handleClick = async () => {
2615
+ await signOut();
2616
+ onSignOut?.();
2617
+ };
2618
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
2619
+ onClick: handleClick,
2620
+ ...props,
2621
+ children: children || 'Sign Out'
2622
+ });
2623
+ }
2624
+
2625
+ exports.AccountModal = UserProfile;
1734
2626
  exports.AuthCard = AuthCard;
2627
+ exports.AuthLoaded = AuthLoaded;
2628
+ exports.AuthLoading = AuthLoading;
1735
2629
  exports.AuthProvider = AuthProvider;
1736
- exports.ForgotPasswordForm = ForgotPasswordForm;
1737
- exports.MagicLinkForm = MagicLinkForm;
1738
- exports.MagicLinkVerify = MagicLinkVerify;
1739
- exports.ProtectedRoute = ProtectedRoute;
1740
- exports.ResetPasswordForm = ResetPasswordForm;
1741
- exports.SignInForm = SignInForm;
1742
- exports.SignUpForm = SignUpForm;
1743
- exports.VerifyEmailCard = VerifyEmailCard;
2630
+ exports.ForgotPassword = ForgotPassword;
2631
+ exports.ForgotPasswordForm = ForgotPassword;
2632
+ exports.MagicLink = MagicLink;
2633
+ exports.MagicLinkCallback = MagicLinkCallback;
2634
+ exports.MagicLinkForm = MagicLink;
2635
+ exports.MagicLinkVerify = MagicLinkCallback;
2636
+ exports.Protect = Protect;
2637
+ exports.ProtectedRoute = Protect;
2638
+ exports.ResetPassword = ResetPassword;
2639
+ exports.ResetPasswordForm = ResetPassword;
2640
+ exports.SignIn = SignIn;
2641
+ exports.SignInButton = SignInButton;
2642
+ exports.SignInForm = SignIn;
2643
+ exports.SignOutButton = SignOutButton;
2644
+ exports.SignUp = SignUp;
2645
+ exports.SignUpButton = SignUpButton;
2646
+ exports.SignUpForm = SignUp;
2647
+ exports.SignedIn = SignedIn;
2648
+ exports.SignedOut = SignedOut;
2649
+ exports.UserProfile = UserProfile;
2650
+ exports.VerifyEmail = VerifyEmail;
2651
+ exports.VerifyEmailCard = VerifyEmail;
2652
+ exports.changeEmail = changeEmail;
2653
+ exports.changePassword = changePassword;
1744
2654
  exports.configure = configure;
1745
2655
  exports.decodeJWT = decodeJWT;
1746
2656
  exports.forgotPassword = forgotPassword;
@@ -1756,6 +2666,8 @@ exports.signIn = signIn;
1756
2666
  exports.signOut = signOut;
1757
2667
  exports.signUp = signUp;
1758
2668
  exports.socialRedirect = socialRedirect;
2669
+ exports.updateProfile = updateProfile;
2670
+ exports.useApplicationLogo = useApplicationLogo;
1759
2671
  exports.useAuth = useAuth;
1760
2672
  exports.useAuthLoading = useAuthLoading;
1761
2673
  exports.useAuthStore = useAuthStore;
@@ -1763,10 +2675,12 @@ exports.useCheckToken = useCheckToken;
1763
2675
  exports.useEmailVerification = useEmailVerification;
1764
2676
  exports.useMagicLink = useMagicLink;
1765
2677
  exports.usePasswordReset = usePasswordReset;
2678
+ exports.useProfile = useUser;
1766
2679
  exports.useSession = useSession;
1767
2680
  exports.useSignIn = useSignIn;
1768
2681
  exports.useSignOut = useSignOut;
1769
2682
  exports.useSignUp = useSignUp;
2683
+ exports.useUser = useUser;
1770
2684
  exports.verifyEmail = verifyEmail;
1771
2685
  exports.verifyMagicLink = verifyMagicLink;
1772
2686
  //# sourceMappingURL=index.js.map