From 30f158d109a4d2dcbe92dd1a6fd679fa573f3a2d Mon Sep 17 00:00:00 2001 From: albemarle <45690905+albemarle@users.noreply.github.com> Date: Thu, 28 Feb 2019 10:53:39 -0500 Subject: [PATCH] i18n all the things (#41) --- src/components/NotFoundPage.jsx | 8 +++- src/components/ProfilePage/AgeMessage.jsx | 26 ++++++++--- src/components/ProfilePage/Bio.jsx | 17 ++++--- src/components/ProfilePage/Bio.messages.jsx | 11 +++++ src/components/ProfilePage/Certificates.jsx | 17 ++++--- .../ProfilePage/Certificates.messages.jsx | 11 +++++ src/components/ProfilePage/Country.jsx | 11 ++++- src/components/ProfilePage/Education.jsx | 28 ++++++++--- .../ProfilePage/Education.messages.jsx | 11 +++++ src/components/ProfilePage/Name.jsx | 30 +++++++++--- src/components/ProfilePage/Name.messages.jsx | 11 +++++ src/components/ProfilePage/SocialLinks.jsx | 27 ++++++++--- .../ProfilePage/SocialLinks.messages.jsx | 11 +++++ .../ProfilePage/elements/EditButton.jsx | 14 ++++-- .../elements/EditButton.messages.jsx | 11 +++++ .../ProfilePage/elements/FormControls.jsx | 27 +++++++---- .../elements/FormControls.messages.jsx | 46 +++++++++++++++++++ src/i18n/messages/es.json | 3 +- 18 files changed, 267 insertions(+), 53 deletions(-) create mode 100644 src/components/ProfilePage/Bio.messages.jsx create mode 100644 src/components/ProfilePage/Certificates.messages.jsx create mode 100644 src/components/ProfilePage/Education.messages.jsx create mode 100644 src/components/ProfilePage/Name.messages.jsx create mode 100644 src/components/ProfilePage/SocialLinks.messages.jsx create mode 100644 src/components/ProfilePage/elements/EditButton.messages.jsx create mode 100644 src/components/ProfilePage/elements/FormControls.messages.jsx diff --git a/src/components/NotFoundPage.jsx b/src/components/NotFoundPage.jsx index bcd9e5f..10b4e1a 100644 --- a/src/components/NotFoundPage.jsx +++ b/src/components/NotFoundPage.jsx @@ -1,4 +1,5 @@ import React, { Component } from 'react'; +import { FormattedMessage } from 'react-intl'; export default class NotFoundPage extends Component { componentDidMount() {} @@ -6,8 +7,11 @@ export default class NotFoundPage extends Component { render() { return (
- The page you're looking for is unavailable or there's an error in the URL. - Please check the URL and try again. +
); } diff --git a/src/components/ProfilePage/AgeMessage.jsx b/src/components/ProfilePage/AgeMessage.jsx index c2112f8..df187c8 100644 --- a/src/components/ProfilePage/AgeMessage.jsx +++ b/src/components/ProfilePage/AgeMessage.jsx @@ -1,16 +1,30 @@ import React from 'react'; import PropTypes from 'prop-types'; import { UncontrolledAlert } from 'reactstrap'; +import { FormattedMessage } from 'react-intl'; function AgeMessage({ accountURL }) { return ( -
Your profile cannot be shared.
-

- To share your profile with other edX learners, - you must confirm that you are over the age of 13. -

- Set your date of birth + + + + +
); } diff --git a/src/components/ProfilePage/Bio.jsx b/src/components/ProfilePage/Bio.jsx index 9355df5..8e5e347 100644 --- a/src/components/ProfilePage/Bio.jsx +++ b/src/components/ProfilePage/Bio.jsx @@ -2,7 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap'; import { connect } from 'react-redux'; -import { FormattedMessage } from 'react-intl'; +import { injectIntl, intlShape, FormattedMessage } from 'react-intl'; + +import messages from './Bio.messages'; // Components import FormControls from './elements/FormControls'; @@ -43,7 +45,7 @@ class Bio extends React.Component { render() { const { - formId, value, visibility, editMode, saveState, error, + formId, value, visibility, editMode, saveState, error, intl, } = this.props; return ( @@ -54,7 +56,7 @@ class Bio extends React.Component { editing: (
- + - +

