"use client"; import { useState, useEffect } from "react"; import Image from "next/image"; import { useApp } from "@/contexts/AppContext"; import { fetchDailyReturns, DailyReturnPoint } from "@/lib/api/fundmarket"; interface PerformanceAnalysisProps { productId: number; } type DayType = "positive" | "negative" | "neutral" | "current"; interface CalendarDayProps { day: number | null; value: string; type: DayType; } function CalendarDay({ day, value, type }: CalendarDayProps) { if (day === null) return
; const typeStyles: Record = { 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]", }; const dayTextStyle = type === "current" ? "text-[#fcfcfd]" : "text-[#9ca1af] dark:text-gray-400"; const valueTextStyle = type === "current" ? "text-[#10b981]" : type === "positive" ? "text-[#10b981] dark:text-green-400" : type === "negative" ? "text-[#dc2626] dark:text-red-400" : "text-[#9ca1af] dark:text-gray-400"; return (
{day}
{value} {type === "current" && ( Today )}
); } function buildCalendar(year: number, month: number, dataMap: Map, today: string) { const firstDay = new Date(year, month - 1, 1).getDay(); // 0=Sun const daysInMonth = new Date(year, month, 0).getDate(); type Cell = { day: number | null; value: string; type: DayType }; const cells: Cell[] = []; // Leading empty cells for (let i = 0; i < firstDay; i++) cells.push({ day: null, value: "", type: "neutral" }); for (let d = 1; d <= daysInMonth; d++) { const dateStr = `${year}-${String(month).padStart(2, "0")}-${String(d).padStart(2, "0")}`; const pt = dataMap.get(dateStr); const isToday = dateStr === today; const isFuture = dateStr > today; if (isFuture) { cells.push({ day: d, value: "--", type: "neutral" }); } else if (!pt || !pt.hasData) { cells.push({ day: d, value: "--", type: "neutral" }); } else { const r = pt.dailyReturn; const label = r === 0 ? "0.00%" : `${r > 0 ? "+" : ""}${r.toFixed(2)}%`; const type: DayType = isToday ? "current" : r > 0 ? "positive" : r < 0 ? "negative" : "neutral"; cells.push({ day: d, value: label, type }); } } // Trailing empty cells to complete the last row while (cells.length % 7 !== 0) cells.push({ day: null, value: "", type: "neutral" }); // Split into weeks const weeks: Cell[][] = []; for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7)); return weeks; } export default function PerformanceAnalysis({ productId }: PerformanceAnalysisProps) { const { t } = useApp(); const today = new Date(); const [year, setYear] = useState(today.getFullYear()); const [month, setMonth] = useState(today.getMonth() + 1); const [dataMap, setDataMap] = useState>(new Map()); const [isLoading, setIsLoading] = useState(true); useEffect(() => { setIsLoading(true); fetchDailyReturns(productId, year, month).then((pts) => { const m = new Map(); pts.forEach((p) => m.set(p.date, p)); setDataMap(m); setIsLoading(false); }); }, [productId, year, month]); const todayStr = today.toISOString().slice(0, 10); const weekData = buildCalendar(year, month, dataMap, todayStr); const monthLabel = new Date(year, month - 1, 1).toLocaleString("en-US", { month: "long", year: "numeric" }); const prevMonth = () => { if (month === 1) { setYear(y => y - 1); setMonth(12); } else setMonth(m => m - 1); }; const nextMonth = () => { const isCurrentMonth = year === today.getFullYear() && month === today.getMonth() + 1; if (isCurrentMonth) return; if (month === 12) { setYear(y => y + 1); setMonth(1); } else setMonth(m => m + 1); }; const isCurrentMonth = year === today.getFullYear() && month === today.getMonth() + 1; return (
{/* Calendar Section */}
{/* Header */}

{t("performance.dailyNetReturns")}

{monthLabel}
{/* Calendar */}
{["sun", "mon", "tue", "wed", "thu", "fri", "sat"].map((day) => (
{t(`performance.weekdays.${day}`)}
))}
{isLoading ? (
Loading...
) : (
{weekData.map((week, wi) => (
{week.map((day, di) => ( ))}
))}
)}
); }