mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(mood): truncate long notes in the entries table
A long free-text note forced the mood entries table into horizontal scroll. Cap the note column width, clamp the note to two lines, and surface the full text on hover through a tooltip. The complete note stays editable in the entry sheet.
This commit is contained in:
1 parent
6e61713fc6
commit
3ecfa3a898
2 files changed
+24
-83
No files matched your search
@@ -1,78 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { formatDateTime } from "@/lib/format";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { MOOD_LABEL_KEYS } from "@/lib/mood/labels";
|
||||
|
||||
/**
|
||||
* v1.8.5 (C1) — notes timeline.
|
||||
*
|
||||
* Chronological feed of recent mood entries that carry a free-text note,
|
||||
* each with its score, mood label, note text, and tag chips. Renders the
|
||||
* note as a plain React text child (no markdown library — the project
|
||||
* forbids one for XSS reasons).
|
||||
*/
|
||||
|
||||
export interface MoodNoteEntry {
|
||||
date: string;
|
||||
loggedAt: string;
|
||||
score: number;
|
||||
mood: string | null;
|
||||
note: string;
|
||||
tags: string[];
|
||||
structuredTagLabelKeys: string[];
|
||||
}
|
||||
|
||||
export function MoodNotesTimeline({ notes }: { notes: MoodNoteEntry[] }) {
|
||||
const { t } = useTranslations();
|
||||
|
||||
return (
|
||||
<ul className="space-y-3" data-slot="mood-notes-timeline">
|
||||
{notes.map((entry) => {
|
||||
const moodLabel =
|
||||
entry.mood && MOOD_LABEL_KEYS[entry.mood]
|
||||
? t(MOOD_LABEL_KEYS[entry.mood])
|
||||
: entry.mood;
|
||||
return (
|
||||
<li
|
||||
key={`${entry.loggedAt}-${entry.date}`}
|
||||
className="border-border/60 border-l-2 pl-3"
|
||||
>
|
||||
<div className="text-muted-foreground flex items-center gap-2 text-xs">
|
||||
<span className="text-foreground font-semibold tabular-nums">
|
||||
{entry.score}
|
||||
</span>
|
||||
{moodLabel && <span>({moodLabel})</span>}
|
||||
<span>·</span>
|
||||
<span>{formatDateTime(entry.loggedAt)}</span>
|
||||
</div>
|
||||
<p className="text-foreground/90 mt-0.5 text-sm whitespace-pre-wrap">
|
||||
{entry.note}
|
||||
</p>
|
||||
{(entry.structuredTagLabelKeys.length > 0 ||
|
||||
entry.tags.length > 0) && (
|
||||
<div className="mt-1 flex flex-wrap gap-1">
|
||||
{entry.structuredTagLabelKeys.map((labelKey) => (
|
||||
<span
|
||||
key={labelKey}
|
||||
className="bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-[10px]"
|
||||
>
|
||||
{t(labelKey)}
|
||||
</span>
|
||||
))}
|
||||
{entry.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="border-border/70 text-muted-foreground rounded-full border px-2 py-0.5 text-[10px]"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
@@ -32,6 +32,12 @@ import {
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { DateTimeInput } from "@/components/ui/date-input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import {
|
||||
@@ -416,12 +422,25 @@ export function MoodList({ onAddFirst }: MoodListProps = {}) {
|
||||
)
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className="text-muted-foreground text-sm">
|
||||
{entry.tags.length > 0 ? entry.tags.join(", ") : "-"}
|
||||
<TableCell className="text-muted-foreground max-w-[18rem] text-sm">
|
||||
<span className="block truncate">
|
||||
{entry.tags.length > 0 ? entry.tags.join(", ") : "-"}
|
||||
</span>
|
||||
{entry.note && (
|
||||
<p className="text-muted-foreground/80 mt-0.5 line-clamp-2 text-xs italic">
|
||||
{entry.note}
|
||||
</p>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<p className="text-muted-foreground/80 mt-0.5 line-clamp-2 cursor-default text-xs italic">
|
||||
{entry.note}
|
||||
</p>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<p className="text-xs whitespace-pre-wrap">
|
||||
{entry.note}
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-muted-foreground text-sm">
|
||||
|
||||
Reference in new issue
Block a user