mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-18 21:54:09 +00:00
selected event is context + some cleanup
This commit is contained in:
+9
-6
@@ -1,17 +1,20 @@
|
|||||||
import { Route } from 'react-router';
|
import { Route } from 'react-router';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
import { EventProvider } from './app/context/eventContext';
|
||||||
import { EventListProvider } from './app/context/eventListContext';
|
import { EventListProvider } from './app/context/eventListContext';
|
||||||
import Editor from './features/editors/Editor';
|
import Editor from './features/editors/Editor';
|
||||||
import DefaultPresenter from './features/viewers/DefaultPresenter';
|
import DefaultPresenter from './features/viewers/DefaultPresenter';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<div className='App'>
|
<EventProvider>
|
||||||
<Route path='/' exact component={DefaultPresenter} />
|
<div className='App'>
|
||||||
<EventListProvider>
|
{/* <Route path='/' exact component={DefaultPresenter} /> */}
|
||||||
<Route path='/editor' exact component={Editor} />
|
<EventListProvider>
|
||||||
</EventListProvider>
|
<Route path='/editor' exact component={Editor} />
|
||||||
</div>
|
</EventListProvider>
|
||||||
|
</div>
|
||||||
|
</EventProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { createContext, useState } from 'react';
|
||||||
|
|
||||||
|
export const EventContext = createContext();
|
||||||
|
|
||||||
|
export function EventProvider(props) {
|
||||||
|
const [event, setEvent] = useState(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EventContext.Provider value={[event, setEvent]}>
|
||||||
|
{props.children}
|
||||||
|
</EventContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,53 +1,45 @@
|
|||||||
import { Button } from '@chakra-ui/button';
|
import { Button } from '@chakra-ui/button';
|
||||||
import { ArrowForwardIcon } from '@chakra-ui/icons';
|
import { ArrowForwardIcon } from '@chakra-ui/icons';
|
||||||
import { Flex, Heading } from '@chakra-ui/layout';
|
import { Grid, GridItem, Heading } from '@chakra-ui/layout';
|
||||||
import { SimpleGrid } from '@chakra-ui/layout';
|
|
||||||
import { Box } from '@chakra-ui/layout';
|
import { Box } from '@chakra-ui/layout';
|
||||||
|
import { useContext } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { sampleData } from '../../app/sampleData';
|
import { EventContext } from '../../app/context/eventContext';
|
||||||
import NumberedText from '../../common/components/text/NumberedText';
|
import NumberedText from '../../common/components/text/NumberedText';
|
||||||
|
import PlaybackControl from '../control/PlaybackControl';
|
||||||
import EventForm from '../form/EventForm';
|
import EventForm from '../form/EventForm';
|
||||||
|
import MessageForm from '../form/MessageForm';
|
||||||
import PreviewContainer from '../viewers/PreviewContainer';
|
import PreviewContainer from '../viewers/PreviewContainer';
|
||||||
import styles from './Editor.module.css';
|
import styles from './Editor.module.css';
|
||||||
import EventList from './list/EventList';
|
import EventList from './list/EventList';
|
||||||
|
|
||||||
export default function Editor() {
|
export default function Editor() {
|
||||||
const [data, setData] = useState(sampleData);
|
|
||||||
const [selectedData, setSelectedData] = useState(null);
|
|
||||||
const [selectedEvent, setSelectedEvent] = useState(null);
|
|
||||||
const [formMode, setFormMode] = useState(null);
|
const [formMode, setFormMode] = useState(null);
|
||||||
|
const [event] = useContext(EventContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEvent === null) {
|
if (event === null) {
|
||||||
setSelectedData(null);
|
|
||||||
setFormMode(null);
|
setFormMode(null);
|
||||||
} else {
|
} else {
|
||||||
const se = data.events.filter((d) => d.id === selectedEvent);
|
|
||||||
if (se.length > 0) setSelectedData(se[0]);
|
|
||||||
setFormMode('edit');
|
setFormMode('edit');
|
||||||
}
|
}
|
||||||
}, [data, selectedEvent]);
|
}, [event]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SimpleGrid
|
<Grid
|
||||||
minChildWidth='120px'
|
templateRows='60% 40%'
|
||||||
spacing='40px'
|
templateColumns='repeat(3, 1fr)'
|
||||||
|
gap={5}
|
||||||
className={styles.mainContainer}
|
className={styles.mainContainer}
|
||||||
>
|
>
|
||||||
<Box className={styles.editor} borderRadius='0.5em'>
|
<GridItem rowSpan={2} colSpan={1}>
|
||||||
<Heading style={{ paddingBottom: '0.25em' }}>List Events</Heading>
|
<Box className={styles.editor} borderRadius='0.5em'>
|
||||||
<NumberedText
|
<Heading style={{ paddingBottom: '0.25em' }}>List Events</Heading>
|
||||||
number={1}
|
<NumberedText
|
||||||
text={'Select event or click Add Event to create new'}
|
number={1}
|
||||||
/>
|
text={'Select event or click Add Event to create new'}
|
||||||
<div className={styles.content}>
|
|
||||||
<EventList
|
|
||||||
data={data}
|
|
||||||
selected={selectedEvent}
|
|
||||||
setSelectedEvent={setSelectedEvent}
|
|
||||||
formMode={formMode}
|
|
||||||
/>
|
/>
|
||||||
<div className={styles.buttonContainer}>
|
<div className={styles.cornerButtonContainer}>
|
||||||
<Button
|
<Button
|
||||||
colorScheme='teal'
|
colorScheme='teal'
|
||||||
variant={formMode === 'add' ? 'solid' : 'outline'}
|
variant={formMode === 'add' ? 'solid' : 'outline'}
|
||||||
@@ -58,29 +50,50 @@ export default function Editor() {
|
|||||||
Add Event
|
Add Event
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box className={styles.editor} borderRadius='0.5em'>
|
<div className={styles.content}>
|
||||||
<Heading style={{ paddingBottom: '0.25em' }}>Event Details</Heading>
|
<EventList formMode={formMode} setFormMode={setFormMode} />
|
||||||
<NumberedText number={2} text={'Edit event info'} />
|
</div>
|
||||||
<div className={styles.content}>
|
</Box>
|
||||||
<EventForm
|
</GridItem>
|
||||||
data={selectedData}
|
|
||||||
formMode={formMode}
|
|
||||||
setFormMode={setFormMode}
|
|
||||||
setSelectedEvent={setSelectedEvent}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box className={styles.editor} borderRadius='0.5em' overflowX='auto'>
|
<GridItem colStart={2} rowSpan={1} colSpan={1}>
|
||||||
<Heading style={{ paddingBottom: '0.25em' }}>List Events</Heading>
|
<Box className={styles.editor} borderRadius='0.5em'>
|
||||||
<NumberedText number={3} text={'Preview layout'} />
|
<Heading style={{ paddingBottom: '0.25em' }}>Event Details</Heading>
|
||||||
<div className={styles.content}>
|
<NumberedText number={2} text={'Edit event info'} />
|
||||||
<PreviewContainer data={selectedData} />
|
<div className={styles.content}>
|
||||||
</div>
|
<EventForm formMode={formMode} setFormMode={setFormMode} />
|
||||||
</Box>
|
</div>
|
||||||
</SimpleGrid>
|
</Box>
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem colStart={3} rowStart={1} rowSpan={1} colSpan={1}>
|
||||||
|
<Box className={styles.editor} borderRadius='0.5em' overflowX='auto'>
|
||||||
|
<Heading style={{ paddingBottom: '0.25em' }}>Screens</Heading>
|
||||||
|
<NumberedText number={3} text={'Preview layout'} />
|
||||||
|
<div className={styles.content}>
|
||||||
|
{/* <PreviewContainer data={selectedData} /> */}
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem colStart={2} rowStart={2} rowSpan={1} colSpan={1}>
|
||||||
|
<Box className={styles.editor} borderRadius='0.5em'>
|
||||||
|
<Heading style={{ paddingBottom: '0.25em' }}>Screen Messages</Heading>
|
||||||
|
<NumberedText number={3} text={'Show / Hide messages on screens'} />
|
||||||
|
<div className={styles.content}></div>
|
||||||
|
<MessageForm />
|
||||||
|
</Box>
|
||||||
|
</GridItem>
|
||||||
|
|
||||||
|
<GridItem colStart={3} rowStart={2} rowSpan={1} colSpan={1}>
|
||||||
|
<Box className={styles.editor} borderRadius='0.5em'>
|
||||||
|
<Heading style={{ paddingBottom: '0.25em' }}>Time Control</Heading>
|
||||||
|
<NumberedText number={0} text={'Control Timer'} />
|
||||||
|
<div className={styles.content}></div>
|
||||||
|
<PlaybackControl />
|
||||||
|
</Box>
|
||||||
|
</GridItem>
|
||||||
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import { Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
|
import { Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
|
import { EventContext } from '../../../app/context/eventContext';
|
||||||
import { EventListContext } from '../../../app/context/eventListContext';
|
import { EventListContext } from '../../../app/context/eventListContext';
|
||||||
import EventListItem from './EventListItem';
|
import EventListItem from './EventListItem';
|
||||||
import { sortByDate } from './listUtils';
|
import { sortByDate } from './listUtils';
|
||||||
|
|
||||||
export default function EventList(props) {
|
export default function EventList(props) {
|
||||||
const [events, setEvents] = useContext(EventListContext);
|
const [events, ] = useContext(EventListContext);
|
||||||
|
const [event, setEvent] = useContext(EventContext);
|
||||||
|
|
||||||
console.log('e', events);
|
const handleSetSelected = (id) => {
|
||||||
console.log('sort', sortByDate(events));
|
setEvent(events.filter((e) => e.id === id)[0]);
|
||||||
|
props.setFormMode('edit');
|
||||||
|
};
|
||||||
|
|
||||||
|
const disabled = props.formMode !== null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table variant='simple' size='sm'>
|
<Table variant='simple' size='sm'>
|
||||||
@@ -26,9 +32,9 @@ export default function EventList(props) {
|
|||||||
<EventListItem
|
<EventListItem
|
||||||
key={e.id}
|
key={e.id}
|
||||||
data={e}
|
data={e}
|
||||||
selected={props.selected}
|
disabled={disabled}
|
||||||
setSelectedEvent={props.setSelectedEvent}
|
selectedId={event?.id}
|
||||||
formMode={props.formMode}
|
setSelected={handleSetSelected}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Tbody>
|
</Tbody>
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import { timeFormat } from '../../../common/dateConfig';
|
|||||||
import { ChevronRightIcon } from '@chakra-ui/icons';
|
import { ChevronRightIcon } from '@chakra-ui/icons';
|
||||||
|
|
||||||
export default function EventListItem(props) {
|
export default function EventListItem(props) {
|
||||||
const selected = props.selected === props.data.id
|
const isSelected = props.selectedId === props.data.id;
|
||||||
return (
|
return (
|
||||||
<Tr
|
<Tr
|
||||||
style={
|
style={
|
||||||
selected
|
isSelected
|
||||||
? { backgroundColor: '#b2f5ea' }
|
? { backgroundColor: '#b2f5ea' }
|
||||||
: { backgroundColor: 'white' }
|
: { backgroundColor: 'white' }
|
||||||
}
|
}
|
||||||
@@ -21,9 +21,9 @@ export default function EventListItem(props) {
|
|||||||
<Td>
|
<Td>
|
||||||
<IconButton
|
<IconButton
|
||||||
colorScheme='teal'
|
colorScheme='teal'
|
||||||
variant={selected ? 'solid' : 'outline'}
|
variant={isSelected ? 'solid' : 'outline'}
|
||||||
onClick={() => props.setSelectedEvent(props.data.id)}
|
onClick={() => props.setSelected(props.data.id)}
|
||||||
disabled={props.formMode !== null}
|
disabled={props.disabled}
|
||||||
size='sm'
|
size='sm'
|
||||||
aria-label='Select Item'
|
aria-label='Select Item'
|
||||||
icon={<ChevronRightIcon />}
|
icon={<ChevronRightIcon />}
|
||||||
|
|||||||
@@ -1,33 +1,48 @@
|
|||||||
import { Button } from '@chakra-ui/button';
|
import { Button } from '@chakra-ui/button';
|
||||||
import { Form, Formik } from 'formik';
|
import { Form, Formik } from 'formik';
|
||||||
import { useContext, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
import ReactDatePicker from 'react-datepicker';
|
|
||||||
import DatePicker from 'react-datepicker';
|
import DatePicker from 'react-datepicker';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
|
import { EventContext } from '../../app/context/eventContext';
|
||||||
import { EventListContext } from '../../app/context/eventListContext';
|
import { EventListContext } from '../../app/context/eventListContext';
|
||||||
import ChakraInput from '../../common/input/ChakraInput';
|
import ChakraInput from '../../common/input/ChakraInput';
|
||||||
import ChakraNumberInput from '../../common/input/ChakraNumberInput';
|
import ChakraNumberInput from '../../common/input/ChakraNumberInput';
|
||||||
import TimeInput from '../../common/input/TimeInput';
|
import TimeInput from '../../common/input/TimeInput';
|
||||||
|
|
||||||
import styles from './EventForm.module.css';
|
import styles from './EventForm.module.css';
|
||||||
|
|
||||||
|
const sampleInitialValues = {
|
||||||
|
title: '',
|
||||||
|
subtitle: '',
|
||||||
|
presenter: '',
|
||||||
|
timeStart: new Date(),
|
||||||
|
timeEnd: new Date(),
|
||||||
|
timerDuration: 5,
|
||||||
|
};
|
||||||
|
|
||||||
export default function EventForm(props) {
|
export default function EventForm(props) {
|
||||||
const [events, setEvents] = useContext(EventListContext);
|
const [event, setEvent] = useContext(EventContext);
|
||||||
const today = new Date();
|
const [, setEvents] = useContext(EventListContext);
|
||||||
const initialValues = props.data ?? {
|
const [initialValues, setInitialValues] = useState(null);
|
||||||
title: '',
|
|
||||||
subtitle: '',
|
useEffect(() => {
|
||||||
presenter: '',
|
if (props.formMode === 'edit') setInitialValues(event);
|
||||||
timeStart: today,
|
else if (props.formMode === 'add') setInitialValues(sampleInitialValues);
|
||||||
timeEnd: today,
|
else if (props.formMode === null) setInitialValues(null);
|
||||||
timerDuration: 30,
|
}, [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({
|
const validationSchema = Yup.object({
|
||||||
title: Yup.string().required('An event requires a title'),
|
title: Yup.string().required('An event requires a title'),
|
||||||
subtitle: Yup.string(),
|
subtitle: Yup.string(),
|
||||||
presenter: Yup.string(),
|
presenter: Yup.string(),
|
||||||
timeStart: Yup.date().nullable(),
|
timeStart: Yup.date(),
|
||||||
|
timeEnd: Yup.date(),
|
||||||
timerDuration: Yup.number()
|
timerDuration: Yup.number()
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(60)
|
.max(60)
|
||||||
@@ -35,12 +50,12 @@ export default function EventForm(props) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const submitForm = (values) => {
|
const submitForm = (values) => {
|
||||||
|
console.log('called submit');
|
||||||
|
|
||||||
// prevent default stops page from refreshing, necessary?
|
// prevent default stops page from refreshing, necessary?
|
||||||
console.log('form', values);
|
|
||||||
|
|
||||||
// update form state
|
// update form state
|
||||||
props.setFormMode(null);
|
props.setFormMode(null);
|
||||||
props.setSelectedEvent(null);
|
|
||||||
|
|
||||||
// are we updating or creating new?
|
// are we updating or creating new?
|
||||||
|
|
||||||
@@ -58,17 +73,14 @@ export default function EventForm(props) {
|
|||||||
|
|
||||||
const cancelForm = () => {
|
const cancelForm = () => {
|
||||||
props.setFormMode(null);
|
props.setFormMode(null);
|
||||||
props.setSelectedEvent(null);
|
setEvent(null);
|
||||||
|
setInitialValues(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (props.data === null || props.data === undefined) {
|
|
||||||
if (props.formMode === null)
|
|
||||||
return <div>Replace with nice empty illustration</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Formik
|
<Formik
|
||||||
|
enableReinitialize={true}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
onSubmit={(values, actions) => {
|
onSubmit={(values, actions) => {
|
||||||
@@ -76,7 +88,10 @@ export default function EventForm(props) {
|
|||||||
submitForm(values);
|
submitForm(values);
|
||||||
}, 100);
|
}, 100);
|
||||||
}}
|
}}
|
||||||
onReset={(values) => cancelForm()}
|
// FIX: This kept being called on render
|
||||||
|
// onReset={() => {
|
||||||
|
// cancelForm();
|
||||||
|
// }}
|
||||||
>
|
>
|
||||||
{(props) => (
|
{(props) => (
|
||||||
<Form onSubmit={props.handleSubmit}>
|
<Form onSubmit={props.handleSubmit}>
|
||||||
@@ -109,9 +124,10 @@ export default function EventForm(props) {
|
|||||||
<Button
|
<Button
|
||||||
variant='outline'
|
variant='outline'
|
||||||
disabled={props.isSubmitting}
|
disabled={props.isSubmitting}
|
||||||
type='reset'
|
// type='reset'
|
||||||
|
onClick={() => cancelForm()}
|
||||||
>
|
>
|
||||||
Cancel
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
colorScheme='teal'
|
colorScheme='teal'
|
||||||
|
|||||||
Reference in New Issue
Block a user