From ff0ab3e87bbe8d0f6fddfe2ffad970e44f51ed73 Mon Sep 17 00:00:00 2001 From: Will Bradley Date: Sun, 25 Oct 2020 00:18:08 -0700 Subject: [PATCH] add ability to edit events. relies upon members_api adjust_event_route_and_permissions --- Dockerfile | 4 +- docker-run.sh | 2 + src/index.js | 2 + src/pages/cert_details.js | 1 + src/pages/event.js | 69 ++++++++----- src/pages/event_edit.js | 201 ++++++++++++++++++++++++++++++++++++++ src/pages/events.js | 8 +- src/state/events.js | 73 ++++++++------ 8 files changed, 300 insertions(+), 60 deletions(-) create mode 100644 src/pages/event_edit.js diff --git a/Dockerfile b/Dockerfile index 64a737d..28e0cc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,6 +32,8 @@ COPY package.json /home/app/ COPY . /home/app #RUN npm run build -RUN npm install +#RUN npm install +RUN yarn CMD ./docker-run.sh + diff --git a/docker-run.sh b/docker-run.sh index 0ac3859..ba3e802 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -14,4 +14,6 @@ echo "Starting up. PORT is $PORT" export PATH=$PATH:$(pwd)/node_modules/.bin +yarn +#yarn run start npm run start diff --git a/src/index.js b/src/index.js index b91e994..cd188c4 100644 --- a/src/index.js +++ b/src/index.js @@ -36,6 +36,7 @@ import Forgot from './pages/forgot'; import UpdatePassword from './pages/updatepassword'; import Events from './pages/events'; import Event from './pages/event'; +import EventEdit from './pages/event_edit'; import Certs from './pages/certs'; import CertDetails from './pages/cert_details'; @@ -59,6 +60,7 @@ render(( + diff --git a/src/pages/cert_details.js b/src/pages/cert_details.js index 1890813..84a78a6 100644 --- a/src/pages/cert_details.js +++ b/src/pages/cert_details.js @@ -120,6 +120,7 @@ class Certs extends Component { -

{ev.name}

