mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(settings): action-button placement consistent across sections (right-side desktop, stacked mobile)
The Account → Password and Account → Restart-onboarding-tour cards
both used `flex items-center justify-between gap-2` to put the action
button right-aligned next to the card title. On a 393-px Pixel 5
viewport the tour button (216 px wide) overflowed the card's right
edge by ~48 px because nothing forced it to wrap.
Apply a single shared layout to every "title + action" row in
Settings: stacked column on `<sm` (button below title + description,
full-width), title + action on the same row on `>=sm`. Same pattern
applied to Dashboard's "Reset to defaults" so the long German copy
("Auf Standard zurücksetzen") cannot push past the card edge either.
Pulled the description paragraph inside the title cluster on the two
account cards so each row is now a clean `<title-block + button>`
flex pair — easier to reason about than the previous title-only flex
with the description orphaned outside.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
0dcc91aae8
commit
9fda634369
2 files changed
+42
-21
No files matched your search
@@ -458,39 +458,57 @@ export function AccountSection() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Password card */}
|
||||
{/* Password card. v1.4.19 A6: action-button placement contract —
|
||||
on mobile (`<sm`) the action button stacks below the title +
|
||||
description and renders full-width; on desktop (`>=sm`) it
|
||||
right-aligns next to the title. The previous
|
||||
`flex items-center justify-between` pattern overflowed the
|
||||
card edge on Pixel 5 once button copy got longer than ~24 ch
|
||||
(the German "Passwort ändern" already pushes it; the tour
|
||||
card's "Restart onboarding tour" actually broke through the
|
||||
right border by ~48 px). */}
|
||||
<div className="bg-card border-border rounded-xl border p-6">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Shield className="text-primary h-5 w-5" />
|
||||
<h2 className="text-lg font-semibold">
|
||||
{t("settings.passwordReset")}
|
||||
</h2>
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-2">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<Shield className="text-primary h-5 w-5" />
|
||||
<h2 className="text-lg font-semibold">
|
||||
{t("settings.passwordReset")}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t("settings.changePasswordDescription")}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => setPasswordDialogOpen(true)}
|
||||
className="w-full shrink-0 sm:w-auto"
|
||||
>
|
||||
{t("settings.changePassword")}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
{t("settings.changePasswordDescription")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Tour replay card. v1.4.15 Phase B5: a one-shot button that
|
||||
resets `users.onboarding_tour_completed` on the server AND
|
||||
dispatches a window event so a dashboard already in the
|
||||
background reopens the spotlight tour immediately. */}
|
||||
background reopens the spotlight tour immediately. v1.4.19
|
||||
A6 — same stack-on-mobile / right-align-on-desktop contract
|
||||
as the password card so both action surfaces look identical. */}
|
||||
<div className="bg-card border-border rounded-xl border p-6">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Compass className="text-primary h-5 w-5" />
|
||||
<h2 className="text-lg font-semibold">
|
||||
{t("onboarding.tour.restart")}
|
||||
</h2>
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-2">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<Compass className="text-primary h-5 w-5" />
|
||||
<h2 className="text-lg font-semibold">
|
||||
{t("onboarding.tour.restart")}
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-xs">
|
||||
{t("onboarding.tour.restartHint")}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -498,6 +516,7 @@ export function AccountSection() {
|
||||
onClick={handleRestartTour}
|
||||
disabled={tourRestarting}
|
||||
data-testid="settings-restart-tour"
|
||||
className="w-full shrink-0 sm:w-auto"
|
||||
>
|
||||
{tourRestarting ? (
|
||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||
@@ -507,9 +526,6 @@ export function AccountSection() {
|
||||
{t("onboarding.tour.restart")}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
{t("onboarding.tour.restartHint")}
|
||||
</p>
|
||||
{tourMsg && (
|
||||
<p
|
||||
role="alert"
|
||||
|
||||
@@ -159,7 +159,11 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
id={id}
|
||||
className="bg-card border-border scroll-mt-28 space-y-5 rounded-xl border p-6"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
{/* v1.4.19 A6 — title / action row uses the same stack-on-mobile,
|
||||
right-align-on-desktop contract as Account → Password +
|
||||
Restart onboarding tour. Avoids the long German "Auf Standard
|
||||
zurücksetzen" copy clipping the card edge at narrow widths. */}
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<LayoutDashboard className="text-primary h-5 w-5" />
|
||||
<h2 className="text-lg font-semibold">
|
||||
@@ -171,6 +175,7 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
size="sm"
|
||||
onClick={() => resetMutation.mutate()}
|
||||
disabled={resetMutation.isPending}
|
||||
className="self-end sm:self-auto"
|
||||
>
|
||||
<RotateCcw className="mr-2 h-3.5 w-3.5" />
|
||||
{t("dashboard.layoutReset")}
|
||||
|
||||
Reference in new issue
Block a user