diff --git a/src/app/sampleData.js b/src/app/sampleData.js index b93a6caa1..082fe14ed 100644 --- a/src/app/sampleData.js +++ b/src/app/sampleData.js @@ -16,32 +16,41 @@ export const sampleData = { title: 'Is the internet a fad?', subtitle: 'It is', presenter: 'Carlos Valente', - timeStart: new Date('March 24, 2021 03:25:00'), - timeEnd: new Date('March 24, 2021 04:24:00'), + timeStart: new Date('October 13, 2014 11:30:00'), + timeEnd: new Date('October 13, 2014 11:50:00'), clockStarted: dummy, timerDuration: 60, + type: 'event', + }, + { + id: 0.4849093424577693, + order: 2, + timerDuration: 25, + type: 'delay', }, { id: '2', - order: 2, + order: 3, title: 'Is reddit a dictatorship?', subtitle: 'It is', presenter: 'Carlos Valente', - timeStart: new Date('March 24, 2021 04:25:00'), - timeEnd: new Date('March 24, 2021 05:24:00'), + timeStart: new Date('October 13, 2014 12:30:00'), + timeEnd: new Date('October 13, 2014 12:50:00'), clockStarted: dummy, timerDuration: 60, + type: 'event', }, { id: '3', - order: 3, + order: 4, title: 'Out of words', subtitle: '', presenter: 'Carlos Valente', - timeStart: new Date('March 24, 2021 05:25:00'), - timeEnd: new Date('March 24, 2021 05:55:00'), + timeStart: new Date('October 13, 2014 13:30:00'), + timeEnd: new Date('October 13, 2014 13:50:00'), clockStarted: dummy, timerDuration: 60, + type: 'event', }, ], }; diff --git a/src/common/dateConfig.js b/src/common/dateConfig.js index 28a59815c..a3ccbe28a 100644 --- a/src/common/dateConfig.js +++ b/src/common/dateConfig.js @@ -1 +1,7 @@ -export const timeFormat = 'HH:mm'; \ No newline at end of file +export const timeFormat = 'HH:mm'; + + // make date with string +export const timeToDate = (time) => { + const today = new Date(); + return new Date(today.toDateString() + ' ' + time); +}; diff --git a/src/features/editors/list/BlockBlock.jsx b/src/features/editors/list/BlockBlock.jsx index ebe611029..55e9d36a5 100644 --- a/src/features/editors/list/BlockBlock.jsx +++ b/src/features/editors/list/BlockBlock.jsx @@ -1,4 +1,24 @@ +import { IconButton } from '@chakra-ui/button'; +import { AddIcon, MinusIcon } from '@chakra-ui/icons'; import style from './List.module.css'; -export default function BlockBlock() { - return
; + +export default function BlockBlock(props) { + return ( +
+
+ } + colorScheme='red' + onClick={() => props.deleteEvent(props.index)} + /> + } + colorScheme='blue' + onClick={() => props.createEvent(props.index)} + /> +
+
+ ); } diff --git a/src/features/editors/list/DelayBlock.jsx b/src/features/editors/list/DelayBlock.jsx index a8b695933..b2c7a1ca6 100644 --- a/src/features/editors/list/DelayBlock.jsx +++ b/src/features/editors/list/DelayBlock.jsx @@ -8,35 +8,40 @@ import { SliderThumb, SliderTrack, } from '@chakra-ui/slider'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import style from './List.module.css'; -export default function DelayBlock() { +export default function DelayBlock(props) { const [delay, setDelay] = useState(0); - const { getIncrementButtonProps, getDecrementButtonProps } = useNumberInput({ - step: 1, - defaultValue: 0, - min: -60, - max: 60, - }); + const { data, ...rest } = props; - const inc = getIncrementButtonProps(); - const dec = getDecrementButtonProps(); + // update delay value in parent + const populateDelay = (value) => { + // check if value has changed + if (data.timerDuration !== value) { + // create object with new field + const newData = { ...data, timerDuration: delay }; - const populateDelay = (val) => { - console.log('set delay in parent', val); + // request update in parent + props.updateData(props.index, newData); + } }; + // update delay value in state + useEffect(() => { + setDelay(data.timerDuration); + }, [data]); + return (
{`${delay} min`}
setDelay(val)} - onChangeEnd={(val) => populateDelay(val)} + onChange={(value) => setDelay(value)} + onChangeEnd={(value) => populateDelay(value)} > @@ -45,8 +50,18 @@ export default function DelayBlock() {
- } colorScheme='red' /> - } colorScheme='blue' /> + } + colorScheme='red' + onClick={() => props.deleteEvent(props.index)} + /> + } + colorScheme='blue' + onClick={() => props.createEvent(props.index)} + />
); diff --git a/src/features/editors/list/EventList.jsx b/src/features/editors/list/EventList.jsx index ebe91d014..1cfdf30ba 100644 --- a/src/features/editors/list/EventList.jsx +++ b/src/features/editors/list/EventList.jsx @@ -8,52 +8,87 @@ import { sortByOrderVal } from './listUtils'; import style from './List.module.css'; import DelayBlock from './DelayBlock'; import BlockBlock from './BlockBlock'; -import { createEvent } from '@testing-library/dom'; export default function EventList(props) { const [events, setEvents] = useContext(EventListContext); const [event, setEvent] = useContext(EventContext); - console.log('in el', events); const selected = event?.id || -1; - const createEvent = (startPosition = 0) => { + const insertItemAt = (item, index) => { + // handle insert at beggining of array + if (index === -1) { + // move all items one element down, starting from new position + events.forEach((e) => { + e.order = e.order + 1; + }); + return [item, ...events]; + } else { + let before = events.slice(0, index + 1); + let after = events.slice(index + 1); + + // move all items one element down, starting from new position + after.forEach((e) => { + e.order = e.order + 1; + }); + return [...before, item, ...after]; + } + }; + + const createEvent = (itemIndex = -1) => { // make an event // TODO: Replace this with global def somewhere // TODO: handle random ids better let newEvent = { - id: Math.floor(Math.random() * 10000000), - order: startPosition + 1, + id: Math.random(), + order: itemIndex + 1, title: '', subtitle: '', presenter: '', - timerStart: '', - timerEnd: '', + timeStart: new Date(), + timeEnd: new Date(), clockStarted: null, timerDuration: 0, + type: 'event', }; - // move all items one element down, starting from new position - let newEvents = events.map((e) => { - if (e.order > startPosition) e.order = e.order + 1; - return e; - }); - - // add an event at the beggining - newEvents = [newEvent, ...events]; - // set to state - setEvents(newEvents); + setEvents(insertItemAt(newEvent, itemIndex)); }; - const deleteEvent = (position) => { - // ?? Should i reorder after? - - // remove event from array - let filtered = events.filter((e) => e.id !== position); + const createDelay = (itemIndex = 0) => { + // make an event + // TODO: Replace this with global def somewhere + // TODO: handle random ids better + let newEvent = { + id: Math.random(), + order: itemIndex + 1, + timerDuration: 0, + type: 'delay', + }; // set to state - setEvents(filtered); + setEvents(insertItemAt(newEvent, itemIndex)); + }; + + const createBlock = (itemIndex = 0) => { + // make an event + // TODO: Replace this with global def somewhere + // TODO: handle random ids better + let newEvent = { + id: Math.random(), + order: itemIndex + 1, + type: 'block', + }; + + // set to state + setEvents(insertItemAt(newEvent, itemIndex)); + }; + + const deleteEvent = (index) => { + // TODO: This feels weird? + let e = events.splice(index, 1); + setEvents([...events]); }; const replaceAt = (array, index, value) => { @@ -65,8 +100,10 @@ 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 ( <>
@@ -84,17 +121,46 @@ export default function EventList(props) { />
- {sortByOrderVal(events).map((e, index) => ( - - ))} + {events.map((e, index) => { + if (e.type === 'event') { + return ( + + ); + } else if (e.type === 'block') { + cumulativeDelay = 0; + return ( + + ); + } else if (e.type === 'delay') { + cumulativeDelay = cumulativeDelay + e.timerDuration; + return ( + + ); + } + })}
); diff --git a/src/features/editors/list/EventListItem.jsx b/src/features/editors/list/EventListItem.jsx index e47ff575b..d85aa7a9f 100644 --- a/src/features/editors/list/EventListItem.jsx +++ b/src/features/editors/list/EventListItem.jsx @@ -12,14 +12,34 @@ import { EditablePreview, EditableInput, } from '@chakra-ui/react'; +import { addMinutes, format } from 'date-fns'; import { useEffect, useState } from 'react'; +import { timeFormat, timeToDate } from '../../../common/dateConfig'; import style from './List.module.css'; +// small shorthand for adding delay and formatting date +const addAndFormat = (time, delay) => { + return format(addMinutes(time, delay), timeFormat); +}; + export default function EventListItem(props) { const [more, setMore] = useState(false); const [armed, setArmed] = useState(false); + // const [timeStart, setTimeStart] = useState( + // addAndFormat(props.data.timeStart, props.delay) + // ); + const [timeStart, setTimeStart] = useState(0); + const [timeEnd, setTimeEnd] = useState( + addAndFormat(props.data.timeEnd, props.delay) + ); - const { data, selected, ...rest } = props; + const { data, selected, delay, ...rest } = props; + + // prepare time fields + useEffect(() => { + setTimeStart(addAndFormat(props.data.timeStart, props.delay)); + setTimeEnd(addAndFormat(props.data.timeEnd, props.delay)); + }, [props.data, props.delay]); const updateValues = (field, value) => { // validate field @@ -43,10 +63,12 @@ export default function EventListItem(props) { />
updateValues('timerStart', v)} - defaultValue={data.timerStart} + onSubmit={(v) => updateValues('timeStart', timeToDate(v))} + value={timeStart} + onChange={(val) => setTimeStart(val)} placeholder='--:--' style={{ textAlign: 'center' }} + className={delay > 0 && style.delayedEditable} > @@ -54,10 +76,12 @@ export default function EventListItem(props) {
updateValues('timerEnd', v)} - defaultValue={data.timerEnd} + onSubmit={(v) => updateValues('timeEnd', timeToDate(v))} + value={timeEnd} + onChange={(val) => setTimeEnd(val)} placeholder='--:--' style={{ textAlign: 'center' }} + className={delay > 0 && style.delayedEditable} > @@ -129,19 +153,25 @@ export default function EventListItem(props) { size='xs' icon={} colorScheme='red' - onClick={() => props.deleteEvent(data.id)} + onClick={() => props.deleteEvent(props.index)} /> } colorScheme='blue' - onClick={() => props.createEvent(data.order)} + onClick={() => props.createEvent(props.index)} + /> + } + colorScheme='yellow' + onClick={() => props.createDelay(props.index)} /> - } colorScheme='yellow' /> } colorScheme='purple' + onClick={() => props.createBlock(props.index)} />
diff --git a/src/features/editors/list/List.module.css b/src/features/editors/list/List.module.css index 4932b335a..3bcaa36bc 100644 --- a/src/features/editors/list/List.module.css +++ b/src/features/editors/list/List.module.css @@ -160,6 +160,10 @@ border: 1px solid #0001; } +.delayedEditable { + background-color: #ecc94b55; +} + /* ============= BLOCK BLOCK ============= */ .blockContainer { position: relative; @@ -170,8 +174,14 @@ background-color: #805ad5aa; border-radius: 8px; color: white; - height: 2em; + height: 3em; border: 1px solid #0001; border-bottom: 8px solid #805ad5; box-sizing: border-box; + + width: 100%; + display: flex; + flex-direction: row-reverse; + margin: auto; + gap: 1em; }