cleanup + lint

This commit is contained in:
cv
2021-03-29 22:14:00 +02:00
parent 714f6bc377
commit 0e73ddd157
20 changed files with 1006 additions and 1374 deletions
+1 -4
View File
@@ -11,16 +11,13 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"date-fns": "^2.19.0",
"formik": "^2.2.6",
"framer-motion": "^4",
"react": "^17.0.1",
"react-datepicker": "^3.6.0",
"react-dom": "^17.0.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1",
"yup": "^0.32.9"
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
-4
View File
@@ -10,16 +10,12 @@ function App() {
return (
<PresenterMessageProvider>
<EventProvider>
<div className='App'>
<Route path='/' exact component={DefaultPresenter} />
<EventListProvider>
<Route path='/editor' exact component={Editor} />
</EventListProvider>
</div>
</EventProvider>
</PresenterMessageProvider>
);
@@ -1,6 +1,6 @@
import styles from './SmallTimer.module.css';
export default function SmallTimer({label, time}) {
export default function SmallTimer({ label, time }) {
return (
<div className={styles.SmallTimer}>
<div className={styles.label}>{label}</div>
+1 -1
View File
@@ -19,4 +19,4 @@ export default function ChakraInput(props) {
}}
</Field>
);
}
}
-38
View File
@@ -1,38 +0,0 @@
import { FormErrorMessage } from '@chakra-ui/form-control';
import { FormLabel } from '@chakra-ui/form-control';
import { FormControl } from '@chakra-ui/form-control';
import { NumberInputStepper } from '@chakra-ui/number-input';
import { NumberInputField } from '@chakra-ui/number-input';
import { NumberDecrementStepper } from '@chakra-ui/number-input';
import { NumberIncrementStepper } from '@chakra-ui/number-input';
import { NumberInput } from '@chakra-ui/number-input';
import { Field } from 'formik';
export default function ChakraNumberInput(props) {
const { label, name, ...rest } = props;
return (
<Field name={name}>
{({ field, form }) => {
return (
<FormControl isInvalid={form.errors[name] && form.touched[name]}>
<FormLabel htmlFor={name}>{label}</FormLabel>
<NumberInput
defaultValue={field.value}
{...rest}
onChange={(val) => form.setFieldValue(field.name, val)}
>
<NumberInputField id={name} {...field} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
<FormErrorMessage>{form.errors[name]}</FormErrorMessage>
</FormControl>
);
}}
</Field>
);
}
-28
View File
@@ -1,28 +0,0 @@
import { FormLabel } from '@chakra-ui/form-control';
import { Text } from '@chakra-ui/layout';
import {
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput,
NumberInputField,
NumberInputStepper,
} from '@chakra-ui/number-input';
import styles from './TimeInput.module.css';
export default function SingleTimeInput(props) {
return (
<div className={styles.container}>
<FormLabel>{props.label}</FormLabel>
<Text className={styles.label}>min</Text>
<div className={styles.timeInput}>
<NumberInput min={0} max={60} maxW={20} allowMouseWheel>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
</div>
</div>
);
}
-36
View File
@@ -1,36 +0,0 @@
import { FormErrorMessage } from '@chakra-ui/form-control';
import { FormLabel } from '@chakra-ui/form-control';
import { FormControl } from '@chakra-ui/form-control';
import DatePicker from 'react-datepicker';
import { Field } from 'formik';
import 'react-datepicker/dist/react-datepicker.css';
import './timeInput.css';
export default function TimeInput(props) {
const { label, name, ...rest } = props;
return (
<Field name={name}>
{({ field, form }) => {
const { setFieldValue } = form;
const { value } = field;
return (
<FormControl isInvalid={form.errors[name] && form.touched[name]}>
<FormLabel htmlFor={name}>{label}</FormLabel>
<DatePicker
id={name}
{...field}
{...rest}
showTimeSelect
showTimeSelectOnly
timeIntervals={15}
dateFormat='hh:mm'
selected={value}
onChange={(val) => setFieldValue(name, val)}
/>
<FormErrorMessage>{form.errors[name]}</FormErrorMessage>
</FormControl>
);
}}
</Field>
);
}
-17
View File
@@ -1,17 +0,0 @@
.container {
padding-right: 1em;
padding-top: 2em;
}
.timeInput {
display: flex;
}
.label {
font-size: 0.9em;
color: #666;
}
.spacer {
width: 0.25em
}
-122
View File
@@ -1,122 +0,0 @@
.react-datepicker {
font-family: unset;
font-size: 0.9rem;
}
.react-datepicker-wrapper,
.react-datepicker__input-container {
display: block;
}
.react-datepicker-popper {
background-color: white;
}
.react-datepicker__input-container {
font-size: 1rem;
padding-left: 1rem;
padding-right: 1rem;
height: 2.5rem;
border-radius: 0.25rem;
border: 1px solid;
border-color: hsl(0,0%,80%);
}
.react-datepicker__input-container:hover {
border-color: hsl(0,0%,70%);
}
.react-datepicker__input-container:focus-within {
z-index: 1;
border-color: #3182ce;
box-shadow: 0 0 0 1px #3182ce;
}
.react-datepicker__input-container > input {
width: 100%;
height: 100%;
outline: 0;
}
.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button) {
right: 90px;
}
.react-datepicker__navigation--previous,
.react-datepicker__navigation--next {
height: 8px;
}
.react-datepicker__navigation--previous {
border-right-color: #cbd5e0;
}
.react-datepicker__navigation--previous:hover {
border-right-color: #a0aec0;
}
.react-datepicker__navigation--next {
border-left-color: #cbd5e0;
}
.react-datepicker__navigation--next:hover {
border-left-color: #a0aec0;
}
.react-datepicker__header {
background: #f7fafc;
}
.react-datepicker__header,
.react-datepicker__time-container {
border-color: #E2E8F0;
}
.react-datepicker__current-month,
.react-datepicker-time__header,
.react-datepicker-year-header {
font-size: inherit;
font-weight: 600;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item {
margin: 0 1px 0 0;
height: auto;
padding: 7px 10px;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover {
background: #edf2f7;
}
.react-datepicker__day:hover {
background: #edf2f7;
}
.react-datepicker__day--selected,
.react-datepicker__day--in-selecting-range,
.react-datepicker__day--in-range,
.react-datepicker__month-text--selected,
.react-datepicker__month-text--in-selecting-range,
.react-datepicker__month-text--in-range,
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected {
background: #3182ce;
font-weight: normal;
}
.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover {
background: #2a69ac;
}
.react-datepicker__close-icon::after {
background-color: unset;
border-radius: unset;
font-size: 1.5rem;
font-weight: bold;
color: hsl(0,0%,80%);
height: 20px;
width: 20px;
}
.react-datepicker__close-icon::after:hover {
color: hsl(0,0%,70%)
}
+1 -54
View File
@@ -2,25 +2,17 @@ import { Button } from '@chakra-ui/button';
import style from './PlaybackControl.module.css';
import Countdown from '../../common/components/countdown/Countdown';
import { useState } from 'react';
import { clamp } from '../../app/utils';
import { ArrowBackIcon, ArrowForwardIcon } from '@chakra-ui/icons';
export default function PlaybackControl() {
const [time, setTime] = useState(15);
const [time] = useState(15);
const [roll, setRoll] = useState(false);
const incrementTimer = (amount = 1) => {
const t = clamp(time + amount * 60, 0, 3600);
setTime(t);
};
const defProps = {
colorScheme: 'blackAlpha',
variant: 'outline',
};
const smallSize = 50;
const midSize = 100;
const bigSize = 120;
return (
@@ -29,44 +21,7 @@ export default function PlaybackControl() {
<div className={style.timer}>
<Countdown time={time} small />
</div>
{/* <Button
width={smallSize}
{...defProps}
className={style.minu1}
disabled={roll}
onClick={() => incrementTimer(-1)}
>
-1
</Button>
<Button
width={smallSize}
{...defProps}
className={style.plus1}
disabled={roll}
onClick={() => incrementTimer()}
>
+1
</Button>
<Button
width={smallSize}
{...defProps}
className={style.minu5}
disabled={roll}
onClick={() => incrementTimer(5)}
>
-5
</Button>
<Button
width={smallSize}
{...defProps}
className={style.plus5}
disabled={roll}
onClick={() => incrementTimer(5)}
>
+5
</Button> */}
</div>
<div className={style.playbackContainer}>
<Button
width={bigSize}
@@ -84,14 +39,6 @@ export default function PlaybackControl() {
>
Pause
</Button>
{/* <Button
width={bigSize}
colorScheme='yellow'
className={style.reset}
disabled={roll}
>
Reset
</Button> */}
</div>
<div className={style.trackContainer}>
<Button
@@ -35,9 +35,9 @@
grid-area: minu5;
}
.playbackContainer, .trackContainer {
.playbackContainer,
.trackContainer {
display: flex;
justify-content: space-evenly;
padding-top: 0.5em;
}
}
+80 -13
View File
@@ -1,5 +1,5 @@
import { Button } from '@chakra-ui/button';
import { ArrowForwardIcon } from '@chakra-ui/icons';
import { IconButton } from '@chakra-ui/button';
import { SettingsIcon } from '@chakra-ui/icons';
import { Grid, GridItem, Heading } from '@chakra-ui/layout';
import { Box } from '@chakra-ui/layout';
import { useContext } from 'react';
@@ -7,7 +7,6 @@ import { useEffect, useState } from 'react';
import { EventContext } from '../../app/context/eventContext';
import NumberedText from '../../common/components/text/NumberedText';
import PlaybackControl from '../control/PlaybackControl';
import EventForm from '../form/EventForm';
import MessageForm from '../form/MessageForm';
import PreviewContainer from '../viewers/PreviewContainer';
import styles from './Editor.module.css';
@@ -34,11 +33,10 @@ export default function Editor() {
>
<GridItem rowSpan={3}>
<Box className={styles.editor} borderRadius='0.5em'>
<Heading style={{ paddingBottom: '0.25em' }}>Event List</Heading>
<NumberedText
number={1}
text={'Manage and select event to run'}
/>
<Heading size='lg' style={{ paddingBottom: '0.25em' }}>
Event List
</Heading>
<NumberedText number={1} text={'Manage and select event to run'} />
<div className={styles.content}>
<EventList formMode={formMode} setFormMode={setFormMode} />
</div>
@@ -47,7 +45,9 @@ export default function Editor() {
<GridItem colStart={2} rowStart={2} rowSpan={2} colSpan={2}>
<Box className={styles.editor} borderRadius='0.5em' overflowX='auto'>
<Heading style={{ paddingBottom: '0.25em' }}>Preview Displays</Heading>
<Heading size='lg' style={{ paddingBottom: '0.25em' }}>
Preview Displays
</Heading>
<NumberedText number={4} text={'Realtime screen preview'} />
<div className={styles.content}>
<PreviewContainer />
@@ -57,8 +57,13 @@ export default function Editor() {
<GridItem colStart={2} rowStart={1} rowSpan={1} colSpan={1}>
<Box className={styles.editor} borderRadius='0.5em'>
<Heading style={{ paddingBottom: '0.25em' }}>Display Messages</Heading>
<NumberedText number={2} text={'Show realtime messages on separate screen types'} />
<Heading size='lg' style={{ paddingBottom: '0.25em' }}>
Display Messages
</Heading>
<NumberedText
number={2}
text={'Show realtime messages on separate screen types'}
/>
<div className={styles.content}></div>
<MessageForm />
</Box>
@@ -66,7 +71,9 @@ export default function Editor() {
<GridItem colStart={3} rowStart={1}>
<Box className={styles.editor} borderRadius='0.5em'>
<Heading style={{ paddingBottom: '0.25em' }}>Time Control</Heading>
<Heading size='lg' style={{ paddingBottom: '0.25em' }}>
Time Control
</Heading>
<NumberedText number={3} text={'Control Timer'} />
<div className={styles.content}></div>
<PlaybackControl />
@@ -74,7 +81,67 @@ export default function Editor() {
</GridItem>
<GridItem colStart={4} rowSpan={3}>
<Box className={styles.editor} borderRadius='0.5em'>S</Box>
<Box className={styles.editor} borderRadius='0.5em'>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '2em',
paddingTop: '3em',
}}
>
<IconButton icon={<SettingsIcon />} isRound variant='outline' />
<div
style={{
width: 35,
height: 35,
backgroundColor: '#3b8cd8',
borderRadius: '50%',
}}
/>
<div
style={{
width: 35,
height: 35,
backgroundColor: '#3182ce',
borderRadius: '50%',
}}
/>
<div
style={{
width: 35,
height: 35,
backgroundColor: '#2778c4',
borderRadius: '50%',
}}
/>
<div
style={{
width: 35,
height: 35,
backgroundColor: '#1d6eba',
borderRadius: '50%',
}}
/>
<div
style={{
width: 35,
height: 35,
backgroundColor: '#1364b0',
borderRadius: '50%',
}}
/>
<div
style={{
width: 35,
height: 35,
backgroundColor: '#095aa6',
borderRadius: '50%',
}}
/>
</div>
</Box>
</GridItem>
</Grid>
);
+1
View File
@@ -8,6 +8,7 @@
height: 100%;
margin-top: 1.5vh;
background-color: #fcfcfa;
/* 011627 */
padding: 1em 1.5em;
display: flex;
-1
View File
@@ -1,7 +1,6 @@
import { IconButton } from '@chakra-ui/button';
import { AddIcon, MinusIcon } from '@chakra-ui/icons';
import { Box } from '@chakra-ui/layout';
import { useNumberInput } from '@chakra-ui/number-input';
import {
Slider,
SliderFilledTrack,
+56 -12
View File
@@ -1,17 +1,29 @@
import { AddIcon, AttachmentIcon, DownloadIcon } from '@chakra-ui/icons';
import { Button, IconButton } from '@chakra-ui/react';
import {
AddIcon,
AttachmentIcon,
ChevronDownIcon,
DownloadIcon,
} from '@chakra-ui/icons';
import {
Button,
ButtonGroup,
IconButton,
Menu,
MenuButton,
MenuItem,
MenuList,
} from '@chakra-ui/react';
import { useContext } from 'react';
import { EventContext } from '../../../app/context/eventContext';
import { EventListContext } from '../../../app/context/eventListContext';
import EventListItem from './EventListItem';
import { sortByOrderVal } from './listUtils';
import style from './List.module.css';
import DelayBlock from './DelayBlock';
import BlockBlock from './BlockBlock';
export default function EventList(props) {
export default function EventList() {
const [events, setEvents] = useContext(EventListContext);
const [event, setEvent] = useContext(EventContext);
const [event] = useContext(EventContext);
const selected = event?.id || -1;
@@ -100,19 +112,51 @@ export default function EventList(props) {
const updateData = (itemIndex, data) => {
const newEvents = replaceAt(events, itemIndex, data);
setEvents(newEvents);
}
};
console.log('events in event list', events);
let cumulativeDelay = 0;
return (
<>
<div className={style.headerButtons}>
<Button size='sm' rightIcon={<AttachmentIcon />} disabled>
Upload
</Button>
<Button size='sm' rightIcon={<DownloadIcon />} disabled>
Download
</Button>
<Menu>
<ButtonGroup isAttached>
<Button size='sm' variant='outline'>
Upload
</Button>
<MenuButton
as={Button}
leftIcon={<AttachmentIcon />}
size='sm'
variant='outline'
>
<ChevronDownIcon />
</MenuButton>
</ButtonGroup>
<MenuList>
<MenuItem>Upload Excel</MenuItem>
<MenuItem>Upload CSV</MenuItem>
</MenuList>
</Menu>
<Menu>
<ButtonGroup isAttached>
<Button size='sm' variant='outline'>
Save
</Button>
<MenuButton
as={Button}
leftIcon={<DownloadIcon />}
size='sm'
variant='outline'
>
<ChevronDownIcon />
</MenuButton>
</ButtonGroup>
<MenuList>
<MenuItem>Download Excel</MenuItem>
<MenuItem>Download CSV</MenuItem>
</MenuList>
</Menu>
<IconButton
size='sm'
icon={<AddIcon />}
-159
View File
@@ -1,159 +0,0 @@
import { Button } from '@chakra-ui/button';
import { Form, Formik } from 'formik';
import { useContext, useEffect, useState } from 'react';
import DatePicker from 'react-datepicker';
import * as Yup from 'yup';
import { EventContext } from '../../app/context/eventContext';
import { EventListContext } from '../../app/context/eventListContext';
import ChakraInput from '../../common/input/ChakraInput';
import ChakraNumberInput from '../../common/input/ChakraNumberInput';
import TimeInput from '../../common/input/TimeInput';
import styles from './EventForm.module.css';
import 'react-datepicker/dist/react-datepicker-cssmodules.css';
import ReactDatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { Wrap } from '@chakra-ui/layout';
import { Flex } from '@chakra-ui/layout';
const sampleInitialValues = {
title: '',
subtitle: '',
presenter: '',
timeStart: new Date(),
timeEnd: new Date(),
timerDuration: 5,
};
export default function EventForm(props) {
const [event, setEvent] = useContext(EventContext);
const [, setEvents] = useContext(EventListContext);
const [initialValues, setInitialValues] = useState(null);
useEffect(() => {
if (props.formMode === 'edit') setInitialValues(event);
else if (props.formMode === 'add') setInitialValues(sampleInitialValues);
else if (props.formMode === null) setInitialValues(null);
}, [event, props.formMode]);
// TODO: Cleanup
if (props.formMode === null || initialValues === null)
return <div>Replace with nice empty illustration</div>;
else if (props.formMode === 'edit' && event === null) {
return <div>Replace with nice empty illustration also</div>;
}
const validationSchema = Yup.object({
title: Yup.string().required('An event requires a title'),
subtitle: Yup.string(),
presenter: Yup.string(),
timeStart: Yup.date(),
timeEnd: Yup.date(),
timerDuration: Yup.number()
.min(1)
.max(60)
.required('An event requires a duration'),
});
const submitForm = (values) => {
console.log('called submit');
// prevent default stops page from refreshing, necessary?
// update form state
props.setFormMode(null);
// are we updating or creating new?
// add new event to data context
if (props.formMode === 'add')
setEvents((prevEvents) => [...prevEvents, { ...values }]);
// edit event data from context
if (props.formMode === 'edit')
setEvents((prevEvents) => [
...prevEvents.filter((pe) => pe.id !== values.id),
{ ...values },
]);
};
const cancelForm = () => {
props.setFormMode(null);
setEvent(null);
setInitialValues(null);
};
return (
<div>
<Formik
// enableReinitialize={true}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={(values, actions) => {
setTimeout(() => {
submitForm(values);
}, 100);
}}
// FIX: This kept being called on render
// onReset={() => {
// cancelForm();
// }}
>
{(props) => (
<Form onSubmit={props.handleSubmit}>
<ChakraInput
name='title'
label='Event Title'
placeholder='eg. Is the Internet a fad?'
/>
<Flex direction='row'>
<ChakraInput
name='subtitle'
label='Event Subtitle'
placeholder='eg. After tea thoughts'
/>
<ChakraInput
name='presenter'
label='Presenter Name'
placeholder='eg. Duran Duran'
/>
</Flex>
{/* <TimeInput name='timeStart' label='Scheduled Start' /> */}
<ChakraNumberInput
name='timerDuration'
label='Timer Duration (minutes)'
allowMouseWheel
min={1}
max={60}
maxW={24}
/>
<Flex direction='row'>
<TimeInput name='timeStart' label='Scheduled Start' />
<TimeInput name='timeEnd' label='Scheduled End' />
</Flex>
<div className={styles.buttons}>
<Button
variant='outline'
disabled={props.isSubmitting}
// type='reset'
onClick={() => cancelForm()}
>
Back
</Button>
<Button
colorScheme='teal'
isLoading={props.isSubmitting}
disabled={!props.isValid || !props.dirty || props.isSubmitting}
type='submit'
>
Save
</Button>
</div>
</Form>
)}
</Formik>
</div>
);
}
-23
View File
@@ -1,23 +0,0 @@
.label {
padding-top: 1.5em;
font-size: 0.9em;
color: #666;
}
.timings {
display: flex;
justify-content: space-between;
}
.timeInput {
display: flex;
gap: 10px;
}
.buttons {
padding-top: 3em;
bottom: 10px;
display: flex;
justify-content: flex-end;
gap: 1em;
}
+7 -4
View File
@@ -6,7 +6,7 @@ import { useContext } from 'react';
import { useState } from 'react';
import { PresenterMessagesContext } from '../../app/context/presenterMessageContext';
export default function MessageForm(props) {
export default function MessageForm() {
const [presenterShow, setPresenterShow] = useState(false);
const [publicShow, setPublicShow] = useState(false);
const [presMessage, setPresMessage] = useContext(PresenterMessagesContext);
@@ -24,11 +24,11 @@ export default function MessageForm(props) {
setPublicShow(!publicShow);
};
const handlePublicChange = () => {};
const handlePublicChange = (val) => {};
return (
<>
<form style={{ display: 'flex', gap: '1em' }}>
<form style={{ display: 'flex', gap: '1em', fontSize: '15px' }}>
<FormControl id='presenterMessage'>
<FormLabel>Presenter screen message</FormLabel>
<Input
@@ -48,7 +48,10 @@ export default function MessageForm(props) {
<form style={{ display: 'flex', gap: '1em', paddingTop: '1em' }}>
<FormControl id='generalMessage'>
<FormLabel>Public screen message</FormLabel>
<Input placeholder='all screens will render this' />
<Input
placeholder='all screens will render this'
onChange={(event) => handlePublicChange(event.target.value)}
/>
</FormControl>
<IconButton
style={{ alignSelf: 'flex-end' }}
+1 -7
View File
@@ -31,11 +31,7 @@ export default function DefaultPresenter() {
setInitialValues(event);
}, [event]);
console.log('local event event', event);
console.log('local event values', values);
console.log('local event initialv', initialValues);
// NITE: test only
// NOTE: test only
const clockStarted = addMinutes(now, 6);
const timer = differenceInSeconds(
@@ -48,8 +44,6 @@ export default function DefaultPresenter() {
const timeEnd = format(values.timeEnd, 'HH:mm');
const elapsed = timer / (values.timerDuration * 60);
console.log('timers', timer, timeStart, currentTime, timeEnd, elapsed);
return (
<div className='presenter'>
<div className='presentationTitle'>{values.title}</div>
+854 -847
View File
File diff suppressed because it is too large Load Diff