mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
788c8ad33540838251e5ea62e300a46cd50a1c60
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
622099c0fd |
fix(settings): About + API surfaces — restructure, fix update check, fit tables
Bucket B of the v1.4.3 polish pass. Three issues, one commit because they're the same surface: 1. **API & Tokens tables overflowed the settings content column.** Each table set `min-w-[760px]` (or 860px) so the table never compressed below that width. On mobile this is intentional (it gives the inner cells breathing room while the outer wrapper horizontally scrolls). On md+ the parent column is smaller than the min-width on common laptop sizings (~800px content area when the browser isn't full-width), which forced an inline scrollbar for no benefit. Switched to `min-w-[760px] md:min-w-0` per table so the constraint releases at the breakpoint where the layout stops scrolling. 2. **"Auf Updates prüfen" button silently did nothing.** The client-side handler called `https://api.github.com/.../releases/ latest` directly. Production CSP locks `connect-src` down to `'self'` + `https://wbsapi.withings.net`, so the fetch was blocked at the browser before it left the tab. Replaced with a server-side proxy at `/api/version/check-updates` that fetches GitHub for the user, compares the running `package.json` version against `tag_name`, and returns one of `up_to_date | newer_ available | unknown`. The route is auth-gated (cookie OR bearer) so anonymous traffic can't burn through GitHub's 60-req/hr anon rate limit on the deployment's IP. The route also annotates the external call into the Wide Event so a future spike is visible in the logs. 3. **The About surface had no headings and a stray Badge box.** The v1.4.2 version put the License inside a `<Badge variant= "outline">`, which created a small framed pill that read as a separate widget rather than a peer of the version number. Below that, the Sources/Changelog/Docs and the update-check button each lived in their own card with no h2 — three nameless cards stacked on the page. Restructured into three titled cards: - **HealthLog** — identity, with version + license rendered inline as plain monospace pairs (no Badge, no nested grid). Build SHA + build timestamp ride along on the same row when set. - **Quellen & Dokumentation / Sources & docs** — links unchanged but now under their own h2. - **Updates** — manual `Check now` button + a passive "Last checked: …" line that pulls from localStorage so the user can see when the previous check ran. On mount, if the last successful check is >24h ago (or has never run), the page auto-checks once. The 24h window is a deliberate compromise between "always fresh" and "GitHub anon rate limit". The error path renders a non-blocking "Couldn't reach GitHub" message with the alert role so screen readers announce it. i18n keys touched in both `de.json` + `en.json`: - `settings.about.linksHeading` (new) - `settings.about.updatesHeading` (new) - `settings.about.checkUpdates` (label shortened) - `settings.about.checking` (button busy state — new) - `settings.about.lastChecked` / `lastCheckedNever` (new) - `settings.about.checkFailed` (new — replaces the misleading `testConnection.errors.connection_failed` reuse) Tests updated for the new heading + button strings; 669/669 green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
8c0593fe79 |
feat(dashboard): single BP tile, equal-height tile strip, settings dashboard/thresholds split
Bucket A of the v1.4.3 polish pass.
Tile-strip width drifted past the chart-strip width by 16px on >=md
because the strip used `-mx-2 px-2` to bleed two pixels past the
parent for a snap-scroll feel. The bleed is real on mobile — the
horizontal-scroll affordance only reads as a scroll if the first/last
tiles touch the viewport edge — but on tablet/desktop where the row
fits without scrolling it just made the tile group visibly wider than
the charts below. Now `md:mx-0 md:px-0` drops the bleed once charts
fit inline, so the two strips share the same content box.
Tile heights varied because the blood-pressure tile rendered as two
stacked TrendCards (sys + dia) inside one tile slot while every
other tile was a single TrendCard. The cleaner fix is one TrendCard
that displays the paired value as `117/79` — TrendCard now accepts an
optional `secondary: { latest, avg7, avg30 }` and the dashboard pushes
ONE BP entry instead of a Fragment of two. Tile count drops from 6
to 5, the strip stops wrapping awkwardly, and the BP card carries
the systolic sparkline + traffic-light tooltip while the diastolic
value rides along under the same heading. Each tile wrapper got
`flex` and the card itself `flex h-full flex-col`, so flex-stretch
inside the strip can do its job and the avg7/avg30 row pins to the
bottom.
Settings nav split: the section formerly titled "Übersicht" was
renamed to "Dashboard" (the term every user already knows from the
main nav), and the embedded Persönliche Zielwerte panel moved out
into its own top-level settings section under `/settings/thresholds`.
Two reasons: the panel is heavy (one card per metric) and was
visually buried behind the layout customizer, and "Übersicht" leaked
internal vocabulary — neither the route slug nor the surrounding nav
entries used it. Tests guarding slug order + section count updated
in lockstep.
Touched:
- messages/de.json, messages/en.json
- src/app/page.tsx (dashboard tile strip)
- src/app/settings/[section]/page.tsx (route wiring)
- src/components/charts/trend-card.tsx (secondary-metric prop)
- src/components/settings/section-slugs.ts
- src/components/settings/settings-shell.tsx (new entry + icon)
- src/components/settings/section-placeholder.tsx
- src/components/settings/dashboard-section.tsx (drop ThresholdsSection)
- src/components/settings/thresholds-settings-section.tsx (new)
- src/components/settings/__tests__/{sections,settings-shell}.test.tsx
Tests + typecheck green (669/669).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
65e86e4a53 |
feat(settings): extract all six remaining sections — content lands at /settings/<slug> (#143)
Replace the SectionPlaceholder fallbacks for Account, AI, Integrations, Notifications, Dashboard, API, Advanced, and About with real per-section components. Every /settings/<slug> URL now renders working content; the placeholder only fires for unknown slugs. A2-content extraction - Account: profile + passkeys + password change (account-section.tsx) - AI: insights + per-user provider override (ai-section.tsx) - Integrations: Withings + moodLog (integrations-section.tsx) - Notifications: Telegram + ntfy + Web Push (split into telegram-card, ntfy-card, web-push-card to keep each file under ~600 LOC) - Dashboard: layout + thresholds wrappers (dashboard-section.tsx) - API: endpoints + tokens (api-section.tsx) - Advanced: export + danger zone (advanced-section.tsx) - About (greenfield): version, license, build SHA, repo/changelog/docs links + "Check for updates" against GitHub releases A2-about - Reads /api/version via TanStack Query, surfaces app version, AGPL-3.0 badge, short build SHA, build timestamp, repo/changelog/docs links. - "Check for updates" button compares against api.github.com latest release tag with up-to-date / newer-available / failure feedback. A8-UI test buttons - Shared TestConnectionButton primitive that POSTs to a test endpoint, surfaces ok-with-latency or translated meta.errorCode failures. - Wired into Withings + moodLog (Integrations) and Web Push (Notifications). Glitchtip + Umami remain admin-only. i18n - New settings.about.* and settings.testConnection.* key groups in en.json and de.json. Cleanup - Delete src/app/settings/page.legacy.tsx (3230 LOC monolith). - Convert sync-from-server patterns to the React-recommended prev-payload-id render-time pattern so the strict react-hooks/set-state-in-effect rule passes without a file-level disable. Tests - New src/components/settings/__tests__/sections.test.tsx with 9 SSR smoke tests (one per section) — total suite 514 (was 505). |
||
|
|
3221f86eea |
feat(settings): introduce dynamic-route shell + redirect /settings → /settings/account (#139)
* feat(settings): introduce dynamic-route shell + redirect /settings → /settings/account
Splits the 3218-LOC /settings monolith into a routing surface only — no
section content moves in this PR. Each of the eight slugs (account,
integrations, notifications, dashboard, ai, api, advanced, about) now lives
at its own /settings/[section] route and renders inside a new
<SettingsShell> sidebar+main layout. Every section currently shows a
placeholder ("Moving here with the next release update") so reviewers can
validate the URL structure in isolation. The historic monolith is preserved
verbatim as page.legacy.tsx for section-by-section extraction by the
follow-up PRs (A2-account, A2-about, A2-ai, A2-integrations,
A2-notifications, A2-rest).
Behaviour change: existing entry points (sidebar nav, topbar dropdown,
onboarding hand-off, dashboard checklist, Withings callback, Codex
callback) now point at /settings/<slug> instead of /settings#anchor. The
/settings root is a 308 (permanentRedirect) to /settings/account so old
bookmarks and external links keep working.
Co-Authored-By: Marc-André Bombeck <mbombeck@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(settings): route every Codex OAuth callback redirect to /settings/integrations
Review-pass H1: only the late success/failure paths in the Codex OAuth
callback were updated to point at the new section route. The four early
branches — rate-limited, provider-supplied `?error=...`, missing params,
invalid state — still redirected to `/settings?codex_error=...`.
After the section split that path 308-redirects to `/settings/account`,
where the Codex error toast/banner doesn't live. Users hitting any of
those edge cases would land on the wrong screen with the error code
silently lost.
All six branches now go to `/settings/integrations?codex_error=...`,
matching the success and token-exchange-failure paths and the existing
Withings callback shape.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|