import React, { useState, useEffect } from 'react'; import { Panel, Form, FormControl, ControlLabel, HelpBlock, Button, ButtonGroup, Message, FormGroup, } from 'rsuite'; import { DateTime } from 'luxon'; import { useHistory } from 'react-router-dom'; import { NavBar, TimezonePicker, DaySelector, DurationSelector, SelectedDates, } from '../components'; import { backend } from '../helpers/http-common'; import { durations } from '../assets/data/durations'; import './styles/Schedule.less'; export default function Schedule({ possibleDates, setPossibleDates, currentMeeting, setCurrentMeeting, }) { const [eventsList, setEventsList] = useState([]); const [datesList, setDatesList] = useState(eventsToDates(eventsList)); const [durationIdx, setDurationIdx] = useState(0); const [error, setError] = useState(false); const history = useHistory(); useEffect(() => { // Push the selected dates up the state tree // but keep all related logic here setPossibleDates(eventsList); }, [eventsList, setPossibleDates]); useEffect(() => { let updatedDates = eventsToDates(eventsList).sort(); setDatesList(updatedDates); }, [eventsList]); // EVENTS & DATES const handleSelectDates = (info) => { let updatedEvents = []; let datesList = new Set(); /// Add each date selected to datesList let start = DateTime.fromISO(info.startStr); let end = DateTime.fromISO(info.endStr); // Check if selection contains only one day let singleDay = end.toISODate() === start.plus({ days: 1 }).toISODate(); if (singleDay) { // When a single date is selected let selectedDate = info.startStr; let selectedEvent = { start: selectedDate, display: 'background' }; // If selectedEvent exists in the list, find and set its index let selectedEventIndex; for (let index = 0; index < eventsList.length; index++) { const eventDate = eventsList[index].start; if (selectedDate === eventDate) { // If it's the case, set current index to selectedEventIndex selectedEventIndex = index; break; } } if (selectedEventIndex !== undefined) { // If selectedEventIndex exists, remove the corresponding event from the list eventsList.splice(selectedEventIndex, 1); updatedEvents = [...eventsList]; } else { // Add selected event to the list updatedEvents = [...eventsList, selectedEvent]; } } else { // When a range of dates is selected let currentDate = start; while (!(+end === +currentDate)) { // Add currentDate to the datesList datesList.add(currentDate.toISODate()); let newDate = currentDate.plus({ days: 1 }); currentDate = newDate; } // Add each date from the eventsList to datesList eventsList.forEach((event) => { datesList.add(event.start); }); // Create events from datesList and add them to updatedEvents datesList.forEach((date) => { updatedEvents.push({ start: date, display: 'background' }); }); } setEventsList(updatedEvents); }; const handleDelete = (date) => { let currentEvent = { start: date.toFormat('yyyy-MM-dd'), display: 'background', }; // Find the event corresponding to the date let selectedEventIndex; for (let index = 0; index < eventsList.length; index++) { const eventDate = eventsList[index].start; if (currentEvent.start === eventDate) { // When it's the case, set current index to selectedEventIndex selectedEventIndex = index; break; } } // Create updated eventsList eventsList.splice(selectedEventIndex, 1); let updatedEvents = [...eventsList]; // Update the eventsList setEventsList(updatedEvents); }; const handleClear = () => { setEventsList([]); }; // MEETING const handleSchedule = () => { backend .post('/meetings', currentMeeting) .then((response) => { history.push('/availability'); }) .catch((error) => { setError('Failed to add new account.'); }); }; const handleSelectTimezone = (value, item, event) => { setCurrentMeeting({ ...currentMeeting, timezone: item.timezone, }); }; const handleClean = (event) => { setCurrentMeeting({ ...currentMeeting, timezone: '', }); }; const handleChangeMeeting = (value, evt) => { setCurrentMeeting({ ...currentMeeting, [evt.target.name]: value, }); }; const handleIncrement = () => { if (durationIdx <= durations.length - 2) { setDurationIdx(durationIdx + 1); } setCurrentMeeting({ ...currentMeeting, duration: durations[durationIdx].duration, }); }; const handleDecrement = () => { if (durationIdx > 0) { setDurationIdx(durationIdx - 1); } setCurrentMeeting({ ...currentMeeting, duration: durations[durationIdx].duration, }); }; return ( <>
Title This field is required Description
Timezone Duration
{error && ( )}
{datesList.length > 0 && ( <> )}
); } // Convert events to Luxon Datetime objects const eventsToDates = (events) => { let dates = []; events.forEach((event) => { dates.push(DateTime.fromFormat(event.start, 'yyyy-MM-dd')); }); return dates; };