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