diff --git a/app/soapbox/features/compose/components/schedule_form.js b/app/soapbox/features/compose/components/schedule_form.js
deleted file mode 100644
index 866b61429..000000000
--- a/app/soapbox/features/compose/components/schedule_form.js
+++ /dev/null
@@ -1,129 +0,0 @@
-'use strict';
-
-import classNames from 'classnames';
-import PropTypes from 'prop-types';
-import React from 'react';
-import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import { connect } from 'react-redux';
-
-import IconButton from 'soapbox/components/icon_button';
-import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
-import { DatePicker } from 'soapbox/features/ui/util/async-components';
-
-import { setSchedule, removeSchedule } from '../../../actions/compose';
-
-const messages = defineMessages({
- schedule: { id: 'schedule.post_time', defaultMessage: 'Post Date/Time' },
- remove: { id: 'schedule.remove', defaultMessage: 'Remove schedule' },
-});
-
-const mapStateToProps = state => ({
- active: state.getIn(['compose', 'schedule']) ? true : false,
- scheduledAt: state.getIn(['compose', 'schedule']),
-});
-
-const mapDispatchToProps = dispatch => ({
- onSchedule(date) {
- dispatch(setSchedule(date));
- },
-
- onRemoveSchedule(date) {
- dispatch(removeSchedule());
- },
-});
-
-export default @connect(mapStateToProps, mapDispatchToProps)
-@injectIntl
-class ScheduleForm extends React.Component {
-
- static propTypes = {
- scheduledAt: PropTypes.instanceOf(Date),
- intl: PropTypes.object.isRequired,
- onSchedule: PropTypes.func.isRequired,
- onRemoveSchedule: PropTypes.func.isRequired,
- dispatch: PropTypes.func,
- active: PropTypes.bool,
- };
-
- state = {
- initialized: false,
- }
-
- setSchedule = date => {
- this.props.onSchedule(date);
- }
-
- setRef = c => {
- this.datePicker = c;
- }
-
- openDatePicker = () => {
- if (!this.datePicker) return;
- this.datePicker.setOpen(true);
- }
-
- isCurrentOrFutureDate(date) {
- return date && new Date().setHours(0, 0, 0, 0) <= new Date(date).setHours(0, 0, 0, 0);
- }
-
- isFiveMinutesFromNow(time) {
- const fiveMinutesFromNow = new Date(new Date().getTime() + 300000); // now, plus five minutes (Pleroma won't schedule posts )
- const selectedDate = new Date(time);
-
- return fiveMinutesFromNow.getTime() < selectedDate.getTime();
- }
-
- handleRemove = e => {
- this.props.onRemoveSchedule();
- e.preventDefault();
- }
-
- initialize = () => {
- const { initialized } = this.state;
-
- if (!initialized && this.datePicker) {
- this.openDatePicker();
- this.setState({ initialized: true });
- }
- }
-
- componentDidUpdate() {
- this.initialize();
- }
-
- render() {
- if (!this.props.active) {
- return null;
- }
-
- const { intl, scheduledAt } = this.props;
-
- return (
-
-
-
-
-
-
- {Component => ()}
-
-
-
-
-
-
- );
- }
-
-}
diff --git a/app/soapbox/features/compose/components/schedule_form.tsx b/app/soapbox/features/compose/components/schedule_form.tsx
new file mode 100644
index 000000000..6467ba51e
--- /dev/null
+++ b/app/soapbox/features/compose/components/schedule_form.tsx
@@ -0,0 +1,84 @@
+'use strict';
+
+import classNames from 'classnames';
+import React from 'react';
+import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
+
+import { setSchedule, removeSchedule } from 'soapbox/actions/compose';
+import IconButton from 'soapbox/components/icon_button';
+import { HStack, Stack, Text } from 'soapbox/components/ui';
+import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
+import { DatePicker } from 'soapbox/features/ui/util/async-components';
+import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
+
+const isCurrentOrFutureDate = (date: Date) => {
+ return date && new Date().setHours(0, 0, 0, 0) <= new Date(date).setHours(0, 0, 0, 0);
+};
+
+const isFiveMinutesFromNow = (time: Date) => {
+ const fiveMinutesFromNow = new Date(new Date().getTime() + 300000); // now, plus five minutes (Pleroma won't schedule posts )
+ const selectedDate = new Date(time);
+
+ return fiveMinutesFromNow.getTime() < selectedDate.getTime();
+};
+
+const messages = defineMessages({
+ schedule: { id: 'schedule.post_time', defaultMessage: 'Post Date/Time' },
+ remove: { id: 'schedule.remove', defaultMessage: 'Remove schedule' },
+});
+
+const ScheduleForm: React.FC = () => {
+ const dispatch = useAppDispatch();
+ const intl = useIntl();
+
+ const scheduledAt = useAppSelector((state) => state.compose.get('schedule'));
+ const active = !!scheduledAt;
+
+ const onSchedule = (date: Date) => {
+ dispatch(setSchedule(date));
+ };
+
+ const handleRemove = (e: React.MouseEvent) => {
+ dispatch(removeSchedule());
+ e.preventDefault();
+ };
+
+ if (!active) {
+ return null;
+ }
+
+ return (
+
+
+
+
+
+
+ {Component => ()}
+
+
+
+
+ );
+};
+
+export default ScheduleForm;
diff --git a/app/styles/components/datepicker.scss b/app/styles/components/datepicker.scss
index 60cb58409..ed5a5d839 100644
--- a/app/styles/components/datepicker.scss
+++ b/app/styles/components/datepicker.scss
@@ -1,14 +1,22 @@
.react-datepicker {
- @apply p-4 font-sans text-xs text-gray-900 border border-solid border-gray-200 rounded-lg;
+ @apply dark:bg-slate-900 dark:border-slate-700 p-4 font-sans text-xs text-gray-900 dark:text-gray-300 border border-solid border-gray-200 rounded-lg;
+}
+
+.react-datepicker__input-container > input {
+ @apply dark:bg-slate-800 dark:text-white block w-full sm:text-sm border-gray-300 dark:border-gray-600 rounded-md focus:ring-indigo-500 focus:border-indigo-500;
+
+ &.has-error {
+ @apply text-red-600 border-red-600;
+ }
}
.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle::before,
.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle::after {
- @apply border-b-white;
+ @apply border-b-white dark:border-b-slate-900;
}
.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle::before {
- @apply border-b-gray-200;
+ @apply border-b-gray-200 dark:border-b-slate-700;
}
.react-datepicker__header:not(.react-datepicker__header--has-time-select) {
@@ -16,14 +24,14 @@
}
.react-datepicker__header {
- @apply bg-white border-b-0 py-1 px-0;
+ @apply bg-white dark:bg-slate-900 border-b-0 py-1 px-0;
// border-top-left-radius: var(--border-radius-lg);
}
.react-datepicker__current-month,
.react-datepicker-time__header,
.react-datepicker-year-header {
- @apply text-gray-900 font-bold text-sm;
+ @apply text-gray-900 dark:text-gray-300 font-bold text-sm;
}
.react-datepicker__current-month {
@@ -31,7 +39,7 @@
}
.react-datepicker__navigation {
- @apply top-4 h-8 w-8 rounded hover:bg-gray-50;
+ @apply top-4 h-8 w-8 rounded hover:bg-gray-50 dark:hover:bg-slate-900/50;
}
.react-datepicker__navigation-icon {
@@ -70,24 +78,37 @@
.react-datepicker__day-names,
.react-datepicker__week {
- display: flex;
- justify-content: space-between;
+ @apply flex justify-between;
+}
+
+.react-datepicker__time {
+ @apply dark:bg-slate-900;
+}
+
+.react-datepicker__time-container {
+ @apply dark:border-slate-700;
}
.react-datepicker__day-name,
.react-datepicker__day,
.react-datepicker__time-name {
- @apply text-gray-900;
+ @apply text-gray-900 dark:text-gray-300;
width: 30px;
height: 30px;
line-height: 30px;
}
+.react-datepicker__time-list-item--disabled,
+.react-datepicker__day--disabled {
+ @apply text-gray-400 dark:text-gray-500;
+}
+
.react-datepicker__day:hover,
.react-datepicker__month-text:hover,
.react-datepicker__quarter-text:hover,
-.react-datepicker__year-text:hover {
- @apply bg-gray-100 rounded;
+.react-datepicker__year-text:hover,
+.react-datepicker__time-list-item:hover {
+ @apply bg-gray-100 dark:bg-slate-700 rounded;
}
.react-datepicker__day--selected,
@@ -102,16 +123,12 @@
.react-datepicker__year-text--selected,
.react-datepicker__year-text--in-selecting-range,
.react-datepicker__year-text--in-range {
- @apply bg-primary-600 hover:bg-primary-700 text-white rounded;
-}
-
-.react-datepicker__day--disabled {
- @apply text-gray-400;
+ @apply bg-primary-600 hover:bg-primary-700 dark:bg-slate-300 dark:hover:bg-slate-200 text-white dark:text-black rounded;
}
.react-datepicker__day--keyboard-selected,
.react-datepicker__month-text--keyboard-selected,
.react-datepicker__quarter-text--keyboard-selected,
.react-datepicker__year-text--keyboard-selected {
- @apply bg-primary-50 hover:bg-primary-100 text-primary-600 dark:text-primary-400;
+ @apply bg-primary-50 hover:bg-primary-100 dark:bg-slate-700 dark:hover:bg-slate-600 text-primary-600 dark:text-primary-400;
}