From 680f84c42672f245805ddb923b56cb86dc98e7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 10 May 2026 01:14:47 +0200 Subject: [PATCH] feat(charts): mood chart mini-mode + windowOverride Mirrors the health-chart B5c mini contract for the mood chart: - mini: drops the range tabs, the toggle row (moving-average / trend / target-bands), and shrinks the chart height to 140px so it fits inside the rationale card without dominating it. Emoji glyphs + lavender gradient + tooltip survive intact. - windowOverride: pins the rangePoints state to the rationale enum value on mount. The mood chart's metric-source key is "mood" (not a measurement-type enum value), so the recommendation-card metric-mapping helper routes mood-rationale charts here rather than through HealthChart. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/charts/mood-chart.tsx | 145 +++++++++++++++++---------- 1 file changed, 93 insertions(+), 52 deletions(-) diff --git a/src/components/charts/mood-chart.tsx b/src/components/charts/mood-chart.tsx index de2b0800a..86c5aaef2 100644 --- a/src/components/charts/mood-chart.tsx +++ b/src/components/charts/mood-chart.tsx @@ -51,6 +51,17 @@ interface ChartDataPoint { interface MoodChartProps { title?: string; + /** + * v1.4.16 phase B5c — compact mode for embedding inside the + * RecommendationCard. Hides the range tabs / toggle row and shrinks + * padding. Tooltip + emoji glyphs at data points stay intact. + */ + mini?: boolean; + /** + * v1.4.16 phase B5c — pin the chart to a specific rationale data + * window regardless of any parent UI state. + */ + windowOverride?: "last7days" | "last30days" | "last90days" | "allTime"; } // --- Constants --- @@ -226,10 +237,23 @@ export function aggregateMoodEntries(entries: MoodEntryDay[]): { // --- Component --- -export function MoodChart({ title }: MoodChartProps) { +const MINI_RANGE_POINTS: Record< + NonNullable, + number +> = { + last7days: 7, + last30days: 30, + last90days: 90, + allTime: 0, +}; + +export function MoodChart({ title, mini = false, windowOverride }: MoodChartProps) { const { isAuthenticated } = useAuth(); const { t } = useTranslations(); - const [rangePoints, setRangePoints] = useState(30); + const initialRangePoints = windowOverride + ? MINI_RANGE_POINTS[windowOverride] + : 30; + const [rangePoints, setRangePoints] = useState(initialRangePoints); const [showMA, setShowMA] = useState(false); const [showTrend, setShowTrend] = useState(false); const [showBands, setShowBands] = useState(false); @@ -408,14 +432,20 @@ export function MoodChart({ title }: MoodChartProps) { if (!isLoading && !data?.entries?.length) return null; return ( - - + +
- + {displayTitle} - {activeBucket !== "day" && ( + {activeBucket !== "day" && !mini && ( {t( activeBucket === "week" @@ -425,53 +455,64 @@ export function MoodChart({ title }: MoodChartProps) { )}
-
- {TIME_RANGES_KEYS.map((r) => ( - + ))} +
+ )} +
+ {!mini && ( +
+
+ + +
+
+ + +
+
+ + +
- -
-
- - -
-
- - -
-
- - -
-
+ )}
{/* v1.4.16 B1a — sibling SVG block for the gradient @@ -506,7 +547,7 @@ export function MoodChart({ title }: MoodChartProps) { height={280} /> ) : ( -
+