anima-ds-nucleus 1.0.17 → 1.0.19
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/anima-ds-nucleus.css +1 -1
- package/dist/anima-ds.cjs.js +111 -95
- package/dist/anima-ds.esm.js +3812 -3025
- package/package.json +1 -1
- package/src/components/DataDisplay/Card/CardTituloCorto.jsx +23 -2
- package/src/components/DataDisplay/Card/CardTituloCortoMasEstado.jsx +23 -2
- package/src/components/DataDisplay/Card/CardTituloLargo.jsx +23 -2
- package/src/components/DataDisplay/Card/CardTituloLargoMasEstado.jsx +23 -2
- package/src/components/Inputs/PasswordInput/PasswordInput.jsx +85 -0
- package/src/components/Layout/Header/HeaderConBuscador.stories.jsx +1 -0
- package/src/components/Layout/Header/HeaderCore.jsx +12 -12
- package/src/components/Layout/Header/HeaderGeneral.jsx +28 -2
- package/src/components/Layout/Header/HeaderPoint.jsx +3 -3
- package/src/components/Layout/NavPoint/NavPoint.jsx +36 -21
- package/src/components/Layout/SaludoConFechaDashboard/SaludoConFechaDashboard.jsx +0 -1
- package/src/components/Layout/Sidebar/SidebarCore.jsx +227 -219
- package/src/components/Views/ForgotPassword/ForgotPassword.jsx +341 -0
- package/src/components/Views/ForgotPassword/ForgotPassword.stories.jsx +186 -0
- package/src/components/Views/LoginForm/LoginForm.jsx +332 -43
- package/src/components/Views/LoginForm/LoginForm.stories.jsx +182 -4
- package/src/i18n/config.js +12 -0
- package/src/index.js +1 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Button } from '../../Atoms/Button/Button';
|
|
4
|
+
import { Typography } from '../../Atoms/Typography/Typography';
|
|
5
|
+
import { Icon } from '../../Atoms/Icon/Icon';
|
|
6
|
+
|
|
7
|
+
export const ForgotPassword = ({
|
|
8
|
+
onBackToLogin,
|
|
9
|
+
onSubmit,
|
|
10
|
+
loading: externalLoading,
|
|
11
|
+
error: externalError,
|
|
12
|
+
className = '',
|
|
13
|
+
variant = 'default',
|
|
14
|
+
...props
|
|
15
|
+
}) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
const isHexaLogin = variant === 'hexa-login';
|
|
18
|
+
|
|
19
|
+
// Estados internos (si no se pasan como props)
|
|
20
|
+
const [email, setEmail] = useState('');
|
|
21
|
+
const [errors, setErrors] = useState({});
|
|
22
|
+
const [internalLoading, setInternalLoading] = useState(false);
|
|
23
|
+
const [resetLink, setResetLink] = useState(null);
|
|
24
|
+
const [internalError, setInternalError] = useState(null);
|
|
25
|
+
|
|
26
|
+
// Usar loading externo o interno
|
|
27
|
+
const loading = externalLoading !== undefined ? externalLoading : internalLoading;
|
|
28
|
+
// Usar error externo o interno
|
|
29
|
+
const error = externalError !== undefined ? externalError : internalError;
|
|
30
|
+
|
|
31
|
+
// Funciones de validación
|
|
32
|
+
const hasAtSymbol = (email) => {
|
|
33
|
+
return email && email.includes('@');
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const isValidEmail = (email) => {
|
|
37
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
38
|
+
return emailRegex.test(email);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const validateForm = () => {
|
|
42
|
+
const newErrors = {};
|
|
43
|
+
|
|
44
|
+
if (!email) {
|
|
45
|
+
newErrors.email = t('errors.required') ?? 'Este campo es obligatorio';
|
|
46
|
+
} else if (!isValidEmail(email)) {
|
|
47
|
+
newErrors.email = t('errors.invalidEmail') ?? 'El mail ingresado no es válido';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setErrors(newErrors);
|
|
51
|
+
return Object.keys(newErrors).length === 0;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleEmailChange = (e) => {
|
|
55
|
+
const value = e.target.value;
|
|
56
|
+
setEmail(value);
|
|
57
|
+
|
|
58
|
+
// Limpiar errores al cambiar
|
|
59
|
+
if (errors.email) {
|
|
60
|
+
setErrors((prev) => ({ ...prev, email: null }));
|
|
61
|
+
}
|
|
62
|
+
// Si hay error interno, limpiarlo
|
|
63
|
+
if (internalError) {
|
|
64
|
+
setInternalError(null);
|
|
65
|
+
}
|
|
66
|
+
// Si hay error externo, no lo manejamos aquí (el componente padre debe manejarlo)
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handleSubmit = async (e) => {
|
|
70
|
+
e.preventDefault();
|
|
71
|
+
|
|
72
|
+
if (!validateForm()) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!onSubmit) {
|
|
77
|
+
console.warn('ForgotPassword: onSubmit prop is required');
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Usar loading interno si no se pasa como prop
|
|
82
|
+
if (externalLoading === undefined) {
|
|
83
|
+
setInternalLoading(true);
|
|
84
|
+
}
|
|
85
|
+
setErrors({});
|
|
86
|
+
setInternalError(null);
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await onSubmit({ email, countryCode: null });
|
|
90
|
+
|
|
91
|
+
if (result?.resetLink) {
|
|
92
|
+
setResetLink(result.resetLink);
|
|
93
|
+
} else {
|
|
94
|
+
// Si no hay resetLink pero no hay error, asumir éxito
|
|
95
|
+
setResetLink('success');
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
let errorMessage = t('forgotPassword.errors.sendFailed') ?? 'Error al enviar el link. Intenta nuevamente.';
|
|
99
|
+
|
|
100
|
+
if (err?.response?.status === 404) {
|
|
101
|
+
errorMessage = err?.response?.data?.message ||
|
|
102
|
+
err?.message ||
|
|
103
|
+
'No se encontró una cuenta asociada a este correo electrónico. Por favor, verifica que el correo esté correcto.';
|
|
104
|
+
} else if (err?.response?.status === 400) {
|
|
105
|
+
errorMessage = err?.response?.data?.message ||
|
|
106
|
+
err?.message ||
|
|
107
|
+
'El correo electrónico ingresado no es válido.';
|
|
108
|
+
} else if (err?.response?.status >= 500) {
|
|
109
|
+
errorMessage = 'Error del servidor. Por favor, intenta más tarde.';
|
|
110
|
+
} else if (err?.message) {
|
|
111
|
+
errorMessage = err.message;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (externalError === undefined) {
|
|
115
|
+
setInternalError(errorMessage);
|
|
116
|
+
}
|
|
117
|
+
// Si el error viene como prop, el componente padre lo maneja
|
|
118
|
+
} finally {
|
|
119
|
+
if (externalLoading === undefined) {
|
|
120
|
+
setInternalLoading(false);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div
|
|
127
|
+
className={`min-h-screen flex flex-col ${className}`}
|
|
128
|
+
style={{ backgroundColor: '#f5f5f5' }}
|
|
129
|
+
{...props}
|
|
130
|
+
>
|
|
131
|
+
<div className="flex-1 flex items-center justify-center p-4">
|
|
132
|
+
<div className="w-full max-w-md">
|
|
133
|
+
{/* Título y subtítulo */}
|
|
134
|
+
<div className="mb-8 text-center">
|
|
135
|
+
<Typography
|
|
136
|
+
variant="h3"
|
|
137
|
+
className="mb-2 font-semibold"
|
|
138
|
+
style={{
|
|
139
|
+
color: '#2D5C63',
|
|
140
|
+
fontFamily: 'inherit',
|
|
141
|
+
fontWeight: 400,
|
|
142
|
+
fontStyle: 'normal',
|
|
143
|
+
fontSize: '32px',
|
|
144
|
+
lineHeight: '48px',
|
|
145
|
+
letterSpacing: '0px',
|
|
146
|
+
textAlign: 'center',
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
{t('forgotPassword.title') ?? 'Recuperar contraseña'}
|
|
150
|
+
</Typography>
|
|
151
|
+
<Typography
|
|
152
|
+
variant="body2"
|
|
153
|
+
className="text-gray-600"
|
|
154
|
+
style={{
|
|
155
|
+
fontFamily: 'inherit',
|
|
156
|
+
fontWeight: 400,
|
|
157
|
+
fontStyle: 'normal',
|
|
158
|
+
fontSize: '16px',
|
|
159
|
+
lineHeight: '24px',
|
|
160
|
+
letterSpacing: '0px',
|
|
161
|
+
textAlign: 'center',
|
|
162
|
+
}}
|
|
163
|
+
>
|
|
164
|
+
{t('forgotPassword.subtitle') ?? 'Ingresa tu correo electrónico y te enviaremos un link para restablecer tu contraseña.'}
|
|
165
|
+
</Typography>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
{/* Card blanca */}
|
|
169
|
+
<div className="bg-white border border-gray-200 rounded-lg p-6 shadow-md">
|
|
170
|
+
{/* Estado de éxito */}
|
|
171
|
+
{resetLink && !loading && (
|
|
172
|
+
<div className="text-center space-y-4">
|
|
173
|
+
<div
|
|
174
|
+
className="rounded-lg p-4 border"
|
|
175
|
+
style={{
|
|
176
|
+
backgroundColor: '#d1fae5',
|
|
177
|
+
borderColor: '#10b981',
|
|
178
|
+
}}
|
|
179
|
+
>
|
|
180
|
+
<Typography
|
|
181
|
+
variant="body2"
|
|
182
|
+
className="font-medium"
|
|
183
|
+
style={{ color: '#065f46' }}
|
|
184
|
+
>
|
|
185
|
+
{t('forgotPassword.success.title') ?? 'Link generado'}
|
|
186
|
+
</Typography>
|
|
187
|
+
<Typography
|
|
188
|
+
variant="body2"
|
|
189
|
+
className="mt-2"
|
|
190
|
+
style={{ color: '#047857', fontSize: '14px' }}
|
|
191
|
+
>
|
|
192
|
+
{t('forgotPassword.success.message') ?? 'Se ha generado un link de recuperación. Haz click en el enlace a continuación para restablecer tu contraseña.'}
|
|
193
|
+
</Typography>
|
|
194
|
+
</div>
|
|
195
|
+
{resetLink !== 'success' && (
|
|
196
|
+
<a
|
|
197
|
+
href={resetLink}
|
|
198
|
+
className="inline-block px-4 py-2 rounded-lg font-medium text-white hover:opacity-90 transition-opacity"
|
|
199
|
+
style={{ backgroundColor: '#2D5C63' }}
|
|
200
|
+
>
|
|
201
|
+
{t('forgotPassword.success.linkLabel') ?? 'Ir a restablecer contraseña'}
|
|
202
|
+
</a>
|
|
203
|
+
)}
|
|
204
|
+
</div>
|
|
205
|
+
)}
|
|
206
|
+
|
|
207
|
+
{/* Estado de carga */}
|
|
208
|
+
{loading && (
|
|
209
|
+
<div className="text-center space-y-4">
|
|
210
|
+
<div
|
|
211
|
+
className="rounded-lg p-4 border"
|
|
212
|
+
style={{
|
|
213
|
+
backgroundColor: '#dbeafe',
|
|
214
|
+
borderColor: '#3b82f6',
|
|
215
|
+
}}
|
|
216
|
+
>
|
|
217
|
+
<Typography
|
|
218
|
+
variant="body2"
|
|
219
|
+
className="font-medium"
|
|
220
|
+
style={{ color: '#1e40af' }}
|
|
221
|
+
>
|
|
222
|
+
{t('forgotPassword.sending') ?? 'Enviando...'}
|
|
223
|
+
</Typography>
|
|
224
|
+
<Typography
|
|
225
|
+
variant="body2"
|
|
226
|
+
className="mt-2"
|
|
227
|
+
style={{ color: '#1e3a8a', fontSize: '14px' }}
|
|
228
|
+
>
|
|
229
|
+
{t('forgotPassword.waitingMessage') ?? 'Espera, estamos procesando tu solicitud...'}
|
|
230
|
+
</Typography>
|
|
231
|
+
<Typography
|
|
232
|
+
variant="body2"
|
|
233
|
+
className="mt-2"
|
|
234
|
+
style={{ color: '#1e3a8a', fontSize: '13px' }}
|
|
235
|
+
>
|
|
236
|
+
{t('forgotPassword.waitingSubmessage') ?? 'Hemos enviado un link de recuperación a tu correo. Esto puede tardar unos momentos.'}
|
|
237
|
+
</Typography>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
)}
|
|
241
|
+
|
|
242
|
+
{/* Estado de formulario */}
|
|
243
|
+
{!resetLink && !loading && (
|
|
244
|
+
<>
|
|
245
|
+
{/* Botón volver */}
|
|
246
|
+
{onBackToLogin && (
|
|
247
|
+
<button
|
|
248
|
+
type="button"
|
|
249
|
+
onClick={onBackToLogin}
|
|
250
|
+
className="flex items-center gap-2 mb-6 text-body-md hover:underline font-medium cursor-pointer"
|
|
251
|
+
style={{ color: '#2D5C63' }}
|
|
252
|
+
>
|
|
253
|
+
<Icon name="ArrowLeftIcon" variant="24-outline" size={18} />
|
|
254
|
+
<span>{t('forgotPassword.backToLogin') ?? 'Volver al inicio de sesión'}</span>
|
|
255
|
+
</button>
|
|
256
|
+
)}
|
|
257
|
+
|
|
258
|
+
{/* Formulario */}
|
|
259
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
260
|
+
{/* Input de email */}
|
|
261
|
+
<div>
|
|
262
|
+
<label
|
|
263
|
+
className="block mb-2 font-medium text-sm"
|
|
264
|
+
style={{ color: '#2D5C63' }}
|
|
265
|
+
>
|
|
266
|
+
{t('login.email') ?? t('form.email') ?? 'Correo electrónico'}
|
|
267
|
+
</label>
|
|
268
|
+
<input
|
|
269
|
+
type="email"
|
|
270
|
+
placeholder={t('login.emailPlaceholder') ?? t('placeholder.email') ?? 'Ingresa tu correo electrónico'}
|
|
271
|
+
value={email}
|
|
272
|
+
onChange={handleEmailChange}
|
|
273
|
+
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-sm text-gray-900"
|
|
274
|
+
style={{
|
|
275
|
+
borderColor: errors.email ? '#ef4444' : '#2D5C63',
|
|
276
|
+
borderWidth: '1px',
|
|
277
|
+
borderStyle: 'solid',
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
{errors.email && (
|
|
281
|
+
<p className="mt-1 text-sm text-red-600">{errors.email}</p>
|
|
282
|
+
)}
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
{/* Error general */}
|
|
286
|
+
{error && (
|
|
287
|
+
<div
|
|
288
|
+
className="rounded-lg p-4 border"
|
|
289
|
+
style={{
|
|
290
|
+
backgroundColor: '#fecaca',
|
|
291
|
+
borderColor: '#ef4444',
|
|
292
|
+
}}
|
|
293
|
+
>
|
|
294
|
+
<Typography
|
|
295
|
+
variant="body2"
|
|
296
|
+
className="font-bold"
|
|
297
|
+
style={{ color: '#b91c1c' }}
|
|
298
|
+
>
|
|
299
|
+
{error}
|
|
300
|
+
</Typography>
|
|
301
|
+
</div>
|
|
302
|
+
)}
|
|
303
|
+
|
|
304
|
+
{/* Botón de envío */}
|
|
305
|
+
<div className="pt-4">
|
|
306
|
+
<Button
|
|
307
|
+
tipo="Primary"
|
|
308
|
+
color="Teal"
|
|
309
|
+
tamaño="Default"
|
|
310
|
+
type="submit"
|
|
311
|
+
className="w-full"
|
|
312
|
+
disabled={loading || !hasAtSymbol(email)}
|
|
313
|
+
>
|
|
314
|
+
<span
|
|
315
|
+
style={{
|
|
316
|
+
fontFamily: "'IBM Plex Sans', sans-serif",
|
|
317
|
+
fontWeight: 400,
|
|
318
|
+
fontStyle: 'normal',
|
|
319
|
+
fontSize: '16px',
|
|
320
|
+
lineHeight: '24px',
|
|
321
|
+
letterSpacing: '0%',
|
|
322
|
+
}}
|
|
323
|
+
>
|
|
324
|
+
{loading
|
|
325
|
+
? t('forgotPassword.sending') ?? 'Enviando...'
|
|
326
|
+
: t('forgotPassword.button') ?? 'Enviar link'}
|
|
327
|
+
</span>
|
|
328
|
+
</Button>
|
|
329
|
+
</div>
|
|
330
|
+
</form>
|
|
331
|
+
</>
|
|
332
|
+
)}
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
</div>
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
export default ForgotPassword;
|
|
341
|
+
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { ForgotPassword } from './ForgotPassword';
|
|
2
|
+
import { I18nProvider } from '../../../providers/I18nProvider';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Views/ForgotPassword',
|
|
6
|
+
component: ForgotPassword,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (
|
|
10
|
+
<I18nProvider language="es-AR">
|
|
11
|
+
<Story />
|
|
12
|
+
</I18nProvider>
|
|
13
|
+
),
|
|
14
|
+
],
|
|
15
|
+
argTypes: {
|
|
16
|
+
variant: {
|
|
17
|
+
control: 'select',
|
|
18
|
+
options: ['default', 'hexa-login'],
|
|
19
|
+
description: 'Variante del componente',
|
|
20
|
+
},
|
|
21
|
+
loading: {
|
|
22
|
+
control: 'boolean',
|
|
23
|
+
description: 'Estado de carga',
|
|
24
|
+
},
|
|
25
|
+
error: {
|
|
26
|
+
control: 'text',
|
|
27
|
+
description: 'Error general del servidor',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Estado por defecto
|
|
33
|
+
export const Default = {
|
|
34
|
+
args: {
|
|
35
|
+
onBackToLogin: () => {
|
|
36
|
+
console.log('Back to login clicked');
|
|
37
|
+
alert('Volver al login');
|
|
38
|
+
},
|
|
39
|
+
onSubmit: async ({ email, countryCode }) => {
|
|
40
|
+
console.log('Forgot password data:', { email, countryCode });
|
|
41
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
42
|
+
return { resetLink: 'https://example.com/reset-password' };
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Estado de carga
|
|
48
|
+
export const Loading = {
|
|
49
|
+
args: {
|
|
50
|
+
loading: true,
|
|
51
|
+
onBackToLogin: () => {
|
|
52
|
+
alert('Volver al login');
|
|
53
|
+
},
|
|
54
|
+
onSubmit: async () => {
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Estado de éxito
|
|
61
|
+
export const Success = {
|
|
62
|
+
args: {
|
|
63
|
+
onBackToLogin: () => {
|
|
64
|
+
alert('Volver al login');
|
|
65
|
+
},
|
|
66
|
+
onSubmit: async ({ email }) => {
|
|
67
|
+
console.log('Email:', email);
|
|
68
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
69
|
+
return { resetLink: 'https://example.com/reset-password?token=abc123' };
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Con error del servidor
|
|
75
|
+
export const WithError = {
|
|
76
|
+
args: {
|
|
77
|
+
error: 'No se encontró una cuenta asociada a este correo electrónico.',
|
|
78
|
+
onBackToLogin: () => {
|
|
79
|
+
alert('Volver al login');
|
|
80
|
+
},
|
|
81
|
+
onSubmit: async () => {
|
|
82
|
+
throw new Error('Usuario no encontrado');
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Error 404
|
|
88
|
+
export const Error404 = {
|
|
89
|
+
args: {
|
|
90
|
+
onBackToLogin: () => {
|
|
91
|
+
alert('Volver al login');
|
|
92
|
+
},
|
|
93
|
+
onSubmit: async () => {
|
|
94
|
+
const error = new Error('Not found');
|
|
95
|
+
error.response = { status: 404, data: { message: 'Usuario no encontrado' } };
|
|
96
|
+
throw error;
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Error 400
|
|
102
|
+
export const Error400 = {
|
|
103
|
+
args: {
|
|
104
|
+
onBackToLogin: () => {
|
|
105
|
+
alert('Volver al login');
|
|
106
|
+
},
|
|
107
|
+
onSubmit: async () => {
|
|
108
|
+
const error = new Error('Bad request');
|
|
109
|
+
error.response = { status: 400, data: { message: 'Email inválido' } };
|
|
110
|
+
throw error;
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Error 500
|
|
116
|
+
export const Error500 = {
|
|
117
|
+
args: {
|
|
118
|
+
onBackToLogin: () => {
|
|
119
|
+
alert('Volver al login');
|
|
120
|
+
},
|
|
121
|
+
onSubmit: async () => {
|
|
122
|
+
const error = new Error('Server error');
|
|
123
|
+
error.response = { status: 500 };
|
|
124
|
+
throw error;
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Variante hexa-login
|
|
130
|
+
export const HexaLogin = {
|
|
131
|
+
args: {
|
|
132
|
+
variant: 'hexa-login',
|
|
133
|
+
onBackToLogin: () => {
|
|
134
|
+
alert('Volver al login');
|
|
135
|
+
},
|
|
136
|
+
onSubmit: async ({ email }) => {
|
|
137
|
+
console.log('Email:', email);
|
|
138
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
139
|
+
return { resetLink: 'https://example.com/reset-password' };
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Versión en español
|
|
145
|
+
export const Spanish = {
|
|
146
|
+
decorators: [
|
|
147
|
+
(Story) => (
|
|
148
|
+
<I18nProvider language="es-AR">
|
|
149
|
+
<Story />
|
|
150
|
+
</I18nProvider>
|
|
151
|
+
),
|
|
152
|
+
],
|
|
153
|
+
args: {
|
|
154
|
+
onBackToLogin: () => {
|
|
155
|
+
alert('Volver al login');
|
|
156
|
+
},
|
|
157
|
+
onSubmit: async ({ email }) => {
|
|
158
|
+
console.log('Email:', email);
|
|
159
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
160
|
+
return { resetLink: 'https://example.com/reset-password' };
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// Versión en portugués
|
|
166
|
+
export const Portuguese = {
|
|
167
|
+
decorators: [
|
|
168
|
+
(Story) => (
|
|
169
|
+
<I18nProvider language="pt-BR">
|
|
170
|
+
<Story />
|
|
171
|
+
</I18nProvider>
|
|
172
|
+
),
|
|
173
|
+
],
|
|
174
|
+
args: {
|
|
175
|
+
onBackToLogin: () => {
|
|
176
|
+
alert('Volver ao login');
|
|
177
|
+
},
|
|
178
|
+
onSubmit: async ({ email }) => {
|
|
179
|
+
console.log('Email:', email);
|
|
180
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
181
|
+
return { resetLink: 'https://example.com/reset-password' };
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
|