From ed64bff3dae3a2dc7e4f11cf9768cf1b9a98283e Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Wed, 17 Jan 2018 11:27:43 +0000 Subject: [PATCH] Switch to react-datetime for the date time picker The reason for that is because not all browsers support input type=date/time --- package.json | 1 + src/components/EventEdit.tsx | 34 +++++++++----- src/widgets/DateTimePicker.tsx | 85 +++++++++------------------------- yarn.lock | 27 ++++++++++- 4 files changed, 73 insertions(+), 74 deletions(-) diff --git a/package.json b/package.json index 8374f46..f046b0d 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "node-rsa": "^0.4.2", "react": "^16.2.0", "react-big-calendar": "^0.17.0", + "react-datetime": "^2.11.1", "react-dom": "^16.2.0", "react-redux": "^5.0.6", "react-router": "^4.2.0", diff --git a/src/components/EventEdit.tsx b/src/components/EventEdit.tsx index 4ecc24b..7c87205 100644 --- a/src/components/EventEdit.tsx +++ b/src/components/EventEdit.tsx @@ -26,8 +26,8 @@ class EventEdit extends React.PureComponent { uid: string, title: string; allDay: boolean; - start: string; - end: string; + start?: Date; + end?: Date; location: string; description: string; journalUid: string; @@ -53,8 +53,6 @@ class EventEdit extends React.PureComponent { allDay: false, location: '', description: '', - start: '', - end: '', journalUid: '', showDeleteDialog: false, @@ -72,8 +70,8 @@ class EventEdit extends React.PureComponent { this.state.uid = event.uid; this.state.title = event.title ? event.title : ''; this.state.allDay = allDay; - this.state.start = event.startDate.toString(); - this.state.end = endDate.toString(); + this.state.start = event.startDate.toJSDate(); + this.state.end = endDate.toJSDate(); this.state.location = event.location ? event.location : ''; this.state.description = event.description ? event.description : ''; } else { @@ -124,12 +122,24 @@ class EventEdit extends React.PureComponent { onSubmit(e: React.FormEvent) { e.preventDefault(); - if ((this.state.start === '') || (this.state.end === '')) { + if ((!this.state.start) || (!this.state.end)) { this.setState({error: 'Both start and end time must be set!'}); return; } - const startDate = ICAL.Time.fromString(this.state.start); - let endDate = ICAL.Time.fromString(this.state.end); + + function fromDate(date: Date, allDay: boolean) { + const ret = ICAL.Time.fromJSDate(date, false); + if (!allDay) { + return ret; + } else { + let data = ret.toJSON(); + data.isDate = allDay; + return ICAL.Time.fromData(data); + } + } + + const startDate = fromDate(this.state.start, this.state.allDay); + const endDate = fromDate(this.state.end, this.state.allDay); if (this.state.allDay) { endDate.adjust(1, 0, 0, 0); @@ -217,16 +227,18 @@ class EventEdit extends React.PureComponent {
this.setState({start: date})} + onChange={(date?: Date) => this.setState({start: date})} />
this.setState({end: date})} + onChange={(date?: Date) => this.setState({end: date})} />
diff --git a/src/widgets/DateTimePicker.tsx b/src/widgets/DateTimePicker.tsx index ee6faf2..4ad07b9 100644 --- a/src/widgets/DateTimePicker.tsx +++ b/src/widgets/DateTimePicker.tsx @@ -1,82 +1,43 @@ import * as React from 'react'; -class DateTimePicker extends React.PureComponent { - state: { - date: string, - time: string, - }; +import * as moment from 'moment'; +import * as Datetime from 'react-datetime'; +import 'react-datetime/css/react-datetime.css'; + +class DateTimePicker extends React.PureComponent { props: { - value?: string, + placeholder: string, + value?: Date, dateOnly?: boolean, - onChange: (date: string) => void; + onChange: (date?: Date) => void; }; constructor(props: any) { super(props); - this.state = { - date: '', - time: '', - }; - - if (props.value) { - const str = props.value; - this.state.date = str.substr(0, 10); - this.state.time = str.substr(11, 5); - } this.handleInputChange = this.handleInputChange.bind(this); - this.reportChange = this.reportChange.bind(this); - } - - handleInputChange(event: React.ChangeEvent) { - const name = event.target.name; - const value = event.target.value; - this.setState( - { - [name]: value - }, - () => this.reportChange(this.props) - ); - } - - componentWillReceiveProps(nextProps: any) { - if (this.props.dateOnly !== nextProps.dateOnly) { - this.reportChange(nextProps); - } } - reportChange(props: any) { - const { date, time } = this.state; - - if (date !== undefined) { - if (props.dateOnly) { - props.onChange(date); - } else if (time !== undefined) { - props.onChange(date + ' ' + time + ':00'); - } + handleInputChange(newDate: string | moment.Moment) { + if (moment.isMoment(newDate)) { + this.props.onChange(newDate.toDate()); + } else { + this.props.onChange(undefined); } } render() { + const inputProps = { + placeholder: this.props.placeholder, + readOnly: true, + }; return ( - - - - {this.props.dateOnly || - } - + ); } } diff --git a/yarn.lock b/yarn.lock index c926a5e..ec3f796 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,6 +1171,14 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-react-class@^15.5.2: + version "15.6.2" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + object-assign "^4.1.1" + cross-spawn@5.1.0, cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1932,7 +1940,7 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs@^0.8.1, fbjs@^0.8.16: +fbjs@^0.8.1, fbjs@^0.8.16, fbjs@^0.8.9: version "0.8.16" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: @@ -3826,6 +3834,10 @@ object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^ version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + object-keys@^1.0.6: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -4588,6 +4600,15 @@ react-big-calendar@^0.17.0: uncontrollable "^3.3.1 || ^4.0.0" warning "^2.0.0" +react-datetime@^2.11.1: + version "2.11.1" + resolved "https://registry.yarnpkg.com/react-datetime/-/react-datetime-2.11.1.tgz#11d15081dd7d6729284e21c1b8ea7b975e3bdc7e" + dependencies: + create-react-class "^15.5.2" + object-assign "^3.0.0" + prop-types "^15.5.7" + react-onclickoutside "^6.5.0" + react-dev-utils@^4.0.1: version "4.2.1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-4.2.1.tgz#9f2763e7bafa1a1b9c52254d2a479deec280f111" @@ -4633,6 +4654,10 @@ react-event-listener@^0.5.1: prop-types "^15.6.0" warning "^3.0.0" +react-onclickoutside@^6.5.0: + version "6.7.1" + resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz#6a5b5b8b4eae6b776259712c89c8a2b36b17be93" + react-overlays@^0.7.0: version "0.7.4" resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.7.4.tgz#ef2ec652c3444ab8aa014262b18f662068e56d5c"