Add sorting functionality to people page
This commit is contained in:
@@ -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() {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user