import { Divider, Tooltip } from "@mui/joy"; import clsx from "clsx"; import dayjs from "dayjs"; import { countBy } from "lodash-es"; import { CalendarDaysIcon, CheckCircleIcon, Code2Icon, LinkIcon, ListTodoIcon, MoreVerticalIcon, RefreshCcwIcon } from "lucide-react"; import { useState } from "react"; import toast from "react-hot-toast"; import { memoServiceClient } from "@/grpcweb"; import useAsyncEffect from "@/hooks/useAsyncEffect"; import useCurrentUser from "@/hooks/useCurrentUser"; import i18n from "@/i18n"; import { useMemoFilterStore, useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import ActivityCalendar from "./ActivityCalendar"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover"; interface UserMemoStats { link: number; taskList: number; code: number; incompleteTasks: number; } const UserStatisticsView = () => { const t = useTranslate(); const currentUser = useCurrentUser(); const memoStore = useMemoStore(); const memoFilterStore = useMemoFilterStore(); const [memoAmount, setMemoAmount] = useState(0); const [memoStats, setMemoStats] = useState({ link: 0, taskList: 0, code: 0, incompleteTasks: 0 }); const [activityStats, setActivityStats] = useState>({}); const [selectedDate] = useState(new Date()); const [monthString, setMonthString] = useState(dayjs(selectedDate.toDateString()).format("YYYY-MM")); const days = Math.ceil((Date.now() - currentUser.createTime!.getTime()) / 86400000); useAsyncEffect(async () => { const { entities } = await memoServiceClient.listMemoProperties({ name: `memos/-`, }); const memoStats: UserMemoStats = { link: 0, taskList: 0, code: 0, incompleteTasks: 0 }; entities.forEach((entity) => { const { property } = entity; if (property?.hasLink) { memoStats.link += 1; } if (property?.hasTaskList) { memoStats.taskList += 1; } if (property?.hasCode) { memoStats.code += 1; } if (property?.hasIncompleteTasks) { memoStats.incompleteTasks += 1; } }); setMemoStats(memoStats); setMemoAmount(entities.length); setActivityStats(countBy(entities.map((entity) => dayjs(entity.displayTime).format("YYYY-MM-DD")))); }, [memoStore.stateId]); const rebuildMemoTags = async () => { await memoServiceClient.rebuildMemoProperty({ name: "memos/-", }); toast.success("Refresh successfully"); window.location.reload(); }; const onCalendarClick = (date: string) => { memoFilterStore.removeFilter((f) => f.factor === "displayTime"); memoFilterStore.addFilter({ factor: "displayTime", value: date }); }; return (
{dayjs(monthString).toDate().toLocaleString(i18n.language, { year: "numeric", month: "long" })} e.target.showPicker()} onChange={(e) => setMonthString(e.target.value || dayjs().format("YYYY-MM"))} />
{memoAmount > 0 && (

{memoAmount} memos in {days} {days > 1 ? "days" : "day"}

)}
memoFilterStore.addFilter({ factor: "property.hasLink", value: "" })} >
{t("memo.links")}
{memoStats.link}
memoFilterStore.addFilter({ factor: "property.hasTaskList", value: "" })} >
{memoStats.incompleteTasks > 0 ? : } {t("memo.to-do")}
{memoStats.incompleteTasks > 0 ? (
{memoStats.taskList - memoStats.incompleteTasks} / {memoStats.taskList}
) : ( {memoStats.taskList} )}
memoFilterStore.addFilter({ factor: "property.hasCode", value: "" })} >
{t("memo.code")}
{memoStats.code}
); }; export default UserStatisticsView;