Merge pull request #5375 from paulkaplan/studio-empty-states

Add empty states for curators and projects
This commit is contained in:
Paul Kaplan 2021-05-11 14:40:01 -04:00 committed by GitHub
commit 0d3f10292b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 137 additions and 44 deletions

View file

@ -11,6 +11,11 @@
"studio.projectsHeader": "Projects", "studio.projectsHeader": "Projects",
"studio.addProjectsHeader": "Add Projects", "studio.addProjectsHeader": "Add Projects",
"studio.addProject": "Add", "studio.addProject": "Add",
"studio.projectsEmptyCanAdd1": "Your studio is looking a little empty.",
"studio.projectsEmptyCanAdd2": "Add your first project!",
"studio.projectsEmpty1": "This studio has no projects yet.",
"studio.projectsEmpty2": "Suggest projects you want to add in the comments!",
"studio.browseProjects": "Browse Projects", "studio.browseProjects": "Browse Projects",
"studio.creatorRole": "Studio Creator", "studio.creatorRole": "Studio Creator",
@ -24,6 +29,9 @@
"studio.inviteCuratorsHeader": "Invite Curators", "studio.inviteCuratorsHeader": "Invite Curators",
"studio.inviteCurator": "Invite", "studio.inviteCurator": "Invite",
"studio.curatorAcceptInvite": "Accept Invite", "studio.curatorAcceptInvite": "Accept Invite",
"studio.curatorsEmptyCanAdd1": "You dont have curators right now.",
"studio.curatorsEmptyCanAdd2": "Add some curators to collaborate with!",
"studio.curatorsEmpty1": "This studio has no curators right now.",
"studio.commentsHeader": "Comments", "studio.commentsHeader": "Comments",

View file

@ -2,6 +2,7 @@ import React, {useEffect} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import classNames from 'classnames';
import {curators} from './lib/redux-modules'; import {curators} from './lib/redux-modules';
import Debug from './debug.jsx'; import Debug from './debug.jsx';
@ -27,22 +28,48 @@ const StudioCurators = ({
data={error} data={error}
/>} />}
<div className="studio-members-grid"> <div className="studio-members-grid">
{items.map(item => {items.length === 0 && !loading ? (
(<CuratorTile <div className="studio-empty">
key={item.username} <img
username={item.username} width="179"
image={item.profile.images['90x90']} height="111"
/>) className="studio-empty-img"
src="/images/studios/curators-empty.png"
/>
{canInviteCurators ? (
<div className="studio-empty-msg">
<div><FormattedMessage id="studio.curatorsEmptyCanAdd1" /></div>
<div><FormattedMessage id="studio.curatorsEmptyCanAdd2" /></div>
</div>
) : (
<div className="studio-empty-msg">
<div><FormattedMessage id="studio.curatorsEmpty1" /></div>
</div>
)}
</div>
) : (
<React.Fragment>
{items.map(item =>
(<CuratorTile
key={item.username}
username={item.username}
image={item.profile.images['90x90']}
/>)
)}
{moreToLoad &&
<div className="studio-members-load-more">
<button
className={classNames('button', {
'mod-mutating': loading
})}
onClick={onLoadMore}
>
<FormattedMessage id="general.loadMore" />
</button>
</div>
}
</React.Fragment>
)} )}
<div className="studio-members-load-more">
{loading ? <small>Loading...</small> : (
moreToLoad ?
<button onClick={onLoadMore}>
<FormattedMessage id="general.loadMore" />
</button> :
<small>No more to load</small>
)}
</div>
</div> </div>
</div>); </div>);
}; };

View file

