mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
fix(dates): show the year whenever a date is not the current one
Sweeps every surface that renders a date from before this year without a year suffix — illness episodes/flares/day-logs, lab and custom-metric charts, the mood chart family, medication titration/side-effects/dose- history/next-dose captions (incl. the Dec→Jan rollover), cycle predictions and history, the BBT chart, the intraday-pulse day-nav, the date-range filter chip, and the nutrient/compliance charts. Each now routes through dateShortSmart / dateWithWeekdaySmart (format-locale.ts) or the matching date-format.ts helper, which add the year only when it differs from the current one — mirroring the workout list's existing model instead of a bare "19.02." that reads as this year's. Also fixes two sites that bypassed the app's locale entirely: the trusted-devices expiry (bare toLocaleDateString, host locale) and the admin token-name timestamp (hard-coded de-DE + Europe/Berlin) now both render through the user's own locale, hour-cycle, and timezone preference.
This commit is contained in:
1 parent
7f44e2fa37
commit
1ff179178f
28 files changed
+158
-104
No files matched your search
@@ -191,7 +191,9 @@ export function BbtChart({
|
||||
scale="time"
|
||||
domain={["dataMin", "dataMax"]}
|
||||
ticks={ticks}
|
||||
tickFormatter={(v) => fmt.dateShort(new Date(v as number))}
|
||||
tickFormatter={(v) =>
|
||||
fmt.dateShortSmart(new Date(v as number))
|
||||
}
|
||||
tick={{ fontSize: 11, fill: "var(--muted-foreground)" }}
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
@@ -285,7 +287,9 @@ function BbtTooltip(props: {
|
||||
"bg-popover border-border rounded-md border px-2.5 py-2 text-xs shadow-md",
|
||||
)}
|
||||
>
|
||||
<p className="text-muted-foreground">{fmt.dateShort(new Date(p.t))}</p>
|
||||
<p className="text-muted-foreground">
|
||||
{fmt.dateShortSmart(new Date(p.t))}
|
||||
</p>
|
||||
<p className="text-foreground font-medium tabular-nums">
|
||||
{t("cycle.bbt.tooltipTemp", { temp: fmt.number(p.temp) })}
|
||||
</p>
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
} from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { TileHeader } from "@/components/insights/tile-header";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { useTranslations, useFormatters } from "@/lib/i18n/context";
|
||||
import type { Formatters } from "@/lib/format-locale";
|
||||
import { FERTILE_HUE, FLOW_HUE, OVULATION_HUE } from "./phase-tokens";
|
||||
import type { CyclePrediction, CycleHistoryResponse } from "./types";
|
||||
|
||||
@@ -26,12 +27,17 @@ import type { CyclePrediction, CycleHistoryResponse } from "./types";
|
||||
* cycle-tracking on-ramp, not repeated beneath every prediction surface.
|
||||
*/
|
||||
|
||||
function formatDate(d: string): string {
|
||||
/**
|
||||
* Issue #66 — was a bespoke `toLocaleDateString(undefined, …)` (browser
|
||||
* locale, never the app's) with no year. Predictions run 1-2 cycles out, so
|
||||
* a window straddling New Year's would otherwise print an unadorned "Jan 3"
|
||||
* in December. Routes through the app-locale conditional-year formatter
|
||||
* instead; `dateShortSmart` already renders day+month in the locale's field
|
||||
* order and only adds the year when it differs from the current one.
|
||||
*/
|
||||
function formatDate(d: string, fmt: Formatters): string {
|
||||
// Render at noon UTC so the YYYY-MM-DD never rolls a day across tz.
|
||||
return new Date(`${d}T12:00:00Z`).toLocaleDateString(undefined, {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
return fmt.dateShortSmart(`${d}T12:00:00Z`);
|
||||
}
|
||||
|
||||
function confidenceTone(c: number): {
|
||||
@@ -60,6 +66,7 @@ export function PredictionsPanel({
|
||||
history,
|
||||
}: PredictionsPanelProps) {
|
||||
const { t } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@@ -92,8 +99,9 @@ export function PredictionsPanel({
|
||||
<Row
|
||||
hue={FERTILE_HUE}
|
||||
label={t("cycle.predictions.fertileWindow")}
|
||||
value={`${formatDate(prediction.fertileWindowStart)} – ${formatDate(
|
||||
value={`${formatDate(prediction.fertileWindowStart, fmt)} – ${formatDate(
|
||||
prediction.fertileWindowEnd,
|
||||
fmt,
|
||||
)}`}
|
||||
/>
|
||||
) : null}
|
||||
@@ -105,7 +113,7 @@ export function PredictionsPanel({
|
||||
? t("cycle.predictions.ovulationConfirmed")
|
||||
: t("cycle.predictions.ovulation")
|
||||
}
|
||||
value={formatDate(prediction.predictedOvulation)}
|
||||
value={formatDate(prediction.predictedOvulation, fmt)}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
@@ -120,6 +128,7 @@ export function PredictionsPanel({
|
||||
|
||||
function NextPeriod({ prediction }: { prediction: CyclePrediction }) {
|
||||
const { t } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const tone = confidenceTone(prediction.confidence);
|
||||
return (
|
||||
<div className="space-y-1.5">
|
||||
@@ -128,8 +137,8 @@ function NextPeriod({ prediction }: { prediction: CyclePrediction }) {
|
||||
hue={FLOW_HUE}
|
||||
label={t("cycle.predictions.nextPeriod")}
|
||||
value={t("cycle.predictions.nextPeriodWindow", {
|
||||
low: formatDate(prediction.nextPeriodStartLow),
|
||||
high: formatDate(prediction.nextPeriodStartHigh),
|
||||
low: formatDate(prediction.nextPeriodStartLow, fmt),
|
||||
high: formatDate(prediction.nextPeriodStartHigh, fmt),
|
||||
})}
|
||||
/>
|
||||
<Badge variant={tone.variant} className="shrink-0">
|
||||
@@ -186,6 +195,7 @@ function HistoryCard({
|
||||
history: CycleHistoryResponse | undefined;
|
||||
}) {
|
||||
const { t } = useTranslations();
|
||||
const fmt = useFormatters();
|
||||
const stats = history?.stats;
|
||||
// Most-recent observed cycles (the spread the regularity number summarises —
|
||||
// seeing it builds trust; the data was already on the wire). QA H2.
|
||||
@@ -253,10 +263,10 @@ function HistoryCard({
|
||||
className="flex items-center justify-between gap-3 py-2 text-sm"
|
||||
>
|
||||
<span className="text-foreground tabular-nums">
|
||||
{formatDate(c.startDate)}
|
||||
{formatDate(c.startDate, fmt)}
|
||||
{" – "}
|
||||
{c.endDate
|
||||
? formatDate(c.endDate)
|
||||
? formatDate(c.endDate, fmt)
|
||||
: t("cycle.history.ongoing")}
|
||||
</span>
|
||||
<span className="text-muted-foreground flex items-center gap-2 tabular-nums">
|
||||
|
||||
Reference in new issue
Block a user