Skip to content

feat(logging): show live distance & bearing when logging a contact - #233

Merged
patrickrb merged 1 commit into
mainfrom
optio/task-eac73876-5daf-47f0-9885-1b06060ab1df
Jul 23, 2026
Merged

feat(logging): show live distance & bearing when logging a contact#233
patrickrb merged 1 commit into
mainfrom
optio/task-eac73876-5daf-47f0-9885-1b06060ab1df

Conversation

@patrickrb

Copy link
Copy Markdown
Owner

Problem

The Nextlog landing page promises operators "name, grid, DXCC, distance and bearing instantly" — but the logging form never actually computed distance or bearing. Worse, contacts logged through the form were persisted with a NULLdistance; only ADIF-imported QSOs ever carried the value, so form-logged contacts exported an empty <DISTANCE> field and were invisible to any distance-based stat.

Solution

Add a small, pure, client-safe Maidenhead + great-circle utility and wire it into the new-contact form.

src/lib/grid.ts (new, no server imports — safe for the browser bundle, mirroring @/lib/bands):

  • gridToLatLon(grid) — centers a 4- or 6-character locator, using the exact centering ContactLocationMap already uses so the map pin and the readout agree.
  • distanceKm (haversine, R=6371), bearingDeg (initial great-circle bearing, 0–360), compassPoint (16-point label), gridPath (grid→grid convenience), kmToMiles, isValidGrid.

src/app/new-contact/page.tsx:

  • The Path card now shows the great-circle distance (km + mi) and bearing (degrees + compass point) from the operator's home grid to the contact. It updates live as the destination resolves — from a QRZ lookup's coordinates when available, falling back to the grid square typed into the form — and renders nothing until both endpoints resolve, so a half-typed grid never shows a bogus reading.
  • The rounded distance is included in the create payload.

src/models/Contact.ts:

  • Contact.create now accepts and persists distance (it was silently dropped before). The column already existed and is read by ADIF export, so form-logged contacts now round-trip a distance through export and are available to awards/stats.

Testing

  • New:tests/grid.spec.ts — 15 pure-function unit tests covering grid validation, square/subsquare centering (checked against real city locations), a zero-distance and a one-degree equatorial arc (~111 km), the four cardinal bearings, compass labeling, and a known FN31→IO91 transatlantic path (~5500 km, NE).
  • npm run typecheck — clean
  • npm run lint — clean (no new warnings)
  • npm run build — succeeds
  • Re-ran the existing pure-function specs (bands, frequency-to-band) alongside the new ones — all green.

Notes / follow-up

  • The "from" reference is the operator's home grid (currentUser.grid_locator), matching the Path map's origin. When no home grid is set, the readout is simply hidden.
  • Backwards compatible: no schema change (the distance column already existed), no API-shape change beyond an additional optional distance field on the create body.
  • Follow-up candidates: surface distance/bearing on the QuickLog dashboard card and in the edit-contact dialog, and recompute distance on grid edits.

🤖 Generated with Claude Code

The landing page promises "distance and bearing instantly", but the
logging form never computed either, and contacts logged via the form
were stored with a null `distance` (only ADIF-imported QSOs carried one).
Add a pure, client-safe Maidenhead/great-circle utility (`src/lib/grid.ts`)
and wire it into the new-contact form:
- `gridToLatLon` centers a 4- or 6-char locator (matching ContactLocationMap),
`distanceKm` (haversine), `bearingDeg`, `compassPoint`, `gridPath`, `kmToMiles`.
- The Path card now shows the great-circle distance (km + mi) and bearing
(degrees + 16-point compass) from the operator's home grid to the contact,
updating live as the grid/coords resolve from a QRZ lookup or manual entry.
- The rounded distance is sent in the create payload and persisted, so it
round-trips through ADIF export and is available to awards/stats.
`Contact.create` now accepts and stores `distance` (previously dropped).
Tested: 15 new pure-function unit tests (tests/grid.spec.ts) covering grid
parsing, cardinal bearings, a one-degree equatorial arc, and a known
transatlantic path. typecheck, lint, and build all pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercelBot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
nodelogReadyReadyPreview, CommentJul 23, 2026 11:10pm

Request Review

Sign up for freeto 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.

1 participant

@patrickrb