@riligar/auth-react 1.9.4 → 1.10.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 +792 -5
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +794 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -3,9 +3,10 @@ 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
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';
|
|
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,18 @@ const useSession = () => useAuthStore(useShallow(s => ({
|
|
|
792
892
|
// Loading States Hook
|
|
793
893
|
const useAuthLoading = () => useAuthStore(s => s.loadingStates);
|
|
794
894
|
|
|
895
|
+
// Profile Management Hook
|
|
896
|
+
const useProfile = () => 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
|
+
|
|
795
907
|
// Application Logo Hook
|
|
796
908
|
const useApplicationLogo = () => {
|
|
797
909
|
const applicationInfo = useAuthStore(s => s.applicationInfo);
|
|
@@ -1728,5 +1840,680 @@ function VerifyEmailCard({
|
|
|
1728
1840
|
});
|
|
1729
1841
|
}
|
|
1730
1842
|
|
|
1731
|
-
|
|
1843
|
+
function AccountModal({
|
|
1844
|
+
// Controle do modal
|
|
1845
|
+
opened,
|
|
1846
|
+
onClose,
|
|
1847
|
+
// Callbacks
|
|
1848
|
+
onProfileUpdate,
|
|
1849
|
+
onPasswordChange,
|
|
1850
|
+
onEmailChange,
|
|
1851
|
+
onError,
|
|
1852
|
+
// Features toggle
|
|
1853
|
+
showAvatar = true,
|
|
1854
|
+
showName = true,
|
|
1855
|
+
showEmail = true,
|
|
1856
|
+
showPassword = true,
|
|
1857
|
+
// Customização
|
|
1858
|
+
labels = {},
|
|
1859
|
+
title = 'Account',
|
|
1860
|
+
subtitle = 'Manage your account info.',
|
|
1861
|
+
// Avatar config
|
|
1862
|
+
maxAvatarSize = 500 * 1024,
|
|
1863
|
+
// 500KB
|
|
1864
|
+
|
|
1865
|
+
...modalProps
|
|
1866
|
+
}) {
|
|
1867
|
+
// Local state - which section is expanded
|
|
1868
|
+
const [editingSection, setEditingSection] = useState(null); // 'password' | 'email' | 'name' | 'avatar' | null
|
|
1869
|
+
|
|
1870
|
+
// Hook para profile
|
|
1871
|
+
const {
|
|
1872
|
+
user,
|
|
1873
|
+
updateProfile,
|
|
1874
|
+
changePassword,
|
|
1875
|
+
changeEmail,
|
|
1876
|
+
loadingUpdateProfile,
|
|
1877
|
+
loadingChangePassword,
|
|
1878
|
+
loadingChangeEmail
|
|
1879
|
+
} = useProfile();
|
|
1880
|
+
|
|
1881
|
+
// Password form
|
|
1882
|
+
const passwordForm = useForm({
|
|
1883
|
+
initialValues: {
|
|
1884
|
+
currentPassword: '',
|
|
1885
|
+
newPassword: '',
|
|
1886
|
+
confirmPassword: ''
|
|
1887
|
+
},
|
|
1888
|
+
validate: {
|
|
1889
|
+
currentPassword: v => !v ? labels.currentPasswordRequired || 'Senha atual obrigatória' : null,
|
|
1890
|
+
newPassword: v => {
|
|
1891
|
+
if (!v) return labels.newPasswordRequired || 'Nova senha obrigatória';
|
|
1892
|
+
if (v.length < 8) return labels.passwordMinLength || 'Mínimo 8 caracteres';
|
|
1893
|
+
return null;
|
|
1894
|
+
},
|
|
1895
|
+
confirmPassword: (v, values) => v !== values.newPassword ? labels.passwordMismatch || 'Senhas não coincidem' : null
|
|
1896
|
+
}
|
|
1897
|
+
});
|
|
1898
|
+
|
|
1899
|
+
// Email form
|
|
1900
|
+
const emailForm = useForm({
|
|
1901
|
+
initialValues: {
|
|
1902
|
+
newEmail: ''
|
|
1903
|
+
},
|
|
1904
|
+
validate: {
|
|
1905
|
+
newEmail: v => {
|
|
1906
|
+
if (!v) return labels.emailRequired || 'Email obrigatório';
|
|
1907
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) return labels.emailInvalid || 'Email inválido';
|
|
1908
|
+
return null;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
});
|
|
1912
|
+
|
|
1913
|
+
// Name form
|
|
1914
|
+
const nameForm = useForm({
|
|
1915
|
+
initialValues: {
|
|
1916
|
+
name: ''
|
|
1917
|
+
},
|
|
1918
|
+
validate: {
|
|
1919
|
+
name: v => !v ? labels.nameRequired || 'Nome obrigatório' : null
|
|
1920
|
+
}
|
|
1921
|
+
});
|
|
1922
|
+
|
|
1923
|
+
// Avatar state (base64)
|
|
1924
|
+
const [avatarPreview, setAvatarPreview] = useState(null);
|
|
1925
|
+
const [avatarFile, setAvatarFile] = useState(null);
|
|
1926
|
+
|
|
1927
|
+
// Handle file selection and convert to base64
|
|
1928
|
+
const handleAvatarFileChange = file => {
|
|
1929
|
+
if (!file) {
|
|
1930
|
+
setAvatarPreview(null);
|
|
1931
|
+
setAvatarFile(null);
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
// Validate file type
|
|
1936
|
+
if (!file.type.startsWith('image/')) {
|
|
1937
|
+
notifications.show({
|
|
1938
|
+
title: labels.errorTitle || 'Erro',
|
|
1939
|
+
message: labels.avatarInvalidType || 'Por favor, selecione uma imagem válida',
|
|
1940
|
+
color: 'red'
|
|
1941
|
+
});
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
// Validate file size
|
|
1946
|
+
if (file.size > maxAvatarSize) {
|
|
1947
|
+
notifications.show({
|
|
1948
|
+
title: labels.errorTitle || 'Erro',
|
|
1949
|
+
message: labels.avatarTooLarge || `Imagem muito grande. Máximo ${Math.round(maxAvatarSize / 1024)}KB.`,
|
|
1950
|
+
color: 'red'
|
|
1951
|
+
});
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
setAvatarFile(file);
|
|
1955
|
+
|
|
1956
|
+
// Convert to base64
|
|
1957
|
+
const reader = new FileReader();
|
|
1958
|
+
reader.onloadend = () => {
|
|
1959
|
+
setAvatarPreview(reader.result);
|
|
1960
|
+
};
|
|
1961
|
+
reader.readAsDataURL(file);
|
|
1962
|
+
};
|
|
1963
|
+
|
|
1964
|
+
// Populate forms when user data is available or section opens
|
|
1965
|
+
useEffect(() => {
|
|
1966
|
+
if (editingSection === 'name' && user?.name) {
|
|
1967
|
+
nameForm.setValues({
|
|
1968
|
+
name: user.name
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
if (editingSection === 'avatar' && user?.image) {
|
|
1972
|
+
setAvatarPreview(user.image);
|
|
1973
|
+
}
|
|
1974
|
+
}, [editingSection, user]);
|
|
1975
|
+
const handleToggleSection = section => {
|
|
1976
|
+
if (editingSection === section) {
|
|
1977
|
+
setEditingSection(null);
|
|
1978
|
+
passwordForm.reset();
|
|
1979
|
+
emailForm.reset();
|
|
1980
|
+
nameForm.reset();
|
|
1981
|
+
setAvatarPreview(null);
|
|
1982
|
+
setAvatarFile(null);
|
|
1983
|
+
} else {
|
|
1984
|
+
setEditingSection(section);
|
|
1985
|
+
}
|
|
1986
|
+
};
|
|
1987
|
+
const handleChangePassword = async values => {
|
|
1988
|
+
try {
|
|
1989
|
+
await changePassword(values.currentPassword, values.newPassword);
|
|
1990
|
+
notifications.show({
|
|
1991
|
+
title: labels.successTitle || 'Sucesso',
|
|
1992
|
+
message: labels.passwordChanged || 'Senha alterada com sucesso',
|
|
1993
|
+
color: 'green'
|
|
1994
|
+
});
|
|
1995
|
+
passwordForm.reset();
|
|
1996
|
+
setEditingSection(null);
|
|
1997
|
+
onPasswordChange?.();
|
|
1998
|
+
} catch (error) {
|
|
1999
|
+
notifications.show({
|
|
2000
|
+
title: labels.errorTitle || 'Erro',
|
|
2001
|
+
message: error.message || labels.passwordChangeFailed || 'Falha ao alterar senha',
|
|
2002
|
+
color: 'red'
|
|
2003
|
+
});
|
|
2004
|
+
onError?.(error);
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
2007
|
+
const handleChangeEmail = async values => {
|
|
2008
|
+
try {
|
|
2009
|
+
await changeEmail(values.newEmail);
|
|
2010
|
+
notifications.show({
|
|
2011
|
+
title: labels.successTitle || 'Sucesso',
|
|
2012
|
+
message: labels.emailVerificationSent || 'Verifique seu novo email para confirmar a alteração',
|
|
2013
|
+
color: 'green'
|
|
2014
|
+
});
|
|
2015
|
+
emailForm.reset();
|
|
2016
|
+
setEditingSection(null);
|
|
2017
|
+
onEmailChange?.(values.newEmail);
|
|
2018
|
+
} catch (error) {
|
|
2019
|
+
notifications.show({
|
|
2020
|
+
title: labels.errorTitle || 'Erro',
|
|
2021
|
+
message: error.message || labels.emailChangeFailed || 'Falha ao alterar email',
|
|
2022
|
+
color: 'red'
|
|
2023
|
+
});
|
|
2024
|
+
onError?.(error);
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2027
|
+
const handleChangeName = async values => {
|
|
2028
|
+
try {
|
|
2029
|
+
await updateProfile({
|
|
2030
|
+
name: values.name
|
|
2031
|
+
});
|
|
2032
|
+
notifications.show({
|
|
2033
|
+
title: labels.successTitle || 'Sucesso',
|
|
2034
|
+
message: labels.nameUpdated || 'Nome atualizado com sucesso',
|
|
2035
|
+
color: 'green'
|
|
2036
|
+
});
|
|
2037
|
+
nameForm.reset();
|
|
2038
|
+
setEditingSection(null);
|
|
2039
|
+
onProfileUpdate?.({
|
|
2040
|
+
name: values.name
|
|
2041
|
+
});
|
|
2042
|
+
} catch (error) {
|
|
2043
|
+
notifications.show({
|
|
2044
|
+
title: labels.errorTitle || 'Erro',
|
|
2045
|
+
message: error.message || labels.nameUpdateFailed || 'Falha ao atualizar nome',
|
|
2046
|
+
color: 'red'
|
|
2047
|
+
});
|
|
2048
|
+
onError?.(error);
|
|
2049
|
+
}
|
|
2050
|
+
};
|
|
2051
|
+
const handleChangeAvatar = async () => {
|
|
2052
|
+
if (!avatarPreview) {
|
|
2053
|
+
notifications.show({
|
|
2054
|
+
title: labels.errorTitle || 'Erro',
|
|
2055
|
+
message: labels.avatarRequired || 'Selecione uma imagem',
|
|
2056
|
+
color: 'red'
|
|
2057
|
+
});
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
try {
|
|
2061
|
+
await updateProfile({
|
|
2062
|
+
image: avatarPreview
|
|
2063
|
+
});
|
|
2064
|
+
notifications.show({
|
|
2065
|
+
title: labels.successTitle || 'Sucesso',
|
|
2066
|
+
message: labels.avatarUpdated || 'Foto de perfil atualizada com sucesso',
|
|
2067
|
+
color: 'green'
|
|
2068
|
+
});
|
|
2069
|
+
setAvatarPreview(null);
|
|
2070
|
+
setAvatarFile(null);
|
|
2071
|
+
setEditingSection(null);
|
|
2072
|
+
onProfileUpdate?.({
|
|
2073
|
+
image: avatarPreview
|
|
2074
|
+
});
|
|
2075
|
+
} catch (error) {
|
|
2076
|
+
notifications.show({
|
|
2077
|
+
title: labels.errorTitle || 'Erro',
|
|
2078
|
+
message: error.message || labels.avatarUpdateFailed || 'Falha ao atualizar foto',
|
|
2079
|
+
color: 'red'
|
|
2080
|
+
});
|
|
2081
|
+
onError?.(error);
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
2084
|
+
const handleRemoveAvatar = async () => {
|
|
2085
|
+
try {
|
|
2086
|
+
await updateProfile({
|
|
2087
|
+
image: ''
|
|
2088
|
+
});
|
|
2089
|
+
notifications.show({
|
|
2090
|
+
title: labels.successTitle || 'Sucesso',
|
|
2091
|
+
message: labels.avatarRemoved || 'Foto de perfil removida',
|
|
2092
|
+
color: 'green'
|
|
2093
|
+
});
|
|
2094
|
+
setAvatarPreview(null);
|
|
2095
|
+
setAvatarFile(null);
|
|
2096
|
+
setEditingSection(null);
|
|
2097
|
+
onProfileUpdate?.({
|
|
2098
|
+
image: ''
|
|
2099
|
+
});
|
|
2100
|
+
} catch (error) {
|
|
2101
|
+
notifications.show({
|
|
2102
|
+
title: labels.errorTitle || 'Erro',
|
|
2103
|
+
message: error.message || labels.avatarRemoveFailed || 'Falha ao remover foto',
|
|
2104
|
+
color: 'red'
|
|
2105
|
+
});
|
|
2106
|
+
onError?.(error);
|
|
2107
|
+
}
|
|
2108
|
+
};
|
|
2109
|
+
|
|
2110
|
+
// Reusable Section Header
|
|
2111
|
+
const SectionHeader = ({
|
|
2112
|
+
icon: Icon,
|
|
2113
|
+
sectionTitle,
|
|
2114
|
+
description
|
|
2115
|
+
}) => /*#__PURE__*/jsxs(Group, {
|
|
2116
|
+
gap: "sm",
|
|
2117
|
+
mb: "lg",
|
|
2118
|
+
children: [/*#__PURE__*/jsx(ThemeIcon, {
|
|
2119
|
+
size: 36,
|
|
2120
|
+
variant: "light",
|
|
2121
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
2122
|
+
size: 18
|
|
2123
|
+
})
|
|
2124
|
+
}), /*#__PURE__*/jsxs(Box, {
|
|
2125
|
+
children: [/*#__PURE__*/jsx(Text, {
|
|
2126
|
+
fw: 600,
|
|
2127
|
+
size: "md",
|
|
2128
|
+
children: sectionTitle
|
|
2129
|
+
}), description && /*#__PURE__*/jsx(Text, {
|
|
2130
|
+
size: "xs",
|
|
2131
|
+
c: "dimmed",
|
|
2132
|
+
children: description
|
|
2133
|
+
})]
|
|
2134
|
+
})]
|
|
2135
|
+
});
|
|
2136
|
+
|
|
2137
|
+
// Reusable Row component
|
|
2138
|
+
const SettingRow = ({
|
|
2139
|
+
label,
|
|
2140
|
+
children,
|
|
2141
|
+
action,
|
|
2142
|
+
actionLabel,
|
|
2143
|
+
onClick,
|
|
2144
|
+
expanded
|
|
2145
|
+
}) => /*#__PURE__*/jsx(Card, {
|
|
2146
|
+
p: "xs",
|
|
2147
|
+
children: /*#__PURE__*/jsxs(Group, {
|
|
2148
|
+
justify: "space-between",
|
|
2149
|
+
wrap: "nowrap",
|
|
2150
|
+
children: [/*#__PURE__*/jsxs(Group, {
|
|
2151
|
+
gap: "xl",
|
|
2152
|
+
wrap: "nowrap",
|
|
2153
|
+
flex: 1,
|
|
2154
|
+
children: [/*#__PURE__*/jsx(Text, {
|
|
2155
|
+
size: "sm",
|
|
2156
|
+
c: "dimmed",
|
|
2157
|
+
w: 100,
|
|
2158
|
+
style: {
|
|
2159
|
+
flexShrink: 0
|
|
2160
|
+
},
|
|
2161
|
+
children: label
|
|
2162
|
+
}), /*#__PURE__*/jsx(Box, {
|
|
2163
|
+
flex: 1,
|
|
2164
|
+
children: children
|
|
2165
|
+
})]
|
|
2166
|
+
}), action && /*#__PURE__*/jsx(Tooltip, {
|
|
2167
|
+
label: actionLabel || action,
|
|
2168
|
+
position: "left",
|
|
2169
|
+
children: /*#__PURE__*/jsx(Anchor, {
|
|
2170
|
+
size: "sm",
|
|
2171
|
+
fw: 500,
|
|
2172
|
+
onClick: onClick,
|
|
2173
|
+
c: expanded ? 'red' : 'blue',
|
|
2174
|
+
children: expanded ? labels.cancel || 'Cancel' : action
|
|
2175
|
+
})
|
|
2176
|
+
})]
|
|
2177
|
+
})
|
|
2178
|
+
});
|
|
2179
|
+
return /*#__PURE__*/jsxs(Modal, {
|
|
2180
|
+
opened: opened,
|
|
2181
|
+
onClose: onClose,
|
|
2182
|
+
size: 550,
|
|
2183
|
+
withCloseButton: true,
|
|
2184
|
+
radius: "lg",
|
|
2185
|
+
overlayProps: {
|
|
2186
|
+
backgroundOpacity: 0.55,
|
|
2187
|
+
blur: 3
|
|
2188
|
+
},
|
|
2189
|
+
title: /*#__PURE__*/jsxs(Group, {
|
|
2190
|
+
gap: "md",
|
|
2191
|
+
children: [/*#__PURE__*/jsx(ThemeIcon, {
|
|
2192
|
+
size: 44,
|
|
2193
|
+
variant: "light",
|
|
2194
|
+
children: /*#__PURE__*/jsx(IconUserCircle, {
|
|
2195
|
+
size: 24
|
|
2196
|
+
})
|
|
2197
|
+
}), /*#__PURE__*/jsxs(Box, {
|
|
2198
|
+
children: [/*#__PURE__*/jsx(Title, {
|
|
2199
|
+
order: 4,
|
|
2200
|
+
children: title
|
|
2201
|
+
}), /*#__PURE__*/jsx(Text, {
|
|
2202
|
+
size: "sm",
|
|
2203
|
+
c: "dimmed",
|
|
2204
|
+
children: subtitle
|
|
2205
|
+
})]
|
|
2206
|
+
})]
|
|
2207
|
+
}),
|
|
2208
|
+
...modalProps,
|
|
2209
|
+
children: [/*#__PURE__*/jsx(Divider, {
|
|
2210
|
+
mb: "md"
|
|
2211
|
+
}), (showAvatar || showName || showEmail) && /*#__PURE__*/jsxs(Box, {
|
|
2212
|
+
mb: "xl",
|
|
2213
|
+
children: [/*#__PURE__*/jsx(SectionHeader, {
|
|
2214
|
+
icon: IconUser,
|
|
2215
|
+
sectionTitle: labels.profileSection || 'Profile',
|
|
2216
|
+
description: labels.profileDescription || 'Your personal information'
|
|
2217
|
+
}), /*#__PURE__*/jsxs(Stack, {
|
|
2218
|
+
gap: "sm",
|
|
2219
|
+
children: [showAvatar && /*#__PURE__*/jsxs(Fragment, {
|
|
2220
|
+
children: [/*#__PURE__*/jsx(SettingRow, {
|
|
2221
|
+
label: labels.avatar || 'Avatar',
|
|
2222
|
+
action: labels.update || 'Update',
|
|
2223
|
+
actionLabel: labels.updateAvatar || 'Update your profile picture',
|
|
2224
|
+
onClick: () => handleToggleSection('avatar'),
|
|
2225
|
+
expanded: editingSection === 'avatar',
|
|
2226
|
+
children: /*#__PURE__*/jsx(Group, {
|
|
2227
|
+
gap: "md",
|
|
2228
|
+
children: /*#__PURE__*/jsx(Avatar, {
|
|
2229
|
+
src: user?.image,
|
|
2230
|
+
name: user?.name || user?.email,
|
|
2231
|
+
size: 48,
|
|
2232
|
+
radius: "xl",
|
|
2233
|
+
color: "initials"
|
|
2234
|
+
})
|
|
2235
|
+
})
|
|
2236
|
+
}), /*#__PURE__*/jsx(Collapse, {
|
|
2237
|
+
in: editingSection === 'avatar',
|
|
2238
|
+
children: /*#__PURE__*/jsx(Card, {
|
|
2239
|
+
p: "md",
|
|
2240
|
+
withBorder: true,
|
|
2241
|
+
children: /*#__PURE__*/jsxs(Stack, {
|
|
2242
|
+
gap: "md",
|
|
2243
|
+
align: "center",
|
|
2244
|
+
children: [/*#__PURE__*/jsx("input", {
|
|
2245
|
+
type: "file",
|
|
2246
|
+
id: "avatar-upload",
|
|
2247
|
+
accept: "image/*",
|
|
2248
|
+
style: {
|
|
2249
|
+
display: 'none'
|
|
2250
|
+
},
|
|
2251
|
+
onChange: e => handleAvatarFileChange(e.target.files?.[0])
|
|
2252
|
+
}), /*#__PURE__*/jsx(Tooltip, {
|
|
2253
|
+
label: labels.clickToChange || 'Clique para alterar',
|
|
2254
|
+
position: "bottom",
|
|
2255
|
+
children: /*#__PURE__*/jsxs(Box, {
|
|
2256
|
+
onClick: () => document.getElementById('avatar-upload')?.click(),
|
|
2257
|
+
style: {
|
|
2258
|
+
position: 'relative',
|
|
2259
|
+
cursor: 'pointer',
|
|
2260
|
+
borderRadius: '50%'
|
|
2261
|
+
},
|
|
2262
|
+
children: [/*#__PURE__*/jsx(Avatar, {
|
|
2263
|
+
src: avatarPreview || user?.image,
|
|
2264
|
+
name: user?.name || user?.email,
|
|
2265
|
+
size: 100,
|
|
2266
|
+
radius: 100,
|
|
2267
|
+
color: "initials"
|
|
2268
|
+
}), /*#__PURE__*/jsx(ThemeIcon, {
|
|
2269
|
+
size: 32,
|
|
2270
|
+
radius: "xl",
|
|
2271
|
+
color: "blue",
|
|
2272
|
+
style: {
|
|
2273
|
+
position: 'absolute',
|
|
2274
|
+
bottom: 0,
|
|
2275
|
+
right: 0,
|
|
2276
|
+
border: '2px solid var(--mantine-color-body)'
|
|
2277
|
+
},
|
|
2278
|
+
children: /*#__PURE__*/jsx(IconPhoto, {
|
|
2279
|
+
size: 16
|
|
2280
|
+
})
|
|
2281
|
+
})]
|
|
2282
|
+
})
|
|
2283
|
+
}), /*#__PURE__*/jsx(Text, {
|
|
2284
|
+
size: "xs",
|
|
2285
|
+
c: "dimmed",
|
|
2286
|
+
ta: "center",
|
|
2287
|
+
children: labels.avatarHint || `Máximo ${Math.round(maxAvatarSize / 1024)}KB • JPG, PNG, GIF, WebP`
|
|
2288
|
+
}), /*#__PURE__*/jsxs(Group, {
|
|
2289
|
+
justify: "center",
|
|
2290
|
+
gap: "sm",
|
|
2291
|
+
children: [user?.image && /*#__PURE__*/jsx(Tooltip, {
|
|
2292
|
+
label: labels.removePhoto || 'Remover foto',
|
|
2293
|
+
children: /*#__PURE__*/jsx(Button, {
|
|
2294
|
+
variant: "light",
|
|
2295
|
+
color: "red",
|
|
2296
|
+
size: "xs",
|
|
2297
|
+
onClick: handleRemoveAvatar,
|
|
2298
|
+
loading: loadingUpdateProfile,
|
|
2299
|
+
leftSection: /*#__PURE__*/jsx(IconTrash, {
|
|
2300
|
+
size: 14
|
|
2301
|
+
}),
|
|
2302
|
+
children: labels.remove || 'Remover'
|
|
2303
|
+
})
|
|
2304
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
2305
|
+
variant: "default",
|
|
2306
|
+
size: "xs",
|
|
2307
|
+
onClick: () => handleToggleSection('avatar'),
|
|
2308
|
+
children: labels.cancel || 'Cancelar'
|
|
2309
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
2310
|
+
size: "xs",
|
|
2311
|
+
loading: loadingUpdateProfile,
|
|
2312
|
+
leftSection: /*#__PURE__*/jsx(IconCheck, {
|
|
2313
|
+
size: 14
|
|
2314
|
+
}),
|
|
2315
|
+
onClick: handleChangeAvatar,
|
|
2316
|
+
disabled: !avatarPreview || avatarPreview === user?.image,
|
|
2317
|
+
children: labels.save || 'Salvar'
|
|
2318
|
+
})]
|
|
2319
|
+
})]
|
|
2320
|
+
})
|
|
2321
|
+
})
|
|
2322
|
+
})]
|
|
2323
|
+
}), showName && /*#__PURE__*/jsxs(Fragment, {
|
|
2324
|
+
children: [/*#__PURE__*/jsx(SettingRow, {
|
|
2325
|
+
label: labels.name || 'Nome',
|
|
2326
|
+
action: labels.change || 'Change',
|
|
2327
|
+
actionLabel: labels.changeName || 'Change your display name',
|
|
2328
|
+
onClick: () => handleToggleSection('name'),
|
|
2329
|
+
expanded: editingSection === 'name',
|
|
2330
|
+
children: /*#__PURE__*/jsxs(Group, {
|
|
2331
|
+
gap: "xs",
|
|
2332
|
+
children: [/*#__PURE__*/jsx(IconPencil, {
|
|
2333
|
+
size: 16,
|
|
2334
|
+
color: "var(--mantine-color-dimmed)"
|
|
2335
|
+
}), /*#__PURE__*/jsx(Text, {
|
|
2336
|
+
size: "sm",
|
|
2337
|
+
children: user?.name || labels.notDefined || 'Não definido'
|
|
2338
|
+
})]
|
|
2339
|
+
})
|
|
2340
|
+
}), /*#__PURE__*/jsx(Collapse, {
|
|
2341
|
+
in: editingSection === 'name',
|
|
2342
|
+
children: /*#__PURE__*/jsx(Card, {
|
|
2343
|
+
p: "md",
|
|
2344
|
+
withBorder: true,
|
|
2345
|
+
children: /*#__PURE__*/jsx("form", {
|
|
2346
|
+
onSubmit: nameForm.onSubmit(handleChangeName),
|
|
2347
|
+
children: /*#__PURE__*/jsxs(Stack, {
|
|
2348
|
+
gap: "sm",
|
|
2349
|
+
children: [/*#__PURE__*/jsx(TextInput, {
|
|
2350
|
+
label: labels.name || 'Nome',
|
|
2351
|
+
placeholder: labels.namePlaceholder || 'Digite seu nome',
|
|
2352
|
+
leftSection: /*#__PURE__*/jsx(IconUser, {
|
|
2353
|
+
size: 16
|
|
2354
|
+
}),
|
|
2355
|
+
...nameForm.getInputProps('name')
|
|
2356
|
+
}), /*#__PURE__*/jsxs(Group, {
|
|
2357
|
+
justify: "flex-end",
|
|
2358
|
+
gap: "sm",
|
|
2359
|
+
children: [/*#__PURE__*/jsx(Button, {
|
|
2360
|
+
variant: "default",
|
|
2361
|
+
size: "xs",
|
|
2362
|
+
onClick: () => handleToggleSection('name'),
|
|
2363
|
+
leftSection: /*#__PURE__*/jsx(IconX, {
|
|
2364
|
+
size: 14
|
|
2365
|
+
}),
|
|
2366
|
+
children: labels.cancel || 'Cancelar'
|
|
2367
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
2368
|
+
type: "submit",
|
|
2369
|
+
size: "xs",
|
|
2370
|
+
loading: loadingUpdateProfile,
|
|
2371
|
+
leftSection: /*#__PURE__*/jsx(IconCheck, {
|
|
2372
|
+
size: 14
|
|
2373
|
+
}),
|
|
2374
|
+
children: labels.save || 'Salvar'
|
|
2375
|
+
})]
|
|
2376
|
+
})]
|
|
2377
|
+
})
|
|
2378
|
+
})
|
|
2379
|
+
})
|
|
2380
|
+
})]
|
|
2381
|
+
}), showEmail && /*#__PURE__*/jsxs(Fragment, {
|
|
2382
|
+
children: [/*#__PURE__*/jsx(SettingRow, {
|
|
2383
|
+
label: labels.email || 'Email',
|
|
2384
|
+
action: labels.change || 'Change',
|
|
2385
|
+
actionLabel: labels.changeEmail || 'Change your email',
|
|
2386
|
+
onClick: () => handleToggleSection('email'),
|
|
2387
|
+
expanded: editingSection === 'email',
|
|
2388
|
+
children: /*#__PURE__*/jsxs(Group, {
|
|
2389
|
+
gap: "xs",
|
|
2390
|
+
children: [/*#__PURE__*/jsx(IconMail, {
|
|
2391
|
+
size: 16,
|
|
2392
|
+
color: "var(--mantine-color-dimmed)"
|
|
2393
|
+
}), /*#__PURE__*/jsx(Text, {
|
|
2394
|
+
size: "sm",
|
|
2395
|
+
children: user?.email || 'email@exemplo.com'
|
|
2396
|
+
})]
|
|
2397
|
+
})
|
|
2398
|
+
}), /*#__PURE__*/jsx(Collapse, {
|
|
2399
|
+
in: editingSection === 'email',
|
|
2400
|
+
children: /*#__PURE__*/jsx(Card, {
|
|
2401
|
+
p: "md",
|
|
2402
|
+
withBorder: true,
|
|
2403
|
+
children: /*#__PURE__*/jsx("form", {
|
|
2404
|
+
onSubmit: emailForm.onSubmit(handleChangeEmail),
|
|
2405
|
+
children: /*#__PURE__*/jsxs(Stack, {
|
|
2406
|
+
gap: "sm",
|
|
2407
|
+
children: [/*#__PURE__*/jsx(TextInput, {
|
|
2408
|
+
label: labels.newEmail || 'Novo Email',
|
|
2409
|
+
placeholder: labels.newEmailPlaceholder || 'Digite o novo email',
|
|
2410
|
+
leftSection: /*#__PURE__*/jsx(IconMail, {
|
|
2411
|
+
size: 16
|
|
2412
|
+
}),
|
|
2413
|
+
...emailForm.getInputProps('newEmail')
|
|
2414
|
+
}), /*#__PURE__*/jsxs(Group, {
|
|
2415
|
+
justify: "flex-end",
|
|
2416
|
+
gap: "sm",
|
|
2417
|
+
children: [/*#__PURE__*/jsx(Button, {
|
|
2418
|
+
variant: "default",
|
|
2419
|
+
size: "xs",
|
|
2420
|
+
onClick: () => handleToggleSection('email'),
|
|
2421
|
+
leftSection: /*#__PURE__*/jsx(IconX, {
|
|
2422
|
+
size: 14
|
|
2423
|
+
}),
|
|
2424
|
+
children: labels.cancel || 'Cancelar'
|
|
2425
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
2426
|
+
type: "submit",
|
|
2427
|
+
size: "xs",
|
|
2428
|
+
loading: loadingChangeEmail,
|
|
2429
|
+
leftSection: /*#__PURE__*/jsx(IconCheck, {
|
|
2430
|
+
size: 14
|
|
2431
|
+
}),
|
|
2432
|
+
children: labels.save || 'Salvar'
|
|
2433
|
+
})]
|
|
2434
|
+
})]
|
|
2435
|
+
})
|
|
2436
|
+
})
|
|
2437
|
+
})
|
|
2438
|
+
})]
|
|
2439
|
+
})]
|
|
2440
|
+
})]
|
|
2441
|
+
}), showPassword && /*#__PURE__*/jsxs(Box, {
|
|
2442
|
+
mb: "md",
|
|
2443
|
+
children: [/*#__PURE__*/jsx(SectionHeader, {
|
|
2444
|
+
icon: IconShield,
|
|
2445
|
+
sectionTitle: labels.securitySection || 'Security',
|
|
2446
|
+
description: labels.securityDescription || 'Protect your account'
|
|
2447
|
+
}), /*#__PURE__*/jsxs(Stack, {
|
|
2448
|
+
gap: "sm",
|
|
2449
|
+
children: [/*#__PURE__*/jsx(SettingRow, {
|
|
2450
|
+
label: labels.password || 'Password',
|
|
2451
|
+
action: labels.change || 'Change',
|
|
2452
|
+
actionLabel: labels.changePassword || 'Change your password',
|
|
2453
|
+
onClick: () => handleToggleSection('password'),
|
|
2454
|
+
expanded: editingSection === 'password',
|
|
2455
|
+
children: /*#__PURE__*/jsxs(Group, {
|
|
2456
|
+
gap: "xs",
|
|
2457
|
+
children: [/*#__PURE__*/jsx(IconKey, {
|
|
2458
|
+
size: 16,
|
|
2459
|
+
color: "var(--mantine-color-dimmed)"
|
|
2460
|
+
}), /*#__PURE__*/jsx(Text, {
|
|
2461
|
+
size: "sm",
|
|
2462
|
+
c: "dimmed",
|
|
2463
|
+
children: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
2464
|
+
})]
|
|
2465
|
+
})
|
|
2466
|
+
}), /*#__PURE__*/jsx(Collapse, {
|
|
2467
|
+
in: editingSection === 'password',
|
|
2468
|
+
children: /*#__PURE__*/jsx(Card, {
|
|
2469
|
+
p: "md",
|
|
2470
|
+
withBorder: true,
|
|
2471
|
+
children: /*#__PURE__*/jsx("form", {
|
|
2472
|
+
onSubmit: passwordForm.onSubmit(handleChangePassword),
|
|
2473
|
+
children: /*#__PURE__*/jsxs(Stack, {
|
|
2474
|
+
gap: "sm",
|
|
2475
|
+
children: [/*#__PURE__*/jsx(PasswordInput, {
|
|
2476
|
+
label: labels.currentPassword || 'Senha Atual',
|
|
2477
|
+
placeholder: labels.currentPasswordPlaceholder || 'Digite sua senha atual',
|
|
2478
|
+
...passwordForm.getInputProps('currentPassword')
|
|
2479
|
+
}), /*#__PURE__*/jsx(PasswordInput, {
|
|
2480
|
+
label: labels.newPassword || 'Nova Senha',
|
|
2481
|
+
placeholder: labels.newPasswordPlaceholder || 'Digite a nova senha',
|
|
2482
|
+
description: labels.passwordDescription || 'Mínimo 8 caracteres',
|
|
2483
|
+
...passwordForm.getInputProps('newPassword')
|
|
2484
|
+
}), /*#__PURE__*/jsx(PasswordInput, {
|
|
2485
|
+
label: labels.confirmPassword || 'Confirmar Nova Senha',
|
|
2486
|
+
placeholder: labels.confirmPasswordPlaceholder || 'Confirme a nova senha',
|
|
2487
|
+
...passwordForm.getInputProps('confirmPassword')
|
|
2488
|
+
}), /*#__PURE__*/jsxs(Group, {
|
|
2489
|
+
justify: "flex-end",
|
|
2490
|
+
gap: "xs",
|
|
2491
|
+
children: [/*#__PURE__*/jsx(Button, {
|
|
2492
|
+
variant: "default",
|
|
2493
|
+
size: "xs",
|
|
2494
|
+
onClick: () => handleToggleSection('password'),
|
|
2495
|
+
leftSection: /*#__PURE__*/jsx(IconX, {
|
|
2496
|
+
size: 14
|
|
2497
|
+
}),
|
|
2498
|
+
children: labels.cancel || 'Cancelar'
|
|
2499
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
2500
|
+
type: "submit",
|
|
2501
|
+
size: "xs",
|
|
2502
|
+
loading: loadingChangePassword,
|
|
2503
|
+
leftSection: /*#__PURE__*/jsx(IconCheck, {
|
|
2504
|
+
size: 14
|
|
2505
|
+
}),
|
|
2506
|
+
children: labels.save || 'Salvar'
|
|
2507
|
+
})]
|
|
2508
|
+
})]
|
|
2509
|
+
})
|
|
2510
|
+
})
|
|
2511
|
+
})
|
|
2512
|
+
})]
|
|
2513
|
+
})]
|
|
2514
|
+
})]
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
export { AccountModal, AuthCard, AuthProvider, ForgotPasswordForm, MagicLinkForm, MagicLinkVerify, ProtectedRoute, ResetPasswordForm, SignInForm, SignUpForm, VerifyEmailCard, changeEmail, changePassword, configure, decodeJWT, forgotPassword, getApplicationInfo, getCurrentUser, getSession, isAuthenticated, refreshToken, resendVerification, resetPassword, sendMagicLink, signIn, signOut, signUp, socialRedirect, updateProfile, useAuth, useAuthLoading, useAuthStore, useCheckToken, useEmailVerification, useMagicLink, usePasswordReset, useProfile, useSession, useSignIn, useSignOut, useSignUp, verifyEmail, verifyMagicLink };
|
|
1732
2519
|
//# sourceMappingURL=index.esm.js.map
|