diff --git a/web/src/components/ActivityCalendar.tsx b/web/src/components/ActivityCalendar.tsx index 7dcdd00c..b41810bd 100644 --- a/web/src/components/ActivityCalendar.tsx +++ b/web/src/components/ActivityCalendar.tsx @@ -5,10 +5,10 @@ import { useWorkspaceSettingStore } from "@/store/v1"; import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service"; import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting"; import { useTranslate } from "@/utils/i18n"; +import { cn } from "@/utils/utils"; interface Props { - // Format: 2021-1 - month: string; + month: string; // Format: 2021-1 selectedDate: string; data: Record; onClick?: (date: string) => void; @@ -16,9 +16,8 @@ interface Props { const getCellAdditionalStyles = (count: number, maxCount: number) => { if (count === 0) { - return "bg-gray-100 text-gray-400 dark:bg-gray-700 dark:text-gray-500"; + return ""; } - const ratio = count / maxCount; if (ratio > 0.7) { return "bg-primary-darker text-gray-100 dark:opacity-80"; @@ -36,72 +35,64 @@ const ActivityCalendar = (props: Props) => { const weekStartDayOffset = ( workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.GENERAL).generalSetting || WorkspaceGeneralSetting.fromPartial({}) ).weekStartDayOffset; + const year = dayjs(monthStr).toDate().getFullYear(); - const month = dayjs(monthStr).toDate().getMonth() + 1; - const dayInMonth = new Date(year, month, 0).getDate(); - const firstDay = (((new Date(year, month - 1, 1).getDay() - weekStartDayOffset) % 7) + 7) % 7; - const lastDay = new Date(year, month - 1, dayInMonth).getDay() - weekStartDayOffset; + const month = dayjs(monthStr).toDate().getMonth(); + const dayInMonth = new Date(year, month + 1, 0).getDate(); + const firstDay = (((new Date(year, month, 1).getDay() - weekStartDayOffset) % 7) + 7) % 7; + const lastDay = new Date(year, month, dayInMonth).getDay() - weekStartDayOffset; + const prevMonthDays = new Date(year, month, 0).getDate(); + const WEEK_DAYS = [t("days.sun"), t("days.mon"), t("days.tue"), t("days.wed"), t("days.thu"), t("days.fri"), t("days.sat")]; const weekDays = WEEK_DAYS.slice(weekStartDayOffset).concat(WEEK_DAYS.slice(0, weekStartDayOffset)); const maxCount = Math.max(...Object.values(data)); const days = []; - for (let i = 0; i < firstDay; i++) { - days.push(0); + // Fill in previous month's days. + for (let i = firstDay - 1; i >= 0; i--) { + days.push({ day: prevMonthDays - i, isCurrentMonth: false }); } + + // Fill in current month's days. for (let i = 1; i <= dayInMonth; i++) { - days.push(i); + days.push({ day: i, isCurrentMonth: true }); } - for (let i = 0; i < 6 - lastDay; i++) { - days.push(0); + + // Fill in next month's days. + for (let i = 1; i < 7 - lastDay; i++) { + days.push({ day: i, isCurrentMonth: false }); } return (
- {weekDays.map((day, index) => { - return ( -
- {day} -
- ); - })} - {days.map((day, index) => { - const date = dayjs(`${year}-${month}-${day}`).format("YYYY-MM-DD"); - const count = data[date] || 0; + {weekDays.map((day, index) => ( +
+ {day} +
+ ))} + {days.map((item, index) => { + const date = dayjs(`${year}-${month + 1}-${item.day}`).format("YYYY-MM-DD"); + const count = item.isCurrentMonth ? data[date] || 0 : 0; const isToday = dayjs().format("YYYY-MM-DD") === date; const tooltipText = count ? t("memo.count-memos-in-date", { count: count, date: date }) : date; const isSelected = dayjs(props.selectedDate).format("YYYY-MM-DD") === date; - return day ? ( - count > 0 ? ( - -
count && onClick && onClick(date)} - > - {day} -
-
- ) : ( + + return ( +
count && onClick && onClick(date)} > - {day} + {item.day}
- ) - ) : ( -
+
); })}
diff --git a/web/src/components/UserStatisticsView.tsx b/web/src/components/UserStatisticsView.tsx index 60775d94..e35ecd29 100644 --- a/web/src/components/UserStatisticsView.tsx +++ b/web/src/components/UserStatisticsView.tsx @@ -1,18 +1,8 @@ import { Divider, Tooltip } from "@mui/joy"; -import { Button } from "@usememos/mui"; import clsx from "clsx"; import dayjs from "dayjs"; import { countBy } from "lodash-es"; -import { - CalendarDaysIcon, - CheckCircleIcon, - ChevronLeftIcon, - ChevronRightIcon, - Code2Icon, - LinkIcon, - ListTodoIcon, - MoreVerticalIcon, -} from "lucide-react"; +import { CalendarDaysIcon, CheckCircleIcon, ChevronLeftIcon, ChevronRightIcon, Code2Icon, LinkIcon, ListTodoIcon } from "lucide-react"; import { useState } from "react"; import useAsyncEffect from "@/hooks/useAsyncEffect"; import useCurrentUser from "@/hooks/useCurrentUser"; @@ -20,7 +10,6 @@ import i18n from "@/i18n"; import { useMemoFilterStore, useMemoMetadataStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import ActivityCalendar from "./ActivityCalendar"; -import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover"; interface UserMemoStats { link: number; @@ -71,33 +60,26 @@ const UserStatisticsView = () => { return (
-
-
- - {dayjs(visibleMonthString).toDate().toLocaleString(i18n.language, { year: "numeric", month: "long" })} +
+
+ + + {dayjs(visibleMonthString).toDate().toLocaleString(i18n.language, { year: "numeric", month: "long" })} +
-
- - - - - - - - - +
+ setVisibleMonthString(dayjs(visibleMonthString).subtract(1, "month").format("YYYY-MM"))} + > + + + setVisibleMonthString(dayjs(visibleMonthString).add(1, "month").format("YYYY-MM"))} + > + +