style: apply prettier across the tree

One-shot prettier pass so the new format:check gate starts from a clean
baseline. Formatting only — no behaviour change. Generator-owned and
vendored artifacts stay untouched via .prettierignore.
This commit is contained in:
Marc-André Bombeck committed 2026-06-19 22:20:31 +02:00
1 parent b3fea2ef59
commit 1f4ba5939d
1000 files changed
+12130 -8385

No files matched your search

+3 -1
View File
@@ -212,7 +212,9 @@ export function AdminShell({ active, children }: AdminShellProps) {
// with the top of the first card by construction. `/admin` overview
// (activeSlug === null) shows the console title; each section shows its own.
const headingTitle =
activeSlug === null ? t("admin.title") : t(`admin.section.${activeSlug}.title`);
activeSlug === null
? t("admin.title")
: t(`admin.section.${activeSlug}.title`);
const headingSubtitle =
activeSlug === null
? t("admin.subtitle")
+60 -60
View File
@@ -115,67 +115,67 @@ export function AiQualitySection() {
<div className="overflow-x-auto">
<table className="w-full text-sm" data-slot="ai-quality-table">
<thead>
<tr className="text-muted-foreground border-border border-b text-left text-xs tracking-wider uppercase">
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colSeverity")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colMetric")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colProvider")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colPromptVersion")}
</th>
<th className="py-2 pr-3 font-medium tabular-nums">
{t("admin.aiQuality.colHelpful")}
</th>
<th className="py-2 pr-3 font-medium tabular-nums">
{t("admin.aiQuality.colNotHelpful")}
</th>
<th className="py-2 font-medium tabular-nums">
{t("admin.aiQuality.colHelpfulRate")}
</th>
</tr>
</thead>
<tbody>
{buckets.map((bucket, idx) => {
const ratePct = Math.round(bucket.helpfulRate * 100);
return (
<tr
key={`${bucket.severity}-${bucket.metricSourceType}-${bucket.providerType}-${bucket.promptVersion}-${idx}`}
className="border-border/40 border-b last:border-0"
data-slot="ai-quality-bucket"
>
<td
className={`py-2 pr-3 font-medium ${
SEVERITY_TINT[bucket.severity] ?? ""
}`}
<tr className="text-muted-foreground border-border border-b text-left text-xs tracking-wider uppercase">
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colSeverity")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colMetric")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colProvider")}
</th>
<th className="py-2 pr-3 font-medium">
{t("admin.aiQuality.colPromptVersion")}
</th>
<th className="py-2 pr-3 font-medium tabular-nums">
{t("admin.aiQuality.colHelpful")}
</th>
<th className="py-2 pr-3 font-medium tabular-nums">
{t("admin.aiQuality.colNotHelpful")}
</th>
<th className="py-2 font-medium tabular-nums">
{t("admin.aiQuality.colHelpfulRate")}
</th>
</tr>
</thead>
<tbody>
{buckets.map((bucket, idx) => {
const ratePct = Math.round(bucket.helpfulRate * 100);
return (
<tr
key={`${bucket.severity}-${bucket.metricSourceType}-${bucket.providerType}-${bucket.promptVersion}-${idx}`}
className="border-border/40 border-b last:border-0"
data-slot="ai-quality-bucket"
>
{bucket.severity}
</td>
<td className="py-2 pr-3">{bucket.metricSourceType}</td>
<td className="py-2 pr-3">{bucket.providerType}</td>
<td className="text-muted-foreground py-2 pr-3 text-xs">
{bucket.promptVersion}
</td>
<td className="py-2 pr-3 tabular-nums">{bucket.helpful}</td>
<td className="py-2 pr-3 tabular-nums">
{bucket.notHelpful}
</td>
<td
className={`py-2 font-semibold tabular-nums ${helpfulRateColour(
bucket.helpfulRate,
)}`}
>
{ratePct}%
</td>
</tr>
);
})}
</tbody>
</table>
<td
className={`py-2 pr-3 font-medium ${
SEVERITY_TINT[bucket.severity] ?? ""
}`}
>
{bucket.severity}
</td>
<td className="py-2 pr-3">{bucket.metricSourceType}</td>
<td className="py-2 pr-3">{bucket.providerType}</td>
<td className="text-muted-foreground py-2 pr-3 text-xs">
{bucket.promptVersion}
</td>
<td className="py-2 pr-3 tabular-nums">{bucket.helpful}</td>
<td className="py-2 pr-3 tabular-nums">
{bucket.notHelpful}
</td>
<td
className={`py-2 font-semibold tabular-nums ${helpfulRateColour(
bucket.helpfulRate,
)}`}
>
{ratePct}%
</td>
</tr>
);
})}
</tbody>
</table>
</div>
)}
</div>
+201 -193
View File
@@ -194,210 +194,218 @@ export function RemindersSection() {
return (
<>
<div className="bg-card border-border rounded-xl border p-4 sm:p-6">
{/* v1.4.22 D / F-58 — icon swap so the section header matches
<div className="bg-card border-border rounded-xl border p-4 sm:p-6">
{/* v1.4.22 D / F-58 — icon swap so the section header matches
the admin-shell nav tile (Bell). Clock now lives on the
timing chips inline instead of competing as the page icon. */}
<SettingsCardHeader
icon={Bell}
title={t("admin.medicationReminders")}
description={t("admin.medicationRemindersDescription")}
/>
<SettingsCardHeader
icon={Bell}
title={t("admin.medicationReminders")}
description={t("admin.medicationRemindersDescription")}
/>
<div className="mt-4 space-y-3 pl-7">
<div className="grid gap-3 sm:grid-cols-2">
<div className="space-y-1.5">
<Label htmlFor="admin-reminder-late" className="text-xs">
{t("admin.reminderLateMinutes")}
</Label>
<p className="text-muted-foreground text-xs">
{t("admin.reminderLateMinutesDescription")}
</p>
<Input
id="admin-reminder-late"
type="number"
inputMode="numeric"
enterKeyHint="next"
min={15}
max={480}
value={reminderLateDraft ?? settings?.reminderLateMinutes ?? 120}
onChange={(e) => setReminderLateDraft(Number(e.target.value))}
autoComplete="off"
data-lpignore="true"
data-1p-ignore="true"
disabled={updateSettings.isPending}
className="w-32"
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="admin-reminder-missed" className="text-xs">
{t("admin.reminderMissedMinutes")}
</Label>
<p className="text-muted-foreground text-xs">
{t("admin.reminderMissedMinutesDescription")}
</p>
<Input
id="admin-reminder-missed"
type="number"
inputMode="numeric"
enterKeyHint="done"
min={30}
max={720}
value={
reminderMissedDraft ?? settings?.reminderMissedMinutes ?? 240
}
onChange={(e) => setReminderMissedDraft(Number(e.target.value))}
autoComplete="off"
data-lpignore="true"
data-1p-ignore="true"
disabled={updateSettings.isPending}
className="w-32"
/>
<div className="mt-4 space-y-3 pl-7">
<div className="grid gap-3 sm:grid-cols-2">
<div className="space-y-1.5">
<Label htmlFor="admin-reminder-late" className="text-xs">
{t("admin.reminderLateMinutes")}
</Label>
<p className="text-muted-foreground text-xs">
{t("admin.reminderLateMinutesDescription")}
</p>
<Input
id="admin-reminder-late"
type="number"
inputMode="numeric"
enterKeyHint="next"
min={15}
max={480}
value={
reminderLateDraft ?? settings?.reminderLateMinutes ?? 120
}
onChange={(e) => setReminderLateDraft(Number(e.target.value))}
autoComplete="off"
data-lpignore="true"
data-1p-ignore="true"
disabled={updateSettings.isPending}
className="w-32"
/>
</div>
<div className="space-y-1.5">
<Label htmlFor="admin-reminder-missed" className="text-xs">
{t("admin.reminderMissedMinutes")}
</Label>
<p className="text-muted-foreground text-xs">
{t("admin.reminderMissedMinutesDescription")}
</p>
<Input
id="admin-reminder-missed"
type="number"
inputMode="numeric"
enterKeyHint="done"
min={30}
max={720}
value={
reminderMissedDraft ?? settings?.reminderMissedMinutes ?? 240
}
onChange={(e) => setReminderMissedDraft(Number(e.target.value))}
autoComplete="off"
data-lpignore="true"
data-1p-ignore="true"
disabled={updateSettings.isPending}
className="w-32"
/>
</div>
</div>
</div>
</div>
<div className="mt-4 flex justify-end gap-2">
<Button
size="sm"
variant="outline"
onClick={() => testNotification.mutate()}
disabled={testNotification.isPending}
>
{testNotification.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
<Bell className="h-3.5 w-3.5" />
{t("admin.notificationTestSend")}
</Button>
<Button
size="sm"
variant="outline"
onClick={() => reminderCheck.mutate()}
disabled={reminderCheck.isPending}
>
{reminderCheck.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
<Activity className="h-3.5 w-3.5" />
{t("admin.reminderCheckRun")}
</Button>
<Button
size="sm"
onClick={() => {
updateSettings.mutate(
{
...(reminderLateDraft != null && {
reminderLateMinutes: reminderLateDraft,
}),
...(reminderMissedDraft != null && {
reminderMissedMinutes: reminderMissedDraft,
}),
},
{
onSuccess: () => {
setReminderLateDraft(null);
setReminderMissedDraft(null);
<div className="mt-4 flex justify-end gap-2">
<Button
size="sm"
variant="outline"
onClick={() => testNotification.mutate()}
disabled={testNotification.isPending}
>
{testNotification.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
<Bell className="h-3.5 w-3.5" />
{t("admin.notificationTestSend")}
</Button>
<Button
size="sm"
variant="outline"
onClick={() => reminderCheck.mutate()}
disabled={reminderCheck.isPending}
>
{reminderCheck.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
<Activity className="h-3.5 w-3.5" />
{t("admin.reminderCheckRun")}
</Button>
<Button
size="sm"
onClick={() => {
updateSettings.mutate(
{
...(reminderLateDraft != null && {
reminderLateMinutes: reminderLateDraft,
}),
...(reminderMissedDraft != null && {
reminderMissedMinutes: reminderMissedDraft,
}),
},
},
);
}}
disabled={
updateSettings.isPending ||
(reminderLateDraft == null && reminderMissedDraft == null)
}
>
{updateSettings.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
{t("common.save")}
</Button>
</div>
{
onSuccess: () => {
setReminderLateDraft(null);
setReminderMissedDraft(null);
},
},
);
}}
disabled={
updateSettings.isPending ||
(reminderLateDraft == null && reminderMissedDraft == null)
}
>
{updateSettings.isPending && (
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
)}
{t("common.save")}
</Button>
</div>
{testNotification.data?.results &&
testNotification.data.results.length > 0 && (
<div className="mt-4 space-y-1">
{testNotification.data.results.map((r, i) => (
<div key={i} className="flex items-center gap-1.5 text-xs">
{r.success ? (
<CheckCircle2 className="text-success h-3.5 w-3.5 shrink-0 dark:text-green-400" />
) : (
<XCircle className="text-destructive h-3.5 w-3.5 shrink-0 dark:text-red-400" />
)}
<span className="font-medium">{r.channel}</span>
{r.error && (
<span className="text-muted-foreground">— {r.error}</span>
)}
</div>
))}
</div>
)}
{reminderCheck.data?.medications &&
reminderCheck.data.medications.length > 0 && (
<div className="mt-4 space-y-2">
{/* v1.4.33 IW9 — h4 -> h2 so the page outline stays
sequential (parent admin SectionFrame ships <h1>). */}
<h2 className="text-sm font-medium">
{t("admin.reminderCheckResults")}
</h2>
<div className="space-y-2">
{reminderCheck.data.medications.map((med, i) => (
<div key={i} className="bg-muted/50 space-y-1.5 rounded-lg p-3">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">
{med.name} ({med.dose})
</span>
<Badge
variant={
med.notificationsEnabled ? "default" : "secondary"
}
>
{med.notificationsEnabled
? t("admin.reminderCheckNotifOn")
: t("admin.reminderCheckNotifOff")}
</Badge>
</div>
<p className="text-muted-foreground text-xs">
{med.user} — {med.dayOfWeek} {med.localTime} —{" "}
{t("admin.reminderCheckEventsToday")}: {med.eventsToday}
</p>
{med.schedules.map((sched, j) => {
const statusColor =
sched.status === "open"
? "text-success dark:text-green-400"
: sched.status === "threshold"
? "text-warning dark:text-yellow-400"
: sched.status === "missed"
? "text-destructive dark:text-red-400"
: sched.status === "skipped"
? "text-muted-foreground"
: "";
return (
<div key={j} className="flex items-start gap-1.5 text-xs">
<span className="text-muted-foreground shrink-0">
{sched.window}
</span>
<span className="text-muted-foreground shrink-0">
[{sched.days}]
</span>
<span className={statusColor}>{sched.label}</span>
{sched.notificationSent && (
<span className="text-success flex shrink-0 items-center gap-0.5 dark:text-green-400">
<Bell className="h-3 w-3" />
{t("admin.reminderCheckNotifSent")}
</span>
)}
</div>
);
})}
{testNotification.data?.results &&
testNotification.data.results.length > 0 && (
<div className="mt-4 space-y-1">
{testNotification.data.results.map((r, i) => (
<div key={i} className="flex items-center gap-1.5 text-xs">
{r.success ? (
<CheckCircle2 className="text-success h-3.5 w-3.5 shrink-0 dark:text-green-400" />
) : (
<XCircle className="text-destructive h-3.5 w-3.5 shrink-0 dark:text-red-400" />
)}
<span className="font-medium">{r.channel}</span>
{r.error && (
<span className="text-muted-foreground">— {r.error}</span>
)}
</div>
))}
</div>
</div>
)}
</div>
<NotificationHealthPanel />
)}
{reminderCheck.data?.medications &&
reminderCheck.data.medications.length > 0 && (
<div className="mt-4 space-y-2">
{/* v1.4.33 IW9 — h4 -> h2 so the page outline stays
sequential (parent admin SectionFrame ships <h1>). */}
<h2 className="text-sm font-medium">
{t("admin.reminderCheckResults")}
</h2>
<div className="space-y-2">
{reminderCheck.data.medications.map((med, i) => (
<div
key={i}
className="bg-muted/50 space-y-1.5 rounded-lg p-3"
>
<div className="flex items-center justify-between">
<span className="text-sm font-medium">
{med.name} ({med.dose})
</span>
<Badge
variant={
med.notificationsEnabled ? "default" : "secondary"
}
>
{med.notificationsEnabled
? t("admin.reminderCheckNotifOn")
: t("admin.reminderCheckNotifOff")}
</Badge>
</div>
<p className="text-muted-foreground text-xs">
{med.user} — {med.dayOfWeek} {med.localTime} —{" "}
{t("admin.reminderCheckEventsToday")}: {med.eventsToday}
</p>
{med.schedules.map((sched, j) => {
const statusColor =
sched.status === "open"
? "text-success dark:text-green-400"
: sched.status === "threshold"
? "text-warning dark:text-yellow-400"
: sched.status === "missed"
? "text-destructive dark:text-red-400"
: sched.status === "skipped"
? "text-muted-foreground"
: "";
return (
<div
key={j}
className="flex items-start gap-1.5 text-xs"
>
<span className="text-muted-foreground shrink-0">
{sched.window}
</span>
<span className="text-muted-foreground shrink-0">
[{sched.days}]
</span>
<span className={statusColor}>{sched.label}</span>
{sched.notificationSent && (
<span className="text-success flex shrink-0 items-center gap-0.5 dark:text-green-400">
<Bell className="h-3 w-3" />
{t("admin.reminderCheckNotifSent")}
</span>
)}
</div>
);
})}
</div>
))}
</div>
</div>
)}
</div>
<NotificationHealthPanel />
</>
);
}