Files
assetx/components/product/PerformanceAnalysis.tsx

213 lines
7.9 KiB
TypeScript
Raw Normal View History

2026-02-04 12:56:06 +08:00
"use client";
import { useState } from "react";
import Image from "next/image";
import { useApp } from "@/contexts/AppContext";
interface CalendarDayProps {
day: number | null;
value: string;
type: "positive" | "negative" | "neutral" | "current";
}
function CalendarDay({ day, value, type }: CalendarDayProps) {
// Empty cell
if (day === null) {
return <div className="flex-1" />;
}
const typeStyles = {
positive: "bg-[#f2fcf7] dark:bg-green-900/20 border-[#cef3e0] dark:border-green-700/30",
negative: "bg-[#fff8f7] dark:bg-red-900/20 border-[#ffdbd5] dark:border-red-700/30",
neutral: "bg-[#f9fafb] dark:bg-gray-700 border-[#f3f4f6] dark:border-gray-600",
current: "bg-[#111827] dark:bg-[#111827] border-[#111827] dark:border-[#111827]",
};
const isCurrent = type === "current";
const dayTextStyle = isCurrent
? "text-[#fcfcfd]"
: "text-[#9ca1af] dark:text-gray-400";
// Value text color should match the type
let valueTextStyle = "";
if (isCurrent) {
valueTextStyle = "text-[#10b981]";
} else if (type === "positive") {
valueTextStyle = "text-[#10b981] dark:text-green-400";
} else if (type === "negative") {
valueTextStyle = "text-[#dc2626] dark:text-red-400";
} else {
valueTextStyle = "text-[#9ca1af] dark:text-gray-400";
}
return (
<div
className={`rounded border flex flex-col items-center justify-center flex-1 p-3 gap-6 ${typeStyles[type]}`}
>
<div className="w-full flex items-start">
<span className={`text-[10px] font-bold leading-[150%] ${dayTextStyle}`}>
{day}
</span>
</div>
<div className="w-full flex flex-col items-end gap-1">
<span className={`text-body-small font-bold leading-[150%] ${valueTextStyle}`}>
{value}
</span>
{isCurrent && (
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9DA1AE]">
Today
</span>
)}
</div>
</div>
);
}
interface StatCardProps {
label: string;
value: string;
}
function StatCard({ label, value }: StatCardProps) {
return (
<div className="flex flex-col items-center gap-1">
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9ca1af] dark:text-gray-400">
{label}
</span>
<span className="text-body-large font-bold text-[#10b981] dark:text-green-400">
{value}
</span>
</div>
);
}
export default function PerformanceAnalysis() {
const { t } = useApp();
const [currentMonth] = useState("November 2025");
// 模拟日历数据 - 5周数据
const weekData = [
[
{ day: 31, value: "0.00%", type: "neutral" as const },
{ day: 1, value: "+0.12%", type: "positive" as const },
{ day: 2, value: "+0.08%", type: "positive" as const },
{ day: 3, value: "-0.03%", type: "negative" as const },
{ day: 4, value: "+0.15%", type: "positive" as const },
{ day: 5, value: "+0.21%", type: "positive" as const },
{ day: 6, value: "0.00%", type: "neutral" as const },
],
[
{ day: 7, value: "+0.12%", type: "positive" as const },
{ day: 8, value: "+0.12%", type: "positive" as const },
{ day: 9, value: "-0.03%", type: "negative" as const },
{ day: 10, value: "+0.08%", type: "positive" as const },
{ day: 11, value: "-0.03%", type: "negative" as const },
{ day: 12, value: "+0.21%", type: "positive" as const },
{ day: 13, value: "0.00%", type: "neutral" as const },
],
[
{ day: 14, value: "-0.03%", type: "negative" as const },
{ day: 15, value: "-0.03%", type: "negative" as const },
{ day: 16, value: "+0.15%", type: "positive" as const },
{ day: 17, value: "+0.21%", type: "positive" as const },
{ day: 18, value: "+0.08%", type: "positive" as const },
{ day: 19, value: "0.00%", type: "neutral" as const },
{ day: 20, value: "+0.12%", type: "positive" as const },
],
[
{ day: 21, value: "+0.08%", type: "positive" as const },
{ day: 22, value: "+0.15%", type: "positive" as const },
{ day: 23, value: "-0.03%", type: "negative" as const },
{ day: 24, value: "+0.12%", type: "current" as const },
{ day: 25, value: "0.00%", type: "neutral" as const },
{ day: 26, value: "+0.21%", type: "positive" as const },
{ day: 27, value: "+0.08%", type: "positive" as const },
],
[
{ day: 28, value: "+0.12%", type: "positive" as const },
{ day: 30, value: "-0.03%", type: "negative" as const },
{ day: 29, value: "-0.03%", type: "negative" as const },
{ day: null, value: "", type: "neutral" as const },
{ day: null, value: "", type: "neutral" as const },
{ day: null, value: "", type: "neutral" as const },
{ day: null, value: "", type: "neutral" as const },
],
];
return (
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-8 flex flex-col gap-8">
{/* Top Section - Title and Stats */}
<div className="flex items-start justify-between pb-8 border-b border-border-gray dark:border-gray-700">
<div className="flex flex-col gap-2">
<h2 className="text-body-large font-bold text-text-primary dark:text-white">
{t("performance.title")}
</h2>
<p className="text-body-small font-regular text-[#9ca1af] dark:text-gray-400">
{t("performance.description")}
</p>
</div>
<div className="flex items-center gap-8">
<StatCard label={t("performance.ytd")} value="+8.7%" />
<StatCard label={t("performance.ytd")} value="+8.7%" />
</div>
</div>
{/* Calendar Section */}
<div className="flex flex-col gap-6">
{/* Calendar Header */}
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="w-6 h-6">
<Image src="/component-114.svg" alt="" width={24} height={24} />
</div>
<h3 className="text-body-small font-bold text-text-primary dark:text-white">
{t("performance.dailyNetReturns")}
</h3>
</div>
<div className="flex items-center gap-2">
<button className="w-6 h-6 rounded-lg flex items-center justify-center hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">
<Image src="/icon9.svg" alt="Previous" width={16} height={16} />
</button>
<span className="text-body-small font-bold text-[#0a0a0a] dark:text-white tracking-tight">
{currentMonth}
</span>
<button className="w-6 h-6 rounded-lg flex items-center justify-center hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">
<Image src="/icon10.svg" alt="Next" width={16} height={16} />
</button>
</div>
</div>
{/* Calendar */}
<div className="flex flex-col gap-4">
{/* Weekday Headers */}
<div className="grid grid-cols-7 gap-2">
{["sun", "mon", "tue", "wed", "thu", "fri", "sat"].map((day) => (
<div key={day} className="flex items-center justify-center">
<span className="text-[10px] font-bold leading-[150%] text-[#94a3b8] dark:text-gray-400">
{t(`performance.weekdays.${day}`)}
</span>
</div>
))}
</div>
{/* Calendar Grid */}
<div className="flex flex-col gap-1">
{weekData.map((week, weekIndex) => (
<div key={weekIndex} className="grid grid-cols-7 gap-2">
{week.map((day, dayIndex) => (
<CalendarDay
key={`${weekIndex}-${dayIndex}`}
day={day.day}
value={day.value}
type={day.type}
/>
))}
</div>
))}
</div>
</div>
</div>
</div>
);
}