Add sorting functionality to people page

This commit is contained in:
2017-02-18 14:12:30 +00:00
parent 1ce3673896
commit ac5fb8c987
3 changed files with 173 additions and 10 deletions

View File

@@ -4,6 +4,7 @@ import s from './Button.css';
class Button extends React.Component { class Button extends React.Component {
static propTypes = { static propTypes = {
to: PropTypes.string,
children: PropTypes.node, children: PropTypes.node,
onClick: PropTypes.func, onClick: PropTypes.func,
}; };
@@ -12,6 +13,10 @@ class Button extends React.Component {
if (this.props.onClick) { if (this.props.onClick) {
this.props.onClick(event); this.props.onClick(event);
} }
if (this.props.to) {
window.location.href = this.props.to;
}
}; };
render() { render() {

View File

@@ -11,6 +11,15 @@
max-width: var(--max-content-width); max-width: var(--max-content-width);
} }
table {
border-spacing: 0;
}
td {
position: relative;
padding: 0 14px;
}
.formGroup { .formGroup {
position: relative; position: relative;
margin-bottom: 15px; margin-bottom: 15px;
@@ -44,3 +53,23 @@
border-color: var(--colour-tertiary); border-color: var(--colour-tertiary);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(0, 116, 194, 0.6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(0, 116, 194, 0.6);
} }
.personForm {
display: none;
}
.personFormVisible {
display: block;
}
.sortIcon {
display: none;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
}
.showSortIcon {
display: inline-block;
}

View File

@@ -19,31 +19,149 @@ class AdminPeople extends React.Component {
})).isRequired, })).isRequired,
}; };
constructor(props) {
super(props);
this.state = {
people: this.props.people,
personFormVisible: false,
sortDirection: false,
};
}
sortPeople = (event, sortedBy) => {
event.preventDefault();
const sortDirection = (sortedBy === this.state.sortedBy) ? !this.state.sortDirection : true;
this.setState({
sortedBy,
sortDirection,
people: this.props.people.sort((a, b) => {
if (a[sortedBy] > b[sortedBy]) {
return sortDirection ? 1 : -1;
}
return sortDirection ? -1 : 1;
}),
});
}
togglePersonForm = (event) => {
event.preventDefault();
this.setState({ personFormVisible: !this.state.personFormVisible });
}
render() { render() {
return ( return (
<div className={s.root}> <div className={s.root}>
<div className={s.container}> <div className={s.container}>
<h1>{this.props.title}</h1> <h1>{this.props.title}</h1>
{this.props.people.length === 0 ? <p> No people yet ☹️</p> : {this.state.people.length === 0 ? <p> No people yet ☹️</p> :
<table> <table>
<thead> <thead>
<tr> <tr>
<td>Name</td> <td>
<td>Email</td> <span
<td>Password</td> className={[
<td>Ceremony</td> s.sortIcon,
<td>Responded</td> this.state.sortedBy === 'firstname' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'firstname' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'firstname')}>First name</a>
</td>
<td>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'lastname' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'lastname' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'lastname')}>Last name</a>
</td>
<td>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'email' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'email' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'email')}>Email</a>
</td>
<td>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'password' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'password' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'password')}>Password</a>
</td>
<td>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'ceremony' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'ceremony' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'ceremony')}>Ceremony</a>
</td>
<td>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'completed' && this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬇</span>
<span
className={[
s.sortIcon,
this.state.sortedBy === 'completed' && !this.state.sortDirection ? s.showSortIcon : null,
].join(' ')}
>⬆</span>
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'completed')}>Responded</a>
</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{this.props.people.map(person => ( {this.state.people.map(person => (
<tr key={person.key}> <tr key={person.key}>
<td><Link to={`/admin/person/${person.key}`}>{person.firstname} {person.lastname}</Link></td> <td>{person.firstname}</td>
<td>{person.lastname}</td>
<td>{person.email}</td> <td>{person.email}</td>
<td><Link to={`/rsvp/${person.password}`}>{person.password}</Link></td> <td><Link to={`/rsvp/${person.password}`}>{person.password}</Link></td>
<td>{person.ceremony ? 'Full day' : 'Evening only'}</td> <td>{person.ceremony ? 'Full day' : 'Evening only'}</td>
<td>{person.completed ? 'Yes' : 'No'}</td> <td>{person.completed ? 'Yes' : 'No'}</td>
<td>
<Button to={`/admin/person/${person.key}`}>Edit</Button>
</td>
<td> <td>
<form method="post" action="/admin/person/delete"> <form method="post" action="/admin/person/delete">
<input type="hidden" name="key" value={person.key} /> <input type="hidden" name="key" value={person.key} />
@@ -57,8 +175,19 @@ class AdminPeople extends React.Component {
</tbody> </tbody>
</table> </table>
} }
<h2>Add Person</h2> <h2>
<form method="post" action="/admin/person"> <a href="#sortcolumn" onClick={this.togglePersonForm}>
<span>{this.state.personFormVisible ? '-' : '+'}</span> Add Person
</a>
</h2>
<form
method="post"
action="/admin/person"
className={[
s.personForm,
this.state.personFormVisible ? s.personFormVisible : null,
].join(' ')}
>
<div className={s.formGroup}> <div className={s.formGroup}>
<label className={s.label} htmlFor="firstname"> <label className={s.label} htmlFor="firstname">
First name: First name: