Connect Schedule to API and

This commit is contained in:
rui hildt 2020-08-22 22:49:03 +02:00
parent 3356c380d7
commit 017f6e3869
6 changed files with 130 additions and 36 deletions

View File

@ -21,9 +21,15 @@ const existingUser = JSON.parse(localStorage.getItem('user'));
export default function App() { export default function App() {
const [isAuthenticated, setIsAuthenticated] = useState(!!existingToken); const [isAuthenticated, setIsAuthenticated] = useState(!!existingToken);
const [currentUser, setCurrentUser] = useState(existingUser || ''); const [currentUser, setCurrentUser] = useState(existingUser || '');
const [possibleDates, setPossibleDates] = useState(); const [possibleDates, setPossibleDates] = useState();
// const [currentMeeting, setCurrentMeeting] = useState(); const [currentMeeting, setCurrentMeeting] = useState({
title: '',
description: '',
timezone: '',
duration: 0,
status: 0,
});
const [authToken, setAuthToken] = useState(existingToken || ''); const [authToken, setAuthToken] = useState(existingToken || '');
@ -68,13 +74,15 @@ export default function App() {
component={Schedule} component={Schedule}
possibleDates={possibleDates} possibleDates={possibleDates}
setPossibleDates={setPossibleDates} setPossibleDates={setPossibleDates}
currentMeeting={currentMeeting}
setCurrentMeeting={setCurrentMeeting}
/> />
<PrivateRoute path='/invite' component={Invite} />
<PrivateRoute <PrivateRoute
path='/availability' path='/availability'
component={Availability} component={Availability}
possibleDates={possibleDates}
/> />
<PrivateRoute path='/schedule' component={Schedule} /> <PrivateRoute path='/invite' component={Invite} />
</Switch> </Switch>
</Router> </Router>
</AuthContext.Provider> </AuthContext.Provider>

View File

@ -8,10 +8,9 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
return ( return (
<Route <Route
{...rest}
render={(props) => render={(props) =>
isAuthenticated ? ( isAuthenticated ? (
<Component {...props} /> <Component {...rest} {...props} />
) : ( ) : (
<Redirect to='/login' /> <Redirect to='/login' />
) )

View File

@ -1,23 +1,13 @@
import React, { useState } from 'react'; import React from 'react';
import { InputGroup, Icon } from 'rsuite'; import { InputGroup, Icon } from 'rsuite';
import { durations } from '../../assets/data/durations'; import { durations } from '../../assets/data/durations';
export default function DurationSelector() { export default function DurationSelector({
const [durationIdx, setDurationIdx] = useState(0); durationIdx,
handleDecrement,
const handleIncrement = () => { handleIncrement,
if (durationIdx <= durations.length - 2) { }) {
setDurationIdx(durationIdx + 1);
}
};
const handleDecrement = () => {
if (durationIdx > 0) {
setDurationIdx(durationIdx - 1);
}
};
return ( return (
<InputGroup style={{ background: 'white' }}> <InputGroup style={{ background: 'white' }}>
<InputGroup.Button onClick={handleDecrement}> <InputGroup.Button onClick={handleDecrement}>

View File

@ -1,9 +1,15 @@
import axios from 'axios'; import axios from 'axios';
import { API_URL } from '../constants'; import { API_URL } from '../constants';
const existingToken = JSON.parse(localStorage.getItem('token'));
export const backend = axios.create({ export const backend = axios.create({
baseURL: API_URL, baseURL: API_URL,
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
}, },
}); });
if (existingToken) {
backend.defaults.headers['Authorization'] = existingToken;
}

View File

@ -14,7 +14,7 @@ import { NavBar, TimezonePicker, IntervalSelector } from '../components';
import './styles/Availability.less'; import './styles/Availability.less';
import './styles/layout.less'; import './styles/layout.less';
export default function Availability() { export default function Availability({ possibleDates }) {
const [availability, setAvailability] = useState([...availabilityList]); const [availability, setAvailability] = useState([...availabilityList]);
const handleClear = () => { const handleClear = () => {

View File

@ -4,7 +4,6 @@ import {
Form, Form,
FormControl, FormControl,
ControlLabel, ControlLabel,
Input,
HelpBlock, HelpBlock,
Button, Button,
ButtonGroup, ButtonGroup,
@ -12,6 +11,7 @@ import {
FormGroup, FormGroup,
} from 'rsuite'; } from 'rsuite';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { useHistory } from 'react-router-dom';
import { import {
NavBar, NavBar,
@ -20,19 +20,36 @@ import {
DurationSelector, DurationSelector,
SelectedDates, SelectedDates,
} from '../components'; } from '../components';
import { backend } from '../helpers/http-common';
import { durations } from '../assets/data/durations';
import './styles/Schedule.less'; import './styles/Schedule.less';
export default function Schedule() { export default function Schedule({
possibleDates,
setPossibleDates,
currentMeeting,
setCurrentMeeting,
}) {
const [eventsList, setEventsList] = useState([]); const [eventsList, setEventsList] = useState([]);
const [datesList, setDatesList] = useState(eventsToDates(eventsList)); 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(datesList)
}, [datesList, setPossibleDates])
// EVENTS & DATES
useEffect(() => { useEffect(() => {
let updatedDates = eventsToDates(eventsList).sort(); let updatedDates = eventsToDates(eventsList).sort();
setDatesList(updatedDates); setDatesList(updatedDates);
}, [eventsList]); }, [eventsList]);
const handleSelect = (info) => { const handleSelectDates = (info) => {
let updatedEvents = []; let updatedEvents = [];
let datesList = new Set(); let datesList = new Set();
@ -90,10 +107,6 @@ export default function Schedule() {
setEventsList(updatedEvents); setEventsList(updatedEvents);
}; };
const handleClear = () => {
setEventsList([]);
};
const handleDelete = (date) => { const handleDelete = (date) => {
let currentEvent = { let currentEvent = {
start: date.toFormat('yyyy-MM-dd'), start: date.toFormat('yyyy-MM-dd'),
@ -117,6 +130,65 @@ export default function Schedule() {
setEventsList(updatedEvents); 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 ( return (
<> <>
<NavBar title='Schedule a meeting' /> <NavBar title='Schedule a meeting' />
@ -125,27 +197,42 @@ export default function Schedule() {
<div className={'meeting-info'}> <div className={'meeting-info'}>
<FormGroup> <FormGroup>
<ControlLabel>Title</ControlLabel> <ControlLabel>Title</ControlLabel>
<FormControl name='title' type='text' /> <FormControl
name='title'
type='text'
formValue={currentMeeting.title}
onChange={handleChangeMeeting}
/>
<HelpBlock>This field is required</HelpBlock> <HelpBlock>This field is required</HelpBlock>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<ControlLabel>Description</ControlLabel> <ControlLabel>Description</ControlLabel>
<Input <FormControl
name='description' name='description'
componentClass='textarea' componentClass='textarea'
type='text' type='text'
rows={3} rows={3}
placeholder='(optional)' placeholder='(optional)'
formValue={currentMeeting.description}
onChange={handleChangeMeeting}
/> />
</FormGroup> </FormGroup>
<div className='meeting-options-inline'> <div className='meeting-options-inline'>
<FormGroup className='meeting-timezone'> <FormGroup className='meeting-timezone'>
<ControlLabel>Timezone</ControlLabel> <ControlLabel>Timezone</ControlLabel>
<TimezonePicker /> <TimezonePicker
handleSelect={handleSelectTimezone}
handleClean={handleClean}
timezone={currentMeeting.timezone}
/>
</FormGroup> </FormGroup>
<FormGroup className='meeting-duration'> <FormGroup className='meeting-duration'>
<ControlLabel>Duration</ControlLabel> <ControlLabel>Duration</ControlLabel>
<DurationSelector /> <DurationSelector
durationIdx={durationIdx}
handleDecrement={handleDecrement}
handleIncrement={handleIncrement}
/>
</FormGroup> </FormGroup>
</div> </div>
<ButtonGroup justified> <ButtonGroup justified>
@ -163,9 +250,13 @@ export default function Schedule() {
size='lg' size='lg'
block block
disabled={datesList.length === 0} disabled={datesList.length === 0}
onClick={handleSchedule}
> >
Confirm dates Confirm dates
</Button> </Button>
{error && (
<Message type='error' description={error} />
)}
</ButtonGroup> </ButtonGroup>
<div className={'selected-dates'}></div> <div className={'selected-dates'}></div>
{datesList.length > 0 && ( {datesList.length > 0 && (
@ -185,7 +276,7 @@ export default function Schedule() {
/> />
<DaySelector <DaySelector
eventsList={eventsList} eventsList={eventsList}
handleSelect={handleSelect} handleSelect={handleSelectDates}
handleClear={handleClear} handleClear={handleClear}
/> />
</div> </div>