Skip to content

Commit

Permalink
feat(dashboard): comment calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
surmon-china committed Sep 5, 2023
1 parent 7fa201a commit a7cee60
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 36 deletions.
91 changes: 59 additions & 32 deletions src/pages/Dashboard/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useMemo, useRef as useReactRef, WheelEventHandler } from 'react'
import { useRef, useComputed, onMounted, onBeforeUnmount } from 'veact'
import { useLoading } from 'veact-use'
import { Card, Tooltip, Divider, Typography } from 'antd'
import { ArticleCalendarItem, getArticleCalendar } from '@/store/system'
import { StatisticsCalendarItem, getArticleCalendar, getCommentCalendar } from '@/store/system'

import styles from './style.module.less'

Expand All @@ -30,12 +30,15 @@ export const Calendar: React.FC = () => {
}
}

const loading = useLoading()
const articleCalendar = useRef<Array<ArticleCalendarItem>>([])
const fetchArticleCalendar = () => {
return loading.promise(getArticleCalendar()).then((result) => {
articleCalendar.value = result
})
const calendarloading = useLoading()
const articleCalendar = useRef<Array<StatisticsCalendarItem>>([])
const commentCalendar = useRef<Array<StatisticsCalendarItem>>([])
const fetchCalendarData = async () => {
const [acResult, ccResult] = await calendarloading.promise(
Promise.all([getArticleCalendar(), getCommentCalendar()])
)
articleCalendar.value = acResult
commentCalendar.value = ccResult
}

// current month | day
Expand All @@ -52,11 +55,12 @@ export const Calendar: React.FC = () => {

const months = useComputed(() => {
const firstArticelDate = articleCalendar.value[0]?.date
if (!firstArticelDate) {
const firstCommentDate = commentCalendar.value[0]?.date
if (!firstArticelDate && !firstCommentDate) {
return []
}

const firstDay = dayjs(firstArticelDate)
const firstDay = dayjs(firstArticelDate || firstCommentDate)
const today = dayjs()
// prev months
const duration = dayjs.duration(firstDay.diff(today))
Expand All @@ -74,7 +78,7 @@ export const Calendar: React.FC = () => {
})

onMounted(() => {
fetchArticleCalendar().then(() => {
fetchCalendarData().then(() => {
setTimeout(() => {
if (calendarElement.current) {
calendarElement.current.scrollLeft = calendarElement.current.scrollWidth
Expand All @@ -89,40 +93,63 @@ export const Calendar: React.FC = () => {
})

const renderDay = (date: string) => {
const count = articleCalendar.value.find((ac) => ac.date === date)?.count || 0
const title = !count ? (
date
) : (
<span>
{date}
<Divider type="vertical" />
<strong>{count}</strong>
</span>
)

const brightnessStyle = !count
? {}
: {
filter: `brightness(${count * 0.5})`
}
const articleCount = articleCalendar.value.find((i) => i.date === date)?.count || 0
const commentCount = commentCalendar.value.find((i) => i.date === date)?.count || 0
const total = articleCount + commentCount
const getPointHeightStyle = (value: number) => {
return isNaN(value) ? 0 : `${Math.floor(value * 100)}%`
}

return (
<Tooltip
title={title}
destroyTooltipOnHide={{ keepParent: false }}
mouseEnterDelay={0}
mouseLeaveDelay={0}
destroyTooltipOnHide={{ keepParent: false }}
title={
total ? (
<div>
<Typography.Text strong>{date}</Typography.Text>
<Divider type="horizontal" style={{ margin: '6px 0' }} />
<div>文章: {articleCount}</div>
<div>评论:{commentCount}</div>
</div>
) : (
<Typography.Text type="secondary">{date} (无)</Typography.Text>
)
}
>
<div
className={classnames(styles.day, count ? styles.active : '')}
style={brightnessStyle}
></div>
className={classnames(styles.day)}
data-date={date}
data-total-count={total}
data-article-count={articleCount}
data-comment-count={commentCount}
>
{!articleCount ? null : (
<div
className={classnames(styles.item, styles.article)}
style={{
height: getPointHeightStyle(articleCount / total),
filter: `brightness(${articleCount * 0.5})`
}}
/>
)}
{!commentCount ? null : (
<div
className={classnames(styles.item, styles.comment)}
style={{
height: getPointHeightStyle(commentCount / total),
filter: `brightness(${commentCount * 0.3})`
}}
/>
)}
</div>
</Tooltip>
)
}

return (
<Card bordered={false} className={styles.calendarCard} loading={loading.state.value}>
<Card bordered={false} className={styles.calendarCard} loading={calendarloading.state.value}>
<div className={styles.calendar} ref={calendarElement}>
{months.value.map((month, index) => (
<div className={styles.month} key={index}>
Expand Down
11 changes: 9 additions & 2 deletions src/pages/Dashboard/style.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@
width: 10px;
height: 10px;
background-color: @app-module-background-lighter;
&.active {
background-color: @app-primary-color;

.item {
width: 100%;
&.article {
background-color: @app-primary-color;
}
&.comment {
background-color: #f8981d;
}
}
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/store/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,24 @@ export function getStatistics() {
.then((response) => response.result)
}

export interface ArticleCalendarItem {
export interface StatisticsCalendarItem {
date: string
count: number
}

/** 获取文章创作日历信息 */
export function getArticleCalendar() {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
return nodepress
.get<Array<ArticleCalendarItem>>('/article/calendar', { params: { timezone } })
.get<Array<StatisticsCalendarItem>>('/article/calendar', { params: { timezone } })
.then((response) => response.result)
}

/** 获取评论创建日历信息 */
export function getCommentCalendar() {
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
return nodepress
.get<Array<StatisticsCalendarItem>>('/comment/calendar', { params: { timezone } })
.then((response) => response.result)
}

Expand Down

0 comments on commit a7cee60

Please sign in to comment.