Add Invite screen

This commit is contained in:
rui hildt 2020-08-14 13:54:36 +02:00
parent 036bbcb396
commit cfb4a7ad0f
6 changed files with 193 additions and 20 deletions

View File

@ -15,11 +15,14 @@ export default function MenuDropdown() {
const MenuPopover = ({ onSelect, ...rest }) => (
<Popover {...rest} full>
<Dropdown.Menu onSelect={onSelect}>
<Dropdown.Item eventKey={'login'}>Login</Dropdown.Item>
<Dropdown.Item eventKey={'register'}>Register</Dropdown.Item>
<Dropdown.Item eventKey={'/'}>Dashboard</Dropdown.Item>
<Dropdown.Item eventKey={'schedule'}>Schedule a Meeting</Dropdown.Item>
<Dropdown.Item eventKey={4}>Account Settings</Dropdown.Item>
<Dropdown.Item eventKey={'register'}>Register</Dropdown.Item>
<Dropdown.Item eventKey={'login'}>Login</Dropdown.Item>
<Dropdown.Item eventKey={'schedule'}>1 - Schedule a meeting</Dropdown.Item>
<Dropdown.Item eventKey={'invite'}>2 - Invite participants</Dropdown.Item>
<Dropdown.Item eventKey={'availability'}>3 - Add your availability</Dropdown.Item>
<Dropdown.Item eventKey={'confirm'}>4 - Confirm meeting date</Dropdown.Item>
<Dropdown.Item eventKey={'settings'}>Settings</Dropdown.Item>
<Dropdown.Item eventKey={5}>Log Out</Dropdown.Item>
</Dropdown.Menu>
</Popover>

View File

@ -5,36 +5,42 @@ import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Dashboard from './Dashboard';
import Schedule from './Schedule/Schedule';
import Availability from './Availability/Availability';
import Invite from './Invite/Invite';
import Login from './Login';
import Register from './Register';
const titles = {
schedule: 'Schedule a meeting',
availability: 'Add you availability',
invite: 'Invite participants',
availability: 'Add your availability',
confirm: 'Confirm meeting date',
dashboard: 'Dashboard',
login: 'Login',
register: 'Registration',
settings: 'Settings'
register: 'Register',
settings: 'Settings',
};
export default function App() {
return (
<Router>
<Switch>
<Route path='/' exact>
<Availability title={titles.availability} />
</Route>
<Route path='/availability'>
<Availability title={titles.availability} />
<Route path='/' exact>
<Invite title={titles.invite} />
</Route>
<Route path='/schedule'>
<Schedule title={titles.schedule} />
</Route>
<Route path='/invite'>
<Invite title={titles.invite} />
</Route>
<Route path='/availability'>
<Availability title={titles.availability} />
</Route>
<Route path='/dashboard'>
<Dashboard title={titles.dashboard}/>
<Dashboard title={titles.dashboard} />
</Route>
<Route path='/login'>
<Login title={titles.login}/>
<Login title={titles.login} />
</Route>
<Route path='/register'>
<Register title={titles.register} />

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import {
Panel,
@ -20,10 +20,6 @@ import './Availability.less';
export default function Availability({ title }) {
const [availability, setAvailability] = useState([...availabilityList]);
useEffect(() => {
console.log(availability);
}, [availability]);
const handleClear = () => {
setAvailability([]);
};

View File

@ -0,0 +1,141 @@
import React, { useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import { Panel, Form, Button, ButtonGroup, Message, TagPicker } from 'rsuite';
import NavBar from '../../components/Navbar/NavBar';
import './Invite.less';
export default function Invite({ title }) {
const [participants, setParticipants] = useState([]);
const [contactDropdown, setContactDropdown] = useState([]);
const history = useHistory();
useEffect(() => {
console.log('useEffect participants: ', participants);
console.log('useEffect contactDropdown: ', contactDropdown);
}, [participants, contactDropdown]);
const handleSelect = (value) => {
// TODO Verify if input contains an email
// TODO Verify if email is already in the participants
let updatedContactDropdown = [...contactDropdown];
if (value.length > 0) {
// Find emails in text input
let emailRegex = /[-.\w]+@([\w-]+\.)+[\w-]+/g;
let emailsRaw = value[value.length - 1].match(emailRegex);
// Remove duplicates from the text input
let emails = [...new Set(emailsRaw)];
if (emails && emails.length > 1) {
// Delete input from participants
value.pop();
emails.forEach((email) => {
// add each email to participants
value.push(email);
// Create new contact and add it to dropdown
let newContact = {
label: email,
value: email,
// TODO add contact groups here
// see rsuite TagPicker doc
};
// Add it to the updated dropdown
updatedContactDropdown.push(newContact);
});
}
// Update dropdown
setContactDropdown(updatedContactDropdown);
}
};
const handleChange = (value) => {
setParticipants(value);
};
const handleClear = () => {
setContactDropdown([]);
setParticipants([]);
};
return (
<>
<NavBar title={title} />
<Panel style={containerStyle}>
<Form className={'av-container'}>
<div className={'interval-selector'}>
<Message
showIcon
type='info'
description='Add emails of participants. (Optional)'
/>
<TagPicker
block
creatable
searchable
data={contactDropdown}
value={participants}
onSelect={(value) => handleSelect(value)}
onChange={(value) => handleChange(value)}
/>
<ButtonGroup justified>
<Button
appearance='ghost'
block
size='lg'
onClick={handleClear}
>
Clear selection
</Button>
<Button appearance='primary' size='lg' block>
Send invites
</Button>
</ButtonGroup>
</div>
<div className={'av-details'}>
<ButtonGroup justified>
<Button
appearance='primary'
size='lg'
block
onClick={() => {history.push('availability');}}
>
Add your availability
</Button>
</ButtonGroup>
</div>
</Form>
</Panel>
</>
);
}
const containerStyle = {
// TODO Move to a .less file
maxWidth: '1200px',
margin: '30px auto',
backgroundColor: 'rgba(255,255,255,0.6)',
};
// TODO Remove fake data
// const contactsList = [
// {
// label: 'rui@protonmail.com',
// value: 'rui@protonmail.com',
// },
// {
// label: 'ln@armada.digital',
// value: 'ln@armada.digital',
// },
// {
// label: 'serge@goldwicht.be',
// value: 'serge@goldwicht.be',
// },
// {
// label: 'penkova@penkova.cc',
// value: 'penkova@penkova.cc',
// },
// ];

View File

@ -0,0 +1,28 @@
.av-container {
display: grid;
grid-template-columns: 6fr 3fr;
grid-template-rows: 1fr;
grid-template-areas:
'selector details';
column-gap: 2em;
row-gap: 2em;
grid-column-gap: 2em;
grid-row-gap: 2em;
}
.av-details {
grid-area: details;
margin: 1em 0 3em 0;
}
.interval-selector {
grid-area: selector;
margin: 1em 0 3em 0;
}
// Fix button alignment bug
// TODO Check if still needed
.rs-btn-block + .rs-btn-block {
margin-top: unset;
}

View File

@ -65,7 +65,6 @@ export default function Schedule({ title }) {
// Add selected event to the list
updatedEvents = [...eventsList, selectedEvent];
}
// setEventsList(updatedEvents);
} else {
// When a range of dates is selected
let currentDate = start;