mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
fix(settings): raise primary controls to the 44px touch floor
Apply the canonical min-h-11 sm:min-h-9 (and min-w-11 for icon-only controls) to the primary Settings controls that sat at 32-40 px on phones: the AI fallback-chain reorder/remove/save/add icons, provider form save/test/connect actions, coach-memory forget, avatar replace and remove, section save/cancel/reset CTAs, the export and import action rows, the About external links, and the thresholds editor row. Collapse the injection-sites checkbox grid to one column on phones and stack the password-change grid below lg.
This commit is contained in:
1 parent
76bc0f2e1f
commit
d9393a2148
19 files changed
+71
-16
No files matched your search
@@ -274,6 +274,7 @@ export function AboutMeSection({
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
data-testid="settings-about-me-clear"
|
||||
disabled={!isAuthenticated || save.isPending}
|
||||
onClick={() =>
|
||||
@@ -292,6 +293,7 @@ export function AboutMeSection({
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
data-testid="settings-about-me-save"
|
||||
disabled={!isAuthenticated || save.isPending || !dirty}
|
||||
onClick={() => save.mutate(value)}
|
||||
|
||||
@@ -269,7 +269,12 @@ export function AboutSection() {
|
||||
className="mb-4"
|
||||
/>
|
||||
<div className="flex flex-col gap-2 pl-7 sm:flex-row sm:flex-wrap">
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<a
|
||||
href={version.repository}
|
||||
target="_blank"
|
||||
@@ -280,7 +285,12 @@ export function AboutSection() {
|
||||
<ExternalLink className="h-3.5 w-3.5" />
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<a
|
||||
href={version.changelog}
|
||||
target="_blank"
|
||||
@@ -291,7 +301,12 @@ export function AboutSection() {
|
||||
<ExternalLink className="h-3.5 w-3.5" />
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<a href={version.docs} target="_blank" rel="noopener noreferrer">
|
||||
<BookOpen className="h-4 w-4" />
|
||||
{t("settings.about.docs")}
|
||||
|
||||
@@ -694,7 +694,7 @@ export function AccountSection() {
|
||||
</DialogHeader>
|
||||
|
||||
<form onSubmit={handleChangePassword} className="space-y-4">
|
||||
<div className="grid gap-3 sm:grid-cols-3">
|
||||
<div className="grid gap-3 lg:grid-cols-3">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="current-password">
|
||||
{t("settings.currentPassword")}
|
||||
@@ -1123,6 +1123,7 @@ function AvatarSection() {
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
disabled={busy}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
>
|
||||
@@ -1138,7 +1139,7 @@ function AvatarSection() {
|
||||
{avatarUrl && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="text-destructive"
|
||||
className="text-destructive min-h-11 sm:min-h-9"
|
||||
disabled={busy}
|
||||
onClick={() => {
|
||||
setMsg(null);
|
||||
|
||||
@@ -164,7 +164,7 @@ function ResearchModeCard() {
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="mt-2"
|
||||
className="mt-2 min-h-11 sm:min-h-9"
|
||||
onClick={() => setDialogOpen(true)}
|
||||
data-slot="settings-research-mode-reprompt-cta"
|
||||
>
|
||||
@@ -286,7 +286,7 @@ function DataResetCard() {
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
disabled={deleting}
|
||||
className="w-full shrink-0 sm:w-auto"
|
||||
className="min-h-11 w-full shrink-0 sm:min-h-9 sm:w-auto"
|
||||
>
|
||||
{deleting ? (
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
|
||||
@@ -428,7 +428,7 @@ function AccountDeleteCard() {
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
disabled={deleting}
|
||||
className="w-full shrink-0 sm:w-auto"
|
||||
className="min-h-11 w-full shrink-0 sm:min-h-9 sm:w-auto"
|
||||
data-slot="settings-account-delete-trigger"
|
||||
>
|
||||
{deleting ? (
|
||||
|
||||
@@ -149,6 +149,7 @@ export function AnthropicProviderForm({
|
||||
<div>
|
||||
<Button
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => saveMutation.mutate()}
|
||||
disabled={saveMutation.isPending}
|
||||
>
|
||||
|
||||
@@ -208,7 +208,7 @@ export function CodexProviderForm({
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="text-destructive shrink-0"
|
||||
className="text-destructive min-h-11 shrink-0 sm:min-h-9"
|
||||
onClick={handleDisconnect}
|
||||
disabled={disconnecting}
|
||||
>
|
||||
@@ -274,7 +274,7 @@ export function CodexProviderForm({
|
||||
variant="outline"
|
||||
onClick={handleConnect}
|
||||
disabled={devicePolling}
|
||||
className="w-full sm:w-auto"
|
||||
className="min-h-11 w-full sm:min-h-9 sm:w-auto"
|
||||
>
|
||||
{devicePolling ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin motion-reduce:animate-none" />
|
||||
|
||||
@@ -196,6 +196,7 @@ export function FallbackChainCard({
|
||||
aria-label={t("settings.ai.providerChain.moveUp")}
|
||||
disabled={idx === 0}
|
||||
onClick={() => move(idx, -1)}
|
||||
className="min-h-11 min-w-11 sm:min-h-9 sm:min-w-9"
|
||||
>
|
||||
<ArrowUp className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -206,6 +207,7 @@ export function FallbackChainCard({
|
||||
aria-label={t("settings.ai.providerChain.moveDown")}
|
||||
disabled={idx === entries.length - 1}
|
||||
onClick={() => move(idx, 1)}
|
||||
className="min-h-11 min-w-11 sm:min-h-9 sm:min-w-9"
|
||||
>
|
||||
<ArrowDown className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -214,7 +216,7 @@ export function FallbackChainCard({
|
||||
size="sm"
|
||||
variant="outline"
|
||||
aria-label={t("settings.ai.providerChain.removeFromChain")}
|
||||
className="text-destructive"
|
||||
className="text-destructive min-h-11 min-w-11 sm:min-h-9 sm:min-w-9"
|
||||
onClick={() => remove(idx)}
|
||||
disabled={entries.length <= 1}
|
||||
>
|
||||
@@ -234,6 +236,7 @@ export function FallbackChainCard({
|
||||
)}
|
||||
<Button
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => saveMutation.mutate(entries)}
|
||||
disabled={saveMutation.isPending || entries.length === 0}
|
||||
data-testid="ai-fallback-chain-save"
|
||||
@@ -247,7 +250,11 @@ export function FallbackChainCard({
|
||||
</Button>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button size="sm" variant="outline">
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
<RotateCcw className="h-4 w-4" />
|
||||
{t("settings.ai.providerChain.resetDefaults")}
|
||||
</Button>
|
||||
@@ -308,6 +315,7 @@ function AddProviderControl({
|
||||
type="button"
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => {
|
||||
if (isProviderType(picked)) onAdd(picked);
|
||||
}}
|
||||
|
||||
@@ -150,6 +150,7 @@ export function LocalProviderForm({
|
||||
<div>
|
||||
<Button
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => saveMutation.mutate()}
|
||||
disabled={saveMutation.isPending}
|
||||
>
|
||||
|
||||
@@ -186,6 +186,7 @@ export function OpenAIProviderForm({
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => saveMutation.mutate()}
|
||||
disabled={saveMutation.isPending}
|
||||
>
|
||||
|
||||
@@ -198,6 +198,7 @@ export function RuntimeActionsRow({
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={runTest}
|
||||
disabled={testing}
|
||||
data-testid="ai-test-active-provider"
|
||||
@@ -213,6 +214,7 @@ export function RuntimeActionsRow({
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={regenerate}
|
||||
disabled={regen}
|
||||
>
|
||||
|
||||
@@ -154,6 +154,7 @@ export function CoachMemorySection({
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
data-testid="settings-coach-memory-forget-all"
|
||||
disabled={!isAuthenticated || forgetAll.isPending}
|
||||
>
|
||||
@@ -245,6 +246,7 @@ export function CoachMemorySection({
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
data-testid="settings-coach-memory-forget"
|
||||
aria-label={t("settings.ai.coachMemory.forgetAria")}
|
||||
// v1.11.2 — per-id pending: only the row being
|
||||
|
||||
@@ -338,6 +338,7 @@ export function CoachPrefsSection({ isAuthenticated }: CoachPrefsSectionProps) {
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => save.mutate(draft)}
|
||||
disabled={save.isPending || isLoading}
|
||||
data-slot="coach-prefs-save"
|
||||
|
||||
@@ -80,7 +80,12 @@ export function CycleTrackingCard({
|
||||
/>
|
||||
</div>
|
||||
{enabled ? (
|
||||
<Button variant="outline" size="sm" asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
asChild
|
||||
>
|
||||
<Link href="/cycle">{t("settings.cycleTracking.manage")}</Link>
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
@@ -337,7 +337,7 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
size="sm"
|
||||
onClick={() => resetMutation.mutate()}
|
||||
disabled={resetMutation.isPending}
|
||||
className="self-end sm:self-auto"
|
||||
className="min-h-11 self-end sm:min-h-9 sm:self-auto"
|
||||
>
|
||||
<RotateCcw className="h-3.5 w-3.5" />
|
||||
{t("dashboard.layoutReset")}
|
||||
@@ -551,6 +551,7 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => setDraft(null)}
|
||||
disabled={saveMutation.isPending}
|
||||
>
|
||||
@@ -558,6 +559,7 @@ export function DashboardLayoutSection({ id }: { id: string }) {
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => layout && saveMutation.mutate(layout)}
|
||||
disabled={saveMutation.isPending}
|
||||
>
|
||||
|
||||
@@ -267,6 +267,7 @@ function CsvCard({
|
||||
data-testid={actionTestId}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={handleDownload}
|
||||
disabled={busy}
|
||||
>
|
||||
@@ -354,6 +355,7 @@ function MedicationsCsvCard() {
|
||||
data-testid="export-action-medications-csv"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={handleDownload}
|
||||
disabled={busy}
|
||||
>
|
||||
@@ -443,6 +445,7 @@ function FullBackupCard() {
|
||||
data-testid="export-action-full-backup"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={handleDownload}
|
||||
disabled={busy}
|
||||
>
|
||||
@@ -552,6 +555,7 @@ function CycleExportCard() {
|
||||
data-testid="export-action-cycle"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={handleGenerate}
|
||||
disabled={busy}
|
||||
>
|
||||
|
||||
@@ -366,6 +366,7 @@ function AppleHealthImportCard() {
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
disabled={busy}
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
data-testid="import-action-apple-health"
|
||||
@@ -615,6 +616,7 @@ function JsonImportCard() {
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
data-testid="import-json-choose-file"
|
||||
>
|
||||
@@ -625,6 +627,7 @@ function JsonImportCard() {
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={downloadExample}
|
||||
data-testid="import-json-download-example"
|
||||
>
|
||||
@@ -634,6 +637,7 @@ function JsonImportCard() {
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
disabled={busy || text.trim().length === 0}
|
||||
onClick={handleImport}
|
||||
data-testid="import-action-json"
|
||||
@@ -863,6 +867,7 @@ function CsvImportCard() {
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
data-testid="import-csv-choose-file"
|
||||
>
|
||||
@@ -873,6 +878,7 @@ function CsvImportCard() {
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={downloadExample}
|
||||
data-testid="import-csv-download-example"
|
||||
>
|
||||
@@ -883,6 +889,7 @@ function CsvImportCard() {
|
||||
type="button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
disabled={busy || text.trim().length === 0}
|
||||
onClick={() => void send(true)}
|
||||
data-testid="import-csv-preview"
|
||||
@@ -895,6 +902,7 @@ function CsvImportCard() {
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
disabled={busy || text.trim().length === 0}
|
||||
onClick={() => void send(false)}
|
||||
data-testid="import-action-csv"
|
||||
|
||||
@@ -72,7 +72,7 @@ export function InjectionSitesCard({
|
||||
title={t("settings.globalExcludedInjectionSitesLabel")}
|
||||
description={t("settings.globalExcludedInjectionSitesHint")}
|
||||
/>
|
||||
<div className="mt-3 grid grid-cols-2 gap-2 pl-7">
|
||||
<div className="mt-3 grid grid-cols-1 gap-2 pl-7 sm:grid-cols-2">
|
||||
{INJECTION_SITE_KEYS.map((site) => (
|
||||
<label key={site} className="flex items-center gap-2 text-sm">
|
||||
<Checkbox
|
||||
|
||||
@@ -224,7 +224,7 @@ export function InsightsPillOrderSection({ id }: { id?: string }) {
|
||||
onClick={() => saveMutation.mutate(draftTiles)}
|
||||
disabled={busy || !dirty}
|
||||
data-slot="insights-pill-order-save"
|
||||
className="self-end sm:self-auto"
|
||||
className="min-h-11 self-end sm:min-h-9 sm:self-auto"
|
||||
>
|
||||
{saveMutation.isPending && (
|
||||
<Loader2 className="h-3.5 w-3.5 animate-spin motion-reduce:animate-none" />
|
||||
|
||||
@@ -324,6 +324,7 @@ function MetricRow({
|
||||
onClick={() => valid && onSave({ min: minNum, max: maxNum })}
|
||||
disabled={busy || !valid}
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
>
|
||||
{t("common.save")}
|
||||
</Button>
|
||||
@@ -331,6 +332,7 @@ function MetricRow({
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11 sm:min-h-9"
|
||||
onClick={onReset}
|
||||
disabled={busy}
|
||||
>
|
||||
|
||||
Reference in new issue
Block a user