mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
refactor(insights): route chart and classification colors through theme tokens
Reference-band fills, classification tones, and the trend-chart palette carried hardcoded hex that rendered identically in both themes and glared on the light surface. Route them through the semantic and chart CSS variables, which already hold per-theme values, so the light theme gets the muted set and the dark theme stays byte-identical.
This commit is contained in:
1 parent
f219072881
commit
c6dea5eb56
8 files changed
+180
-85
No files matched your search
@@ -13,35 +13,39 @@ export interface BmiClassification {
|
||||
|
||||
export function classifyBMI(bmi: number): BmiClassification {
|
||||
if (bmi < 18.5) {
|
||||
return { category: "Underweight", color: "#f1fa8c", severity: "warning" };
|
||||
return {
|
||||
category: "Underweight",
|
||||
color: "var(--dracula-yellow)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (bmi < 25) {
|
||||
return { category: "Normal", color: "#50fa7b", severity: "normal" };
|
||||
return { category: "Normal", color: "var(--success)", severity: "normal" };
|
||||
}
|
||||
if (bmi < 30) {
|
||||
return {
|
||||
category: "Overweight",
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (bmi < 35) {
|
||||
return {
|
||||
category: "Obesity Grade I",
|
||||
color: "#ff79c6",
|
||||
color: "var(--chart-3)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
if (bmi < 40) {
|
||||
return {
|
||||
category: "Obesity Grade II",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
return {
|
||||
category: "Obesity Grade III",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
@@ -56,35 +60,35 @@ export interface BpClassification {
|
||||
|
||||
export function classifyBP(sys: number, dia: number): BpClassification {
|
||||
if (sys < 120 && dia < 80) {
|
||||
return { category: "Optimal", color: "#50fa7b", severity: "normal" };
|
||||
return { category: "Optimal", color: "var(--success)", severity: "normal" };
|
||||
}
|
||||
if (sys < 130 && dia < 85) {
|
||||
return { category: "Normal", color: "#8be9fd", severity: "normal" };
|
||||
return { category: "Normal", color: "var(--info)", severity: "normal" };
|
||||
}
|
||||
if (sys < 140 && dia < 90) {
|
||||
return {
|
||||
category: "High-normal",
|
||||
color: "#f1fa8c",
|
||||
color: "var(--dracula-yellow)",
|
||||
severity: "elevated",
|
||||
};
|
||||
}
|
||||
if (sys < 160 && dia < 100) {
|
||||
return {
|
||||
category: "Hypertension Grade 1",
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (sys < 180 && dia < 110) {
|
||||
return {
|
||||
category: "Hypertension Grade 2",
|
||||
color: "#ff79c6",
|
||||
color: "var(--chart-3)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
return {
|
||||
category: "Hypertension Grade 3",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
@@ -99,15 +103,23 @@ export interface PulseClassification {
|
||||
|
||||
export function classifyPulse(bpm: number): PulseClassification {
|
||||
if (bpm < 60) {
|
||||
return { category: "Bradycardia", color: "#8be9fd", severity: "info" };
|
||||
return { category: "Bradycardia", color: "var(--info)", severity: "info" };
|
||||
}
|
||||
if (bpm <= 100) {
|
||||
return { category: "Normal", color: "#50fa7b", severity: "normal" };
|
||||
return { category: "Normal", color: "var(--success)", severity: "normal" };
|
||||
}
|
||||
if (bpm <= 120) {
|
||||
return { category: "Elevated", color: "#ffb86c", severity: "warning" };
|
||||
return {
|
||||
category: "Elevated",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
return { category: "Tachycardia", color: "#ff5555", severity: "danger" };
|
||||
return {
|
||||
category: "Tachycardia",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
|
||||
// ── Sleep Duration Classification (AASM/SRS) ───────────
|
||||
@@ -124,22 +136,34 @@ export function classifySleepDuration(
|
||||
if (hours < 6) {
|
||||
return {
|
||||
category: "Far too short",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (hours < 7) {
|
||||
return { category: "Too short", color: "#ffb86c", severity: "warning" };
|
||||
return {
|
||||
category: "Too short",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (hours <= 9) {
|
||||
return { category: "On target", color: "#50fa7b", severity: "normal" };
|
||||
return {
|
||||
category: "On target",
|
||||
color: "var(--success)",
|
||||
severity: "normal",
|
||||
};
|
||||
}
|
||||
if (hours <= 10) {
|
||||
return { category: "Slightly long", color: "#8be9fd", severity: "info" };
|
||||
return {
|
||||
category: "Slightly long",
|
||||
color: "var(--info)",
|
||||
severity: "info",
|
||||
};
|
||||
}
|
||||
return {
|
||||
category: "Far too long",
|
||||
color: "#ff79c6",
|
||||
color: "var(--chart-3)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
@@ -220,23 +244,35 @@ export function classifyBodyFat(
|
||||
// hormonal / cardiac risk in chronic depletion).
|
||||
return {
|
||||
category: "Below essential",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
if (pct <= essentialMax) {
|
||||
return { category: "Essential", color: "#f1fa8c", severity: "warning" };
|
||||
return {
|
||||
category: "Essential",
|
||||
color: "var(--dracula-yellow)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (pct <= athleteMax) {
|
||||
return { category: "Athletic", color: "#50fa7b", severity: "normal" };
|
||||
return {
|
||||
category: "Athletic",
|
||||
color: "var(--success)",
|
||||
severity: "normal",
|
||||
};
|
||||
}
|
||||
if (pct <= fitnessMax) {
|
||||
return { category: "Fitness", color: "#50fa7b", severity: "normal" };
|
||||
return { category: "Fitness", color: "var(--success)", severity: "normal" };
|
||||
}
|
||||
if (pct <= acceptableMax) {
|
||||
return { category: "Acceptable", color: "#ffb86c", severity: "warning" };
|
||||
return {
|
||||
category: "Acceptable",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
return { category: "Obese", color: "#ff5555", severity: "danger" };
|
||||
return { category: "Obese", color: "var(--destructive)", severity: "danger" };
|
||||
}
|
||||
|
||||
// ── Activity Steps Classification ───────────────────────
|
||||
@@ -259,24 +295,32 @@ export function classifySteps(steps: number): StepsClassification {
|
||||
if (steps < 3000) {
|
||||
return {
|
||||
category: "Very low",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (steps < 5000) {
|
||||
return { category: "Low active", color: "#ffb86c", severity: "warning" };
|
||||
return {
|
||||
category: "Low active",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (steps < 7500) {
|
||||
return {
|
||||
category: "Moderately active",
|
||||
color: "#f1fa8c",
|
||||
color: "var(--dracula-yellow)",
|
||||
severity: "info",
|
||||
};
|
||||
}
|
||||
if (steps < 10000) {
|
||||
return { category: "Active", color: "#50fa7b", severity: "normal" };
|
||||
return { category: "Active", color: "var(--success)", severity: "normal" };
|
||||
}
|
||||
return { category: "Very active", color: "#50fa7b", severity: "normal" };
|
||||
return {
|
||||
category: "Very active",
|
||||
color: "var(--success)",
|
||||
severity: "normal",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,30 +110,34 @@ export function classifyPulseByTarget(
|
||||
if (bpm < target.orangeMin) {
|
||||
return {
|
||||
category: "Significantly low",
|
||||
color: "#8be9fd",
|
||||
color: "var(--info)",
|
||||
severity: "info",
|
||||
};
|
||||
}
|
||||
if (bpm < target.greenMin) {
|
||||
return {
|
||||
category: "Slightly low",
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
if (bpm <= target.greenMax) {
|
||||
return { category: "On target", color: "#50fa7b", severity: "normal" };
|
||||
return {
|
||||
category: "On target",
|
||||
color: "var(--success)",
|
||||
severity: "normal",
|
||||
};
|
||||
}
|
||||
if (bpm <= target.orangeMax) {
|
||||
return {
|
||||
category: "Slightly elevated",
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
severity: "warning",
|
||||
};
|
||||
}
|
||||
return {
|
||||
category: "Significantly elevated",
|
||||
color: "#ff5555",
|
||||
color: "var(--destructive)",
|
||||
severity: "danger",
|
||||
};
|
||||
}
|
||||
@@ -39,11 +39,21 @@ export function buildTrafficLightBands(
|
||||
const upperBound = options.upperBound ?? orangeHigh + Math.max(span, 1) * 2;
|
||||
|
||||
const bands: ValueBand[] = [
|
||||
{ min: lowerBound, max: orangeLow, color: "#ff5555", opacity: 0.16 },
|
||||
{ min: orangeLow, max: min, color: "#ffb86c", opacity: 0.18 },
|
||||
{ min, max, color: "#50fa7b", opacity: 0.2 },
|
||||
{ min: max, max: orangeHigh, color: "#ffb86c", opacity: 0.18 },
|
||||
{ min: orangeHigh, max: upperBound, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: lowerBound,
|
||||
max: orangeLow,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
{ min: orangeLow, max: min, color: "var(--warning)", opacity: 0.18 },
|
||||
{ min, max, color: "var(--success)", opacity: 0.2 },
|
||||
{ min: max, max: orangeHigh, color: "var(--warning)", opacity: 0.18 },
|
||||
{
|
||||
min: orangeHigh,
|
||||
max: upperBound,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
];
|
||||
|
||||
return bands.filter((band) => band.max > band.min);
|
||||
@@ -88,26 +98,36 @@ export function buildWeightBandsFromHeight(
|
||||
const upperBound = options.upperBound ?? 250;
|
||||
|
||||
return [
|
||||
{ min: lowerBound, max: range.orangeMin, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: lowerBound,
|
||||
max: range.orangeMin,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
{
|
||||
min: range.orangeMin,
|
||||
max: range.greenMin,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{
|
||||
min: range.greenMin,
|
||||
max: range.greenMax,
|
||||
color: "#50fa7b",
|
||||
color: "var(--success)",
|
||||
opacity: 0.2,
|
||||
},
|
||||
{
|
||||
min: range.greenMax,
|
||||
max: range.orangeMax,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{ min: range.orangeMax, max: upperBound, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: range.orangeMax,
|
||||
max: upperBound,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
].filter((band) => band.max > band.min);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,26 +58,36 @@ function clientBands(profile: {
|
||||
orangeMax: pulseTarget.orangeMax,
|
||||
},
|
||||
pulseBands: [
|
||||
{ min: 30, max: pulseTarget.orangeMin, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: 30,
|
||||
max: pulseTarget.orangeMin,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.orangeMin,
|
||||
max: pulseTarget.greenMin,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.greenMin,
|
||||
max: pulseTarget.greenMax,
|
||||
color: "#50fa7b",
|
||||
color: "var(--success)",
|
||||
opacity: 0.2,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.greenMax,
|
||||
max: pulseTarget.orangeMax,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{ min: pulseTarget.orangeMax, max: 220, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: pulseTarget.orangeMax,
|
||||
max: 220,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
].filter((b) => b.max > b.min),
|
||||
bodyFatRange,
|
||||
bodyFatBands: buildTrafficLightBands(bodyFatRange.min, bodyFatRange.max, {
|
||||
|
||||
@@ -88,26 +88,36 @@ export function buildDashboardBands(profile: {
|
||||
? buildTrafficRange(bpTargets.diaLow, bpTargets.diaHigh)
|
||||
: null;
|
||||
const pulseBands = [
|
||||
{ min: 30, max: pulseTarget.orangeMin, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: 30,
|
||||
max: pulseTarget.orangeMin,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.orangeMin,
|
||||
max: pulseTarget.greenMin,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.greenMin,
|
||||
max: pulseTarget.greenMax,
|
||||
color: "#50fa7b",
|
||||
color: "var(--success)",
|
||||
opacity: 0.2,
|
||||
},
|
||||
{
|
||||
min: pulseTarget.greenMax,
|
||||
max: pulseTarget.orangeMax,
|
||||
color: "#ffb86c",
|
||||
color: "var(--warning)",
|
||||
opacity: 0.18,
|
||||
},
|
||||
{ min: pulseTarget.orangeMax, max: 220, color: "#ff5555", opacity: 0.16 },
|
||||
{
|
||||
min: pulseTarget.orangeMax,
|
||||
max: 220,
|
||||
color: "var(--destructive)",
|
||||
opacity: 0.16,
|
||||
},
|
||||
].filter((band) => band.max > band.min);
|
||||
const bodyFatBands = buildTrafficLightBands(
|
||||
bodyFatRange.min,
|
||||
|
||||
@@ -100,7 +100,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "bp",
|
||||
kind: "health-chart",
|
||||
types: ["BLOOD_PRESSURE_SYS", "BLOOD_PRESSURE_DIA"],
|
||||
colors: ["#ff79c6", "#8be9fd"],
|
||||
colors: ["var(--chart-3)", "var(--chart-4)"],
|
||||
unit: "mmHg",
|
||||
yAxisUnit: "mmHg",
|
||||
titleKey: "charts.bloodPressure",
|
||||
@@ -112,7 +112,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "weight",
|
||||
kind: "health-chart",
|
||||
types: ["WEIGHT"],
|
||||
colors: ["#bd93f9"],
|
||||
colors: ["var(--chart-1)"],
|
||||
unit: "kg",
|
||||
titleKey: "charts.weight",
|
||||
captionKey: "insights.trendsRow.caption.weight",
|
||||
@@ -123,7 +123,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "pulse",
|
||||
kind: "health-chart",
|
||||
types: ["PULSE"],
|
||||
colors: ["#50fa7b"],
|
||||
colors: ["var(--chart-2)"],
|
||||
unit: "bpm",
|
||||
yAxisUnit: "bpm",
|
||||
titleKey: "charts.pulse",
|
||||
@@ -144,7 +144,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "sleep",
|
||||
kind: "health-chart",
|
||||
types: ["SLEEP_DURATION"],
|
||||
colors: ["#8be9fd"],
|
||||
colors: ["var(--chart-4)"],
|
||||
unit: "h",
|
||||
yAxisUnit: "h",
|
||||
titleKey: "charts.sleep",
|
||||
@@ -155,7 +155,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "steps",
|
||||
kind: "health-chart",
|
||||
types: ["ACTIVITY_STEPS"],
|
||||
colors: ["#50fa7b"],
|
||||
colors: ["var(--chart-2)"],
|
||||
unit: "steps",
|
||||
yAxisUnit: "steps",
|
||||
titleKey: "charts.steps",
|
||||
@@ -166,7 +166,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "hrv",
|
||||
kind: "health-chart",
|
||||
types: ["HEART_RATE_VARIABILITY"],
|
||||
colors: ["#bd93f9"],
|
||||
colors: ["var(--chart-1)"],
|
||||
unit: "ms",
|
||||
yAxisUnit: "ms",
|
||||
titleKey: "charts.hrv",
|
||||
@@ -177,7 +177,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "resting_hr",
|
||||
kind: "health-chart",
|
||||
types: ["RESTING_HEART_RATE"],
|
||||
colors: ["#ff79c6"],
|
||||
colors: ["var(--chart-3)"],
|
||||
unit: "bpm",
|
||||
yAxisUnit: "bpm",
|
||||
titleKey: "charts.restingHeartRate",
|
||||
@@ -188,7 +188,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "active_energy",
|
||||
kind: "health-chart",
|
||||
types: ["ACTIVE_ENERGY_BURNED"],
|
||||
colors: ["#ffb86c"],
|
||||
colors: ["var(--chart-5)"],
|
||||
unit: "kcal",
|
||||
yAxisUnit: "kcal",
|
||||
titleKey: "charts.activeEnergy",
|
||||
@@ -199,7 +199,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "flights",
|
||||
kind: "health-chart",
|
||||
types: ["FLIGHTS_CLIMBED"],
|
||||
colors: ["#f1fa8c"],
|
||||
colors: ["var(--dracula-yellow)"],
|
||||
unit: "flights",
|
||||
yAxisUnit: "flights",
|
||||
titleKey: "charts.flights",
|
||||
@@ -210,7 +210,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "distance",
|
||||
kind: "health-chart",
|
||||
types: ["WALKING_RUNNING_DISTANCE"],
|
||||
colors: ["#8be9fd"],
|
||||
colors: ["var(--chart-4)"],
|
||||
unit: "km",
|
||||
yAxisUnit: "km",
|
||||
titleKey: "charts.distance",
|
||||
@@ -221,7 +221,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "vo2_max",
|
||||
kind: "health-chart",
|
||||
types: ["VO2_MAX"],
|
||||
colors: ["#50fa7b"],
|
||||
colors: ["var(--chart-2)"],
|
||||
unit: "mL/kg·min",
|
||||
yAxisUnit: "mL/kg·min",
|
||||
titleKey: "charts.vo2Max",
|
||||
@@ -232,7 +232,7 @@ export const TREND_CHART_CONFIG: Record<
|
||||
metric: "body_temp",
|
||||
kind: "health-chart",
|
||||
types: ["BODY_TEMPERATURE"],
|
||||
colors: ["#ff5555"],
|
||||
colors: ["var(--destructive)"],
|
||||
unit: "°C",
|
||||
yAxisUnit: "°C",
|
||||
titleKey: "charts.bodyTemperature",
|
||||
|
||||
@@ -171,7 +171,11 @@ export const SIGNALS: Record<string, SignalDefinition> = {
|
||||
archetype: "physiological-vital",
|
||||
normalRange: { low: 50, high: 100 },
|
||||
referenceMetric: "RESTING_HEART_RATE",
|
||||
chart: { overlayKey: "restingHr", color: "#ff5555", yAxisUnit: "bpm" },
|
||||
chart: {
|
||||
overlayKey: "restingHr",
|
||||
color: "var(--destructive)",
|
||||
yAxisUnit: "bpm",
|
||||
},
|
||||
surfaces: {
|
||||
detailPage: true,
|
||||
correlationEligible: false,
|
||||
|
||||
@@ -828,10 +828,10 @@ export async function buildTargetsResponse(user: AuthedUser) {
|
||||
classification:
|
||||
bpInTargetRate != null
|
||||
? bpInTargetRate >= 70
|
||||
? { category: "Good", color: "#50fa7b" }
|
||||
? { category: "Good", color: "var(--success)" }
|
||||
: bpInTargetRate >= 40
|
||||
? { category: "Moderate", color: "#f1fa8c" }
|
||||
: { category: "Low", color: "#ff5555" }
|
||||
? { category: "Moderate", color: "var(--dracula-yellow)" }
|
||||
: { category: "Low", color: "var(--destructive)" }
|
||||
: null,
|
||||
source: "ESH 2023",
|
||||
...inTargetConsistency,
|
||||
@@ -1233,10 +1233,10 @@ export async function buildTargetsResponse(user: AuthedUser) {
|
||||
classification:
|
||||
complianceRate7 != null
|
||||
? complianceRate7 >= 90
|
||||
? { category: "Very good", color: "#50fa7b" }
|
||||
? { category: "Very good", color: "var(--success)" }
|
||||
: complianceRate7 >= 70
|
||||
? { category: "Good", color: "#f1fa8c" }
|
||||
: { category: "Low", color: "#ff5555" }
|
||||
? { category: "Good", color: "var(--dracula-yellow)" }
|
||||
: { category: "Low", color: "var(--destructive)" }
|
||||
: null,
|
||||
source: "7-day",
|
||||
details: {
|
||||
@@ -1358,10 +1358,10 @@ export async function buildTargetsResponse(user: AuthedUser) {
|
||||
const moodClassification =
|
||||
latestMoodScore != null
|
||||
? latestMoodScore >= 3.5
|
||||
? { category: "Good", color: "#50fa7b" }
|
||||
? { category: "Good", color: "var(--success)" }
|
||||
: latestMoodScore >= 2
|
||||
? { category: "Moderate", color: "#f1fa8c" }
|
||||
: { category: "Low", color: "#ff5555" }
|
||||
? { category: "Moderate", color: "var(--dracula-yellow)" }
|
||||
: { category: "Low", color: "var(--destructive)" }
|
||||
: null;
|
||||
|
||||
const moodRange = { min: 3.5, max: 5 };
|
||||
@@ -1397,10 +1397,10 @@ export async function buildTargetsResponse(user: AuthedUser) {
|
||||
|
||||
const stabilityClassification =
|
||||
stdDev <= 0.5
|
||||
? { category: "Very stable", color: "#50fa7b" }
|
||||
? { category: "Very stable", color: "var(--success)" }
|
||||
: stdDev <= 1.0
|
||||
? { category: "Stable", color: "#f1fa8c" }
|
||||
: { category: "Fluctuating", color: "#ff5555" };
|
||||
? { category: "Stable", color: "var(--dracula-yellow)" }
|
||||
: { category: "Fluctuating", color: "var(--destructive)" };
|
||||
|
||||
// Mood stability is computed from the same recent-mood window;
|
||||
// consistency mirrors MOOD_SCORE so the strip aligns with the
|
||||
@@ -1476,11 +1476,14 @@ export async function buildTargetsResponse(user: AuthedUser) {
|
||||
let classification: { category: string; color: string } | null = null;
|
||||
if (range && effRange) {
|
||||
if (latest >= range.min && latest <= range.max) {
|
||||
classification = { category: "Optimal", color: "#50fa7b" };
|
||||
classification = { category: "Optimal", color: "var(--success)" };
|
||||
} else if (latest >= effRange.orangeMin && latest <= effRange.orangeMax) {
|
||||
classification = { category: "Elevated", color: "#f1fa8c" };
|
||||
classification = {
|
||||
category: "Elevated",
|
||||
color: "var(--dracula-yellow)",
|
||||
};
|
||||
} else {
|
||||
classification = { category: "High", color: "#ff5555" };
|
||||
classification = { category: "High", color: "var(--destructive)" };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user