2019-03-02 10:35:40 +01:00
|
|
|
import format from 'date-fns/format';
|
2018-02-07 19:06:07 +01:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React from 'react';
|
2019-03-02 10:35:40 +01:00
|
|
|
import { Helmet } from 'react-helmet';
|
|
|
|
import InlineSVG from 'react-inlinesvg';
|
2016-08-15 23:06:12 +02:00
|
|
|
import { connect } from 'react-redux';
|
2019-03-02 10:35:40 +01:00
|
|
|
import { browserHistory, Link } from 'react-router';
|
2016-08-15 23:06:12 +02:00
|
|
|
import { bindActionCreators } from 'redux';
|
|
|
|
import * as ProjectActions from '../actions/project';
|
2019-03-02 10:35:40 +01:00
|
|
|
import * as SketchActions from '../actions/projects';
|
2017-01-06 19:08:03 +01:00
|
|
|
import * as ToastActions from '../actions/toast';
|
2019-05-01 22:32:39 +02:00
|
|
|
import Loader from '../../App/components/loader';
|
2017-02-22 20:29:35 +01:00
|
|
|
|
2016-10-12 20:24:53 +02:00
|
|
|
const trashCan = require('../../../images/trash-can.svg');
|
2016-08-15 23:06:12 +02:00
|
|
|
|
|
|
|
class SketchList extends React.Component {
|
2016-11-10 22:13:00 +01:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2017-02-17 21:47:54 +01:00
|
|
|
this.props.getProjects(this.props.username);
|
2016-11-10 22:13:00 +01:00
|
|
|
}
|
|
|
|
|
2018-02-23 17:31:41 +01:00
|
|
|
getSketchesTitle() {
|
|
|
|
if (this.props.username === this.props.user.username) {
|
|
|
|
return 'p5.js Web Editor | My sketches';
|
|
|
|
}
|
|
|
|
return `p5.js Web Editor | ${this.props.username}'s sketches`;
|
|
|
|
}
|
|
|
|
|
2019-05-01 22:32:39 +02:00
|
|
|
hasSketches() {
|
|
|
|
return !this.props.loading && this.props.sketches.length > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderLoader() {
|
|
|
|
if (this.props.loading) return <Loader />;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderEmptyTable() {
|
|
|
|
if (!this.props.loading && this.props.sketches.length === 0) return (<p className="sketches-table__empty">No sketches.</p>);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-08-15 23:06:12 +02:00
|
|
|
render() {
|
2016-12-01 23:12:34 +01:00
|
|
|
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
|
2016-08-15 23:06:12 +02:00
|
|
|
return (
|
2017-07-11 17:37:43 +02:00
|
|
|
<div className="sketches-table-container">
|
2018-02-23 17:31:41 +01:00
|
|
|
<Helmet>
|
|
|
|
<title>{this.getSketchesTitle()}</title>
|
|
|
|
</Helmet>
|
2019-05-01 22:32:39 +02:00
|
|
|
{this.renderLoader()}
|
|
|
|
{this.renderEmptyTable()}
|
|
|
|
{this.hasSketches() &&
|
2017-07-24 17:12:11 +02:00
|
|
|
<table className="sketches-table" summary="table containing all saved projects">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th className="sketch-list__trash-column" scope="col"></th>
|
|
|
|
<th scope="col">Sketch</th>
|
|
|
|
<th scope="col">Date created</th>
|
|
|
|
<th scope="col">Date updated</th>
|
2016-08-15 23:06:12 +02:00
|
|
|
</tr>
|
2017-07-24 17:12:11 +02:00
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
{this.props.sketches.map(sketch =>
|
|
|
|
// eslint-disable-next-line
|
|
|
|
<tr
|
|
|
|
className="sketches-table__row visibility-toggle"
|
|
|
|
key={sketch.id}
|
|
|
|
onClick={() => browserHistory.push(`/${username}/sketches/${sketch.id}`)}
|
|
|
|
>
|
|
|
|
<td className="sketch-list__trash-column">
|
|
|
|
{(() => { // eslint-disable-line
|
2018-05-05 02:22:39 +02:00
|
|
|
if (this.props.username === this.props.user.username || this.props.username === undefined) {
|
|
|
|
return (
|
|
|
|
<button
|
|
|
|
className="sketch-list__trash-button"
|
|
|
|
onClick={(e) => {
|
|
|
|
e.stopPropagation();
|
|
|
|
if (window.confirm(`Are you sure you want to delete "${sketch.name}"?`)) {
|
|
|
|
this.props.deleteProject(sketch.id);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<InlineSVG src={trashCan} alt="Delete Project" />
|
|
|
|
</button>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})()}
|
2017-07-24 17:12:11 +02:00
|
|
|
</td>
|
|
|
|
<th scope="row"><Link to={`/${username}/sketches/${sketch.id}`}>{sketch.name}</Link></th>
|
2019-03-02 10:35:40 +01:00
|
|
|
<td>{format(new Date(sketch.createdAt), 'MMM D, YYYY h:mm A')}</td>
|
|
|
|
<td>{format(new Date(sketch.updatedAt), 'MMM D, YYYY h:mm A')}</td>
|
2018-05-05 02:22:39 +02:00
|
|
|
</tr>)}
|
2017-07-24 17:12:11 +02:00
|
|
|
</tbody>
|
|
|
|
</table>}
|
2017-07-11 17:37:43 +02:00
|
|
|
</div>
|
2016-08-15 23:06:12 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SketchList.propTypes = {
|
2017-02-22 20:29:35 +01:00
|
|
|
user: PropTypes.shape({
|
|
|
|
username: PropTypes.string
|
|
|
|
}).isRequired,
|
2016-08-15 23:06:12 +02:00
|
|
|
getProjects: PropTypes.func.isRequired,
|
2017-02-22 20:29:35 +01:00
|
|
|
sketches: PropTypes.arrayOf(PropTypes.shape({
|
|
|
|
id: PropTypes.string.isRequired,
|
|
|
|
name: PropTypes.string.isRequired,
|
|
|
|
createdAt: PropTypes.string.isRequired,
|
|
|
|
updatedAt: PropTypes.string.isRequired
|
|
|
|
})).isRequired,
|
2016-10-12 20:24:53 +02:00
|
|
|
username: PropTypes.string,
|
2019-05-01 22:32:39 +02:00
|
|
|
loading: PropTypes.bool.isRequired,
|
2017-07-11 17:37:43 +02:00
|
|
|
deleteProject: PropTypes.func.isRequired
|
2017-02-22 20:29:35 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
SketchList.defaultProps = {
|
|
|
|
username: undefined
|
2016-08-15 23:06:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
function mapStateToProps(state) {
|
|
|
|
return {
|
|
|
|
user: state.user,
|
2019-05-01 22:32:39 +02:00
|
|
|
sketches: state.sketches,
|
|
|
|
loading: state.loading,
|
2016-08-15 23:06:12 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapDispatchToProps(dispatch) {
|
2017-01-06 19:08:03 +01:00
|
|
|
return bindActionCreators(Object.assign({}, SketchActions, ProjectActions, ToastActions), dispatch);
|
2016-08-15 23:06:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(SketchList);
|