event list style

change user flow
This commit is contained in:
cv
2021-03-26 20:53:03 +01:00
parent 870cdb5048
commit 9ec1e76750
5 changed files with 350 additions and 78 deletions
+4
View File
@@ -0,0 +1,4 @@
import style from './List.module.css';
export default function BlockBlock() {
return <div className={style.blockContainer} />;
}
+53
View File
@@ -0,0 +1,53 @@
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,
SliderThumb,
SliderTrack,
} from '@chakra-ui/slider';
import { useState } from 'react';
import style from './List.module.css';
export default function DelayBlock() {
const [delay, setDelay] = useState(0);
const { getIncrementButtonProps, getDecrementButtonProps } = useNumberInput({
step: 1,
defaultValue: 0,
min: -60,
max: 60,
});
const inc = getIncrementButtonProps();
const dec = getDecrementButtonProps();
const populateDelay = (val) => {
console.log('set delay in parent', val);
};
return (
<div className={style.delayContainer}>
<div className={style.delayValue}>{`${delay} min`}</div>
<Slider
defaultValue={0}
min={-60}
max={60}
step={5}
onChange={(val) => setDelay(val)}
onChangeEnd={(val) => populateDelay(val)}
>
<SliderTrack bg='orange.100'>
<Box position='relative' right={10} />
<SliderFilledTrack bg='orange' />
</SliderTrack>
<SliderThumb boxSize={4} />
</Slider>
<div className={style.actionOverlay}>
<IconButton size='xs' icon={<MinusIcon />} colorScheme='red' />
<IconButton size='xs' icon={<AddIcon />} colorScheme='blue' />
</div>
</div>
);
}
+29 -33
View File
@@ -1,44 +1,40 @@
import { Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react'; import { AddIcon, AttachmentIcon, DownloadIcon } from '@chakra-ui/icons';
import { Button, IconButton } from '@chakra-ui/react';
import { useContext } from 'react'; import { useContext } from 'react';
import { EventContext } from '../../../app/context/eventContext'; 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, sortByNumber } from './listUtils'; import { sortByNumber } 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(props) {
const [events] = useContext(EventListContext); const [events] = useContext(EventListContext);
const [event, setEvent] = useContext(EventContext); const [, setEvent] = useContext(EventContext);
const handleSetSelected = (id) => {
setEvent(events.filter((e) => e.id === id)[0]);
props.setFormMode('edit');
};
const disabled = props.formMode !== null;
return ( return (
<Table variant='simple' size='sm'> <>
<Thead> <div className={style.headerButtons}>
<Tr> <Button size='sm' rightIcon={<AttachmentIcon />}>
<Th>Event Title</Th> Upload
<Th>Event Subtitle</Th> </Button>
<Th>Presenter Name</Th> <Button size='sm' rightIcon={<DownloadIcon />}>
<Th>Time Start</Th> Download
<Th>Time End</Th> </Button>
<Th></Th> <IconButton size='sm' icon={<AddIcon />} colorScheme='blue' />
</Tr> </div>
</Thead> <div className={style.eventContainer}>
<Tbody> <EventListItem />
{sortByNumber(events).map((e) => (
<EventListItem <EventListItem />
key={e.id} <DelayBlock />
data={e}
disabled={disabled} <EventListItem />
selectedId={event?.id} <BlockBlock />
setSelected={handleSetSelected}
/> <EventListItem />
))} </div>
</Tbody> </>
</Table>
); );
} }
+89 -45
View File
@@ -1,50 +1,94 @@
import { IconButton } from '@chakra-ui/button'; import {
import { Td, Tr } from '@chakra-ui/table'; AddIcon,
import { format } from 'date-fns'; ChevronDownIcon,
import { timeFormat } from '../../../common/dateConfig'; ChevronUpIcon,
import { LockIcon, ChevronRightIcon } from '@chakra-ui/icons'; MinusIcon,
NotAllowedIcon,
TimeIcon,
} from '@chakra-ui/icons';
import {
IconButton,
Editable,
EditablePreview,
EditableInput,
} from '@chakra-ui/react';
import { useState } from 'react';
import style from './List.module.css';
export default function EventListItem(props) { export default function EventListItem(props) {
const isSelected = props.selectedId === props.data.id; const [more, setMore] = useState(false);
console.log(props); const [armed, setArmed] = useState(false);
return ( return (
<Tr <div className={armed ? style.eventRowActive : style.eventRow}>
style={ <div
isSelected className={armed ? style.armActive : style.arm}
? { backgroundColor: '#b2f5ea' } onClick={() => setArmed(!armed)}
: { backgroundColor: 'white' } />
} <div className={style.time}>
> <Editable defaultValue='11:20' style={{ textAlign: 'center' }}>
<Td>{props.data.title}</Td> <EditablePreview />
<Td>{props.data.subtitle}</Td> <EditableInput />
<Td>{props.data.presenter}</Td> </Editable>
<Td> </div>
{props.data.timeStart && format(props.data.timeStart, timeFormat)} <div className={style.rowDetailed}>
</Td> {more ? (
<Td>{props.data?.timeEnd && format(props.data?.timeEnd, timeFormat)}</Td>{' '} <div className={style.detailedContainer}>
<Td>{props.data?.timerDuration}</Td> <div style={{ display: 'block' }}>
<Td> <span className={style.detailedTitleUnderlined}>Title</span>
<IconButton <Editable
colorScheme='teal' defaultValue='Event Title'
variant={isSelected ? 'solid' : 'outline'} style={{ display: 'inline' }}
onClick={() => props.setSelected(props.data.id)} >
disabled={props.disabled} <EditablePreview />
size='sm' <EditableInput style={{width:'15em'}} />
aria-label='Select Item' </Editable>
icon={<LockIcon />} </div>
/> <div style={{ display: 'block' }}>
</Td> <span className={style.detailedTitleUnderlined}>Subtitle</span>
<Td> <Editable
<IconButton defaultValue='Event Subtitle'
colorScheme='teal' style={{ display: 'inline' }}
variant={isSelected ? 'solid' : 'outline'} >
onClick={() => props.setSelected(props.data.id)} <EditablePreview />
disabled={props.disabled} <EditableInput style={{width:'15em'}} />
size='sm' </Editable>
aria-label='Select Item' </div>
icon={<ChevronRightIcon />} <div style={{ display: 'block' }}>
/> <span className={style.detailedTitleUnderlined}>Presenter</span>
</Td> <Editable
</Tr> defaultValue='Presenter Name'
style={{ display: 'inline' }}
>
<EditablePreview style={{}} />
<EditableInput style={{width:'15em'}} />
</Editable>
</div>
</div>
) : (
<div className={style.titleContainer}>
<div>
<span className={style.detailedTitle}>Title</span>
<Editable
defaultValue='Event Title'
style={{ display: 'inline' }}
>
<EditablePreview />
<EditableInput style={{width:'15em'}} />
</Editable>
</div>
</div>
)}
<div className={style.more} onClick={() => setMore(!more)}>
{more ? <ChevronUpIcon /> : <ChevronDownIcon />}
</div>
</div>
<div className={style.actionOverlay}>
<IconButton size='xs' icon={<MinusIcon />} colorScheme='red' />
<IconButton size='xs' icon={<AddIcon />} colorScheme='blue' />
<IconButton size='xs' icon={<TimeIcon />} colorScheme='yellow' />
<IconButton size='xs' icon={<NotAllowedIcon />} colorScheme='purple' />
</div>
</div>
); );
} }
+175
View File
@@ -0,0 +1,175 @@
/* ============= EVENT LIST ============= */
.headerButtons {
display: flex;
gap: 0.5em;
align-content: center;
justify-content: flex-end;
}
.eventContainer {
}
/* ============= EVENT ITEM ============= */
.eventRow,
.eventRowActive {
margin: 0.2em 0;
padding: 0.2em 0.5em;
position: relative;
top: 1em;
left: 0;
width: 100%;
display: grid;
grid-template-columns: 2em 5em 1fr auto;
gap: 0.5em;
justify-content: center;
align-content: center;
align-items: center;
border-radius: 8px;
}
.eventRow {
background-color: #0001;
}
.eventRowActive {
background-color: #b2f5eaaa;
}
.arm,
.armActive {
width: 20px;
height: 20px;
border-radius: 10px;
cursor: pointer;
}
.arm {
background-color: #888;
border: 1px solid #444;
}
.armActive {
background: radial-gradient(
circle,
rgba(22, 255, 0, 1) 0%,
rgba(50, 255, 31, 1) 49%,
rgba(0, 0, 0, 1) 65%,
rgba(0, 255, 156, 0.7083333333333333) 81%
);
border: 1px solid #256e62;
}
.time,
.titleContainer,
.detailedContainer {
background-color: #fff8;
border: 1px solid #0001;
border-radius: 3px;
}
.time {
width: 4em;
height: fit-content;
}
.rowDetailed {
display: inline-flex;
position: relative;
}
.titleContainer,
.detailedContainer {
width: 90%;
display: block;
}
.detailedContainer > div,
.titleContainer > div {
display: inline;
}
.detailedTitle,
.detailedTitleUnderlined {
padding-left: 1em;
font-size: 0.8em;
color: #888;
display: inline-block;
width: 6em;
}
.detailedTitleUnderlined {
border-bottom: 1px solid #0001;
}
.more {
position: absolute;
right: 0.25em;
top: 0em;
}
.actionOverlay {
display: flex;
flex-direction: row;
gap: 0.5em;
align-content: center;
align-self: center;
opacity: 0.6;
transition: linear 0.1s;
}
.eventRow:hover > .actionOverlay {
opacity: 0.9;
transition: linear 0.1s;
}
.actionOverlay:hover {
opacity: 1;
}
/* ============= DELAY BLOCK ============= */
.delayContainer {
position: relative;
top: 1em;
margin: 0.2em 0;
padding: 0.2em 1em;
width: 100%;
background-color: #ecc94baa;
border-radius: 8px;
color: white;
border: 1px solid #0001;
border-top: 8px solid #ecc94b;
box-sizing: border-box;
width: 100%;
display: flex;
margin: auto;
gap: 1em;
}
.delayValue {
color: #000;
background-color: #fff5;
border-radius: 4px;
padding: 0.2em;
text-align: center;
width: 6em;
border: 1px solid #0001;
}
/* ============= BLOCK BLOCK ============= */
.blockContainer {
position: relative;
top: 1em;
margin: 0.2em 0;
padding: 0.2em 1em;
width: 100%;
background-color: #805ad5aa;
border-radius: 8px;
color: white;
height: 2em;
border: 1px solid #0001;
border-bottom: 8px solid #805ad5;
box-sizing: border-box;
}