mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
refactor(ui): simplify and polish insight card components
Replace hardcoded hex color values with Dracula CSS var tokens (text-dracula-purple, text-dracula-green, etc.) for theme consistency. Add prefers-reduced-motion support for insight animations, aria-expanded on the data quality toggle, and extract nested ternary into lookup map. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a4c8f28ecb
commit
9932f88666
3 files changed
+38
-29
No files matched your search
@@ -182,3 +182,9 @@
|
||||
.animate-insight-in {
|
||||
animation: insight-fade-in 0.4s ease-out forwards;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.animate-insight-in {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
@@ -39,28 +39,28 @@ const CLASSIFICATION_STYLES: Record<
|
||||
> = {
|
||||
optimal: {
|
||||
badge:
|
||||
"bg-[#50fa7b]/10 text-[#50fa7b] border border-[#50fa7b]/25 hover:bg-[#50fa7b]/15",
|
||||
border: "border-l-[#50fa7b]",
|
||||
"bg-dracula-green/10 text-dracula-green border border-dracula-green/25 hover:bg-dracula-green/15",
|
||||
border: "border-l-dracula-green",
|
||||
},
|
||||
gut: {
|
||||
badge:
|
||||
"bg-[#8be9fd]/10 text-[#8be9fd] border border-[#8be9fd]/25 hover:bg-[#8be9fd]/15",
|
||||
border: "border-l-[#8be9fd]",
|
||||
"bg-dracula-cyan/10 text-dracula-cyan border border-dracula-cyan/25 hover:bg-dracula-cyan/15",
|
||||
border: "border-l-dracula-cyan",
|
||||
},
|
||||
grenzwertig: {
|
||||
badge:
|
||||
"bg-[#f1fa8c]/10 text-[#f1fa8c] border border-[#f1fa8c]/25 hover:bg-[#f1fa8c]/15",
|
||||
border: "border-l-[#f1fa8c]",
|
||||
"bg-dracula-yellow/10 text-dracula-yellow border border-dracula-yellow/25 hover:bg-dracula-yellow/15",
|
||||
border: "border-l-dracula-yellow",
|
||||
},
|
||||
erhoht: {
|
||||
badge:
|
||||
"bg-[#ffb86c]/10 text-[#ffb86c] border border-[#ffb86c]/25 hover:bg-[#ffb86c]/15",
|
||||
border: "border-l-[#ffb86c]",
|
||||
"bg-dracula-orange/10 text-dracula-orange border border-dracula-orange/25 hover:bg-dracula-orange/15",
|
||||
border: "border-l-dracula-orange",
|
||||
},
|
||||
kritisch: {
|
||||
badge:
|
||||
"bg-[#ff5555]/10 text-[#ff5555] border border-[#ff5555]/25 hover:bg-[#ff5555]/15",
|
||||
border: "border-l-[#ff5555]",
|
||||
"bg-dracula-red/10 text-dracula-red border border-dracula-red/25 hover:bg-dracula-red/15",
|
||||
border: "border-l-dracula-red",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -73,22 +73,28 @@ function AssessmentIcon({
|
||||
}) {
|
||||
switch (assessment) {
|
||||
case "positive":
|
||||
return <CheckCircle2 className="h-4 w-4 shrink-0 text-[#50fa7b]" />;
|
||||
return <CheckCircle2 className="h-4 w-4 shrink-0 text-dracula-green" />;
|
||||
case "neutral":
|
||||
return <Minus className="h-4 w-4 shrink-0 text-[#9aa3b3]" />;
|
||||
return <Minus className="h-4 w-4 shrink-0 text-muted-foreground" />;
|
||||
case "attention":
|
||||
return <AlertCircle className="h-4 w-4 shrink-0 text-[#ffb86c]" />;
|
||||
return <AlertCircle className="h-4 w-4 shrink-0 text-dracula-orange" />;
|
||||
case "warning":
|
||||
return <AlertTriangle className="h-4 w-4 shrink-0 text-[#ff5555]" />;
|
||||
return <AlertTriangle className="h-4 w-4 shrink-0 text-dracula-red" />;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Confidence Colors ────────────────────────────────────
|
||||
|
||||
const CONFIDENCE_STYLES: Record<string, string> = {
|
||||
hoch: "text-[#50fa7b]",
|
||||
mittel: "text-[#f1fa8c]",
|
||||
gering: "text-[#ffb86c]",
|
||||
hoch: "text-dracula-green",
|
||||
mittel: "text-dracula-yellow",
|
||||
gering: "text-dracula-orange",
|
||||
};
|
||||
|
||||
const CONFIDENCE_LABELS: Record<string, string> = {
|
||||
hoch: "Hoch",
|
||||
mittel: "Mittel",
|
||||
gering: "Gering",
|
||||
};
|
||||
|
||||
// ─── Section Separator ────────────────────────────────────
|
||||
@@ -126,7 +132,7 @@ export function InsightAdvisorCard({
|
||||
return (
|
||||
<Card>
|
||||
<CardContent className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-[#bd93f9]" />
|
||||
<Loader2 className="h-6 w-6 animate-spin text-dracula-purple" />
|
||||
<span className="ml-2 text-sm text-muted-foreground">
|
||||
{/* TODO: i18n */}
|
||||
Analyse wird erstellt...
|
||||
@@ -144,7 +150,7 @@ export function InsightAdvisorCard({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
{icon ?? (
|
||||
<Sparkles className="h-5 w-5 text-[#bd93f9]" />
|
||||
<Sparkles className="h-5 w-5 text-dracula-purple" />
|
||||
)}
|
||||
{/* TODO: i18n */}
|
||||
<CardTitle className="text-lg">KI-Gesundheitsanalyse</CardTitle>
|
||||
@@ -196,7 +202,7 @@ export function InsightAdvisorCard({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
{icon ?? (
|
||||
<Sparkles className="h-5 w-5 text-[#bd93f9]" />
|
||||
<Sparkles className="h-5 w-5 text-dracula-purple" />
|
||||
)}
|
||||
{/* TODO: i18n */}
|
||||
<CardTitle className="text-lg">KI-Gesundheitsanalyse</CardTitle>
|
||||
@@ -237,8 +243,8 @@ export function InsightAdvisorCard({
|
||||
|
||||
{/* Primary Recommendation */}
|
||||
{insight.primaryRecommendation && (
|
||||
<div className="rounded-md border-l-2 border-[#bd93f9] bg-[#bd93f9]/5 px-4 py-3">
|
||||
<p className="mb-1 text-xs font-medium uppercase tracking-widest text-[#bd93f9]">
|
||||
<div className="rounded-md border-l-2 border-dracula-purple bg-dracula-purple/5 px-4 py-3">
|
||||
<p className="mb-1 text-xs font-medium uppercase tracking-widest text-dracula-purple">
|
||||
{/* TODO: i18n */}
|
||||
Das Wichtigste
|
||||
</p>
|
||||
@@ -327,6 +333,7 @@ export function InsightAdvisorCard({
|
||||
<div>
|
||||
<button
|
||||
onClick={() => setDataQualityOpen((v) => !v)}
|
||||
aria-expanded={dataQualityOpen}
|
||||
className="flex w-full items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
{dataQualityOpen ? (
|
||||
@@ -342,11 +349,7 @@ export function InsightAdvisorCard({
|
||||
<span
|
||||
className={`font-medium ${CONFIDENCE_STYLES[insight.dataQuality.confidence] ?? ""}`}
|
||||
>
|
||||
{insight.dataQuality.confidence === "hoch"
|
||||
? "Hoch"
|
||||
: insight.dataQuality.confidence === "mittel"
|
||||
? "Mittel"
|
||||
: "Gering"}
|
||||
{CONFIDENCE_LABELS[insight.dataQuality.confidence]}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -31,7 +31,7 @@ export function InsightStatusCard({
|
||||
return (
|
||||
<Card>
|
||||
<CardContent className="flex items-center justify-center py-8">
|
||||
<Loader2 className="h-5 w-5 animate-spin text-[#bd93f9]" />
|
||||
<Loader2 className="h-5 w-5 animate-spin text-dracula-purple" />
|
||||
<span className="ml-2 text-sm text-muted-foreground">
|
||||
{/* TODO: i18n */}
|
||||
Wird geladen...
|
||||
@@ -83,7 +83,7 @@ export function InsightStatusCard({
|
||||
|
||||
// ── Populated Card ────────────────────────────────────
|
||||
return (
|
||||
<Card className="animate-insight-in border-l-2 border-l-[#bd93f9]">
|
||||
<Card className="animate-insight-in border-l-2 border-l-dracula-purple">
|
||||
<CardHeader className="pb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
Reference in new issue
Block a user