"use client"; import { useMemo } from "react"; import { Activity } from "lucide-react"; import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { TileHeader } from "@/components/insights/tile-header"; import { useTranslations } from "@/lib/i18n/context"; import { CYCLE_SYMPTOM_CATALOG } from "./symptom-catalog"; import { PHASE_HUE } from "./phase-tokens"; import type { CyclePhase } from "./types"; import type { SymptomPhaseRow } from "./use-cycle"; /** * v1.15.0 — symptom patterns by phase (the cycle-NATIVE insight). * * The phase×vitals crosstab correlates the cycle against your measurements; * this card answers the complementary, cycle-own question: which of your logged * symptoms cluster in which phase. Each row shows the symptom's per-phase * distribution as a proportional 4-segment bar (phase-hued, never colour-only — * the dominant phase is named in words) plus "mostly in your luteal phase * (7 of 9 days)". Observational, never causal; only symptoms logged on ≥3 * phase-labelled days surface (the server floor). */ const PHASE_ORDER: CyclePhase[] = [ "MENSTRUAL", "FOLLICULAR", "OVULATORY", "LUTEAL", ]; export interface CycleSymptomPatternsProps { rows: SymptomPhaseRow[]; } export function CycleSymptomPatterns({ rows }: CycleSymptomPatternsProps) { const { t } = useTranslations(); // Flatten the catalog once: symptom key → { labelKey, icon }. const byKey = useMemo(() => { const map = new Map< string, { labelKey: string; icon: (typeof CYCLE_SYMPTOM_CATALOG)[number]["symptoms"][number]["icon"]; } >(); for (const cat of CYCLE_SYMPTOM_CATALOG) { for (const s of cat.symptoms) { map.set(s.key, { labelKey: s.labelKey, icon: s.icon }); } } return map; }, []); return ( {rows.length === 0 ? (

{t("cycle.insights.symptomPatternsEmpty")}

) : ( )}
); }