sipp11
7 years ago
21 changed files with 521 additions and 66 deletions
@ -0,0 +1,217 @@ |
|||||||
|
import React, { Component } from 'react' |
||||||
|
import styled from 'styled-components' |
||||||
|
import { connect } from 'react-redux' |
||||||
|
import { Redirect, Link } from 'react-router-dom' |
||||||
|
|
||||||
|
import { updateCalendar, createCalendar, deleteCalendar } from '../actions/calendar' |
||||||
|
import store from '../store' |
||||||
|
import HorizontalInput from './parts/HorizontalInput' |
||||||
|
import HorizontalDate from './parts/HorizontalDate' |
||||||
|
import HorizontalCheckbox from './parts/HorizontalCheckbox' |
||||||
|
|
||||||
|
const StyledCalendarForm = styled.div` |
||||||
|
padding: 1rem; |
||||||
|
background: #fafafa; |
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarForm extends Component { |
||||||
|
|
||||||
|
state = { |
||||||
|
id: null, |
||||||
|
service_id: "", |
||||||
|
start_date: "", |
||||||
|
end_date: "", |
||||||
|
monday: false, |
||||||
|
tuesday: false, |
||||||
|
wednesday: false, |
||||||
|
thursday: false, |
||||||
|
friday: false, |
||||||
|
saturday: false, |
||||||
|
sunday: false, |
||||||
|
} |
||||||
|
|
||||||
|
constructor() { |
||||||
|
super() |
||||||
|
this.handleChange = this.handleChange.bind(this) |
||||||
|
this.handleSubmit = this.handleSubmit.bind(this) |
||||||
|
this.handleDelete = this.handleDelete.bind(this) |
||||||
|
this.renderForm = this.renderForm.bind(this) |
||||||
|
} |
||||||
|
|
||||||
|
handleChange(evt) { |
||||||
|
let updated = {} |
||||||
|
updated[evt.target.name] = evt.target.value |
||||||
|
this.setState(updated) |
||||||
|
} |
||||||
|
|
||||||
|
handleSubmit() { |
||||||
|
const { id } = this.state |
||||||
|
let body = {...this.state} |
||||||
|
delete body.id |
||||||
|
if (id !== null) { |
||||||
|
store.dispatch(updateCalendar(id, body)) |
||||||
|
} else { |
||||||
|
store.dispatch(createCalendar(body)) |
||||||
|
} |
||||||
|
this.setState({justSubmit: true}) |
||||||
|
} |
||||||
|
|
||||||
|
handleDelete() { |
||||||
|
const { id } = this.state |
||||||
|
store.dispatch(deleteCalendar(id)) |
||||||
|
this.setState({justSubmit: true}) |
||||||
|
} |
||||||
|
|
||||||
|
componentWillMount() { |
||||||
|
const { props } = this |
||||||
|
const { serviceId } = props.match.params |
||||||
|
const { results } = props.calendar |
||||||
|
const ones = results.filter(ele => ele.service_id === serviceId) |
||||||
|
if (ones.length > 0) { |
||||||
|
this.setState(ones[0]) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
renderForm() { |
||||||
|
const one = this.state |
||||||
|
const { fetching } = this.props.calendar |
||||||
|
return ( |
||||||
|
<StyledCalendarForm> |
||||||
|
<h1 className="title">{one.name} </h1> |
||||||
|
<div className="content"> |
||||||
|
<HorizontalInput |
||||||
|
label="Calendar ID" |
||||||
|
type="text" |
||||||
|
fieldName="service_id" |
||||||
|
value={one.service_id || ''} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalDate |
||||||
|
label="Start Date" |
||||||
|
type="text" |
||||||
|
fieldName="start_date" |
||||||
|
value={one.start_date || ''} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalDate |
||||||
|
key="end_date" |
||||||
|
label="End Date" |
||||||
|
type="text" |
||||||
|
fieldName="end_date" |
||||||
|
value={one.end_date || ''} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Monday" |
||||||
|
label="Monday" |
||||||
|
type="text" |
||||||
|
fieldName="monday" |
||||||
|
value={one.monday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Tuesday" |
||||||
|
label="Tuesday" |
||||||
|
type="text" |
||||||
|
fieldName="tuesday" |
||||||
|
value={one.tuesday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Wednesday" |
||||||
|
label="Wednesday" |
||||||
|
type="text" |
||||||
|
fieldName="wednesday" |
||||||
|
value={one.wednesday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Thursday" |
||||||
|
label="Thursday" |
||||||
|
type="text" |
||||||
|
fieldName="thursday" |
||||||
|
value={one.thursday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Friday" |
||||||
|
label="Friday" |
||||||
|
type="text" |
||||||
|
fieldName="friday" |
||||||
|
value={one.friday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Saturday" |
||||||
|
label="Saturday" |
||||||
|
type="text" |
||||||
|
fieldName="saturday" |
||||||
|
value={one.saturday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
<HorizontalCheckbox |
||||||
|
key="Sunday" |
||||||
|
label="Sunday" |
||||||
|
type="text" |
||||||
|
fieldName="sunday" |
||||||
|
value={one.sunday || false} |
||||||
|
handleChange={this.handleChange} /> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
<div className="field is-grouped"> |
||||||
|
<div className="control"> |
||||||
|
<button className="button is-link" |
||||||
|
onClick={this.handleSubmit} |
||||||
|
disabled={fetching}> |
||||||
|
Save</button> |
||||||
|
</div> |
||||||
|
{one.id !== null && <div className="control"> |
||||||
|
<button className="button is-danger" |
||||||
|
onClick={this.handleDelete} |
||||||
|
disabled={fetching}> |
||||||
|
DELETE</button> |
||||||
|
</div>} |
||||||
|
<div className="control"> |
||||||
|
<Link to={`/calendar`} className="button is-text">Cancel</Link> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</StyledCalendarForm> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
const one = this.state |
||||||
|
const { fetching } = this.props.calendar |
||||||
|
// redirect to view page if no data
|
||||||
|
const { serviceId } = this.props.match.params |
||||||
|
// this is a create form
|
||||||
|
if (serviceId === undefined) { |
||||||
|
if (one.justSubmit === true && !fetching) { |
||||||
|
return <Redirect to={`/calendar`} /> |
||||||
|
} |
||||||
|
return this.renderForm() |
||||||
|
} |
||||||
|
|
||||||
|
if (one.id === null && serviceId.length > 0) |
||||||
|
return <Redirect to={`/calendar`} /> |
||||||
|
|
||||||
|
// redirect to calendar list if submitted
|
||||||
|
if (one.justSubmit === true && !fetching) { |
||||||
|
return <Redirect to={`/calendar`} /> |
||||||
|
} |
||||||
|
return this.renderForm() |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({ |
||||||
|
calendar: state.calendar |
||||||
|
}) |
||||||
|
|
||||||
|
const connectCalendarFom = connect( |
||||||
|
mapStateToProps, |
||||||
|
)(CalendarForm) |
||||||
|
export default connectCalendarFom |
@ -0,0 +1,112 @@ |
|||||||
|
import React, { Component } from 'react' |
||||||
|
import styled from 'styled-components' |
||||||
|
import { connect } from 'react-redux' |
||||||
|
import { Link } from 'react-router-dom' |
||||||
|
|
||||||
|
import { getCalendar } from '../actions/calendar' |
||||||
|
import store from '../store' |
||||||
|
|
||||||
|
|
||||||
|
const StyledBox = styled.div` |
||||||
|
padding: 1rem; |
||||||
|
background: #fafafa; |
||||||
|
` |
||||||
|
|
||||||
|
const GapBox = styled.span` |
||||||
|
margin-right: 5px; |
||||||
|
color: ${props => props.checked ? 'green' : 'gray'};; |
||||||
|
` |
||||||
|
|
||||||
|
const FakeRow = styled.nav` |
||||||
|
padding-top: 5px; |
||||||
|
padding-bottom: 5px; |
||||||
|
background: white; |
||||||
|
margin-bottom: 1rem; |
||||||
|
` |
||||||
|
|
||||||
|
|
||||||
|
const CheckboxIcon = (props) => ( |
||||||
|
<GapBox checked={props.checked}> |
||||||
|
{props.checked === true && <span><i className="fas fa-check-square"></i></span>} |
||||||
|
{props.checked !== true && <span><i className="fas fa-square"></i></span>} |
||||||
|
</GapBox> |
||||||
|
) |
||||||
|
|
||||||
|
class CalendarList extends Component { |
||||||
|
|
||||||
|
componentWillMount() { |
||||||
|
const { count } = this.props.calendar |
||||||
|
if (count === 0) |
||||||
|
store.dispatch(getCalendar()) |
||||||
|
} |
||||||
|
|
||||||
|
render() { |
||||||
|
const { results } = this.props.calendar |
||||||
|
const { match } = this.props |
||||||
|
return ( |
||||||
|
<StyledBox> |
||||||
|
<h1 className="title">Service</h1> |
||||||
|
<div className="columns"> |
||||||
|
<div className="column is-12"> |
||||||
|
<nav className="level is-mobile"> |
||||||
|
<p className="level-item has-text-centered"> |
||||||
|
<Link className="link is-info" to={`${match.url}/new`}> |
||||||
|
<i className="fas fa-plus" /> New service |
||||||
|
</Link> |
||||||
|
</p> |
||||||
|
</nav> |
||||||
|
{results && Object.keys(results).map(i => ( |
||||||
|
<FakeRow className="level panel" key={i}> |
||||||
|
<div className="level-item has-text-centered"> |
||||||
|
<div> |
||||||
|
<p className="heading">Service ID</p> |
||||||
|
<p className="title"><Link to={`${match.url}/${results[i].service_id}`}>{results[i].service_id}</Link></p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="level-item has-text-centered"> |
||||||
|
<div> |
||||||
|
<p className="heading">Start</p> |
||||||
|
<p className="title">{results[i].start_date}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="level-item has-text-centered"> |
||||||
|
<div> |
||||||
|
<p className="heading">End</p> |
||||||
|
<p className="title">{results[i].end_date}</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="level-item has-text-centered"> |
||||||
|
<div> |
||||||
|
<p className="heading">M T W Th F Sa Su</p> |
||||||
|
<p className="title"> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].monday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].tuesday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].wednesday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].thursday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].friday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].saturday} /> |
||||||
|
<CheckboxIcon disabled={true} checked={results[i].sunday} /> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</FakeRow> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</StyledBox> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = state => ({ |
||||||
|
calendar: state.calendar |
||||||
|
}) |
||||||
|
const connectCalendarList = connect( |
||||||
|
mapStateToProps, |
||||||
|
{}, |
||||||
|
)(CalendarList) |
||||||
|
|
||||||
|
export default styled(connectCalendarList)` |
||||||
|
color: palevioletred; |
||||||
|
font-weight: bold; |
||||||
|
` |
@ -0,0 +1,30 @@ |
|||||||
|
import React from 'react' |
||||||
|
|
||||||
|
const HorizontalInput = (props) => ( |
||||||
|
<div className="field is-horizontal"> |
||||||
|
<div className="field-label is-normal"> |
||||||
|
{/* <label for={`id_${props.fieldName}`} className="label">{props.label}</label> */} |
||||||
|
</div> |
||||||
|
<div className="field-body"> |
||||||
|
<div className="field"> |
||||||
|
<input |
||||||
|
className="is-checkradio has-background-color is-info" |
||||||
|
id={`id_${props.fieldName}`} |
||||||
|
type="checkbox" |
||||||
|
name={props.fieldName} |
||||||
|
defaultChecked={props.value} |
||||||
|
onChange={(evt) => { |
||||||
|
let res = { |
||||||
|
target: { |
||||||
|
name: evt.target.name, |
||||||
|
value: evt.target.checked |
||||||
|
} |
||||||
|
} |
||||||
|
return props.handleChange(res)}} /> |
||||||
|
<label htmlFor={`id_${props.fieldName}`}>{props.label}</label> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
export default HorizontalInput |
@ -0,0 +1,30 @@ |
|||||||
|
import React from 'react' |
||||||
|
import Flatpickr from 'react-flatpickr' |
||||||
|
import 'flatpickr/dist/themes/airbnb.css' |
||||||
|
|
||||||
|
|
||||||
|
const HorizontalDate = (props) => ( |
||||||
|
<div className="field is-horizontal"> |
||||||
|
<div className="field-label is-normal"> |
||||||
|
<label className="label">{props.label}</label> |
||||||
|
</div> |
||||||
|
<div className="field-body"> |
||||||
|
<div className="field"> |
||||||
|
<p className="control"> |
||||||
|
<Flatpickr |
||||||
|
className="input" |
||||||
|
defaultValue={props.value} |
||||||
|
onChange={(date) => { |
||||||
|
let evt = { |
||||||
|
target: { |
||||||
|
name: props.fieldName, |
||||||
|
value: date[0].toISOString('YYYY-MM-DD').slice(0, 10) |
||||||
|
}} |
||||||
|
return props.handleChange(evt)}} /> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
export default HorizontalDate |
@ -0,0 +1,21 @@ |
|||||||
|
import React from 'react' |
||||||
|
|
||||||
|
const HorizontalInput = (props) => ( |
||||||
|
<div className="field is-horizontal"> |
||||||
|
<div className="field-label is-normal"> |
||||||
|
<label className="label">{props.label}</label> |
||||||
|
</div> |
||||||
|
<div className="field-body"> |
||||||
|
<div className="field"> |
||||||
|
<p className="control"> |
||||||
|
<input className="input" type={props.type || 'text'} |
||||||
|
name={props.fieldName} |
||||||
|
onChange={props.handleChange} |
||||||
|
defaultValue={props.value} /> |
||||||
|
</p> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
|
||||||
|
export default HorizontalInput |
Loading…
Reference in new issue