fix: ui polish (#79)
* fix: change label of language to primary language spoken * fix: add labels to top of empty states * fix: add help text to name field in editable or empty states * fix: move repeated messages into separate files * fix: translate missed string
This commit is contained in:
@@ -191,7 +191,7 @@ export class ProfilePage extends React.Component {
|
||||
{...commonFormProps}
|
||||
/>
|
||||
</Col>
|
||||
<Col md={8} className="pt-md-3">
|
||||
<Col md={8} lg={{ size: 8, offset: 1 }} className="pt-md-3">
|
||||
{shouldShowAgeMessage ? <AgeMessage accountURL="#account" /> : null}
|
||||
<Bio
|
||||
bio={bio}
|
||||
|
||||
@@ -94,13 +94,16 @@ class Bio extends React.Component {
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.bio.empty"
|
||||
defaultMessage="Add a short bio"
|
||||
description="instructions when the user hasn't written an About Me"
|
||||
/>
|
||||
</EmptyContent>
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.bio.about.me'])} />
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.bio.empty"
|
||||
defaultMessage="Add a short bio"
|
||||
description="instructions when the user hasn't written an About Me"
|
||||
/>
|
||||
</EmptyContent>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
|
||||
@@ -148,7 +148,7 @@ class Certificates extends React.Component {
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content={intl.formatMessage(messages['profile.certificates.my.certificates'])}
|
||||
showEditButton
|
||||
@@ -157,7 +157,7 @@ class Certificates extends React.Component {
|
||||
visibility={visibilityCourseCertificates}
|
||||
/>
|
||||
{this.renderCertificates()}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
|
||||
@@ -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 } from 'react-intl';
|
||||
|
||||
import messages from './Country.messages';
|
||||
|
||||
// Components
|
||||
import FormControls from './elements/FormControls';
|
||||
@@ -49,7 +51,7 @@ class Country extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
formId, country, visibilityCountry, editMode, saveState, error,
|
||||
formId, country, visibilityCountry, editMode, saveState, error, intl,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -62,11 +64,7 @@ class Country extends React.Component {
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup>
|
||||
<Label for="country" id={`${formId}-label`}>
|
||||
<FormattedMessage
|
||||
id="profile.country.label"
|
||||
defaultMessage="Location"
|
||||
description="Location form label"
|
||||
/>
|
||||
{intl.formatMessage(messages['profile.country.label'])}
|
||||
</Label>
|
||||
<Input
|
||||
type="select"
|
||||
@@ -97,7 +95,7 @@ class Country extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content="Location"
|
||||
content={intl.formatMessage(messages['profile.country.label'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibilityCountry !== null}
|
||||
@@ -107,17 +105,20 @@ class Country extends React.Component {
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.country.empty"
|
||||
defaultMessage="Add location"
|
||||
description="instructions when the user doesn't have a location set"
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content={intl.formatMessage(messages['profile.country.label'])}
|
||||
/>
|
||||
</EmptyContent>
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
{intl.formatMessage(messages['profile.country.empty'])}
|
||||
</EmptyContent>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content="Location" />
|
||||
<EditableItemHeader
|
||||
content={intl.formatMessage(messages['profile.country.label'])}
|
||||
/>
|
||||
<p className="h5">{ALL_COUNTRIES[country]}</p>
|
||||
</React.Fragment>
|
||||
),
|
||||
@@ -146,6 +147,9 @@ Country.propTypes = {
|
||||
submitHandler: PropTypes.func.isRequired,
|
||||
closeHandler: PropTypes.func.isRequired,
|
||||
openHandler: PropTypes.func.isRequired,
|
||||
|
||||
// i18n
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
Country.defaultProps = {
|
||||
@@ -159,4 +163,4 @@ Country.defaultProps = {
|
||||
export default connect(
|
||||
editableFormSelector,
|
||||
{},
|
||||
)(Country);
|
||||
)(injectIntl(Country));
|
||||
|
||||
16
src/components/ProfilePage/Country.messages.jsx
Normal file
16
src/components/ProfilePage/Country.messages.jsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
'profile.country.label': {
|
||||
id: 'profile.country.label',
|
||||
defaultMessage: 'Location',
|
||||
description: 'The label for a country in a user profile.',
|
||||
},
|
||||
'profile.country.empty': {
|
||||
id: 'profile.country.empty',
|
||||
defaultMessage: 'Add location',
|
||||
description: 'The affordance to add country location to a user’s profile.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -105,13 +105,16 @@ class Education extends React.Component {
|
||||
</React.Fragment>
|
||||
),
|
||||
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>
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.education.education'])} />
|
||||
<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>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
|
||||
@@ -2,7 +2,7 @@ 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 { injectIntl, intlShape } from 'react-intl';
|
||||
|
||||
import messages from './Name.messages';
|
||||
|
||||
@@ -60,7 +60,9 @@ class Name extends React.Component {
|
||||
<div role="dialog" aria-labelledby={`${formId}-label`}>
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup>
|
||||
<Label for="name" id={`${formId}-label`}>Full Name</Label>
|
||||
<Label for="name" id={`${formId}-label`}>
|
||||
{intl.formatMessage(messages['profile.name.full.name'])}
|
||||
</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id={formId}
|
||||
@@ -71,11 +73,7 @@ class Name extends React.Component {
|
||||
aria-describedby={`${formId}-error-feedback ${formId}-help-text`}
|
||||
/>
|
||||
<FormText id={`${formId}-help-text`}>
|
||||
<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"
|
||||
/>
|
||||
{intl.formatMessage(messages['profile.name.details'])}
|
||||
</FormText>
|
||||
<FormFeedback id={`${formId}-error-feedback`}>{error}</FormFeedback>
|
||||
</FormGroup>
|
||||
@@ -99,16 +97,21 @@ class Name extends React.Component {
|
||||
visibility={visibilityName}
|
||||
/>
|
||||
<p className="h5">{name}</p>
|
||||
<FormText>
|
||||
{intl.formatMessage(messages['profile.name.details'])}
|
||||
</FormText>
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.name.empty"
|
||||
defaultMessage="Add name"
|
||||
description="instructions when the user hasn't entered their name"
|
||||
/>
|
||||
</EmptyContent>
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.name.full.name'])} />
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
{intl.formatMessage(messages['profile.name.empty'])}
|
||||
</EmptyContent>
|
||||
<FormText>
|
||||
{intl.formatMessage(messages['profile.name.details'])}
|
||||
</FormText>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
|
||||
@@ -6,6 +6,16 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Full Name',
|
||||
description: 'A section of a user profile',
|
||||
},
|
||||
'profile.name.details': {
|
||||
id: 'profile.name.details',
|
||||
defaultMessage: 'This is the name that appears in your account and on your certificates.',
|
||||
description: 'Describes the area for a user to update their name.',
|
||||
},
|
||||
'profile.name.empty': {
|
||||
id: 'profile.name.empty',
|
||||
defaultMessage: 'Add name',
|
||||
description: 'The affordance to add a name to a user’s profile.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -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 } from 'react-intl';
|
||||
|
||||
import messages from './PreferredLanguage.messages';
|
||||
|
||||
// Components
|
||||
import FormControls from './elements/FormControls';
|
||||
@@ -57,7 +59,13 @@ class PreferredLanguage extends React.Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
formId, languageProficiencies, visibilityLanguageProficiencies, editMode, saveState, error,
|
||||
formId,
|
||||
languageProficiencies,
|
||||
visibilityLanguageProficiencies,
|
||||
editMode,
|
||||
saveState,
|
||||
error,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
const value = languageProficiencies.length ? languageProficiencies[0].code : '';
|
||||
@@ -72,11 +80,7 @@ class PreferredLanguage extends React.Component {
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup>
|
||||
<Label for={formId} id={`${formId}-label`}>
|
||||
<FormattedMessage
|
||||
id="profile.preferredlanguage.label"
|
||||
defaultMessage="Language"
|
||||
description="Preferred language label"
|
||||
/>
|
||||
{intl.formatMessage(messages['profile.preferredlanguage.label'])}
|
||||
</Label>
|
||||
<Input
|
||||
type="select"
|
||||
@@ -107,13 +111,7 @@ class PreferredLanguage extends React.Component {
|
||||
editable: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content={(
|
||||
<FormattedMessage
|
||||
id="profile.preferredlanguage.label"
|
||||
defaultMessage="Language"
|
||||
description="Preferred language label"
|
||||
/>
|
||||
)}
|
||||
content={intl.formatMessage(messages['profile.preferredlanguage.label'])}
|
||||
showEditButton
|
||||
onClickEdit={this.handleOpen}
|
||||
showVisibility={visibilityLanguageProficiencies !== null}
|
||||
@@ -123,24 +121,19 @@ class PreferredLanguage extends React.Component {
|
||||
</React.Fragment>
|
||||
),
|
||||
empty: (
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
<FormattedMessage
|
||||
id="profile.preferredlanguage.empty"
|
||||
defaultMessage="Add language"
|
||||
description="instructions when the user doesn't have a location set"
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content={intl.formatMessage(messages['profile.preferredlanguage.label'])}
|
||||
/>
|
||||
</EmptyContent>
|
||||
<EmptyContent onClick={this.handleOpen}>
|
||||
{intl.formatMessage(messages['profile.preferredlanguage.empty'])}
|
||||
</EmptyContent>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
<EditableItemHeader
|
||||
content={(
|
||||
<FormattedMessage
|
||||
id="profile.preferredlanguage.label"
|
||||
defaultMessage="Language"
|
||||
description="Preferred language label"
|
||||
/>
|
||||
)}
|
||||
content={intl.formatMessage(messages['profile.preferredlanguage.label'])}
|
||||
/>
|
||||
<p className="h5">{ALL_LANGUAGES[value]}</p>
|
||||
</React.Fragment>
|
||||
@@ -175,6 +168,9 @@ PreferredLanguage.propTypes = {
|
||||
submitHandler: PropTypes.func.isRequired,
|
||||
closeHandler: PropTypes.func.isRequired,
|
||||
openHandler: PropTypes.func.isRequired,
|
||||
|
||||
// i18n
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
PreferredLanguage.defaultProps = {
|
||||
@@ -188,4 +184,4 @@ PreferredLanguage.defaultProps = {
|
||||
export default connect(
|
||||
editableFormSelector,
|
||||
{},
|
||||
)(PreferredLanguage);
|
||||
)(injectIntl(PreferredLanguage));
|
||||
|
||||
16
src/components/ProfilePage/PreferredLanguage.messages.jsx
Normal file
16
src/components/ProfilePage/PreferredLanguage.messages.jsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
'profile.preferredlanguage.empty': {
|
||||
id: 'profile.preferredlanguage.empty',
|
||||
defaultMessage: 'Add language',
|
||||
description: 'Instructions when the user doesn’t have a preferred language set.',
|
||||
},
|
||||
'profile.preferredlanguage.label': {
|
||||
id: 'profile.preferredlanguage.label',
|
||||
defaultMessage: 'Primary Language Spoken',
|
||||
description: 'The label for a user’s primary spoken language.',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -101,15 +101,18 @@ class SocialLinks extends React.Component {
|
||||
expression={editMode}
|
||||
cases={{
|
||||
empty: (
|
||||
<ul className="list-unstyled">
|
||||
{socialLinks.map(({ platform }) => (
|
||||
<EmptyListItem
|
||||
key={platform}
|
||||
onClick={this.handleOpen}
|
||||
name={platformDisplayInfo[platform].name}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
<React.Fragment>
|
||||
<EditableItemHeader content={intl.formatMessage(messages['profile.sociallinks.social.links'])} />
|
||||
<ul className="list-unstyled">
|
||||
{socialLinks.map(({ platform }) => (
|
||||
<EmptyListItem
|
||||
key={platform}
|
||||
onClick={this.handleOpen}
|
||||
name={platformDisplayInfo[platform].name}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</React.Fragment>
|
||||
),
|
||||
static: (
|
||||
<React.Fragment>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button } from 'reactstrap';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faPlus } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
@@ -17,16 +16,14 @@ function EmptyContent({ children, onClick, showPlusIcon }) {
|
||||
return (
|
||||
<div>
|
||||
{onClick ? (
|
||||
<Button
|
||||
type="button"
|
||||
color="link"
|
||||
block
|
||||
className="pl-0 text-left"
|
||||
<a
|
||||
role="button"
|
||||
className="pl-0 text-left d-block"
|
||||
{...interactiveProps}
|
||||
>
|
||||
{showPlusIcon ? <FontAwesomeIcon size="xs" className="mr-2" icon={faPlus} /> : null}
|
||||
{children}
|
||||
</Button>
|
||||
</a>
|
||||
) : children}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user