Skip to content

Commit

Permalink
feat: ✨ add dashboard [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
haydenull committed Apr 29, 2022
1 parent 17553a0 commit 1d75bb3
Show file tree
Hide file tree
Showing 14 changed files with 628 additions and 139 deletions.
5 changes: 3 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import { getSubCalendarSchedules } from '@/util/subscription'

const App: React.FC<{}> = () => {

const [projectSchedules, setProjectSchedules] = useAtom(projectSchedulesAtom)
const [subscriptionSchedules, setSubscriptionSchedules] = useAtom(subscriptionSchedulesAtom)
// TODO: 使用 only-write 减少重新渲染
const [, setProjectSchedules] = useAtom(projectSchedulesAtom)
const [, setSubscriptionSchedules] = useAtom(subscriptionSchedulesAtom)

useEffect(() => {
async function fetchSchedules() {
Expand Down
42 changes: 42 additions & 0 deletions src/components/Polygonal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState } from 'react'

const Polygonal: React.FC<{}> = () => {
return (
<div>
<svg height="410">
<defs>
<radialGradient id="r1" cx="0" cy="0" r="1">
<stop offset="0%" stop-color="#FFB64833"></stop>
<stop offset="100%" stop-color="#FFB64800"></stop>
</radialGradient>
<radialGradient id="r2" cx="1" cy="0" r="1">
<stop offset="0%" stop-color="#FF5A4833"></stop>
<stop offset="100%" stop-color="#FF5A4800"></stop>
</radialGradient>
<linearGradient id="b1" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#FFB64833" stop-opacity="0.5"></stop>
<stop offset="100%" stop-color="#FFB64800"></stop>
</linearGradient>
<linearGradient id="b2" x1="1" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FF5A4833"></stop>
<stop offset="100%" stop-color="#FF5A4800" stop-opacity="0.5"></stop>
</linearGradient>
</defs>
<linearGradient id="b3" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#FFB648"></stop>
<stop offset="100%" stop-color="#FF5A48"></stop>
</linearGradient>

<path d="M 3,185.5 V 57 Q 49.25,27.5 99.5,27.5 T 197.5,46 T 295.5,2 V 185.5 Z" fill="url(#r1)" stroke-width="1" />
<path d="M 3,185.5 V 57 Q 49.25,27.5 99.5,27.5 T 197.5,46 T 295.5,2 V 185.5 Z" fill="url(#r2)" stroke-width="1" />
<path d="M 3,57 Q 49.25,27.5 99.5,27.5 T 197.5,46 T 295.5,2" fill="none" stroke="url(#b3)" stroke-width="2" />
<circle r="4" cx="3" cy="57" fill="#FFB648" />
<circle r="4" cx="99.5" cy="27.5" fill="#FFB648" />
<circle r="4" cx="197.5" cy="46" fill="#FFB648" />
<circle r="4" cx="295.5" cy="2" fill="#FFB648" />
</svg>
</div>
)
}

export default Polygonal
4 changes: 4 additions & 0 deletions src/components/SiderTabs/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
height: 46px;
background-color: var(--ls-quaternary-background-color);
color: var(--ls-tertiary-background-color);
transition: all 0.3s ease;
@apply rounded-xl shadow flex justify-center items-center text-xl cursor-pointer;
&:hover {
@apply text-2xl;
}
&.active {
background-color: var(--ls-tertiary-background-color);
color: var(--ls-quaternary-background-color);
Expand Down
2 changes: 2 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import weekday from 'dayjs/plugin/weekday'
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
import localeData from 'dayjs/plugin/localeData'
import difference from 'lodash/difference'
import isBetween from 'dayjs/plugin/isBetween'
import { initializeSettings } from './util/baseInfo'
import App from './App'
import 'tui-calendar/dist/tui-calendar.css'
Expand All @@ -15,6 +16,7 @@ dayjs.extend(weekday)
dayjs.extend(isSameOrBefore)
dayjs.extend(localeData)
dayjs.extend(difference)
dayjs.extend(isBetween)

const isDevelopment = import.meta.env.DEV

Expand Down
5 changes: 5 additions & 0 deletions src/model/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { atom } from 'jotai'
import { getInitalSettings } from '@/util/baseInfo'
import type { ISettingsForm } from '@/util/type'

export const settingsAtom = atom<ISettingsForm>(getInitalSettings())
49 changes: 49 additions & 0 deletions src/pages/Dashboard/components/Project.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useState } from 'react'
import { IGroup } from '@/packages/Gantt/type'
import { IoIosArrowUp, IoIosArrowDown} from 'react-icons/io'

import s from '../index.module.less'
import classNames from 'classnames'

const Project: React.FC<{
data: IGroup
}> = ({ data }) => {
const [expand, setExpand] = useState(false)

return (
<div className={classNames(s.project)}>
<div className="flex justify-between items-center h-24 ">
<div className={s.projectContent}>
<div>{data.title?.[0]?.toUpperCase()}</div>
<div>{data.title}</div>
<div>
todo: 10 doing: 5 done: 5
</div>
</div>

<div className={s.milestone}>
<span>30</span>
<span>Apr.</span>
<span>left: 1d</span>
</div>
<div className={s.milestone}>
<span>30</span>
<span>Apr.</span>
<span>left: 1d</span>
</div>

<div className={s.option}>
{ expand ? <IoIosArrowUp onClick={() => setExpand(false)} /> : <IoIosArrowDown onClick={() => setExpand(true)} /> }
</div>
</div>

<div className={classNames(s.timeline, { [s.showTimeline]: expand })}>
{ expand && (
<div>timeline</div>
) }
</div>
</div>
)
}

export default Project
32 changes: 32 additions & 0 deletions src/pages/Dashboard/components/Task.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import classNames from 'classnames'
import React, { useState } from 'react'
import { RiExternalLinkLine } from 'react-icons/ri'
import type { ISchedule } from 'tui-calendar'
import dayjs from 'dayjs'
import s from '../index.module.less'

const Task: React.FC<{
task: ISchedule
showTimeDot?: boolean
type?: 'overdule' | 'allDay' | 'time'
}> = ({ task, showTimeDot = false, type = 'allDay' }) => {
// @ts-ignore
const isActive = dayjs().isBetween(dayjs(task.start), dayjs(task.end))
return (
<div className={classNames(s.task, { [s.taskActive]: isActive }, s?.[type], 'flex pl-5 pr-4 py-2 items-center justify-between')}>
{/* @ts-ignore */}
{ showTimeDot && <div className={classNames(s.time)}><span>{dayjs(task.start)?.format('HH:mm')}</span></div> }
<div className="w-7 h-7 rounded-full flex items-center justify-center" style={{ backgroundColor: task.bgColor }}>{task?.calendarId?.[0]?.toUpperCase()}</div>
<div className="flex flex-col flex-1 ellipsis mx-4">
<span className="ellipsis">{task.title}</span>
<div className={classNames(s.subscription, 'text-xs ellipsis')}>
<span>{task.start}-{task?.end}</span>
<span>{task.calendarId}</span>
</div>
</div>
<div className="w-5 h-5"><RiExternalLinkLine /></div>
</div>
)
}

export default Task
81 changes: 81 additions & 0 deletions src/pages/Dashboard/components/TaskLines.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { useState } from 'react'
import { ISchedule } from 'tui-calendar'
import { RiExternalLinkLine } from 'react-icons/ri'

import s from '../index.module.less'
import classNames from 'classnames'
import dayjs from 'dayjs'
import Task from './Task'

const MOCK_TASKS: ISchedule[] = [
{ id: '111', title: 'foo', start: '2022-04-29T16:00', end: '2022-04-29T17:00', isAllDay: true, calendarId: 'overdule-journal', bgColor: '#aaa' },
{ id: '222', title: 'sdf', start: '2022-04-29T17:00', end: '2022-04-29T18:00', isAllDay: true, calendarId: 'journal', bgColor: '#aaa' },
{ id: 'eee', title: 'asdfa', start: '2022-04-29T17:20', end: '2022-04-29T19:00', isAllDay: false, calendarId: 'journal', bgColor: '#aaa' },
{ id: '444', title: 'foasdfaso', start: '2022-04-29T19:00', end: '2022-04-29T20:00', isAllDay: false, calendarId: 'journal', bgColor: '#aaa' },
{ id: '5', title: 'dgfd', start: '2022-04-29T20:00', end: '2022-04-29T21:00', isAllDay: false, calendarId: 'journal', bgColor: '#aaa' },
{ id: '6', title: 'dgfsd', start: '2022-04-29T21:00', end: '2022-04-29T22:00', isAllDay: false, calendarId: 'journal', bgColor: '#aaa' },
]

function categorizeTasks (tasks: ISchedule[]) {
let overduleTasks: ISchedule[] = []
let allDayTasks: ISchedule[] = []
let timeTasks: ISchedule[] = []
tasks.forEach(task => {
if (task.calendarId?.startsWith('overdule-')) {
overduleTasks.push(task)
} else if (task.isAllDay) {
allDayTasks.push(task)
} else {
timeTasks.push(task)
}
})

return { overduleTasks, allDayTasks, timeTasks }
}

const TaskLines: React.FC<{}> = () => {
const { overduleTasks, allDayTasks, timeTasks } = categorizeTasks(MOCK_TASKS)

return (
<div className={s.taskLine}>
{
overduleTasks.length > 0 && (
<div className={s.module}>
<span>Overdule</span>
{
overduleTasks.map(task => (
<Task key={task.id} task={task} type="overdule" />
))
}
</div>
)
}
{
allDayTasks.length > 0 && (
<div className={s.module}>
<span>All Day</span>
{
allDayTasks.map(task => (
<Task key={task.id} task={task} type="allDay" />
))
}
</div>
)
}
{
timeTasks.length > 0 && (
<div className={s.module}>
<span>Time</span>
{
timeTasks.map(task => (
<Task key={task.id} task={task} type="time" showTimeDot />
))
}
</div>
)
}
</div>
)
}

export default TaskLines
Loading

0 comments on commit 1d75bb3

Please sign in to comment.