import { Tooltip } from "@mui/joy"; import dayjs from "dayjs"; import { countBy } from "lodash-es"; import { CheckCircleIcon, ChevronRightIcon, ChevronLeftIcon, Code2Icon, LinkIcon, ListTodoIcon, BookmarkIcon } from "lucide-react"; import { observer } from "mobx-react-lite"; import { useState } from "react"; import DatePicker from "react-datepicker"; import { matchPath, useLocation } from "react-router-dom"; import useAsyncEffect from "@/hooks/useAsyncEffect"; import useCurrentUser from "@/hooks/useCurrentUser"; import i18n from "@/i18n"; import { Routes } from "@/router"; import { useMemoFilterStore } from "@/store/v1"; import { userStore } from "@/store/v2"; import { UserStats_MemoTypeStats } from "@/types/proto/api/v1/user_service"; import { cn } from "@/utils"; import { useTranslate } from "@/utils/i18n"; import ActivityCalendar from "./ActivityCalendar"; import "react-datepicker/dist/react-datepicker.css"; const StatisticsView = observer(() => { const t = useTranslate(); const location = useLocation(); const memoFilterStore = useMemoFilterStore(); const currentUser = useCurrentUser(); const [memoTypeStats, setMemoTypeStats] = useState(UserStats_MemoTypeStats.fromPartial({})); const [activityStats, setActivityStats] = useState>({}); const [selectedDate] = useState(new Date()); const [visibleMonthString, setVisibleMonthString] = useState(dayjs(selectedDate.toDateString()).format("YYYY-MM")); useAsyncEffect(async () => { const memoTypeStats = UserStats_MemoTypeStats.fromPartial({}); const displayTimeList: Date[] = []; for (const stats of Object.values(userStore.state.userStatsByName)) { displayTimeList.push(...stats.memoDisplayTimestamps); if (stats.memoTypeStats) { memoTypeStats.codeCount += stats.memoTypeStats.codeCount; memoTypeStats.linkCount += stats.memoTypeStats.linkCount; memoTypeStats.todoCount += stats.memoTypeStats.todoCount; memoTypeStats.undoCount += stats.memoTypeStats.undoCount; } } setMemoTypeStats(memoTypeStats); setActivityStats(countBy(displayTimeList.map((date) => dayjs(date).format("YYYY-MM-DD")))); }, [userStore.state.userStatsByName]); const onCalendarClick = (date: string) => { memoFilterStore.removeFilter((f) => f.factor === "displayTime"); memoFilterStore.addFilter({ factor: "displayTime", value: date }); }; const currentMonth = dayjs(visibleMonthString).toDate(); return (
{ if (date) { setVisibleMonthString(dayjs(date).format("YYYY-MM")); } }} dateFormat="MMMM yyyy" showMonthYearPicker showFullMonthYearPicker customInput={ {dayjs(visibleMonthString).toDate().toLocaleString(i18n.language, { year: "numeric", month: "long" })} } popperPlacement="bottom-start" calendarClassName="!bg-white !border-gray-200 !font-normal !shadow-lg" />
setVisibleMonthString(dayjs(visibleMonthString).subtract(1, "month").format("YYYY-MM"))} > setVisibleMonthString(dayjs(visibleMonthString).add(1, "month").format("YYYY-MM"))} >
{matchPath(Routes.ROOT, location.pathname) && currentUser && userStore.state.currentUserStats && userStore.state.currentUserStats.pinnedMemos.length > 0 && (
memoFilterStore.addFilter({ factor: "pinned", value: "" })} >
Pinned
{userStore.state.currentUserStats.pinnedMemos.length}
)}
memoFilterStore.addFilter({ factor: "property.hasLink", value: "" })} >
{t("memo.links")}
{memoTypeStats.linkCount}
memoFilterStore.addFilter({ factor: "property.hasTaskList", value: "" })} >
{memoTypeStats.undoCount > 0 ? : } {t("memo.to-do")}
{memoTypeStats.undoCount > 0 ? (
{memoTypeStats.todoCount - memoTypeStats.undoCount} / {memoTypeStats.todoCount}
) : ( {memoTypeStats.todoCount} )}
memoFilterStore.addFilter({ factor: "property.hasCode", value: "" })} >
{t("memo.code")}
{memoTypeStats.codeCount}
); }); export default StatisticsView;