251 lines
5.7 KiB
JavaScript
251 lines
5.7 KiB
JavaScript
import React, { useState } from 'react';
|
|
import { Redirect, useHistory } from 'react-router-dom';
|
|
import {
|
|
Panel,
|
|
Form,
|
|
ControlLabel,
|
|
Button,
|
|
ButtonGroup,
|
|
Message,
|
|
FormGroup,
|
|
} from 'rsuite';
|
|
|
|
import {
|
|
NavBar,
|
|
TimezonePicker,
|
|
TimePicker,
|
|
IntervalSelector,
|
|
} from '../components';
|
|
import dtToUTC from '../helpers/datetimeToUTC';
|
|
import { backend } from '../helpers/http-common';
|
|
import './styles/Availability.less';
|
|
import './styles/layout.less';
|
|
// // DEV possibleDates
|
|
// const possibleDates = [
|
|
// {
|
|
// id: 63,
|
|
// start: '2020-08-01',
|
|
// display: 'background',
|
|
// },
|
|
// {
|
|
// id: 64,
|
|
// start: '2020-08-02',
|
|
// display: 'background',
|
|
// },
|
|
// ];
|
|
|
|
// NOTES:
|
|
// Even though Fullcalendar is supposed to work with timezone,
|
|
// it seems the custom rendering code breaks it.
|
|
// Possible Dates ID are also striped by custom code.
|
|
// That's why timezone and possible dates id are only set when posting an availability.
|
|
|
|
export default function Availability({
|
|
currentUser,
|
|
currentMeeting,
|
|
possibleDates,
|
|
}) {
|
|
const [availability, setAvailability] = useState([]);
|
|
const [timezone, setTimezone] = useState(currentUser.timezone);
|
|
const [times, setTimes] = useState({
|
|
earliest: currentUser.earliest_time,
|
|
latest: currentUser.latest_time,
|
|
});
|
|
const [status, setStatus] = useState({
|
|
error: null,
|
|
success: null,
|
|
message: '',
|
|
});
|
|
|
|
const history = useHistory();
|
|
|
|
const handleClear = () => {
|
|
setAvailability([]);
|
|
};
|
|
|
|
const handleSelect = ({ start, end }) => {
|
|
setAvailability([
|
|
...availability,
|
|
{
|
|
start: start,
|
|
end: end,
|
|
},
|
|
]);
|
|
};
|
|
|
|
const handleSubmit = () => {
|
|
// Create a list of availability to post
|
|
const availabilityList = availability.map((event) => {
|
|
// Format start date to availability
|
|
const selectedDate = event.start.toISOString().substring(0, 10);
|
|
// Find the date id
|
|
const [date] = possibleDates.filter(
|
|
(date) => date.start === selectedDate,
|
|
);
|
|
|
|
return {
|
|
meeting_id: currentMeeting.id,
|
|
account_id: currentUser.id,
|
|
possible_date_id: date.id,
|
|
preference: false, // set to 'true" when implementing preference
|
|
start_time: dtToUTC(event.start, timezone),
|
|
end_time: dtToUTC(event.end, timezone),
|
|
};
|
|
});
|
|
|
|
// Create availability post request
|
|
const postAvailability = (data) => {
|
|
return backend.post('/availability', data);
|
|
};
|
|
|
|
const requests = availabilityList.map((event) =>
|
|
postAvailability(event),
|
|
);
|
|
|
|
Promise.all(requests)
|
|
.then(function (results) {
|
|
// Add confirmation message
|
|
setStatus({
|
|
success: true,
|
|
error: false,
|
|
message: 'Your availability has been added to the meeting.',
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
setStatus({
|
|
error: true,
|
|
success: false,
|
|
message:
|
|
"Your availability couldn't be added to the meeting.",
|
|
});
|
|
});
|
|
};
|
|
|
|
const handleSelectTimezone = (value, item, event) => {
|
|
setTimezone(item.timezone);
|
|
};
|
|
|
|
const handleClearTimezone = () => {
|
|
setTimezone(currentUser.timezone);
|
|
};
|
|
|
|
const handleEarliest = (value, item, event) => {
|
|
setTimes({
|
|
...times,
|
|
earliest: value,
|
|
});
|
|
};
|
|
|
|
const handleLatest = (value, item, event) => {
|
|
setTimes({
|
|
...times,
|
|
latest: value,
|
|
});
|
|
};
|
|
|
|
if (!possibleDates) {
|
|
return <Redirect to='/dashboard' />;
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<NavBar title='Add your availability' />
|
|
<Panel className={'app-container'}>
|
|
<Form className={'av-container'}>
|
|
<div className={'av-details'}>
|
|
<FormGroup>
|
|
<ControlLabel>Earliest time</ControlLabel>
|
|
<TimePicker
|
|
time={times.earliest}
|
|
handleSelect={handleEarliest}
|
|
/>
|
|
</FormGroup>
|
|
<FormGroup>
|
|
<ControlLabel>Latest time</ControlLabel>
|
|
<TimePicker
|
|
time={times.latest}
|
|
handleSelect={handleLatest}
|
|
/>
|
|
</FormGroup>
|
|
<FormGroup className='av-timezone'>
|
|
<ControlLabel>Timezone</ControlLabel>
|
|
<TimezonePicker
|
|
timezone={timezone}
|
|
handleSelect={handleSelectTimezone}
|
|
handleClean={handleClearTimezone}
|
|
/>
|
|
</FormGroup>
|
|
<div className='av-controls'>
|
|
{!status.success && (
|
|
<ButtonGroup justified>
|
|
<Button
|
|
appearance='ghost'
|
|
block
|
|
size='lg'
|
|
disabled={availability.length === 0}
|
|
onClick={() => handleClear()}
|
|
>
|
|
Clear selection
|
|
</Button>
|
|
<Button
|
|
appearance='primary'
|
|
size='lg'
|
|
block
|
|
disabled={availability.length === 0}
|
|
onClick={handleSubmit}
|
|
>
|
|
Save your availability
|
|
</Button>
|
|
</ButtonGroup>
|
|
)}
|
|
|
|
{status.success && (
|
|
<ButtonGroup justified>
|
|
<Button
|
|
appearance='ghost'
|
|
size='lg'
|
|
block
|
|
onClick={() => history.push('dashboard')}
|
|
>
|
|
Go to dashboard
|
|
</Button>
|
|
<Button
|
|
appearance='primary'
|
|
size='lg'
|
|
block
|
|
onClick={() => history.push('invite')}
|
|
>
|
|
Invite Participants
|
|
</Button>
|
|
</ButtonGroup>
|
|
)}
|
|
{(status.error || status.success) && (
|
|
<Message
|
|
type={status.success ? 'success' : 'error'}
|
|
description={status.message}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className={'interval-selector'}>
|
|
<Message
|
|
showIcon
|
|
type='info'
|
|
description='Select your availability on the calendar.'
|
|
/>
|
|
<IntervalSelector
|
|
selectedDates={possibleDates}
|
|
availability={availability}
|
|
setAvailability={setAvailability}
|
|
handleSelect={handleSelect}
|
|
handleClear={handleClear}
|
|
slotMinTime={times.earliest}
|
|
slotMaxTime={times.latest}
|
|
/>
|
|
</div>
|
|
</Form>
|
|
</Panel>
|
|
</>
|
|
);
|
|
}
|