@ -2,6 +2,7 @@ import React, {useEffect} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import classNames from 'classnames';
import {managers} from './lib/redux-modules'; import {managers} from './lib/redux-modules';
import {loadManagers} from './lib/studio-member-actions'; import {loadManagers} from './lib/studio-member-actions';
@ -30,15 +31,18 @@ const StudioManagers = ({items, error, loading, moreToLoad, onLoadMore}) => {
image={item.profile.images['90x90']} image={item.profile.images['90x90']}
/>) />)
)} )}
<div className="studio-members-load-more"> {moreToLoad &&
{loading ? <small>Loading...</small> : ( <div className="studio-members-load-more">
moreToLoad ? <button
<button onClick={onLoadMore}> className={classNames('button', {
<FormattedMessage id="general.loadMore" /> 'mod-mutating': loading
</button> : })}
<small>No more to load</small> onClick={onLoadMore}
)} >
</div> <FormattedMessage id="general.loadMore" />
</button>
</div>
}
</div> </div>
</div> </div>
); );

View file

@ -10,6 +10,7 @@ import Debug from './debug.jsx';
import StudioProjectAdder from './studio-project-adder.jsx'; import StudioProjectAdder from './studio-project-adder.jsx';
import StudioProjectTile from './studio-project-tile.jsx'; import StudioProjectTile from './studio-project-tile.jsx';
import {loadProjects} from './lib/studio-project-actions.js'; import {loadProjects} from './lib/studio-project-actions.js';
import classNames from 'classnames';
const StudioProjects = ({ const StudioProjects = ({
canAddProjects, canEditOpenToAll, items, error, loading, moreToLoad, onLoadMore canAddProjects, canEditOpenToAll, items, error, loading, moreToLoad, onLoadMore
@ -28,27 +29,64 @@ const StudioProjects = ({
data={error} data={error}
/>} />}
<div className="studio-projects-grid"> <div className="studio-projects-grid">
{items.map(item => {items.length === 0 && !loading ? (
(<StudioProjectTile <div className="studio-empty">
fetching={loading} {canAddProjects ? (
key={item.id} <React.Fragment>
id={item.id} <img
title={item.title} width="388"
image={item.image} height="265"
avatar={item.avatar['90x90']} className="studio-empty-img"
username={item.username} src="/images/studios/projects-empty-can-add.png"
addedBy={item.actor_id} />
/>) <div className="studio-empty-msg">
<div><FormattedMessage id="studio.projectsEmptyCanAdd1" /></div>
<div><FormattedMessage id="studio.projectsEmptyCanAdd2" /></div>
</div>
</React.Fragment>
) : (
<React.Fragment>
<img
width="186"
height="138"
className="studio-empty-img"
src="/images/studios/projects-empty.png"
/>
<div className="studio-empty-msg">
<div><FormattedMessage id="studio.projectsEmpty1" /></div>
<div><FormattedMessage id="studio.projectsEmpty2" /></div>
</div>
</React.Fragment>
)}
</div>
) : (
<React.Fragment>
{items.map(item =>
(<StudioProjectTile
fetching={loading}
key={item.id}
id={item.id}
title={item.title}
image={item.image}
avatar={item.avatar['90x90']}
username={item.username}
addedBy={item.actor_id}
/>)
)}
{moreToLoad &&
<div className="studio-projects-load-more">
<button
className={classNames('button', {
'mod-mutating': loading
})}
onClick={onLoadMore}
>
<FormattedMessage id="general.loadMore" />
</button>
</div>
}
</React.Fragment>
)} )}
<div className="studio-projects-load-more">
{loading ? <small>Loading...</small> : (
moreToLoad ?
<button onClick={onLoadMore}>
<FormattedMessage id="general.loadMore" />
</button> :
<small>No more to load</small>
)}
</div>
</div> </div>
</div> </div>
); );

View file

@ -267,6 +267,22 @@ $radius: 8px;
} }
} }
.studio-empty {
grid-column: 1 / -1; /* take up all columns */
text-align: center;
.studio-empty-img {
margin-top: 45px;
margin-bottom: 25px;
}
.studio-empty-msg {
font-size: 20px;
line-height: 30px;
font-style: italic;
}
}
/* Modification classes for different interaction states */ /* Modification classes for different interaction states */
.mod-fetching { /* When a field has no content to display yet */ .mod-fetching { /* When a field has no content to display yet */
position: relative; position: relative;

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB