WIP Display collection

This commit is contained in:
Andrew Nicolaou 2019-09-08 18:54:49 +02:00 committed by Cassie Tarakajian
parent 521e117d95
commit 8781036ac7
9 changed files with 117 additions and 70 deletions

View File

@ -187,7 +187,7 @@ class CollectionListRowBase extends React.Component {
key={collection.id}
>
<th scope="row">
<Link to={`/${username}/collections/${collection.id}`}>
<Link to={{ pathname: `/${username}/collections/${collection.id}`, state: { skipSavingPath: true } }}>
{renameOpen ? '' : collection.name}
</Link>
{renameOpen

View File

@ -7,15 +7,14 @@ import { connect } from 'react-redux';
import { Link } from 'react-router';
import { bindActionCreators } from 'redux';
import classNames from 'classnames';
import * as ProjectActions from '../actions/project';
import * as ProjectsActions from '../actions/projects';
import * as CollectionsActions from '../actions/collections';
import * as ToastActions from '../actions/toast';
import * as SortingActions from '../actions/sorting';
import * as IdeActions from '../actions/ide';
import { getCollection } from '../selectors/collections';
import * as ProjectActions from '../../IDE/actions/project';
import * as ProjectsActions from '../../IDE/actions/projects';
import * as CollectionsActions from '../../IDE/actions/collections';
import * as ToastActions from '../../IDE/actions/toast';
import * as SortingActions from '../../IDE/actions/sorting';
import * as IdeActions from '../../IDE/actions/ide';
import { getCollection } from '../../IDE/selectors/collections';
import Loader from '../../App/components/loader';
import Overlay from '../../App/components/Overlay';
const arrowUp = require('../../../images/sort-arrow-up.svg');
const arrowDown = require('../../../images/sort-arrow-down.svg');
@ -259,9 +258,13 @@ class Collection extends React.Component {
}
_renderCollectionMetadata() {
const { name, description, items, owner } = this.props.collection;
return (
<div className="collections-metadata">
<p>{this.props.collection.description}</p>
<div className="collection-metadata">
<h2 className="collection-metadata__name">{name}</h2>
<p className="collection-metadata__user">{items.length} sketches collected by {owner.username}</p>
<p className="collection-metadata__description">{description}</p>
</div>
);
}
@ -299,15 +302,11 @@ class Collection extends React.Component {
const title = this.hasCollection() ? this.getCollectionName() : null;
return (
<Overlay
ariaLabel="collection"
title={title}
previousPath={this.props.previousPath}
>
<div className="sketches-table-container">
<Helmet>
<title>{this.getTitle()}</title>
</Helmet>
<section className="collection-container">
<Helmet>
<title>{this.getTitle()}</title>
</Helmet>
<div className="">
{this._renderLoader()}
{this.hasCollection() && this._renderCollectionMetadata()}
{this._renderEmptyTable()}
@ -332,7 +331,7 @@ class Collection extends React.Component {
</tbody>
</table>}
</div>
</Overlay>
</section>
);
}
}
@ -343,7 +342,10 @@ Collection.propTypes = {
authenticated: PropTypes.bool.isRequired
}).isRequired,
getCollections: PropTypes.func.isRequired,
collection: PropTypes.shape({}).isRequired, // TODO
collection: PropTypes.shape({
name: PropTypes.string.isRequired,
description: PropTypes.string,
}).isRequired,
username: PropTypes.string,
loading: PropTypes.bool.isRequired,
toggleDirectionForField: PropTypes.func.isRequired,

View File

@ -41,7 +41,10 @@ class CollectionCreate extends React.Component {
this.props.createCollection(this.state.collection)
.then(({ id, owner }) => {
browserHistory.replace(`/${owner.username}/collections/${id}`);
const pathname = `/${owner.username}/collections/${id}`;
const location = { pathname, state: { skipSavingPath: true } };
browserHistory.replace(location);
})
.catch((error) => {
console.error('Error creating collection', error);
@ -58,42 +61,49 @@ class CollectionCreate extends React.Component {
const invalid = name === '' || name == null;
return (
<div className="sketches-table-container">
<section className="dashboard-header">
<Helmet>
<title>{this.getTitle()}</title>
</Helmet>
<form className="form" onSubmit={this.handleCreateCollection}>
{creationError && <span className="form-error">Couldn&apos;t create collection</span>}
<p className="form__field">
<label htmlFor="name" className="form__label">Collection name</label>
<input
className="form__input"
aria-label="name"
type="text"
id="name"
value={name}
placeholder={generatedCollectionName}
onChange={this.handleTextChange('name')}
/>
{invalid && <span className="form-error">Collection name is required</span>}
</p>
<p className="form__field">
<label htmlFor="description" className="form__label">Description (optional)</label>
<textarea
className="form__input form__input-flexible-height"
aria-label="description"
type="text"
id="description"
value={description}
onChange={this.handleTextChange('description')}
placeholder="My fave sketches"
rows="4"
/>
</p>
<input type="submit" disabled={invalid} value="Create collection" aria-label="create collection" />
</form>
</div>
<div className="dashboard-header__header">
<h2 className="dashboard-header__header__title">Create collection</h2>
</div>
<div className="dashboard-content">
<div className="sketches-table-container">
<form className="form" onSubmit={this.handleCreateCollection}>
{creationError && <span className="form-error">Couldn&apos;t create collection</span>}
<p className="form__field">
<label htmlFor="name" className="form__label">Collection name</label>
<input
className="form__input"
aria-label="name"
type="text"
id="name"
value={name}
placeholder={generatedCollectionName}
onChange={this.handleTextChange('name')}
/>
{invalid && <span className="form-error">Collection name is required</span>}
</p>
<p className="form__field">
<label htmlFor="description" className="form__label">Description (optional)</label>
<textarea
className="form__input form__input-flexible-height"
aria-label="description"
type="text"
id="description"
value={description}
onChange={this.handleTextChange('description')}
placeholder="My fave sketches"
rows="4"
/>
</p>
<input type="submit" disabled={invalid} value="Create collection" aria-label="create collection" />
</form>
</div>
</div>
</section>
);
}
}

View File

@ -7,6 +7,7 @@ import { updateSettings, initiateVerification, createApiKey, removeApiKey } from
import NavBasic from '../../../components/NavBasic';
import CollectionCreate from '../components/CollectionCreate';
import Collection from '../components/Collection';
class CollectionView extends React.Component {
static defaultProps = {
@ -61,7 +62,12 @@ class CollectionView extends React.Component {
return <CollectionCreate />;
}
return 'collection page';
return (
<Collection
collectionId={this.props.params.collection_id}
username={this.props.params.username}
/>
);
}
render() {
@ -69,15 +75,7 @@ class CollectionView extends React.Component {
<div className="dashboard">
<NavBasic onBack={this.closeAccountPage} />
<section className="dashboard-header">
<div className="dashboard-header__header">
<h2 className="dashboard-header__header__title">{this.pageTitle()}</h2>
</div>
<div className="dashboard-content">
{this.renderContent()}
</div>
</section>
{this.renderContent()}
</div>
);
}
@ -102,6 +100,7 @@ CollectionView.propTypes = {
pathname: PropTypes.string.isRequired,
}).isRequired,
params: PropTypes.shape({
collection_id: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
}).isRequired,
previousPath: PropTypes.string.isRequired,

View File

@ -46,7 +46,7 @@ const routes = store => (
<Route path="/:username/sketches" component={DashboardView} />
<Route path="/:username/collections" component={DashboardView} />
<Route path="/:username/collections/create" component={CollectionView} />
<Route path="/:username/collections/:collection_id" component={DashboardView} />
<Route path="/:username/collections/:collection_id" component={CollectionView} />
<Route path="/about" component={IDEView} />
<Route path="/feedback" component={IDEView} />
</Route>

View File

@ -0,0 +1,21 @@
.collection-container {
}
.collection-metadata {
margin: 0px #{56 / $base-font-size}rem;
padding: #{24 / $base-font-size}rem #{10 / $base-font-size}rem;
@include themify() {
background-color: getThemifyVariable('modal-background-color');
border-bottom: 1px dotted getThemifyVariable('modal-border-color');
}
}
.collection-metadata__user {
padding-top: #{12 / $base-font-size}rem;
}
.collection-metadata__description {
padding-top: #{24 / $base-font-size}rem;
}

View File

@ -7,6 +7,10 @@
flex-direction:column;
}
.dashboard-header--no-vertical-padding {
padding: 0 66px;
}
.dashboard-header__tabs {
display: flex;
padding-top: #{24 / $base-font-size}rem;

View File

@ -49,6 +49,7 @@
@import 'components/tabs';
@import 'components/dashboard-header';
@import 'components/editable-input';
@import 'components/collection';
@import 'layout/dashboard';
@import 'layout/ide';

View File

@ -112,10 +112,14 @@ router.get('/:username/sketches', (req, res) => {
));
});
router.get('/:username/collections', (req, res) => {
userExists(req.params.username, exists => (
exists ? res.send(renderIndex()) : get404Sketch(html => res.send(html))
));
router.get('/:username/collections/create', (req, res) => {
userExists(req.params.username, (exists) => {
const isLoggedInUser = req.user && req.user.username === req.params.username;
const canAccess = exists && isLoggedInUser;
return canAccess ?
res.send(renderIndex()) :
get404Sketch(html => res.send(html));
});
});
router.get('/:username/collections/create', (req, res) => {
@ -136,4 +140,10 @@ router.get('/:username/collections/:id', (req, res) => {
));
});
router.get('/:username/collections', (req, res) => {
userExists(req.params.username, exists => (
exists ? res.send(renderIndex()) : get404Sketch(html => res.send(html))
));
});
export default router;