Skip to content

Commit

Permalink
fix schedule form
Browse files Browse the repository at this point in the history
  • Loading branch information
IldarKamalov committed Aug 25, 2023
1 parent 83e4017 commit 84d29e5
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 74 deletions.
1 change: 1 addition & 0 deletions client/src/__locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@
"schedule_invalid_select": "The start time must be before the end time",
"schedule_select_days": "Select days",
"schedule_timezone": "Select timezone",
"schedule_current_timezone": "Current timezone: {{value}}",
"schedule_time_all_day": "All day",
"schedule_modal_description": "This schedule will replace any existing schedules for the same day of the week. Each day of the week can have only one inactivity period.",
"schedule_modal_time_off": "Blocked services are disabled at this time:",
Expand Down
64 changes: 45 additions & 19 deletions client/src/components/Filters/Services/ScheduleForm/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ReactModal from 'react-modal';

import { Timezone, LOCAL_TIMEZONE_VALUE } from './Timezone';
import { TimeSelect } from './TimeSelect';
import { TimePeriod } from './TimePeriod';
import { getFullDayName, getShortDayName } from './helpers';

export const DAYS_OF_WEEK = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
Expand All @@ -31,6 +32,8 @@ export const Modal = ({
const [startTime, setStartTime] = useState(INITIAL_START_TIME_MS);
const [endTime, setEndTime] = useState(INITIAL_END_TIME_MS);

const [wrongPeriod, setWrongPeriod] = useState(true);

useEffect(() => {
if (currentDay) {
const newDays = new Set([currentDay]);
Expand All @@ -41,6 +44,14 @@ export const Modal = ({
}
}, [currentDay]);

useEffect(() => {
if (startTime >= endTime) {
setWrongPeriod(true);
} else {
setWrongPeriod(false);
}
}, [startTime, endTime]);

const addDays = (day) => {
const newDays = new Set(days);

Expand Down Expand Up @@ -124,28 +135,34 @@ export const Modal = ({
)) }
</div>

{/* TODO add validation for selected time */}
<div className="schedule__time-row">
<TimeSelect
value={startTime}
onChange={(v) => setStartTime(v)}
/>

<TimeSelect
value={endTime}
onChange={(v) => setEndTime(v)}
/>
<div className="schedule__time-wrap">
<div className="schedule__time-row">
<TimeSelect
value={startTime}
onChange={(v) => setStartTime(v)}
/>

<TimeSelect
value={endTime}
onChange={(v) => setEndTime(v)}
/>
</div>

{wrongPeriod && (
<div className="schedule__error">
{t('schedule_invalid_select')}
</div>
)}
</div>

<div className="schedule__info">
<div className="schedule__info-title">
{t('schedule_modal_time_off')}
</div>
<div className="schedule__info-row">
{/* TODO: add calendar icon from DNS */}
{/* <svg className="icons schedule__info-icon">
<svg className="icons schedule__info-icon">
<use xlinkHref="#calendar" />
</svg> */}
</svg>
{days.size ? (
Array.from(days).map((day) => getFullDayName(t, day)).join(', ')
) : (
Expand All @@ -154,12 +171,21 @@ export const Modal = ({
</span>
)}
</div>
{/* TODO: show selected time */}
{/* <div>
<svg className="icons">
<div className="schedule__info-row">
<svg className="icons schedule__info-icon">
<use xlinkHref="#watch" />
</svg>
</div> */}
{wrongPeriod ? (
<span>
</span>
) : (
<TimePeriod
startTimeMs={startTime}
endTimeMs={endTime}
/>
)}
</div>
</div>

<div className="schedule__notice">
Expand All @@ -171,7 +197,7 @@ export const Modal = ({
<button
type="submit"
className="btn btn-success btn-standard"
disabled={days.size === 0}
disabled={days.size === 0 || wrongPeriod}
>
{currentDay ? t('schedule_save') : t('schedule_add')}
</button>
Expand Down
25 changes: 25 additions & 0 deletions client/src/components/Filters/Services/ScheduleForm/TimePeriod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';

import { getTimeFromMs } from './helpers';

export const TimePeriod = ({
startTimeMs,
endTimeMs,
}) => {
const startTime = getTimeFromMs(startTimeMs);
const endTime = getTimeFromMs(endTimeMs);

return (
<div className="schedule__time">
<time>{startTime.hours}:{startTime.minutes}</time>
&nbsp;–&nbsp;
<time>{endTime.hours}:{endTime.minutes}</time>
</div>
);
};

TimePeriod.propTypes = {
startTimeMs: PropTypes.number.isRequired,
endTimeMs: PropTypes.number.isRequired,
};
101 changes: 53 additions & 48 deletions client/src/components/Filters/Services/ScheduleForm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
import PropTypes from 'prop-types';

import { Modal } from './Modal';
import { getFullDayName, getTimeFromMs } from './helpers';

import { getFullDayName, getShortDayName } from './helpers';
import { TimePeriod } from './TimePeriod';
import './styles.css';

export const ScheduleForm = ({
Expand Down Expand Up @@ -53,56 +53,61 @@ export const ScheduleForm = ({

return (
<div>
{filteredScheduleKeys.map((day) => {
const data = schedule[day];

if (!data) {
return undefined;
}

const startTime = getTimeFromMs(data.start);
const endTime = getTimeFromMs(data.end);

return (
<div key={day} className="schedule__row">
<div className="schedule__day">
{getFullDayName(t, day)}
</div>
<div className="schedule__time">
<time>{startTime.hours}:{startTime.minutes}</time>
&nbsp;–&nbsp;
<time>{endTime.hours}:{endTime.minutes}</time>
</div>
<div className="schedule__actions">
<button
type="button"
className="btn btn-icon btn-outline-primary btn-sm schedule__button"
title={t('edit_table_action')}
onClick={() => onEdit(day)}
>
<svg className="icons icon12">
<use xlinkHref="#edit" />
</svg>
</button>

<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm schedule__button"
title={t('delete_table_action')}
onClick={() => onDelete(day)}
>
<svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button>
<div className="schedule__current-timezone">
{t('schedule_current_timezone', { value: schedule.time_zone })}
</div>

<div className="schedule__rows">
{filteredScheduleKeys.map((day) => {
const data = schedule[day];

if (!data) {
return undefined;
}

return (
<div key={day} className="schedule__row">
<div className="schedule__day">
{getFullDayName(t, day)}
</div>
<div className="schedule__day schedule__day--mobile">
{getShortDayName(t, day)}
</div>
<TimePeriod
startTimeMs={data.start}
endTimeMs={data.end}
/>
<div className="schedule__actions">
<button
type="button"
className="btn btn-icon btn-outline-primary btn-sm schedule__button"
title={t('edit_table_action')}
onClick={() => onEdit(day)}
>
<svg className="icons icon12">
<use xlinkHref="#edit" />
</svg>
</button>

<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm schedule__button"
title={t('delete_table_action')}
onClick={() => onDelete(day)}
>
<svg className="icons">
<use xlinkHref="#delete" />
</svg>
</button>
</div>
</div>
</div>
);
})}
);
})}
</div>

<button
type="button"
className="btn btn-success btn-standard mt-3"
className="btn btn-success btn-standard"
onClick={onAdd}
>
{t('schedule_new')}
Expand Down
67 changes: 60 additions & 7 deletions client/src/components/Filters/Services/ScheduleForm/styles.css
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
.schedule__row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}

.schedule__row:last-child {
margin-bottom: 0;
}

.schedule__rows {
margin-bottom: 24px;
}

.schedule__day {
display: none;
min-width: 110px;
}

.schedule__time {
min-width: 110px;
.schedule__day--mobile {
display: block;
min-width: 50px;
}

@media screen and (min-width: 767px) {
.schedule__row {
justify-content: flex-start;
}

.schedule__day {
display: block;
}

.schedule__day--mobile {
display: none;
}

.schedule__actions {
margin-left: 32px;
white-space: nowrap;
}
}

.schedule__actions {
margin-left: 32px;
.schedule__time {
min-width: 110px;
}

.schedule__button {
Expand Down Expand Up @@ -48,10 +78,13 @@
border-color: var(--btn-success-bgcolor);
}

.schedule__time-wrap {
margin-bottom: 24px;
}

.schedule__time-row {
display: flex;
align-items: center;
margin-bottom: 24px;
gap: 16px;
}

Expand All @@ -60,10 +93,20 @@
align-items: center;
}

.schedule__error {
margin-top: 4px;
font-size: 13px;
color: #cd201f;
}

.schedule__timezone {
margin-bottom: 24px;
}

.schedule__current-timezone {
margin-bottom: 16px;
}

.schedule__info {
margin-bottom: 24px;
}
Expand All @@ -73,9 +116,19 @@
}

.schedule__info-title {
margin-bottom: 4px;
margin-bottom: 8px;
}

.schedule__info-row {
font-size: 13px;
display: flex;
align-items: center;
margin-bottom: 4px;
}

.schedule__info-icon {
width: 24px;
height: 24px;
margin-right: 8px;
color: #495057;
flex-shrink: 0;
}
Loading

0 comments on commit 84d29e5

Please sign in to comment.