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 { EventContext } from '../../../app/context/eventContext';
import { EventListContext } from '../../../app/context/eventListContext';
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) {
const [events] = useContext(EventListContext);
const [event, setEvent] = useContext(EventContext);
const handleSetSelected = (id) => {
setEvent(events.filter((e) => e.id === id)[0]);
props.setFormMode('edit');
};
const disabled = props.formMode !== null;
const [, setEvent] = useContext(EventContext);
return (
<Table variant='simple' size='sm'>
<Thead>
<Tr>
<Th>Event Title</Th>
<Th>Event Subtitle</Th>
<Th>Presenter Name</Th>
<Th>Time Start</Th>
<Th>Time End</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{sortByNumber(events).map((e) => (
<EventListItem
key={e.id}
data={e}
disabled={disabled}
selectedId={event?.id}
setSelected={handleSetSelected}
/>
))}
</Tbody>
</Table>
<>
<div className={style.headerButtons}>
<Button size='sm' rightIcon={<AttachmentIcon />}>
Upload
</Button>
<Button size='sm' rightIcon={<DownloadIcon />}>
Download
</Button>
<IconButton size='sm' icon={<AddIcon />} colorScheme='blue' />
</div>
<div className={style.eventContainer}>
<EventListItem />
<EventListItem />
<DelayBlock />
<EventListItem />
<BlockBlock />
<EventListItem />
</div>
</>
);
}
+89 -45
View File
@@ -1,50 +1,94 @@
import { IconButton } from '@chakra-ui/button';
import { Td, Tr } from '@chakra-ui/table';
import { format } from 'date-fns';
import { timeFormat } from '../../../common/dateConfig';
import { LockIcon, ChevronRightIcon } from '@chakra-ui/icons';
import {
AddIcon,
ChevronDownIcon,
ChevronUpIcon,
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) {
const isSelected = props.selectedId === props.data.id;
console.log(props);
const [more, setMore] = useState(false);
const [armed, setArmed] = useState(false);
return (
<Tr
style={
isSelected
? { backgroundColor: '#b2f5ea' }
: { backgroundColor: 'white' }
}
>
<Td>{props.data.title}</Td>
<Td>{props.data.subtitle}</Td>
<Td>{props.data.presenter}</Td>
<Td>
{props.data.timeStart && format(props.data.timeStart, timeFormat)}
</Td>
<Td>{props.data?.timeEnd && format(props.data?.timeEnd, timeFormat)}</Td>{' '}
<Td>{props.data?.timerDuration}</Td>
<Td>
<IconButton
colorScheme='teal'
variant={isSelected ? 'solid' : 'outline'}
onClick={() => props.setSelected(props.data.id)}
disabled={props.disabled}
size='sm'
aria-label='Select Item'
icon={<LockIcon />}
/>
</Td>
<Td>
<IconButton
colorScheme='teal'
variant={isSelected ? 'solid' : 'outline'}
onClick={() => props.setSelected(props.data.id)}
disabled={props.disabled}
size='sm'
aria-label='Select Item'
icon={<ChevronRightIcon />}
/>
</Td>
</Tr>
<div className={armed ? style.eventRowActive : style.eventRow}>
<div
className={armed ? style.armActive : style.arm}
onClick={() => setArmed(!armed)}
/>
<div className={style.time}>
<Editable defaultValue='11:20' style={{ textAlign: 'center' }}>
<EditablePreview />
<EditableInput />
</Editable>
</div>
<div className={style.rowDetailed}>
{more ? (
<div className={style.detailedContainer}>
<div style={{ display: 'block' }}>
<span className={style.detailedTitleUnderlined}>Title</span>
<Editable
defaultValue='Event Title'
style={{ display: 'inline' }}
>
<EditablePreview />
<EditableInput style={{width:'15em'}} />
</Editable>
</div>
<div style={{ display: 'block' }}>
<span className={style.detailedTitleUnderlined}>Subtitle</span>
<Editable
defaultValue='Event Subtitle'
style={{ display: 'inline' }}
>
<EditablePreview />
<EditableInput style={{width:'15em'}} />
</Editable>
</div>
<div style={{ display: 'block' }}>
<span className={style.detailedTitleUnderlined}>Presenter</span>
<Editable
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;
}