fix(Maps): render notes in marker popup when populated

Closes #796.

The maps API has accepted and persisted `notes` on map markers since
PR #770, but the marker popup component still rendered name only and
ignored the field. Now the popup shows a notes block beneath the name
when it's populated, with whitespace preserved and long text wrapped.

Threaded `notes` through the read path:
- `api.listMapMarkers` / `api.createMapMarker` response types
- `MapMarker` interface in `useMapMarkers` and the data.map projection
- `MapComponent`'s selectedMarker popup

The create/update UI is unchanged — users still set notes via the API
or DB directly, matching the issue's stated scope. A marker entry with
empty/whitespace-only notes renders the same as before.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Sherwood 2026-05-04 15:41:23 -07:00 committed by Jake Turner
parent 03ab614f99
commit 63282565a9
3 changed files with 10 additions and 2 deletions

View File

@ -243,6 +243,11 @@ export default function MapComponent({
closeOnClick={false} closeOnClick={false}
> >
<div className="text-sm font-medium">{selectedMarker.name}</div> <div className="text-sm font-medium">{selectedMarker.name}</div>
{selectedMarker.notes && selectedMarker.notes.trim() && (
<div className="mt-1 text-xs text-desert-stone-dark whitespace-pre-wrap break-words max-w-[240px]">
{selectedMarker.notes}
</div>
)}
</Popup> </Popup>
)} )}

View File

@ -18,6 +18,7 @@ export interface MapMarker {
longitude: number longitude: number
latitude: number latitude: number
color: PinColorId color: PinColorId
notes: string | null
createdAt: string createdAt: string
} }
@ -36,6 +37,7 @@ export function useMapMarkers() {
longitude: m.longitude, longitude: m.longitude,
latitude: m.latitude, latitude: m.latitude,
color: m.color as PinColorId, color: m.color as PinColorId,
notes: m.notes ?? null,
createdAt: m.created_at, createdAt: m.created_at,
})) }))
) )
@ -54,6 +56,7 @@ export function useMapMarkers() {
longitude: result.longitude, longitude: result.longitude,
latitude: result.latitude, latitude: result.latitude,
color: result.color as PinColorId, color: result.color as PinColorId,
notes: result.notes ?? null,
createdAt: result.created_at, createdAt: result.created_at,
} }
setMarkers((prev) => [...prev, marker]) setMarkers((prev) => [...prev, marker])

View File

@ -631,7 +631,7 @@ class API {
async listMapMarkers() { async listMapMarkers() {
return catchInternal(async () => { return catchInternal(async () => {
const response = await this.client.get< const response = await this.client.get<
Array<{ id: number; name: string; longitude: number; latitude: number; color: string; created_at: string }> Array<{ id: number; name: string; longitude: number; latitude: number; color: string; notes: string | null; created_at: string }>
>('/maps/markers') >('/maps/markers')
return response.data return response.data
})() })()
@ -640,7 +640,7 @@ class API {
async createMapMarker(data: { name: string; longitude: number; latitude: number; color?: string }) { async createMapMarker(data: { name: string; longitude: number; latitude: number; color?: string }) {
return catchInternal(async () => { return catchInternal(async () => {
const response = await this.client.post< const response = await this.client.post<
{ id: number; name: string; longitude: number; latitude: number; color: string; created_at: string } { id: number; name: string; longitude: number; latitude: number; color: string; notes: string | null; created_at: string }
>('/maps/markers', data) >('/maps/markers', data)
return response.data return response.data
})() })()