Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = {
'explicit-module-boundary-types': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'jsx-a11y/no-autofocus': 'off',
'no-console': 2,
'no-console': 1,
},
settings: {
react: {
Expand Down
2 changes: 1 addition & 1 deletion src/components/AddEntryButton/AddEntryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const AddEntryButton = ({ onClick, errors }: AddEntryButtonProps) => {
<Button
color="primary"
onClick={() => onClick()}
disabled={disabled}
isDisabled={disabled}
disabledTooltip={disabledMessage}
>
Add
Expand Down
85 changes: 45 additions & 40 deletions src/components/EntryList/EntryList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { palette, SPACING_SMALL } from 'config'
import { ChangeEvent } from 'react'
import { ChangeEvent, useState } from 'react'
import {
BsArrowLeftCircle,
BsArrowRightCircle,
BsExclamationOctagon,
} from 'react-icons/bs'
import { TimeEntry } from 'services'
import { Button } from 'shared/components'
import { EditEntryContext } from 'shared/utils'
import {
ControlsWrapper,
DateField,
Expand All @@ -20,6 +22,7 @@ import TimeSumup from './TimeSumup'
type ChangeEv = ChangeEvent<HTMLInputElement>

const EntryList = () => {
const [editing, setEditing] = useState<TimeEntry['id'] | null>(null)
const {
entriesFromDay,
labels,
Expand All @@ -32,45 +35,47 @@ const EntryList = () => {
const onDateChange = (e: ChangeEv) => setTargetDate(e.target.value)

return (
<EntryListSection>
<div>
<b>Selected date:</b>
<ControlsWrapper>
<Button
onClick={() => setDate(-1)}
color="primary"
variant="outlined"
margin={SPACING_SMALL}
>
<BsArrowLeftCircle size={13} />
</Button>
<DateField type="date" value={targetDate} onChange={onDateChange} />
<Button
onClick={() => setDate(1)}
color="primary"
variant="outlined"
margin={SPACING_SMALL}
>
<BsArrowRightCircle size={13} />
</Button>
</ControlsWrapper>
<TimeSumup
regularTime={summedTimeFromDay}
scaledTime={summedTimeFromDayScaled}
/>
</div>
<List>
{entriesFromDay.map(item => (
<ListItem key={item.id} {...item} labels={labels} />
))}
{entriesFromDay.length === 0 && (
<EmptyList>
<h1>No time entries</h1>
<BsExclamationOctagon size={100} color={palette.accent.accent} />
</EmptyList>
)}
</List>
</EntryListSection>
<EditEntryContext.Provider value={{ editing, setEditing }}>
<EntryListSection>
<div>
<b>Selected date:</b>
<ControlsWrapper>
<Button
onClick={() => setDate(-1)}
color="primary"
variant="outlined"
margin={SPACING_SMALL}
>
<BsArrowLeftCircle size={13} />
</Button>
<DateField type="date" value={targetDate} onChange={onDateChange} />
<Button
onClick={() => setDate(1)}
color="primary"
variant="outlined"
margin={SPACING_SMALL}
>
<BsArrowRightCircle size={13} />
</Button>
</ControlsWrapper>
<TimeSumup
regularTime={summedTimeFromDay}
scaledTime={summedTimeFromDayScaled}
/>
</div>
<List>
{entriesFromDay.map(item => (
<ListItem key={item.id} {...item} labels={labels} />
))}
{entriesFromDay.length === 0 && (
<EmptyList>
<h1>No time entries</h1>
<BsExclamationOctagon size={100} color={palette.accent.accent} />
</EmptyList>
)}
</List>
</EntryListSection>
</EditEntryContext.Provider>
)
}

Expand Down
68 changes: 41 additions & 27 deletions src/components/EntryList/ListItem/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { SPACING_SMALL } from 'config'
import { useContext } from 'react'
import { BsFillPencilFill, BsFillTrashFill } from 'react-icons/bs'
import { DB, TimeEntry } from 'services'
import { Button, TextArea } from 'shared/components'
import { DISABLED_ENTRY_LIST_ITEMS_TEXT, SPACING_SMALL } from 'config'
import { BsCheckLg, BsFillPencilFill, BsFillTrashFill } from 'react-icons/bs'
import { TimeEntry } from 'services'
import { Button, TextArea, Tooltip } from 'shared/components'
import { Label } from 'shared/types'
import { EntryListContext } from 'shared/utils'
import { EntryTimeField, Labels } from '../../index'
import { ActionsWrapper, Item } from './ListItem.style'
import { calculateTimeEntry, getSelectedLabels } from './ListItem.utils'

const db = new DB()
import {
calculateTimeEntry,
getSelectedLabels,
useDeleteEntry,
useEdit,
} from './ListItem.utils'

interface ListItemProps extends TimeEntry {
labels: Label[]
Expand All @@ -23,25 +24,34 @@ const ListItem = ({
labels,
id,
}: ListItemProps) => {
const { setUpdateEntryList } = useContext(EntryListContext) || {}
const deleteEntry = () => {
db.deleteTimeEntry(id)
setUpdateEntryList?.(true)
}
const deleteEntry = useDeleteEntry(id)
const { disabled, toggleEditing } = useEdit(id)

return (
<Item>
<TextArea
value={timeEntryDescription}
color="primary"
height={75}
width={400}
/>
<Labels
labels={labels}
selectedLabels={getSelectedLabels(labels, selectedLabels)}
/>
<EntryTimeField hours={entryTimeHours} minutes={entryTimeMinutes} />
<Tooltip show={disabled} text={DISABLED_ENTRY_LIST_ITEMS_TEXT}>
<TextArea
value={timeEntryDescription}
color="primary"
height={75}
width={400}
disabled={disabled}
/>
</Tooltip>
<Tooltip show={disabled} text={DISABLED_ENTRY_LIST_ITEMS_TEXT}>
<Labels
labels={labels}
selectedLabels={getSelectedLabels(labels, selectedLabels)}
disabled={disabled}
/>
</Tooltip>
<Tooltip show={disabled} text={DISABLED_ENTRY_LIST_ITEMS_TEXT}>
<EntryTimeField
hours={entryTimeHours}
minutes={entryTimeMinutes}
disabled={disabled}
/>
</Tooltip>
<div>
Scaled time: {calculateTimeEntry(entryTimeHours, entryTimeMinutes)}
</div>
Expand All @@ -54,8 +64,12 @@ const ListItem = ({
>
<BsFillTrashFill />
</Button>
<Button color="primary" margin={`${SPACING_SMALL}px 0 0 0`}>
<BsFillPencilFill />
<Button
color="primary"
margin={`${SPACING_SMALL}px 0 0 0`}
onClick={toggleEditing}
>
{disabled ? <BsFillPencilFill /> : <BsCheckLg />}
</Button>
</ActionsWrapper>
</Item>
Expand Down
27 changes: 26 additions & 1 deletion src/components/EntryList/ListItem/ListItem.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { TIME_MULTIPLY_RATIO } from 'config'
import { Label } from 'shared/types'
import { useContext } from 'react'
import { DB } from 'services'
import { ID, Label } from 'shared/types'
import { EditEntryContext, EntryListContext } from 'shared/utils'

const db = new DB()

export const calculateTimeEntry = (hours: number, minutes: number) => {
const scaledTime = Math.round(minutes / TIME_MULTIPLY_RATIO)
Expand All @@ -19,3 +24,23 @@ export const getSelectedLabels = (

return filteredLabels
}

export const useEdit = (id: ID) => {
const { setEditing, editing } = useContext(EditEntryContext) || {}
const toggleEditing = () => {
setEditing?.(id)
if (editing === id) setEditing?.(null)
}
const disabled = id !== editing

return { toggleEditing, disabled }
}

export const useDeleteEntry = (id: ID) => {
const { setUpdateEntryList } = useContext(EntryListContext) || {}

return () => {
db.deleteTimeEntry(id)
setUpdateEntryList?.(true)
}
}
28 changes: 25 additions & 3 deletions src/components/EntryTimeField/EntryTimeField.style.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import {
palette,
SPACING_REGULAR,
TIME_FIELD_MARGIN,
TIME_FIELD_WIDTH,
} from 'config'
import { darken } from 'polished'
import {
Input as BaseInput,
InputProps as BaseInputProps,
} from 'shared/components'
import styled from 'styled-components'
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort imports

import { SPACING_REGULAR, TIME_FIELD_MARGIN, TIME_FIELD_WIDTH } from 'config'
import { Input } from 'shared/components'

export const TimeField = styled(Input)({
export const TimeField = styled(BaseInput)({
width: TIME_FIELD_WIDTH,
margin: `0 ${TIME_FIELD_MARGIN}px`,
})
Expand All @@ -12,3 +21,16 @@ export const Form = styled('form')({
justifyContent: 'space-between',
gap: SPACING_REGULAR,
})

interface InputProps extends BaseInputProps {
disabled?: boolean
}
export const Input = styled(BaseInput)<InputProps>(({ disabled }) => ({
...(disabled && {
cursor: 'not-allowed',
'&:hover': {
backgroundColor: palette.disabled,
borderColor: darken(0.2, palette.disabled),
},
}),
}))
7 changes: 5 additions & 2 deletions src/components/EntryTimeField/EntryTimeField.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Input } from 'shared/components'
import { setTimeFunc } from 'shared/types'
import { HOURS_LIMIT, MINUTES_LIMIT } from '../../config'
import { useEntryTimeField } from './EntryTime.utils'
import { Form } from './EntryTimeField.style'
import { Form, Input } from './EntryTimeField.style'

interface EntryTimeFieldProps {
hours: number
minutes: number
setHours?: setTimeFunc
setMinutes?: setTimeFunc
disabled?: boolean
}

const EntryTimeField = ({
hours,
minutes,
setHours,
setMinutes,
disabled = false,
}: EntryTimeFieldProps) => {
const { error, handleChange } = useEntryTimeField()

Expand All @@ -31,6 +32,7 @@ const EntryTimeField = ({
max={HOURS_LIMIT}
error={error.hours}
width={100}
disabled={disabled}
/>

<Input
Expand All @@ -42,6 +44,7 @@ const EntryTimeField = ({
onChange={e => handleChange(e.target.value, MINUTES_LIMIT, setMinutes)}
error={error.minutes}
width={100}
disabled={disabled}
/>
</Form>
)
Expand Down
3 changes: 2 additions & 1 deletion src/components/Labels/AddNewLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ export const AddNewLabel = ({ onAdd }: AddNewLabelProps) => {
setLabelName(e.target.value)

const onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (!onAdd) return
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could be connected with if below

if (e.charCode !== 13) return
db.addNewLabel(labelName)
setInitiated(false)
onAdd && onAdd(true)
onAdd(true)
setLabelName('')
}

Expand Down
27 changes: 22 additions & 5 deletions src/components/Labels/Labels.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
transition,
typography,
} from 'config'
import { darken } from 'polished'
import { LabelProps } from 'shared/types'
import styled from 'styled-components'
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imports order


Expand Down Expand Up @@ -38,8 +39,24 @@ export const StyledLabel = styled('button')<LabelProps>(({ active }) => ({
},
}))

export const LabelWrapper = styled('div')({
display: 'flex',
width: LABEL_WRAPPER_WIDTH,
flexWrap: 'wrap',
})
interface LabelWrapperProps {
disabled: boolean
}
export const LabelWrapper = styled('div')<LabelWrapperProps>(
({ disabled }) => ({
display: 'flex',
width: LABEL_WRAPPER_WIDTH,
flexWrap: 'wrap',

...(disabled && {
'& button:hover': {
backgroundColor: palette.disabled,
borderColor: darken(0.2, palette.disabled),
cursor: 'not-allowed',
},
'& button:last-of-type': {
display: 'none',
},
}),
})
)
Loading