Skip to content

Commit ff40de3

Browse files
authored
Spanish Translation: Reset password Form and View (#1545)
* Reset Password Form using login view translation keys * reduxFormUtils.js with i18 functionality to translate validations
1 parent 9694719 commit ff40de3

File tree

5 files changed

+96
-45
lines changed

5 files changed

+96
-45
lines changed

client/modules/User/components/ResetPasswordForm.jsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
3-
3+
import { withTranslation } from 'react-i18next';
44
import { domOnlyProps } from '../../../utils/reduxFormUtils';
55
import Button from '../../../common/Button';
66

77
function ResetPasswordForm(props) {
88
const {
9-
fields: { email }, handleSubmit, submitting, invalid, pristine
9+
fields: { email }, handleSubmit, submitting, invalid, pristine, t
1010
} = props;
1111
return (
1212
<form className="form" onSubmit={handleSubmit(props.initiateResetPassword.bind(this))}>
1313
<p className="form__field">
14-
<label htmlFor="email" className="form__label">Email used for registration</label>
14+
<label htmlFor="email" className="form__label">{t('ResetPasswordForm.Email')}</label>
1515
<input
1616
className="form__input"
17-
aria-label="email"
17+
aria-label={t('ResetPasswordForm.EmailARIA')}
1818
type="text"
1919
id="email"
2020
{...domOnlyProps(email)}
@@ -24,7 +24,7 @@ function ResetPasswordForm(props) {
2424
<Button
2525
type="submit"
2626
disabled={submitting || invalid || pristine || props.user.resetPasswordInitiate}
27-
>Send Password Reset Email
27+
>{t('ResetPasswordForm.Submit')}
2828
</Button>
2929
</form>
3030
);
@@ -41,7 +41,8 @@ ResetPasswordForm.propTypes = {
4141
pristine: PropTypes.bool,
4242
user: PropTypes.shape({
4343
resetPasswordInitiate: PropTypes.bool
44-
}).isRequired
44+
}).isRequired,
45+
t: PropTypes.func.isRequired
4546
};
4647

4748
ResetPasswordForm.defaultProps = {
@@ -50,4 +51,4 @@ ResetPasswordForm.defaultProps = {
5051
invalid: false
5152
};
5253

53-
export default ResetPasswordForm;
54+
export default withTranslation()(ResetPasswordForm);

client/modules/User/pages/ResetPasswordView.jsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import classNames from 'classnames';
66
import { bindActionCreators } from 'redux';
77
import { reduxForm } from 'redux-form';
88
import { Helmet } from 'react-helmet';
9+
import { withTranslation } from 'react-i18next';
910
import * as UserActions from '../actions';
1011
import ResetPasswordForm from '../components/ResetPasswordForm';
1112
import { validateResetPassword } from '../../../utils/reduxFormUtils';
@@ -23,19 +24,18 @@ function ResetPasswordView(props) {
2324
<Nav layout="dashboard" />
2425
<div className={resetPasswordClass}>
2526
<Helmet>
26-
<title>p5.js Web Editor | Reset Password</title>
27+
<title>{props.t('ResetPasswordView.Title')}</title>
2728
</Helmet>
2829
<div className="form-container__content">
29-
<h2 className="form-container__title">Reset Your Password</h2>
30+
<h2 className="form-container__title">{props.t('ResetPasswordView.Reset')}</h2>
3031
<ResetPasswordForm {...props} />
3132
<p className="reset-password__submitted">
32-
Your password reset email should arrive shortly. If you don&apos;t see it, check
33-
in your spam folder as sometimes it can end up there.
33+
{props.t('ResetPasswordView.Submitted')}
3434
</p>
3535
<p className="form__navigation-options">
36-
<Link className="form__login-button" to="/login">Log In</Link>
37-
&nbsp;or&nbsp;
38-
<Link className="form__signup-button" to="/signup">Sign Up</Link>
36+
<Link className="form__login-button" to="/login">{props.t('ResetPasswordView.Login')}</Link>
37+
&nbsp;{props.t('ResetPasswordView.LoginOr')}&nbsp;
38+
<Link className="form__signup-button" to="/signup">{props.t('ResetPasswordView.SignUp')}</Link>
3939
</p>
4040
</div>
4141
</div>
@@ -48,6 +48,7 @@ ResetPasswordView.propTypes = {
4848
user: PropTypes.shape({
4949
resetPasswordInitiate: PropTypes.bool
5050
}).isRequired,
51+
t: PropTypes.func.isRequired
5152
};
5253

5354
function mapStateToProps(state) {
@@ -60,8 +61,8 @@ function mapDispatchToProps(dispatch) {
6061
return bindActionCreators(UserActions, dispatch);
6162
}
6263

63-
export default reduxForm({
64+
export default withTranslation()(reduxForm({
6465
form: 'reset-password',
6566
fields: ['email'],
6667
validate: validateResetPassword
67-
}, mapStateToProps, mapDispatchToProps)(ResetPasswordView);
68+
}, mapStateToProps, mapDispatchToProps)(ResetPasswordView));

client/utils/reduxFormUtils.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable */
2+
import i18n from 'i18next';
23
export const domOnlyProps = ({
34
initialValue,
45
autofill,
@@ -20,19 +21,19 @@ const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))
2021

2122
function validateNameEmail(formProps, errors) {
2223
if (!formProps.username) {
23-
errors.username = 'Please enter a username.';
24+
errors.username = i18n.t('ReduxFormUtils.errorEmptyUsername');
2425
} else if (!formProps.username.match(/^.{1,20}$/)) {
25-
errors.username = 'Username must be less than 20 characters.';
26+
errors.username = i18n.t('ReduxFormUtils.errorLongUsername');
2627
} else if (!formProps.username.match(/^[a-zA-Z0-9._-]{1,20}$/)) {
27-
errors.username = 'Username must only consist of numbers, letters, periods, dashes, and underscores.';
28+
errors.username = i18n.t('ReduxFormUtils.errorValidUsername');
2829
}
2930

3031
if (!formProps.email) {
31-
errors.email = 'Please enter an email.';
32+
errors.email = i18n.t('ReduxFormUtils.errorEmptyEmail');
3233
} else if (
3334
// eslint-disable-next-line max-len
3435
!formProps.email.match(EMAIL_REGEX)) {
35-
errors.email = 'Please enter a valid email address.';
36+
errors.email = i18n.t('ReduxFormUtils.errorInvalidEmail');
3637
}
3738
}
3839

@@ -42,21 +43,21 @@ export function validateSettings(formProps) {
4243
validateNameEmail(formProps, errors);
4344

4445
if (formProps.currentPassword && !formProps.newPassword) {
45-
errors.newPassword = 'Please enter a new password or leave the current password empty.';
46+
errors.newPassword = i18n.t('ReduxFormUtils.errorNewPassword');
4647
}
4748
if (formProps.newPassword && formProps.newPassword.length < 6) {
48-
errors.newPassword = 'Password must be at least 6 characters';
49+
errors.newPassword = i18n.t('ReduxFormUtils.errorShortPassword');
4950
}
5051
return errors;
5152
}
5253

5354
export function validateLogin(formProps) {
5455
const errors = {};
5556
if (!formProps.email) {
56-
errors.email = 'Please enter an email';
57+
errors.email = i18n.t('ReduxFormUtils.errorEmptyEmail');
5758
}
5859
if (!formProps.password) {
59-
errors.password = 'Please enter a password';
60+
errors.password = i18n.t('ReduxFormUtils.errorEmptyPassword');
6061
}
6162
return errors;
6263
}
@@ -67,29 +68,29 @@ export function validateSignup(formProps) {
6768
validateNameEmail(formProps, errors);
6869

6970
if (!formProps.password) {
70-
errors.password = 'Please enter a password';
71+
errors.password = i18n.t('ReduxFormUtils.errorEmptyPassword');
7172
}
7273
if (formProps.password && formProps.password.length < 6) {
73-
errors.password = 'Password must be at least 6 characters';
74+
errors.password = i18n.t('ReduxFormUtils.errorShortPassword');
7475
}
7576
if (!formProps.confirmPassword) {
76-
errors.confirmPassword = 'Please enter a password confirmation';
77+
errors.confirmPassword = i18n.t('ReduxFormUtils.errorConfirmPassword');
7778
}
7879

7980
if (formProps.password !== formProps.confirmPassword && formProps.confirmPassword) {
80-
errors.confirmPassword = 'Passwords must match';
81+
errors.confirmPassword = i18n.t('ReduxFormUtils.errorPasswordMismatch');
8182
}
8283

8384
return errors;
8485
}
8586
export function validateResetPassword(formProps) {
8687
const errors = {};
8788
if (!formProps.email) {
88-
errors.email = 'Please enter an email.';
89+
errors.email = i18n.t('ReduxFormUtils.errorEmptyEmail');
8990
} else if (
9091
// eslint-disable-next-line max-len
9192
!formProps.email.match(EMAIL_REGEX)) {
92-
errors.email = 'Please enter a valid email address.';
93+
errors.email = i18n.t('ReduxFormUtils.errorInvalidEmail');
9394
}
9495
return errors;
9596
}

translations/locales/en-US/translations.json

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,21 +183,20 @@
183183
"Error": "Error",
184184
"Save": "Save",
185185
"p5logoARIA": "p5.js Logo"
186-
187186
},
188187
"IDEView": {
189188
"SubmitFeedback": "Submit Feedback"
190189
},
191190
"NewFileModal": {
192191
"Title": "Create File",
193-
"CloseButtonARIA": "Close New File Modal",
192+
"CloseButtonARIA": "Close New File Modal",
194193
"EnterName": "Please enter a name",
195194
"InvalidType": "Invalid file type. Valid extensions are .js, .css, .json, .txt, .csv, .tsv, .frag, and .vert."
196195
},
197196
"NewFileForm": {
198-
"AddFileSubmit": "Add File",
197+
"AddFileSubmit": "Add File",
199198
"Placeholder": "Name"
200-
},
199+
},
201200
"NewFolderModal": {
202201
"Title": "Create Folder",
203202
"CloseButtonARIA": "Close New Folder Modal",
@@ -208,5 +207,30 @@
208207
"NewFolderForm": {
209208
"AddFolderSubmit": "Add Folder",
210209
"Placeholder": "Name"
210+
},
211+
"ResetPasswordForm": {
212+
"Email": "Email used for registration",
213+
"EmailARIA": "email",
214+
"Submit": "Send Password Reset Email"
215+
},
216+
"ResetPasswordView": {
217+
"Title": "p5.js Web Editor | Reset Password",
218+
"Reset": "Reset Your Password",
219+
"Submitted": "Your password reset email should arrive shortly. If you don't see it, check\n in your spam folder as sometimes it can end up there.",
220+
"Login": "Log In",
221+
"LoginOr": "or",
222+
"SignUp": "Sign Up"
223+
},
224+
"ReduxFormUtils": {
225+
"errorInvalidEmail": "Please enter a valid email address",
226+
"errorEmptyEmail": "Please enter an email",
227+
"errorPasswordMismatch": "Passwords must match",
228+
"errorEmptyPassword": "Please enter a password",
229+
"errorShortPassword": "Password must be at least 6 characters",
230+
"errorConfirmPassword": "Please enter a password confirmation",
231+
"errorNewPassword": "Please enter a new password or leave the current password empty.",
232+
"errorEmptyUsername": "Please enter a username.",
233+
"errorLongUsername": "Username must be less than 20 characters.",
234+
"errorValidUsername": "Username must only consist of numbers, letters, periods, dashes, and underscores."
211235
}
212236
}

translations/locales/es-419/translations.json

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@
188188
"SubmitFeedback": "Enviar retroalimentación"
189189
},
190190
"NewFileModal": {
191-
"Title": "Crear Archivo",
192-
"CloseButtonARIA": "Cerrar diálogo de crear archivo",
191+
"Title": "Crear Archivo",
192+
"CloseButtonARIA": "Cerrar diálogo de crear archivo",
193193
"EnterName": "Por favor introduce un nombre",
194194
"InvalidType": "Tipo de archivo inválido. Las extensiones válidas son .js, .css, .json, .txt, .csv, .tsv, .frag y .vert."
195195
},
@@ -198,18 +198,42 @@
198198
"Placeholder": "Nombre"
199199
},
200200
"NewFolderModal": {
201-
"Title": "Crear Directorio",
202-
"CloseButtonARIA": "Cerrar Diálogo de Nuevo Directorio",
203-
"EnterName": "Por favor introduce un nombre",
204-
"EmptyName": " El nombre del directorio no debe contener solo espacios vacíos",
205-
"InvalidExtension": "El nombre del directorio no debe contener una extensión"
206-
},
201+
"Title": "Crear Directorio",
202+
"CloseButtonARIA": "Cerrar Diálogo de Nuevo Directorio",
203+
"EnterName": "Por favor introduce un nombre",
204+
"EmptyName": " El nombre del directorio no debe contener solo espacios vacíos",
205+
"InvalidExtension": "El nombre del directorio no debe contener una extensión"
206+
},
207207
"NewFolderForm": {
208208
"AddFolderSubmit": "Agregar Directorio",
209209
"Placeholder": "Nombre"
210+
},
211+
"ResetPasswordForm": {
212+
"Email": "Correo electrónico usado al registrarse",
213+
"EmailARIA": "correo electrónico",
214+
"Submit": "Enviar correo para regenerar contraseña"
215+
},
216+
"ResetPasswordView": {
217+
"Title": "Editor Web p5.js | Regenerar Contraseña",
218+
"Reset": "Regenerar Contraseña",
219+
"Submitted": "Your password reset email should arrive shortly. If you don't see it, check\n in your spam folder as sometimes it can end up there.",
220+
"Login": "Ingresa",
221+
"LoginOr": "o",
222+
"SignUp": "Registráte"
223+
},
224+
"ReduxFormUtils": {
225+
"errorInvalidEmail": "Por favor introduce un correo electrónico válido",
226+
"errorEmptyEmail": "Por favor introduce un correo electrónico",
227+
"errorPasswordMismatch": "Las contraseñas deben coincidir",
228+
"errorEmptyPassword": "Por favor introduce una contraseña",
229+
"errorShortPassword": "La contraseña debe tener al menos 6 caracteres",
230+
"errorConfirmPassword": "Por favor confirma una contraseña",
231+
"errorNewPassword": "Por favor introduce una nueva contraseña o deja la actual contraseña vacía",
232+
"errorEmptyUsername": "Por favor introduce tu identificación",
233+
"errorLongUsername": "La identificación debe ser menor a 20 caracteres.",
234+
"errorValidUsername": "La identificación debe consistir solamente de números, letras, puntos, guiones y guiones bajos."
235+
210236
}
211237
}
212238

213239

214-
215-

0 commit comments

Comments
 (0)