{value}

), @@ -126,6 +128,9 @@ Bio.propTypes = { submitHandler: PropTypes.func.isRequired, closeHandler: PropTypes.func.isRequired, openHandler: PropTypes.func.isRequired, + + // i18n + intl: intlShape.isRequired, }; Bio.defaultProps = { @@ -139,4 +144,4 @@ Bio.defaultProps = { export default connect( editableFormSelector, {}, -)(Bio); +)(injectIntl(Bio)); diff --git a/src/components/ProfilePage/Bio.messages.jsx b/src/components/ProfilePage/Bio.messages.jsx new file mode 100644 index 0000000..83db328 --- /dev/null +++ b/src/components/ProfilePage/Bio.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.bio.about.me': { + id: 'profile.bio.about.me', + defaultMessage: 'About Me', + description: 'A section of a user profile', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/Certificates.jsx b/src/components/ProfilePage/Certificates.jsx index 5b545c3..aff4200 100644 --- a/src/components/ProfilePage/Certificates.jsx +++ b/src/components/ProfilePage/Certificates.jsx @@ -1,11 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedMessage } from 'react-intl'; +import { injectIntl, intlShape, FormattedMessage } from 'react-intl'; import { Row, Col, Card, CardBody, CardTitle, Button, Form } from 'reactstrap'; import { connect } from 'react-redux'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faDownload } from '@fortawesome/free-solid-svg-icons'; +import messages from './Certificates.messages'; + // Components import FormControls from './elements/FormControls'; import EditableItemHeader from './elements/EditableItemHeader'; @@ -79,7 +81,7 @@ class Certificates extends React.Component { render() { const { - formId, visibility, editMode, saveState, + formId, visibility, editMode, saveState, intl, } = this.props; return ( @@ -89,7 +91,7 @@ class Certificates extends React.Component { cases={{ editing: ( - + {this.renderCertificates()} - + {this.renderCertificates()} ), @@ -153,6 +155,9 @@ Certificates.propTypes = { submitHandler: PropTypes.func.isRequired, closeHandler: PropTypes.func.isRequired, openHandler: PropTypes.func.isRequired, + + // i18n + intl: intlShape.isRequired, }; Certificates.defaultProps = { @@ -165,4 +170,4 @@ Certificates.defaultProps = { export default connect( certificatesSelector, {}, -)(Certificates); +)(injectIntl(Certificates)); diff --git a/src/components/ProfilePage/Certificates.messages.jsx b/src/components/ProfilePage/Certificates.messages.jsx new file mode 100644 index 0000000..26a582c --- /dev/null +++ b/src/components/ProfilePage/Certificates.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.certificates.my.certificates': { + id: 'profile.certificates.my.certificates', + defaultMessage: 'My Certificates', + description: 'A section of a user profile', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/Country.jsx b/src/components/ProfilePage/Country.jsx index a41a4d8..9c49f59 100644 --- a/src/components/ProfilePage/Country.jsx +++ b/src/components/ProfilePage/Country.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap'; import { connect } from 'react-redux'; +import { FormattedMessage } from 'react-intl'; // Components import FormControls from './elements/FormControls'; @@ -95,7 +96,15 @@ class Country extends React.Component {
{ALL_COUNTRIES[value]}
), - empty: Add location, + empty: ( + + + + ), static: ( diff --git a/src/components/ProfilePage/Education.jsx b/src/components/ProfilePage/Education.jsx index 86e7f75..148066c 100644 --- a/src/components/ProfilePage/Education.jsx +++ b/src/components/ProfilePage/Education.jsx @@ -2,6 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Form, FormFeedback, FormGroup, Input, Label } from 'reactstrap'; import { connect } from 'react-redux'; +import { FormattedMessage, injectIntl, intlShape } from 'react-intl'; + +import messages from './Education.messages'; // Components import FormControls from './elements/FormControls'; @@ -48,7 +51,7 @@ class Education extends React.Component { render() { const { - formId, value, visibility, editMode, saveState, error, + formId, value, visibility, editMode, saveState, error, intl, } = this.props; return ( @@ -59,7 +62,9 @@ class Education extends React.Component { editing: ( - + {EDUCATION[value]} ), - empty: Add education, + empty: ( + + + + ), static: ( - +
{EDUCATION[value]}
), @@ -127,6 +140,9 @@ Education.propTypes = { submitHandler: PropTypes.func.isRequired, closeHandler: PropTypes.func.isRequired, openHandler: PropTypes.func.isRequired, + + // i18n + intl: intlShape.isRequired, }; Education.defaultProps = { @@ -140,4 +156,4 @@ Education.defaultProps = { export default connect( editableFormSelector, {}, -)(Education); +)(injectIntl(Education)); diff --git a/src/components/ProfilePage/Education.messages.jsx b/src/components/ProfilePage/Education.messages.jsx new file mode 100644 index 0000000..b350220 --- /dev/null +++ b/src/components/ProfilePage/Education.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.education.education': { + id: 'profile.education.education', + defaultMessage: 'Education', + description: 'A section of a user profile', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/Name.jsx b/src/components/ProfilePage/Name.jsx index e7db1d7..8e335dc 100644 --- a/src/components/ProfilePage/Name.jsx +++ b/src/components/ProfilePage/Name.jsx @@ -2,6 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Form, FormFeedback, FormGroup, FormText, Input, Label } from 'reactstrap'; import { connect } from 'react-redux'; +import { injectIntl, intlShape, FormattedMessage } from 'react-intl'; + +import messages from './Name.messages'; // Components import FormControls from './elements/FormControls'; @@ -45,7 +48,7 @@ class Name extends React.Component { render() { const { - formId, value, visibility, editMode, saveState, error, + formId, value, visibility, editMode, saveState, error, intl, } = this.props; return ( @@ -59,7 +62,11 @@ class Name extends React.Component { - This is the name that appears in your account and on your certificates. + {error}
@@ -75,7 +82,7 @@ class Name extends React.Component { editable: ( {value} ), - empty: Add name, + empty: ( + + + + ), static: ( - +
{value}
), @@ -116,6 +131,9 @@ Name.propTypes = { submitHandler: PropTypes.func.isRequired, closeHandler: PropTypes.func.isRequired, openHandler: PropTypes.func.isRequired, + + // i18n + intl: intlShape.isRequired, }; Name.defaultProps = { @@ -129,4 +147,4 @@ Name.defaultProps = { export default connect( editableFormSelector, {}, -)(Name); +)(injectIntl(Name)); diff --git a/src/components/ProfilePage/Name.messages.jsx b/src/components/ProfilePage/Name.messages.jsx new file mode 100644 index 0000000..7cdf91a --- /dev/null +++ b/src/components/ProfilePage/Name.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.name.full.name': { + id: 'profile.name.full.name', + defaultMessage: 'Full Name', + description: 'A section of a user profile', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/SocialLinks.jsx b/src/components/ProfilePage/SocialLinks.jsx index 7d7aa20..a4a6294 100644 --- a/src/components/ProfilePage/SocialLinks.jsx +++ b/src/components/ProfilePage/SocialLinks.jsx @@ -4,6 +4,9 @@ import { Form, Input, FormFeedback } from 'reactstrap'; import { connect } from 'react-redux'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTwitter, faFacebook, faLinkedin } from '@fortawesome/free-brands-svg-icons'; +import { injectIntl, intlShape, FormattedMessage } from 'react-intl'; + +import messages from './SocialLinks.messages'; // Components import FormControls from './elements/FormControls'; @@ -73,7 +76,7 @@ class SocialLinks extends React.Component { render() { const { - formId, value: values, visibility, editMode, saveState, error, + formId, value: values, visibility, editMode, saveState, error, intl, } = this.props; return ( @@ -94,7 +97,7 @@ class SocialLinks extends React.Component { ), static: ( - +
    {values.map(({ platform, social_link: socialLink }) => ( - +
      {values.map(({ platform, social_link: socialLink }) => ( - Add {name} + + + ); } diff --git a/src/components/ProfilePage/SocialLinks.messages.jsx b/src/components/ProfilePage/SocialLinks.messages.jsx new file mode 100644 index 0000000..feb2c43 --- /dev/null +++ b/src/components/ProfilePage/SocialLinks.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.sociallinks.social.links': { + id: 'profile.sociallinks.social.links', + defaultMessage: 'Social Links', + description: 'A section of a user profile', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/elements/EditButton.jsx b/src/components/ProfilePage/elements/EditButton.jsx index b3efc02..9920730 100644 --- a/src/components/ProfilePage/elements/EditButton.jsx +++ b/src/components/ProfilePage/elements/EditButton.jsx @@ -3,25 +3,33 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPencilAlt } from '@fortawesome/free-solid-svg-icons'; +import { injectIntl, intlShape } from 'react-intl'; -function EditButton({ onClick, className, style }) { +import messages from './EditButton.messages'; + +function EditButton({ + onClick, className, style, intl, +}) { return ( ); } -export default EditButton; +export default injectIntl(EditButton); EditButton.propTypes = { onClick: PropTypes.func.isRequired, className: PropTypes.string, style: PropTypes.object, // eslint-disable-line + + // i18n + intl: intlShape.isRequired, }; EditButton.defaultProps = { diff --git a/src/components/ProfilePage/elements/EditButton.messages.jsx b/src/components/ProfilePage/elements/EditButton.messages.jsx new file mode 100644 index 0000000..63b5c3d --- /dev/null +++ b/src/components/ProfilePage/elements/EditButton.messages.jsx @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.editbutton.edit': { + id: 'profile.editbutton.edit', + defaultMessage: 'Edit', + description: 'A button label', + }, +}); + +export default messages; diff --git a/src/components/ProfilePage/elements/FormControls.jsx b/src/components/ProfilePage/elements/FormControls.jsx index c6ae689..ea59766 100644 --- a/src/components/ProfilePage/elements/FormControls.jsx +++ b/src/components/ProfilePage/elements/FormControls.jsx @@ -1,17 +1,21 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Input, Button, Label, Row, Col } from 'reactstrap'; +import { injectIntl, intlShape } from 'react-intl'; + +import messages from './FormControls.messages'; + import AsyncActionButton from './AsyncActionButton'; function FormControls({ - formId, cancelHandler, changeHandler, visibility, saveState, + formId, cancelHandler, changeHandler, visibility, saveState, intl, }) { const visibilityId = `${formId}-visibility`; return ( @@ -51,7 +55,7 @@ function FormControls({ ); } -export default FormControls; +export default injectIntl(FormControls); FormControls.propTypes = { formId: PropTypes.string.isRequired, @@ -59,6 +63,9 @@ FormControls.propTypes = { visibility: PropTypes.oneOf(['private', 'all_users']), cancelHandler: PropTypes.func.isRequired, changeHandler: PropTypes.func.isRequired, + + // i18n + intl: intlShape.isRequired, }; FormControls.defaultProps = { diff --git a/src/components/ProfilePage/elements/FormControls.messages.jsx b/src/components/ProfilePage/elements/FormControls.messages.jsx new file mode 100644 index 0000000..12dcea3 --- /dev/null +++ b/src/components/ProfilePage/elements/FormControls.messages.jsx @@ -0,0 +1,46 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + 'profile.formcontrols.who.can.see': { + id: 'profile.formcontrols.who.can.see', + defaultMessage: 'Who can see this:', + description: 'What users can see this area?', + }, + 'profile.formcontrols.who.just.me': { + id: 'profile.formcontrols.who.just.me', + defaultMessage: 'Just me', + description: 'What users can see this area?', + }, + 'profile.formcontrols.who.everyone': { + id: 'profile.formcontrols.who.everyone', + defaultMessage: 'Everyone on edX', + description: 'What users can see this area?', + }, + 'profile.formcontrols.button.cancel': { + id: 'profile.formcontrols.button.cancel', + defaultMessage: 'Cancel', + description: 'A button label', + }, + 'profile.formcontrols.button.save': { + id: 'profile.formcontrols.button.save', + defaultMessage: 'Save', + description: 'A button label', + }, + 'profile.formcontrols.button.saving': { + id: 'profile.formcontrols.button.saving', + defaultMessage: 'Saving', + description: 'A button label', + }, + 'profile.formcontrols.button.saved': { + id: 'profile.formcontrols.button.saved', + defaultMessage: 'Saved', + description: 'A button label', + }, + 'profile.formcontrols.button.save.failed': { + id: 'profile.formcontrols.button.save.failed', + defaultMessage: 'Save Failed', + description: 'A button label', + }, +}); + +export default messages; diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index 1807a5b..9d91a98 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -1,4 +1,5 @@ { "profile.no.certificates": "Aún no tienes ningún certificado.", - "profile.bio.empty": "Añada una breve biografía" + "profile.bio.about.me": "Sobre Mi", + "profile.bio.empty": "Añade una breve biografía" }