mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-07 00:13:53 +00:00
cleanup + lint
This commit is contained in:
+1
-4
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -19,4 +19,4 @@ export default function ChakraInput(props) {
|
||||
}}
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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%)
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
height: 100%;
|
||||
margin-top: 1.5vh;
|
||||
background-color: #fcfcfa;
|
||||
/* 011627 */
|
||||
padding: 1em 1.5em;
|
||||
|
||||
display: flex;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 />}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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' }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user