Connect Schedule to API and
This commit is contained in:
parent
3356c380d7
commit
017f6e3869
16
src/App.js
16
src/App.js
@ -21,9 +21,15 @@ const existingUser = JSON.parse(localStorage.getItem('user'));
|
||||
export default function App() {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(!!existingToken);
|
||||
const [currentUser, setCurrentUser] = useState(existingUser || '');
|
||||
|
||||
|
||||
const [possibleDates, setPossibleDates] = useState();
|
||||
// const [currentMeeting, setCurrentMeeting] = useState();
|
||||
const [currentMeeting, setCurrentMeeting] = useState({
|
||||
title: '',
|
||||
description: '',
|
||||
timezone: '',
|
||||
duration: 0,
|
||||
status: 0,
|
||||
});
|
||||
|
||||
const [authToken, setAuthToken] = useState(existingToken || '');
|
||||
|
||||
@ -68,13 +74,15 @@ export default function App() {
|
||||
component={Schedule}
|
||||
possibleDates={possibleDates}
|
||||
setPossibleDates={setPossibleDates}
|
||||
currentMeeting={currentMeeting}
|
||||
setCurrentMeeting={setCurrentMeeting}
|
||||
/>
|
||||
<PrivateRoute path='/invite' component={Invite} />
|
||||
<PrivateRoute
|
||||
path='/availability'
|
||||
component={Availability}
|
||||
possibleDates={possibleDates}
|
||||
/>
|
||||
<PrivateRoute path='/schedule' component={Schedule} />
|
||||
<PrivateRoute path='/invite' component={Invite} />
|
||||
</Switch>
|
||||
</Router>
|
||||
</AuthContext.Provider>
|
||||
|
@ -8,10 +8,9 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
|
||||
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={(props) =>
|
||||
isAuthenticated ? (
|
||||
<Component {...props} />
|
||||
<Component {...rest} {...props} />
|
||||
) : (
|
||||
<Redirect to='/login' />
|
||||
)
|
||||
|
@ -1,23 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import { InputGroup, Icon } from 'rsuite';
|
||||
|
||||
import { durations } from '../../assets/data/durations';
|
||||
|
||||
export default function DurationSelector() {
|
||||
const [durationIdx, setDurationIdx] = useState(0);
|
||||
|
||||
const handleIncrement = () => {
|
||||
if (durationIdx <= durations.length - 2) {
|
||||
setDurationIdx(durationIdx + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDecrement = () => {
|
||||
if (durationIdx > 0) {
|
||||
setDurationIdx(durationIdx - 1);
|
||||
}
|
||||
};
|
||||
|
||||
export default function DurationSelector({
|
||||
durationIdx,
|
||||
handleDecrement,
|
||||
handleIncrement,
|
||||
}) {
|
||||
return (
|
||||
<InputGroup style={{ background: 'white' }}>
|
||||
<InputGroup.Button onClick={handleDecrement}>
|
||||
|
@ -1,9 +1,15 @@
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '../constants';
|
||||
|
||||
const existingToken = JSON.parse(localStorage.getItem('token'));
|
||||
|
||||
export const backend = axios.create({
|
||||
baseURL: API_URL,
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (existingToken) {
|
||||
backend.defaults.headers['Authorization'] = existingToken;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import { NavBar, TimezonePicker, IntervalSelector } from '../components';
|
||||
import './styles/Availability.less';
|
||||
import './styles/layout.less';
|
||||
|
||||
export default function Availability() {
|
||||
export default function Availability({ possibleDates }) {
|
||||
const [availability, setAvailability] = useState([...availabilityList]);
|
||||
|
||||
const handleClear = () => {
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
Form,
|
||||
FormControl,
|
||||
ControlLabel,
|
||||
Input,
|
||||
HelpBlock,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
@ -12,6 +11,7 @@ import {
|
||||
FormGroup,
|
||||
} from 'rsuite';
|
||||
import { DateTime } from 'luxon';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
NavBar,
|
||||
@ -20,19 +20,36 @@ import {
|
||||
DurationSelector,
|
||||
SelectedDates,
|
||||
} from '../components';
|
||||
|
||||
import { backend } from '../helpers/http-common';
|
||||
import { durations } from '../assets/data/durations';
|
||||
import './styles/Schedule.less';
|
||||
|
||||
export default function Schedule() {
|
||||
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(datesList)
|
||||
}, [datesList, setPossibleDates])
|
||||
|
||||
// EVENTS & DATES
|
||||
useEffect(() => {
|
||||
let updatedDates = eventsToDates(eventsList).sort();
|
||||
setDatesList(updatedDates);
|
||||
}, [eventsList]);
|
||||
|
||||
const handleSelect = (info) => {
|
||||
const handleSelectDates = (info) => {
|
||||
let updatedEvents = [];
|
||||
let datesList = new Set();
|
||||
|
||||
@ -90,10 +107,6 @@ export default function Schedule() {
|
||||
setEventsList(updatedEvents);
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
setEventsList([]);
|
||||
};
|
||||
|
||||
const handleDelete = (date) => {
|
||||
let currentEvent = {
|
||||
start: date.toFormat('yyyy-MM-dd'),
|
||||
@ -117,6 +130,65 @@ export default function Schedule() {
|
||||
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 (
|
||||
<>
|
||||
<NavBar title='Schedule a meeting' />
|
||||
@ -125,27 +197,42 @@ export default function Schedule() {
|
||||
<div className={'meeting-info'}>
|
||||
<FormGroup>
|
||||
<ControlLabel>Title</ControlLabel>
|
||||
<FormControl name='title' type='text' />
|
||||
<FormControl
|
||||
name='title'
|
||||
type='text'
|
||||
formValue={currentMeeting.title}
|
||||
onChange={handleChangeMeeting}
|
||||
/>
|
||||
<HelpBlock>This field is required</HelpBlock>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<ControlLabel>Description</ControlLabel>
|
||||
<Input
|
||||
<FormControl
|
||||
name='description'
|
||||
componentClass='textarea'
|
||||
type='text'
|
||||
rows={3}
|
||||
placeholder='(optional)'
|
||||
formValue={currentMeeting.description}
|
||||
onChange={handleChangeMeeting}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div className='meeting-options-inline'>
|
||||
<FormGroup className='meeting-timezone'>
|
||||
<ControlLabel>Timezone</ControlLabel>
|
||||
<TimezonePicker />
|
||||
<TimezonePicker
|
||||
handleSelect={handleSelectTimezone}
|
||||
handleClean={handleClean}
|
||||
timezone={currentMeeting.timezone}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup className='meeting-duration'>
|
||||
<ControlLabel>Duration</ControlLabel>
|
||||
<DurationSelector />
|
||||
<DurationSelector
|
||||
durationIdx={durationIdx}
|
||||
handleDecrement={handleDecrement}
|
||||
handleIncrement={handleIncrement}
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<ButtonGroup justified>
|
||||
@ -163,9 +250,13 @@ export default function Schedule() {
|
||||
size='lg'
|
||||
block
|
||||
disabled={datesList.length === 0}
|
||||
onClick={handleSchedule}
|
||||
>
|
||||
Confirm dates
|
||||
</Button>
|
||||
{error && (
|
||||
<Message type='error' description={error} />
|
||||
)}
|
||||
</ButtonGroup>
|
||||
<div className={'selected-dates'}></div>
|
||||
{datesList.length > 0 && (
|
||||
@ -185,7 +276,7 @@ export default function Schedule() {
|
||||
/>
|
||||
<DaySelector
|
||||
eventsList={eventsList}
|
||||
handleSelect={handleSelect}
|
||||
handleSelect={handleSelectDates}
|
||||
handleClear={handleClear}
|
||||
/>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user