-
{dateRange.full_date_string} ({ev.frequency})
- {ev.location} + return ( +
+
+ {read ? ( + <> +

{this.state.name}

+
+ {formatDateRange(this.state.start_date, this.state.end_date).full_date_string} +  ({this.state.frequency}) +
+ {this.state.location}

- {ev.description} + {this.state.description}

-
- ) - } - - return ( -
-
- {eventList} -
+ Edit + + ) : ( + + )} + ); } } @@ -67,4 +82,4 @@ function mapStateToProps(state) { } -export default connect(mapStateToProps, actionCreators)(App); +export default connect(mapStateToProps, { read })(App); diff --git a/src/pages/event_edit.js b/src/pages/event_edit.js new file mode 100644 index 0000000..fa8fb1b --- /dev/null +++ b/src/pages/event_edit.js @@ -0,0 +1,201 @@ +// Copyright 2019 Iced Development, LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { Link } from 'react-router-dom'; +import CircularProgress from '@material-ui/core/CircularProgress'; +import TextField from '@material-ui/core/TextField'; +import Button from '@material-ui/core/Button'; +import { DataGrid } from '@material-ui/data-grid'; +import Header from '../components/header'; +import { read, edit, add } from '../state/events'; + + +const styles = { + eventDescription: { + whiteSpace: 'pre-line', + }, + tableContainer: { + // margin: '10px', + }, + gridContainer: { + width: '100%', + display: 'flex', + height: 450 + }, + nameField: { + fontSize: '1.5em', + magin: '5px', + }, + descriptionFeild: { + width: '125ch', + magin: '5px', + }, + form: { + width: '90%', + margin: '5px', + }, + formButton: { + margin: '5px', + }, +}; + +const columns = [ + { field: 'id', hide: true }, + { + field: 'user_name', + headerName: 'Name', + align: 'left', + width: 250, + renderCell: (params) => { + return {params.value} + }, + }, + { + field: 'created_at', + headerName: 'Created', + align: 'right', + valueFormatter: (params) => { + return new Date(params.value).toLocaleDateString(); + }, + }, +]; + +class Events extends Component { + state = { + name: '', + frequency: '', + location: '', + description: '', + start_date: '', + end_date: '' + }; + + nameChange = (e) => { + this.setState({name: e.target.value}); + }; + + frequencyChange = (e) => { + this.setState({frequency: e.target.value}); + }; + + locationChange = (e) => { + this.setState({location: e.target.value}); + }; + + descriptionChange = (e) => { + this.setState({description: e.target.value}); + }; + + startDateChange = (e) => { + this.setState({start_date: e.target.value}); + }; + + endDateChange = (e) => { + this.setState({end_date: e.target.value}); + }; + + submitForm = () => { + const { event_id } = this.props.match.params; + const { name, frequency, description } = this.state; + this.props.edit(event_id, { name, frequency, description }); + }; + + async componentDidMount(){ + const { event_id } = this.props.match.params; + const { id, name, frequency, location, description, start_date, end_date } = await this.props.read(event_id); + this.setState({ id, name, frequency, location, description, start_date, end_date }); + } + + render() { + + const { read } = this.props.events; + const { auth } = this.props.user; + return ( +
+
+ {auth.isAdmin && read ? ( +
+ +
+ +
+ +
+ + + +
+ + Back +
+ ) : ( + <> +

{read ? read.name : ''}

+

{read ? read.description : ''}

+ + )} + +
+ ); + } +} + +function mapStateToProps(state) { + const { events } = state; + return { events }; +} + + +export default connect(mapStateToProps, { read, edit, add })(Events); diff --git a/src/pages/events.js b/src/pages/events.js index a0ca198..5b688d0 100644 --- a/src/pages/events.js +++ b/src/pages/events.js @@ -53,17 +53,17 @@ class App extends Component { render() { const { events } = this.props; let allEventList = ''; + console.log(events); - if(events.all) { + if(events.getAll) { allEventList = (

All Events

- {events.all.map((e) => { - const dateRange = formatDateRange(e); + {events.getAll.map((e) => { return
{e.name}
- {dateRange.full_date_string} ({e.frequency})
+ {formatDateRange(e.start_date, e.end_date).full_date_string} ({e.frequency})
{e.location}

{e.description}

; diff --git a/src/state/events.js b/src/state/events.js index 882069b..4727feb 100644 --- a/src/state/events.js +++ b/src/state/events.js @@ -12,44 +12,61 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { combinedHandler } from 'cooldux'; +import { makeDuck, resetReducer } from 'cooldux'; import { get } from 'lodash'; import { apiFetch } from '../lib/fetch'; -const { - allHandler, - oneHandler, - reducerCombined -} = combinedHandler(['all','one'], 'events'); +const duck = makeDuck({ + getAll: () => apiFetch('/events'), // browse + read: (id) => apiFetch(`/events/${id}`), + add: (body) => apiFetch('/events', { method: 'POST', body }), + edit: (id, body) => apiFetch(`/events/${id}`, { method: 'PUT', body }), +}); -export function getOne(event_id) { - return function dispatcher(dispatch, getState) { - const state = getState(); - const token = get(state, 'user.auth.token', null); +export const { getAll, add, edit, read, initialStateCombined } = duck; - const promise = apiFetch(`/events/${event_id}`, { headers: { Authorization: token } }); - return oneHandler(promise, dispatch); - }; -} +const reducer = resetReducer(initialStateCombined, (state = initialStateCombined, action) => { + return duck.reducerCombined(state, action); +}); -export function getAll() { - return function dispatcher(dispatch, getState) { - const state = getState(); - const token = get(state, 'user.auth.token', null); +export default reducer; - const promise = apiFetch('/events', { headers: { Authorization: token } }); - return allHandler(promise, dispatch); - }; -} -export function formatDateRange(event) { +// const { +// // allHandler, +// // oneHandler, +// reducerCombined +// } = combinedHandler(['all','one'], 'events'); + +// export function read(event_id) { +// return function dispatcher(dispatch, getState) { +// const state = getState(); +// const token = get(state, 'user.auth.token', null); + +// const promise = apiFetch(`/events/${event_id}`, { headers: { Authorization: token } }); +// return oneHandler(promise, dispatch); +// }; +// } + +// export function getAll() { +// return function dispatcher(dispatch, getState) { +// const state = getState(); +// const token = get(state, 'user.auth.token', null); + +// const promise = apiFetch('/events', { headers: { Authorization: token } }); +// return allHandler(promise, dispatch); +// }; +// } + + +export function formatDateRange(start_date, end_date) { var out = { - start_date: new Date(event.start_date), + start_date: new Date(start_date), start_date_string: "", start_time_string: "", - end_date: new Date(event.end_date), + end_date: new Date(end_date), end_date_string: "", end_time_string: "", full_date_string: "" @@ -60,11 +77,11 @@ export function formatDateRange(event) { out.end_date_string = out.end_date.toLocaleDateString(); out.end_time_string = out.end_date.toLocaleTimeString(); - if (event.start_date != null) { + if (start_date != null) { out.full_date_string = out.start_date_string+" "+out.start_time_string; } - if (event.end_date != null) { + if (end_date != null) { if (out.start_date_string === out.end_date_string && out.start_time_string === out.end_time_string) { out.full_date_string = out.start_date_string+" "+out.start_time_string; } else if (out.start_date_string === out.end_date_string) { @@ -77,4 +94,4 @@ export function formatDateRange(event) { return out; } -export default reducerCombined; +// export default reducerCombined;