chore: update StatCard component for improved icon and count rendering in StatisticsView

This commit is contained in:
Steven 2025-10-14 23:15:16 +08:00
parent 56758f107c
commit 228cc6105d
2 changed files with 46 additions and 34 deletions

View file

@ -1,37 +1,55 @@
import { cloneElement, isValidElement } from "react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import type { StatCardProps } from "@/types/statistics";
export const StatCard = ({ icon, label, count, onClick, tooltip, className }: StatCardProps) => {
const content = (
<div
const iconNode = isValidElement(icon)
? cloneElement(icon, {
className: cn("h-3.5 w-3.5", icon.props.className),
})
: icon;
const countNode = (() => {
if (typeof count === "number" || typeof count === "string") {
return <span className="text-foreground/80">{count}</span>;
}
if (isValidElement(count)) {
return cloneElement(count, {
className: cn("text-foreground/80", count.props.className),
});
}
return <span className="text-foreground/80">{count}</span>;
})();
const button = (
<button
type="button"
onClick={onClick}
className={cn(
"w-auto border pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center",
"cursor-pointer hover:bg-muted transition-colors",
"inline-flex items-center gap-1 rounded-md border border-border/40 bg-background/80 px-1 pr-2 py-0.5 text-sm leading-none text-muted-foreground transition-colors",
"hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/70 focus-visible:ring-offset-1 focus-visible:ring-offset-background",
className,
)}
onClick={onClick}
>
<div className="w-auto flex justify-start items-center mr-1">
{icon}
<span className="block text-sm opacity-80">{label}</span>
</div>
<span className="text-sm truncate opacity-80">{count}</span>
</div>
<span className="flex h-5 w-5 items-center justify-center text-muted-foreground/80">{iconNode}</span>
<span className="truncate text-sm text-foreground/70">{label}</span>
<span className="ml-1 flex items-center text-sm">{countNode}</span>
</button>
);
if (tooltip) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{content}</TooltipTrigger>
<TooltipContent>
<p>{tooltip}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
if (!tooltip) {
return button;
}
return content;
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{button}</TooltipTrigger>
<TooltipContent>
<p>{tooltip}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};

View file

@ -46,10 +46,10 @@ const StatisticsView = observer(() => {
/>
</div>
<div className="pt-1 w-full flex flex-row justify-start items-center gap-1 flex-wrap">
<div className="pt-2 w-full flex flex-wrap items-center gap-2">
{isRootPath && hasPinnedMemos && (
<StatCard
icon={<BookmarkIcon className="w-4 h-auto mr-1 opacity-70" />}
icon={<BookmarkIcon className="opacity-70" />}
label={t("common.pinned")}
count={userStore.state.currentUserStats!.pinnedMemos.length}
onClick={() => handleFilterClick("pinned")}
@ -57,20 +57,14 @@ const StatisticsView = observer(() => {
)}
<StatCard
icon={<LinkIcon className="w-4 h-auto mr-1 opacity-70" />}
icon={<LinkIcon className="opacity-70" />}
label={t("memo.links")}
count={memoTypeStats.linkCount}
onClick={() => handleFilterClick("property.hasLink")}
/>
<StatCard
icon={
memoTypeStats.undoCount > 0 ? (
<ListTodoIcon className="w-4 h-auto mr-1 opacity-70" />
) : (
<CheckCircleIcon className="w-4 h-auto mr-1 opacity-70" />
)
}
icon={memoTypeStats.undoCount > 0 ? <ListTodoIcon className="opacity-70" /> : <CheckCircleIcon className="opacity-70" />}
label={t("memo.to-do")}
count={
memoTypeStats.undoCount > 0 ? (
@ -88,7 +82,7 @@ const StatisticsView = observer(() => {
/>
<StatCard
icon={<Code2Icon className="w-4 h-auto mr-1 opacity-70" />}
icon={<Code2Icon className="opacity-70" />}
label={t("memo.code")}
count={memoTypeStats.codeCount}
onClick={() => handleFilterClick("property.hasCode")}