All files / src/components/charts MetricTrendRow.tsx

100% Statements 12/12
77.77% Branches 14/18
100% Functions 1/1
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                    4x 4x 4x 4x   4x 4x 4x     4x 4x 4x 4x   4x                                                                        
"use client";
 
/**
 * MetricTrendRow — a labelled trend series (value + unit + improving/declining
 * chip + TrendChart). Optional `markers` annotate ePA events on the line, and a
 * multi-year series shows its date range. Pure presentational; synthetic data.
 */
import { TrendingUp, TrendingDown } from "lucide-react";
import { TrendChart, type TrendMarker } from "@/components/charts/TrendChart";
import type { TrendSeries } from "@/lib/journey-config";
 
export function MetricTrendRow({
  s,
  markers = [],
}: {
  s: TrendSeries;
  markers?: TrendMarker[];
}) {
  const first = s.points[0];
  const last = s.points[s.points.length - 1];
  const rising = last >= first;
  const improving = rising === (s.goodDirection === "up");
  const pct =
    first === 0 ? 0 : Math.round(((last - first) / Math.abs(first)) * 100);
  const Icon = rising ? TrendingUp : TrendingDown;
  const colour = improving ? "#1E8449" : "#CA6F1E";
 
  // Span label: multi-year series show their year span; otherwise "3 mo".
  const fromYear = s.from?.slice(0, 4);
  const toYear = s.to?.slice(0, 4);
  const years = fromYear && toYear ? Number(toYear) - Number(fromYear) : 0;
  const span = years >= 1 ? `${years}y` : "3 mo";
 
  return (
    <div className="rounded-xl border border-[var(--border)] bg-[var(--surface-2)] p-3">
      <div className="flex items-baseline justify-between gap-2 mb-1.5">
        <div className="flex items-baseline gap-2">
          <span className="text-sm font-bold text-[var(--text-primary)]">
            {s.label}
          </span>
          <span className="text-base font-black text-[var(--text-primary)]">
            {s.current}
          </span>
          <span className="text-xs text-[var(--text-secondary)]">{s.unit}</span>
        </div>
        <span
          className="inline-flex items-center gap-1 text-xs font-semibold px-2 py-0.5 rounded-full"
          style={{ color: colour, background: `${colour}1a` }}
        >
          <Icon size={12} />
          {pct > 0 ? "+" : ""}
          {pct}% · {span}
        </span>
      </div>
      <TrendChart
        points={s.points}
        color={s.color}
        height={56}
        markers={markers}
      />
      {fromYear && toYear && (
        <div className="flex justify-between text-[10px] text-[var(--text-secondary)] mt-1 tabular-nums">
          <span>{fromYear}</span>
          <span>{toYear}</span>
        </div>
      )}
    </div>
  );
}