Add empty state cases for each section. Update SwitchContent to handle forwarding of cases.

This commit is contained in:
Adam Butterworth
2019-02-14 17:08:10 -05:00
committed by Adam Butterworth
parent 174d8de17d
commit aaf1c5f1ea
5 changed files with 72 additions and 62 deletions

View File

@@ -1,12 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Input } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import EditControls from './elements/EditControls';
import EditableItemHeader from './elements/EditableItemHeader';
import SwitchContent from './elements/SwitchContent';
import EmptyContent from './elements/EmptyContent';
class SocialLinks extends React.Component {
@@ -35,13 +34,13 @@ class SocialLinks extends React.Component {
saveState,
} = this.props;
if (socialLinks === null) return null;
const socialLinksObj = {};
socialLinks.forEach(({ platform, socialLink }) => {
socialLinksObj[platform] = socialLink;
});
if (socialLinks !== null) {
socialLinks.forEach(({ platform, socialLink }) => {
socialLinksObj[platform] = socialLink;
});
}
return (
@@ -83,7 +82,7 @@ class SocialLinks extends React.Component {
content="Social Links"
showEditButton
onClickEdit={() => onEdit('socialLinks')}
showVisibility={Boolean(socialLinks.length)}
showVisibility={Boolean(socialLinks && socialLinks.length)}
visibility="Everyone"
/>
<ul className="list-unstyled">
@@ -93,14 +92,7 @@ class SocialLinks extends React.Component {
socialLinksObj[key] ? (
<a href={socialLinksObj[key]}>{name}</a>
) : (
<button
className="btn btn-link btn-sm"
tabIndex="0"
onClick={() => onEdit('socialLinks')}
onKeyDown={e => (e.key === 'Enter' ? onEdit('socialLinks') : null)}
>
<FontAwesomeIcon className="mr-2" icon={faPencilAlt} />{`Add ${name}`}
</button>
<EmptyContent onClick={() => onEdit('socialLinks')}>Add {name}</EmptyContent>
)
}
</li>
@@ -108,6 +100,15 @@ class SocialLinks extends React.Component {
</ul>
</React.Fragment>
),
empty: (
<ul className="list-unstyled">
{this.props.platforms.map(({ key, name }) => (
<li key={key} className="mb-4">
<EmptyContent onClick={() => onEdit('socialLinks')}>Add {name}</EmptyContent>
</li>
))}
</ul>
),
static: (
<React.Fragment>
<EditableItemHeader content="Social Links" />

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faPlus } from '@fortawesome/free-solid-svg-icons';
function EmptyContent({ children, onClick, showPlusIcon }) {
const onKeyDown = (e) => { if (e.key === 'Enter') onClick(); };
@@ -34,7 +34,7 @@ function EmptyContent({ children, onClick, showPlusIcon }) {
return (
<div {...props}>
{showPlusIcon ? <FontAwesomeIcon className="ml-1 mr-3" icon={faPencilAlt} /> : null}
{showPlusIcon ? <FontAwesomeIcon className="ml-1 mr-3" icon={faPlus} /> : null}
{children}
</div>
);

View File

@@ -18,9 +18,21 @@ const onChildExit = (htmlNode) => {
function SwitchContent({ expression, cases, className }) {
if (!cases[expression] && !cases.default) {
const getContent = (caseKey) => {
if (cases[caseKey]) {
if (typeof cases[caseKey] === 'string') {
return getContent(cases[caseKey]);
}
return React.cloneElement(cases[caseKey], { key: caseKey });
} else if (cases.default) {
if (typeof cases.default === 'string') {
return getContent(cases.default);
}
React.cloneElement(cases.default, { key: 'default' });
}
return null;
}
};
return (
<TransitionReplace
@@ -28,7 +40,7 @@ function SwitchContent({ expression, cases, className }) {
onChildEntered={onChildEntered}
onChildExit={onChildExit}
>
{expression ? React.cloneElement(cases[expression], { key: expression }) : React.cloneElement(cases.default, { key: 'default' })}
{getContent(expression)}
</TransitionReplace>
);
}

View File

@@ -89,9 +89,9 @@ class UserProfile extends React.Component {
error,
};
const getEditMode = (name) => {
const getMode = (name) => {
if (name === this.props.currentlyEditingField) return 'editing';
if (!this.props[name] || !this.props[name].length) return 'empty';
return 'editable';
};
@@ -119,25 +119,25 @@ class UserProfile extends React.Component {
<FullName
fullName={fullName}
editMode={getEditMode('fullName')}
editMode={getMode('fullName')}
{...commonProps}
/>
<UserLocation
userLocation={userLocation}
editMode={getEditMode('userLocation')}
editMode={getMode('userLocation')}
{...commonProps}
/>
<Education
education={education}
editMode={getEditMode('education')}
editMode={getMode('education')}
{...commonProps}
/>
<SocialLinks
socialLinks={socialLinks}
editMode={getEditMode('socialLinks')}
editMode={getMode('socialLinks')}
{...commonProps}
/>
@@ -146,13 +146,13 @@ class UserProfile extends React.Component {
<Bio
bio={bio}
editMode={getEditMode('bio')}
editMode={getMode('bio')}
{...commonProps}
/>
<MyCertificates
certificates={certificates}
editMode={getEditMode('certificates')}
editMode={getMode('certificates')}
{...commonProps}
/>
@@ -193,15 +193,15 @@ UserProfile.defaultProps = {
currentlyEditingField: null,
saveState: null,
error: null,
profileImage: 'https://source.unsplash.com/featured/200x200/?face',
fullName: 'Hermione Granger',
username: 'itslevioooosa20',
userLocation: 'London, UK',
profileImage: null,
fullName: null,
username: null,
userLocation: null,
education: null,
socialLinks: [],
aboutMe: 'These are some words about me and who I am as a person.',
bio: 'These are some words about me and who I am as a person.',
certificates: [{ title: 'Certificate 1' }, { title: 'Certificate 2' }, { title: 'Certificate 3' }],
aboutMe: null,
bio: null,
certificates: null,
saveUserProfile: null,
};
@@ -264,13 +264,12 @@ function FullName({
showVisibility={Boolean(fullName)}
visibility="Everyone"
/>
{fullName ? (
<h5>{fullName}</h5>
) : (
<EmptyContent onClick={() => onEdit('fullName')}>Add name</EmptyContent>
)}
<h5>{fullName}</h5>
</React.Fragment>
),
empty: (
<EmptyContent onClick={() => onEdit('fullName')}>Add name</EmptyContent>
),
static: (
<React.Fragment>
<EditableItemHeader content="Full Name" />
@@ -340,13 +339,12 @@ function UserLocation({
showVisibility={Boolean(userLocation)}
visibility="Everyone"
/>
{userLocation ? (
<h5>{ALL_COUNTRIES[userLocation]}</h5>
) : (
<EmptyContent onClick={() => onEdit('userLocation')}>Add location</EmptyContent>
)}
<h5>{ALL_COUNTRIES[userLocation]}</h5>
</React.Fragment>
),
empty: (
<EmptyContent onClick={() => onEdit('userLocation')}>Add location</EmptyContent>
),
static: (
<React.Fragment>
<EditableItemHeader content="Location" />
@@ -416,13 +414,12 @@ function Education({
showVisibility={Boolean(education)}
visibility="Everyone"
/>
{education ? (
<h5>{EDUCATION[education]}</h5>
) : (
<EmptyContent onClick={() => onEdit('education')}>Add education</EmptyContent>
)}
<h5>{EDUCATION[education]}</h5>
</React.Fragment>
),
empty: (
<EmptyContent onClick={() => onEdit('education')}>Add education</EmptyContent>
),
static: (
<React.Fragment>
<EditableItemHeader content="Education" />
@@ -487,13 +484,12 @@ function Bio({
showVisibility={Boolean(bio)}
visibility="Everyone"
/>
{bio ? (
<p className="lead">{bio}</p>
) : (
<EmptyContent onClick={() => onEdit('bio')}>Tell other learners a little about yourself...</EmptyContent>
)}
<p className="lead">{bio}</p>
</React.Fragment>
),
empty: (
<EmptyContent onClick={() => onEdit('bio')}>Add a short bio</EmptyContent>
),
static: (
<React.Fragment>
<EditableItemHeader content="About Me" />
@@ -526,9 +522,7 @@ function MyCertificates({
saveState,
}) {
const renderCertificates = () => {
if (!certificates) {
return <EmptyContent onClick={() => onEdit('certificates')}>You don&quot;t have any certificates yet.</EmptyContent>;
}
if (!certificates) return null;
return (
<Row>
@@ -575,6 +569,11 @@ function MyCertificates({
{renderCertificates()}
</React.Fragment>
),
empty: (
<div>
You dont have any certificates yet. Find a course.
</div>
),
static: (
<React.Fragment>
<EditableItemHeader content="My Certificates" />

View File

@@ -11,7 +11,6 @@ const mapStateToProps = state => ({
currentlyEditingField: state.profile.currentlyEditingField,
saveState: state.profile.saveState,
error: state.profile.error,
bannerImage: 'https://source.unsplash.com/featured/1000x200/?colored,pattern',
profileImage: state.userAccount.profileImage.imageUrlLarge,
fullName: state.userAccount.name,
username: state.userAccount.username,
@@ -19,8 +18,7 @@ const mapStateToProps = state => ({
education: state.userAccount.levelOfEducation,
socialLinks: state.userAccount.socialLinks,
bio: state.userAccount.bio,
certificates: [{ title: 'Certificate 1' }, { title: 'Certificate 2' }, { title: 'Certificate 3' }],
courses: [{ title: 'Course ' }, { title: 'Course 2' }, { title: 'Course 3' }],
certificates: null,
});
export default connect(mapStateToProps, {