Lift Schedule child components state to parent

This commit is contained in:
rui hildt 2020-06-02 16:17:17 +02:00
parent 38858668eb
commit 950e2e3165
3 changed files with 160 additions and 178 deletions

View File

@ -1,79 +1,9 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import interaction from '@fullcalendar/interaction';
import { DateTime } from 'luxon';
export default function DaySelector() {
const [eventsList, setEventsList] = useState([]);
useEffect(() => {
console.log('Latest events list: ', eventsList);
}, [eventsList]);
const handleSelect = (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];
}
// setEventsList(updatedEvents);
} 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 handleClear = () => {
setEventsList([])
}
export default function DaySelector({ eventsList, handleSelect, handleClear }) {
return (
<FullCalendar
initialView='dayGridMonth'
@ -83,8 +13,10 @@ export default function DaySelector() {
select={(info) => handleSelect(info)}
defaultAllDay={true}
events={eventsList}
customButtons={{resetSelection:{text: 'clear selection', click: handleClear}}}
headerToolbar={{right: 'resetSelection today prev,next'}}
customButtons={{
resetSelection: { text: 'clear selection', click: handleClear },
}}
headerToolbar={{ right: 'resetSelection today prev,next' }}
/>
);
}

View File

@ -1,102 +1,26 @@
import React, { useState, useEffect } from 'react';
import { DateTime } from 'luxon';
import React from 'react';
import { Divider, Icon, IconButton } from 'rsuite';
export default function SelectedDates() {
const [eventsList, setEventsList] = useState([
{
start: '2020-04-29',
display: 'background',
},
{
start: '2020-04-30',
display: 'background',
},
{
start: '2020-05-07',
display: 'background',
},
{
start: '2020-05-06',
display: 'background',
},
]);
const [datesList, setDatesList] = useState(eventsToDates(eventsList));
useEffect(() => {
// Update selected dates
let updatedDates = eventsToDates(eventsList);
setDatesList(updatedDates);
}, [eventsList]);
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);
};
export default function SelectedDates({ datesList, eventsList, handleDelete }) {
return (
<>
{datesList.length > 0 && (
<div>
<h3>Dates selected</h3>
<ul>
{datesList.map((date) => (
<li key={date}>
{date.setLocale('en-gb').toLocaleString()}
{` (${date.weekdayShort})`}
<Divider vertical />
<IconButton
icon={<Icon icon='close' />}
appearance='subtle'
circle
onClick={() => handleDelete(date)}
></IconButton>
</li>
))}
</ul>
</div>
)}
</>
<div>
<h3>Dates selected</h3>
<ul>
{datesList.map((date) => (
<li key={date}>
{date.setLocale('en-gb').toLocaleString()}
{` (${date.weekdayShort})`}
<Divider vertical />
<IconButton
icon={<Icon icon='close' />}
appearance='subtle'
circle
onClick={() => handleDelete(date)}
></IconButton>
</li>
))}
</ul>
</div>
);
}
// 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;
};
// Convert Luxon Datetime objects to events
const datesToEvents = (dates) => {
let events = [];
dates.forEach((date) => {
let event = {
start: date.toFormat('yyyy-MM-dd'),
display: 'background',
};
events.push(event);
});
return events;
};

View File

@ -1,5 +1,6 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import { Container, Form, FormControl, FormGroup, Input, Button } from 'rsuite';
import { DateTime } from 'luxon';
import TimezonePicker from '../components/General/TimezonePicker';
import DaySelector from '../components/Schedule/DaySelector';
@ -7,6 +8,101 @@ import DurationSelector from '../components/Schedule/DurationSelector';
import SelectedDates from '../components/Schedule/SelectedDates';
export default function Schedule() {
const [eventsList, setEventsList] = useState([]);
const [datesList, setDatesList] = useState(eventsToDates(eventsList));
useEffect(() => {
// Update selected dates
let updatedDates = eventsToDates(eventsList);
setDatesList(updatedDates);
}, [eventsList]);
const handleSelect = (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];
}
// setEventsList(updatedEvents);
} 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 handleClear = () => {
setEventsList([]);
};
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);
};
return (
<Container>
<h3>Schedule a meeting</h3>
@ -30,15 +126,45 @@ export default function Schedule() {
<DurationSelector />
</FormGroup>
<FormGroup>
<DaySelector />
</FormGroup>
<FormGroup>
<SelectedDates />
</FormGroup>
<FormGroup>
<Button>Confirm dates</Button>
<DaySelector
eventsList={eventsList}
handleSelect={handleSelect}
handleClear={handleClear}
/>
</FormGroup>
{datesList.length > 0 && (
<FormGroup>
<SelectedDates
datesList={datesList}
eventsList={eventsList}
handleDelete={handleDelete}
/>
<Button>Confirm dates</Button>
</FormGroup>
)}
</Form>
</Container>
);
}
// 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;
};
// Convert Luxon Datetime objects to events
const datesToEvents = (dates) => {
let events = [];
dates.forEach((date) => {
let event = {
start: date.toFormat('yyyy-MM-dd'),
display: 'background',
};
events.push(event);
});
return events;
};