Skip to content

feat: Withings weight sync + dedicated Biometrics category UX#96

Open
marian001 wants to merge 1 commit intoelkimek:mainfrom
marian001:feature/withings-weight-biometrics-ux
Open

feat: Withings weight sync + dedicated Biometrics category UX#96
marian001 wants to merge 1 commit intoelkimek:mainfrom
marian001:feature/withings-weight-biometrics-ux

Conversation

@marian001
Copy link
Copy Markdown

@marian001 marian001 commented Mar 29, 2026

Summary

This PR adds a first wearable integration via Withings and introduces a dedicated Biometrics category UX for time-series biometrics.

It implements OAuth connection + sync from Withings, imports weight data into the existing biometrics structure, and surfaces biometrics as a first-class category in the sidebar with standard chart/detail interactions.

Closes the immediate use case discussed in #5 around wearables integration by shipping an initial, practical scope.

What was added/changed

1) Withings integration (initial scope: weight only)

  • New module: js/withings-weight.js
    • OAuth authorize URL creation (user.metrics scope)
    • OAuth callback handling in-app
    • Token exchange + refresh flow
    • Weight fetch from Withings measure/getmeas
    • Mapping of Withings weight measurements into importedData.biometrics.weight
    • Incremental sync via lastupdate
    • Remove/disconnect flow for imported Withings weight rows
  • js/main.js
    • OAuth callback routing updated so Withings callback is handled first when applicable

2) Settings UI for Withings

  • js/settings.js
    • New Withings Integration section in Settings
    • Fields: Client ID, Client Secret, Redirect URI
    • Actions:
      • Save credentials
      • Authorize
      • Sync weight
      • Delete Withings data (and disconnect)
    • Connection status + last sync display
    • Note in UI that this initial version imports only weight

3) Biometrics as dedicated category + UX parity improvements

  • New module: js/biometrics-view.js
    • Dedicated Biometrics category view rendering
    • 3 cards/charts: Weight, Blood Pressure, Pulse
    • Uses shared createLineChart(...) (axes/tooltips/grid), not mini custom sparkline charts
    • Category-level time range filter (1M / 3M / 9M / All) applied across all biometrics charts
    • Detail modal per biometrics type with:
      • chart + modal-level range filter
      • measurement list
      • add new measurement form
      • delete measurement
      • inline value editing (same interaction style as marker modal: click value -> editable input, Enter/blur save, Esc cancel)
    • Editing enabled for Withings-imported weight rows as user override

4) Navigation and routing updates

  • js/nav.js
    • Biometrics appears as its own item under Categories (when biometrics data exists)
    • Genetics dashboard-scroll behavior made more robust
  • js/views.js
    • New route: navigate('biometrics') -> showBiometrics()
    • Dashboard no longer renders biometrics block directly (biometrics live in dedicated screen)
    • Empty-state gating updated so biometrics-only profiles still count as having data

How it works

Data model

  • Reuses existing state.importedData.biometrics structure:
    • weight[] with { date, value, unit, source }
    • bp[] with { date, sys, dia, source }
    • pulse[] with { date, value, source }
  • Withings sync writes source: 'withings' rows for weight
  • Manual edits/additions write source: 'manual'

Sync behavior

  • OAuth state is stored in session storage and validated on callback
  • Access token is refreshed when near expiry
  • Sync can run incrementally based on last sync timestamp (lastupdate)
  • For each day, latest measurement in day is used

How to use Withings integration

  1. Create/configure a Withings API app in the Withings developer dashboard: https://developer.withings.com/dashboard/
  2. In your Withings app settings, get Client ID and Client Secret and set the Callback URL.
  3. Open Settings in getbased.
  4. In Withings Integration, enter:
    • Withings Client ID
    • Withings Client Secret
    • Redirect URI (defaults to current app URL)
  5. Ensure the Withings Callback URL exactly matches the Redirect URI configured in getbased.
  6. Click Save credentials.
  7. Click Authorize and complete Withings OAuth consent.
  8. Back in app, click Sync weight.
  9. Open Categories → Biometrics to view charts and manage data.

Optional:

  • Delete Withings data removes imported Withings weight rows and disconnects.

Scope note / future extension

This PR intentionally ships weight-only import for now, even though Withings API exposes additional measurements. The integration path and UI scaffolding are now in place, so additional types (e.g., blood pressure, heart rate, body composition metrics) can be added incrementally in follow-up PRs.

Related issue

Files changed

  • js/main.js
  • js/nav.js
  • js/settings.js
  • js/views.js
  • js/withings-weight.js (new)
  • js/biometrics-view.js (new)

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 29, 2026

@marian001 is attempting to deploy a commit to the elkimek's projects Team on Vercel.

A member of the Team first needs to authorize it.

@elkimek
Copy link
Copy Markdown
Owner

elkimek commented Mar 30, 2026

Thanks for the PR Marian, I can't merge it right now as I'm in process of rewriting getbased to V2 (Tauri/TypeScript/Svetle) and these integration will need a proper system, can't be just glued into it. Will look into this ASAP once V2 is stable and released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants