i18n all the things (#41)
This commit is contained in:
@@ -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 (
|
||||
<div>
|
||||
The page you're looking for is unavailable or there's an error in the URL.
|
||||
Please check the URL and try again.
|
||||
<FormattedMessage
|
||||
id="profile.notfound.message"
|
||||
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again."
|
||||
description="error message when a page does not exist"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<UncontrolledAlert color="info">
|
||||
<h6>Your profile cannot be shared.</h6>
|
||||
<p>
|
||||
To share your profile with other edX learners,
|
||||
you must confirm that you are over the age of 13.
|
||||
</p>
|
||||
<a href={accountURL}>Set your date of birth</a>
|
||||
<FormattedMessage
|
||||
id="profile.age.headline"
|
||||
defaultMessage="Your profile cannot be shared."
|
||||
description="error message"
|
||||
tagName="h6"
|
||||
/>
|
||||
<FormattedMessage
|
||||
id="profile.age.details"
|
||||
defaultMessage="To share your profile with other edX learners, you must confirm that you are over the age of 13."
|
||||
description="error message"
|
||||
tagName="p"
|
||||
/>
|
||||
<a href={accountURL}>
|
||||
<FormattedMessage
|
||||
id="profile.age.set.date"
|
||||
defaultMessage="Set your date of birth"
|
||||
description="label on a link to set birthday"
|
||||
/>
|
||||
</a>
|
||||
</UncontrolledAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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: (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup>
|
||||
<Label for={formId}>About Me</Label>
|
||||
<Label for={formId}>{intl.formatMessage(messages['profile.bio.about.me'])}</Label>
|
||||
<Input
|
||||
type="textarea"
|
||||
id={formId}
|
||||
@@ -77,7 +79,7 @@ class Bio extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="About Me"
|
||||
content={intl.formatMessage(messages['profile.bio.about.me'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibility !== null}
|
||||
@@ -97,7 +99,7 @@ class Bio extends React.Component {
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="About Me" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.bio.about.me'])} />
|
||||
<p className="lead">{value}</p>
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -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));
|
||||
|
||||
11
src/components/ProfilePage/Bio.messages.jsx
Normal file
11
src/components/ProfilePage/Bio.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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: (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<EditableItemHeader content="My Certificates" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.certificates.my.certificates'])} />
|
||||
{this.renderCertificates()}
|
||||
<FormControls
|
||||
formId={formId}
|
||||
@@ -103,7 +105,7 @@ class Certificates extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="My Certificates"
|
||||
content={intl.formatMessage(messages['profile.certificates.my.certificates'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibility !== null}
|
||||
@@ -123,7 +125,7 @@ class Certificates extends React.Component {
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="My Certificates" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.certificates.my.certificates'])} />
|
||||
{this.renderCertificates()}
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -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));
|
||||
|
||||
11
src/components/ProfilePage/Certificates.messages.jsx
Normal file
11
src/components/ProfilePage/Certificates.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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 {
|
||||
<h5>{ALL_COUNTRIES[value]}</h5>
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: <EmptyContent onClick={this.handleOpen}>Add location</EmptyContent>,
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.country.empty"
|
||||
defaultMessage="Add location"
|
||||
description="instructions when the user doesn't have a location set"
|
||||
/>
|
||||
</EmptyContent>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="Location" />
|
||||
|
||||
@@ -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: (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup>
|
||||
<Label for="education">Education</Label>
|
||||
<Label for="education">
|
||||
{intl.formatMessage(messages['profile.education.education'])}
|
||||
</Label>
|
||||
<Input
|
||||
type="select"
|
||||
name={formId}
|
||||
@@ -86,7 +91,7 @@ class Education extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="Education"
|
||||
content={intl.formatMessage(messages['profile.education.education'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibility !== null}
|
||||
@@ -95,10 +100,18 @@ class Education extends React.Component {
|
||||
<h5>{EDUCATION[value]}</h5>
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: <EmptyContent onClick={this.handleOpen}>Add education</EmptyContent>,
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.education.empty"
|
||||
defaultMessage="Add education"
|
||||
description="instructions when the user doesn't have their level of education set"
|
||||
/>
|
||||
</EmptyContent>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="Education" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.education.education'])} />
|
||||
<h5>{EDUCATION[value]}</h5>
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -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));
|
||||
|
||||
11
src/components/ProfilePage/Education.messages.jsx
Normal file
11
src/components/ProfilePage/Education.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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 {
|
||||
<Label for="name">Full Name</Label>
|
||||
<Input type="text" name={formId} value={value} invalid={error != null} onChange={this.handleChange} />
|
||||
<FormText>
|
||||
This is the name that appears in your account and on your certificates.
|
||||
<FormattedMessage
|
||||
id="profile.name.details"
|
||||
defaultMessage="This is the name that appears in your account and on your certificates."
|
||||
description="describes the area for the user to update their name"
|
||||
/>
|
||||
</FormText>
|
||||
<FormFeedback>{error}</FormFeedback>
|
||||
</FormGroup>
|
||||
@@ -75,7 +82,7 @@ class Name extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="Full Name"
|
||||
content={intl.formatMessage(messages['profile.name.full.name'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibility !== null}
|
||||
@@ -84,10 +91,18 @@ class Name extends React.Component {
|
||||
<h5>{value}</h5>
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: <EmptyContent onClick={this.handleOpen}>Add name</EmptyContent>,
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.name.empty"
|
||||
defaultMessage="Add name"
|
||||
description="instructions when the user hasn't entered their name"
|
||||
/>
|
||||
</EmptyContent>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="Full Name" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.name.full.name'])} />
|
||||
<h5>{value}</h5>
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -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));
|
||||
|
||||
11
src/components/ProfilePage/Name.messages.jsx
Normal file
11
src/components/ProfilePage/Name.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="Social Links" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.sociallinks.social.links'])} />
|
||||
<ul className="list-unstyled">
|
||||
{values.map(({ platform, social_link: socialLink }) => (
|
||||
<StaticListItem
|
||||
@@ -110,7 +113,7 @@ class SocialLinks extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="Social Links"
|
||||
content={intl.formatMessage(messages['profile.sociallinks.social.links'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibility !== null}
|
||||
@@ -131,7 +134,7 @@ class SocialLinks extends React.Component {
|
||||
),
|
||||
editing: (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<EditableItemHeader content="Social Links" />
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.sociallinks.social.links'])} />
|
||||
<ul className="list-unstyled">
|
||||
{values.map(({ platform, social_link: socialLink }) => (
|
||||
<EditingListItem
|
||||
@@ -185,6 +188,9 @@ SocialLinks.propTypes = {
|
||||
submitHandler: PropTypes.func.isRequired,
|
||||
closeHandler: PropTypes.func.isRequired,
|
||||
openHandler: PropTypes.func.isRequired,
|
||||
|
||||
// i18n
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
SocialLinks.defaultProps = {
|
||||
@@ -199,7 +205,7 @@ SocialLinks.defaultProps = {
|
||||
export default connect(
|
||||
editableFormSelector,
|
||||
{},
|
||||
)(SocialLinks);
|
||||
)(injectIntl(SocialLinks));
|
||||
|
||||
function SocialLink({ url, name, platform }) {
|
||||
return (
|
||||
@@ -281,7 +287,16 @@ EditingListItem.defaultProps = {
|
||||
function EmptyListItem({ onClick, name }) {
|
||||
return (
|
||||
<li className="mb-4">
|
||||
<EmptyContent onClick={onClick}>Add {name}</EmptyContent>
|
||||
<EmptyContent onClick={onClick}>
|
||||
<FormattedMessage
|
||||
id="profile.sociallinks.add"
|
||||
defaultMessage="Add {network}"
|
||||
values={{
|
||||
network: { name },
|
||||
}}
|
||||
description="{network} is the name of a social network such as Facebook or Twitter"
|
||||
/>
|
||||
</EmptyContent>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
11
src/components/ProfilePage/SocialLinks.messages.jsx
Normal file
11
src/components/ProfilePage/SocialLinks.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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 (
|
||||
<button
|
||||
className={classNames('btn btn-sm btn-link', className)}
|
||||
onClick={onClick}
|
||||
style={style}
|
||||
>
|
||||
<FontAwesomeIcon icon={faPencilAlt} /> Edit
|
||||
<FontAwesomeIcon icon={faPencilAlt} /> {intl.formatMessage(messages['profile.editbutton.edit'])}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
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 = {
|
||||
|
||||
11
src/components/ProfilePage/elements/EditButton.messages.jsx
Normal file
11
src/components/ProfilePage/elements/EditButton.messages.jsx
Normal file
@@ -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;
|
||||
@@ -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 (
|
||||
<Row className="align-items-center flex-wrap-1 pt-3">
|
||||
<Col xs="auto" className="d-flex mb-3">
|
||||
<Label className="flex-shrink-0 d-inline-block mb-0 mr-2" size="sm" for={visibilityId}>
|
||||
Who can see this:
|
||||
{intl.formatMessage(messages['profile.formcontrols.who.can.see'])}
|
||||
</Label>
|
||||
<span>
|
||||
<Input
|
||||
@@ -24,26 +28,26 @@ function FormControls({
|
||||
onChange={changeHandler}
|
||||
>
|
||||
<option key="private" value="private">
|
||||
Just me
|
||||
{intl.formatMessage(messages['profile.formcontrols.who.just.me'])}
|
||||
</option>
|
||||
<option key="all_users" value="all_users">
|
||||
Everyone on edX
|
||||
{intl.formatMessage(messages['profile.formcontrols.who.everyone'])}
|
||||
</option>
|
||||
</Input>
|
||||
</span>
|
||||
</Col>
|
||||
<Col xs="auto" className="flex-grow-1 d-flex justify-content-end mb-3">
|
||||
<Button color="link" onClick={cancelHandler}>
|
||||
Cancel
|
||||
{intl.formatMessage(messages['profile.formcontrols.button.cancel'])}
|
||||
</Button>
|
||||
<AsyncActionButton
|
||||
type="submit"
|
||||
variant={saveState}
|
||||
labels={{
|
||||
default: 'Save',
|
||||
pending: 'Saving',
|
||||
complete: 'Saved',
|
||||
error: 'Save Failed',
|
||||
default: intl.formatMessage(messages['profile.formcontrols.button.save']),
|
||||
pending: intl.formatMessage(messages['profile.formcontrols.button.saving']),
|
||||
complete: intl.formatMessage(messages['profile.formcontrols.button.saved']),
|
||||
error: intl.formatMessage(messages['profile.formcontrols.button.save.failed']),
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user