diff --git a/package.json b/package.json index f7dc488..6cf5702 100644 --- a/package.json +++ b/package.json @@ -237,6 +237,7 @@ "@ant-design/icons": "4.6.2", "antd": "4.15.0", "caniuse-lite": "1.0.30001214", + "clsx": "^1.1.1", "date-fns": "2.20.1", "electron-debug": "^3.1.0", "electron-log": "^4.2.4", @@ -250,6 +251,7 @@ "moment": "2.29.1", "react": "^17.0.1", "react-dom": "^17.0.1", + "react-jss": "^10.6.0", "react-router-dom": "^5.2.0", "regenerator-runtime": "^0.13.5", "source-map-support": "^0.5.19" diff --git a/src/components/CircleButton/CircleButton.less b/src/components/CircleButton/CircleButton.less deleted file mode 100644 index fc2d464..0000000 --- a/src/components/CircleButton/CircleButton.less +++ /dev/null @@ -1,10 +0,0 @@ -.circle-button { - display: inline-flex; - align-items: center; - justify-content: center; - height: 28px; - width: 28px; - border-radius: 14px; - cursor: pointer; - background-color: black; -} diff --git a/src/components/CircleButton/CircleButton.tsx b/src/components/CircleButton/CircleButton.tsx index 4256afa..558502a 100644 --- a/src/components/CircleButton/CircleButton.tsx +++ b/src/components/CircleButton/CircleButton.tsx @@ -1,9 +1,7 @@ import React, { SyntheticEvent } from 'react'; import { observer } from 'mobx-react'; - -import './CircleButton.less'; - -import cn from '../../helpers/ClassNameHelper'; +import { createUseStyles } from 'react-jss'; +import clsx from 'clsx'; interface CircleButtonProps { className?: string; @@ -16,9 +14,24 @@ export default observer(function CircleButton({ children, onClick, }: CircleButtonProps) { + const classes = useStyles(); + return ( - + {children} ); }); + +const useStyles = createUseStyles({ + circleButton: { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + height: 28, + width: 28, + borderRadius: 14, + cursor: 'pointer', + backgroundColor: 'black', + }, +}); diff --git a/src/components/HeaderMenu/HeaderMenu.less b/src/components/HeaderMenu/HeaderMenu.less deleted file mode 100644 index d235b0e..0000000 --- a/src/components/HeaderMenu/HeaderMenu.less +++ /dev/null @@ -1,7 +0,0 @@ -.header-menu { - padding: 0 20px; -} - -.header-menu a { - color: white; -} diff --git a/src/components/HeaderMenu/HeaderMenu.tsx b/src/components/HeaderMenu/HeaderMenu.tsx index 16434f7..a56c4aa 100644 --- a/src/components/HeaderMenu/HeaderMenu.tsx +++ b/src/components/HeaderMenu/HeaderMenu.tsx @@ -1,12 +1,23 @@ import React from 'react'; import { observer } from 'mobx-react'; - -import './HeaderMenu.less'; +import { createUseStyles } from 'react-jss'; interface HeaderMenuProps { children: React.ReactNode; } export default observer(function HeaderMenu({ children }: HeaderMenuProps) { - return {children}; + const classes = useStyles(); + + return {children}; +}); + +const useStyles = createUseStyles({ + root: { + padding: '0 20px', + + '& a': { + color: 'white', + }, + }, }); diff --git a/src/components/IconTile/IconTile.less b/src/components/IconTile/IconTile.less deleted file mode 100644 index 475340c..0000000 --- a/src/components/IconTile/IconTile.less +++ /dev/null @@ -1,9 +0,0 @@ -.icon-tile { - display: flex; - justify-content: center; - align-items: center; - height: 30px; - width: 30px; - padding: 8px; - border-radius: 5px; -} diff --git a/src/components/IconTile/IconTile.tsx b/src/components/IconTile/IconTile.tsx index 9274498..e0f1c8a 100644 --- a/src/components/IconTile/IconTile.tsx +++ b/src/components/IconTile/IconTile.tsx @@ -1,8 +1,7 @@ import React from 'react'; import { observer } from 'mobx-react'; - -import './IconTile.less'; -import cn from '../../helpers/ClassNameHelper'; +import { createUseStyles } from 'react-jss'; +import clsx from 'clsx'; interface IconTileProps { children: React.ReactNode; @@ -15,9 +14,23 @@ export default observer(function IconTile({ children, backgroundColor, }: IconTileProps) { + const classes = useStyles(); + return ( - + {children} ); }); + +const useStyles = createUseStyles({ + root: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + height: 30, + width: 30, + padding: 8, + borderRadius: 5, + }, +}); diff --git a/src/components/PlayStopButton/PlayStopButton.less b/src/components/PlayStopButton/PlayStopButton.less deleted file mode 100644 index 2a54b53..0000000 --- a/src/components/PlayStopButton/PlayStopButton.less +++ /dev/null @@ -1,3 +0,0 @@ -.anticon.play-stop-button__icon { - color: white; -} diff --git a/src/components/PlayStopButton/PlayStopButton.tsx b/src/components/PlayStopButton/PlayStopButton.tsx index 4b5bcf0..cf61e7f 100644 --- a/src/components/PlayStopButton/PlayStopButton.tsx +++ b/src/components/PlayStopButton/PlayStopButton.tsx @@ -1,13 +1,12 @@ import React, { SyntheticEvent } from 'react'; import { CaretRightFilled, PauseOutlined } from '@ant-design/icons'; import { observer } from 'mobx-react'; - -import './PlayStopButton.less'; +import clsx from 'clsx'; +import { createUseStyles } from 'react-jss'; import CircleButton from '../CircleButton/CircleButton'; import rootStore from '../../services/RootStore'; import TaskModel from '../../models/TaskModel'; -import cn from '../../helpers/ClassNameHelper'; const { tasksStore } = rootStore; @@ -20,6 +19,8 @@ export default observer(function PlayStopButton({ task, className, }: PlayStopButtonProps) { + const classes = useStyles(); + function handleClick(e: SyntheticEvent) { e.stopPropagation(); if (task) { @@ -34,13 +35,19 @@ export default observer(function PlayStopButton({ return ( {!task?.active ? ( - + ) : ( - + )} ); }); + +const useStyles = createUseStyles({ + icon: { + color: 'white', + }, +}); diff --git a/src/components/TaskControl/TaskControl.less b/src/components/TaskControl/TaskControl.less index 925e681..6ea85ae 100644 --- a/src/components/TaskControl/TaskControl.less +++ b/src/components/TaskControl/TaskControl.less @@ -9,7 +9,7 @@ border-radius: 5px; line-height: 16px; color: white; - background-color: @purple; + background-color: @purple; /* TODO refactor and use Theme */ } .task-control__info { diff --git a/src/components/TimeRangeModal/TimeRangeModal.less b/src/components/TimeRangeModal/TimeRangeModal.less deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/TimeRangeModal/TimeRangeModal.tsx b/src/components/TimeRangeModal/TimeRangeModal.tsx index 2004525..e32ddde 100644 --- a/src/components/TimeRangeModal/TimeRangeModal.tsx +++ b/src/components/TimeRangeModal/TimeRangeModal.tsx @@ -6,8 +6,6 @@ import { DeleteFilled } from '@ant-design/icons'; import { observer } from 'mobx-react'; import isBefore from 'date-fns/isBefore'; -import './TimeRangeModal.less'; - import rootStore from '../../services/RootStore'; import TaskTimeItemModel from '../../models/TaskTimeItemModel'; import { ITimeRangeModel } from '../../models/TaskModel'; diff --git a/src/helpers/IterateLastCurrent.ts b/src/helpers/IterateLastCurrent.ts index 43fead7..8ccb110 100644 --- a/src/helpers/IterateLastCurrent.ts +++ b/src/helpers/IterateLastCurrent.ts @@ -1,6 +1,6 @@ type Callback = (last: T | undefined, cur: T, index: number) => R; -export function mapLastCurrent( +export function mapPrevCurrent( items: T[], callback: Callback ): R[] { diff --git a/src/screens/Main.less b/src/screens/Main.less deleted file mode 100644 index ba4c8ad..0000000 --- a/src/screens/Main.less +++ /dev/null @@ -1,4 +0,0 @@ -.ant-layout-sider.sider { - background-color: #f0f2f5; - border-right: 1px solid #d9d9d9; -} diff --git a/src/screens/Main.tsx b/src/screens/Main.tsx index 0082ac5..5c26536 100644 --- a/src/screens/Main.tsx +++ b/src/screens/Main.tsx @@ -3,8 +3,6 @@ import { Route, Switch, Link, Redirect } from 'react-router-dom'; import { Layout } from 'antd'; import { observer } from 'mobx-react'; -import './Main.less'; - import Projects from './projects/Projects'; import TaskControl from '../components/TaskControl/TaskControl'; import HeaderMenu from '../components/HeaderMenu/HeaderMenu'; diff --git a/src/screens/hours/HoursView.less b/src/screens/hours/HoursView.less deleted file mode 100644 index d94dcd0..0000000 --- a/src/screens/hours/HoursView.less +++ /dev/null @@ -1,13 +0,0 @@ -.hours { - overflow-y: scroll; - padding: 12px; -} - -.hours .ant-space-item { - display: flex; - justify-content: center; -} - -.hours .ant-card-body { - padding: 8px; -} diff --git a/src/screens/hours/HoursView.tsx b/src/screens/hours/HoursView.tsx index 4c9325a..6396ab4 100644 --- a/src/screens/hours/HoursView.tsx +++ b/src/screens/hours/HoursView.tsx @@ -2,8 +2,6 @@ import React, { useMemo, useState } from 'react'; import { Layout, Space } from 'antd'; import { observer } from 'mobx-react'; -import './HoursView.less'; - import rootStore from '../../services/RootStore'; import HoursCard from './components/HoursCard/HoursCard'; import getTimeItems from '../../services/TaskTimeItem'; @@ -12,10 +10,12 @@ import TimeRangeModal from '../../components/TimeRangeModal/TimeRangeModal'; import TaskTimeItemModel from '../../models/TaskTimeItemModel'; import { Undefined } from '../../types/CommonTypes'; import TotalHours from './components/TotalHours/TotalHours'; +import { createUseStyles } from 'react-jss'; const { tasksStore } = rootStore; export default observer(function HoursView() { + const classes = useStyles(); const [date, setDate] = useState(new Date()); const [currentTaskTime, setCurrentTaskTime] = useState< Undefined @@ -25,7 +25,7 @@ export default observer(function HoursView() { const timeItems = getTimeItems(tasks, date); return ( - + @@ -45,3 +45,19 @@ export default observer(function HoursView() { ); }); + +const useStyles = createUseStyles({ + hours: { + overflowY: 'auto', + padding: 12, + + '& .ant-space-item': { + display: 'flex', + justifyContent: 'center', + }, + + '& .ant-card-body': { + padding: 8, + }, + }, +}); diff --git a/src/screens/hours/components/HoursCard/HoursCard.less b/src/screens/hours/components/HoursCard/HoursCard.less deleted file mode 100644 index 1bf7aa5..0000000 --- a/src/screens/hours/components/HoursCard/HoursCard.less +++ /dev/null @@ -1,47 +0,0 @@ -.hours-card { - width: 300px; - - .ant-card-body { - display: flex; - flex-direction: row; - cursor: pointer; - } - - .hours-card__info { - flex: 1; - } - - .project-title { - font-size: 12px; - } - - .task-title { - font-weight: bold; - font-size: 12px; - } - - .description { - font-size: 11px; - } - - .time-container { - display: flex; - flex-direction: row; - justify-content: space-between; - margin-top: 8px; - } - - .time { - font-size: 11px; - } - - .play-stop-button { - display: none; - position: absolute; - right: 8px; - } - - &:hover .play-stop-button { - display: inline-flex; - } -} diff --git a/src/screens/hours/components/HoursCard/HoursCard.tsx b/src/screens/hours/components/HoursCard/HoursCard.tsx index eb4ae6b..ade4fd5 100644 --- a/src/screens/hours/components/HoursCard/HoursCard.tsx +++ b/src/screens/hours/components/HoursCard/HoursCard.tsx @@ -2,8 +2,7 @@ import React, { useMemo } from 'react'; import { Card } from 'antd'; import format from 'date-fns/format'; import { observer } from 'mobx-react'; - -import './HoursCard.less'; +import { createUseStyles } from 'react-jss'; import TaskTimeItemModel from '../../../../models/TaskTimeItemModel'; import PlayStopButton from '../../../../components/PlayStopButton/PlayStopButton'; @@ -30,6 +29,7 @@ export default observer(function HoursCard({ onClick, }: HoursCardProps) { const { task, time } = taskTime; + const classes = useStyle(); const project = useMemo(() => projectStore.get(task.projectId), [task]); const duration = time.end ? msToTime(time.end.getTime() - time.start.getTime()) @@ -37,24 +37,67 @@ export default observer(function HoursCard({ return ( onClick(taskTime)} style={ project?.color ? { borderLeft: `4px solid ${project?.color}` } : {} } > -
-
{project?.title}
-
{task.title}
-
{time.description}
-
-
{`${timeFormat(time.start)} - ${timeFormat( - time.end - )}`}
-
{duration}
+
+
{project?.title}
+
{task.title}
+
{time.description}
+
+
{`${timeFormat( + time.start + )} - ${timeFormat(time.end)}`}
+
{duration}
- + ); }); + +const useStyle = createUseStyles({ + root: { + width: 300, + + '& .ant-card-body': { + display: 'flex', + flexDirection: 'row', + cursor: 'pointer', + }, + + '&:hover $playButton': { + display: 'inline-flex', + }, + }, + hoursCard: { + flex: 1, + }, + projectTitle: { + fontSize: 12, + }, + taskTitle: { + fontWeight: 'bold', + fontSize: 12, + }, + description: { + fontSize: 11, + }, + timeContainer: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + marginTop: 8, + }, + time: { + fontSize: 11, + }, + playButton: { + display: 'none', + position: 'absolute', + right: 8, + }, +}); diff --git a/src/screens/projects/Projects.less b/src/screens/projects/Projects.less deleted file mode 100644 index be693d2..0000000 --- a/src/screens/projects/Projects.less +++ /dev/null @@ -1,3 +0,0 @@ -.root { -} - diff --git a/src/screens/projects/Projects.tsx b/src/screens/projects/Projects.tsx index 9537be7..d349c09 100644 --- a/src/screens/projects/Projects.tsx +++ b/src/screens/projects/Projects.tsx @@ -2,8 +2,7 @@ import React, { useState } from 'react'; import { Button, Layout, Space } from 'antd'; import { observer } from 'mobx-react'; import { Key } from 'rc-tree/lib/interface'; - -import './Projects.less'; +import { createUseStyles } from 'react-jss'; import TaskInput from './components/TaskInput'; import rootStore from '../../services/RootStore'; @@ -53,6 +52,7 @@ const ProjectList = TreeList( ); export default observer(function Projects() { + const classes = useStyles(); const [showProjectModal, setShowProjectModal] = useState(false); const [drawerVisible, setDrawerVisible] = useState(false); const [selectedTask, setSelectedTask] = useState(); @@ -77,8 +77,8 @@ export default observer(function Projects() { return ( - - + +