diff --git a/src/App.jsx b/src/App.jsx index d33a299..14f4e01 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import { useMemo, useState } from 'react' import MapView from './MapView.jsx' -import { searchMap } from './api.js' +import { associatedPhoneLabel, searchMap } from './api.js' const EMPTY_COLLECTION = { features: [], providers: {}, metadata: {} } @@ -23,7 +23,7 @@ function ResultCard({ item, onArchive }) { {details.distance_miles != null && {details.distance_miles} mi} {details.associated_phones?.length > 0 && ( -

Associated phones: {details.associated_phones.map((phone) => phone.phone || phone).join(', ')}

+

Associated phones: {details.associated_phones.map(associatedPhoneLabel).join(', ')}

)}
Provenance diff --git a/src/MapView.jsx b/src/MapView.jsx index 7bf1825..f1b0a65 100644 --- a/src/MapView.jsx +++ b/src/MapView.jsx @@ -1,6 +1,7 @@ import { useEffect } from 'react' import L from 'leaflet' import { MapContainer, Marker, Popup, TileLayer, useMap } from 'react-leaflet' +import { associatedPhoneLabel } from './api.js' const markerIcon = L.divIcon({ className: 'evidence-marker', html: '', iconSize: [22, 22], iconAnchor: [11, 11] }) const originIcon = L.divIcon({ className: 'origin-marker', html: '', iconSize: [28, 28], iconAnchor: [14, 14] }) @@ -31,7 +32,7 @@ function MarkerDetails({ item }) { {details.distance_miles != null && <>
Distance
{details.distance_miles} mi
} {details.associated_phones?.length > 0 && ( -

Associated phone records: {details.associated_phones.map((phone) => phone.phone || phone).join(', ')}

+

Associated phone records: {details.associated_phones.map(associatedPhoneLabel).join(', ')}

)} {details.url && Open source} diff --git a/src/api.js b/src/api.js index 47aa093..debd6d2 100644 --- a/src/api.js +++ b/src/api.js @@ -1,5 +1,10 @@ export const API_BASE = (import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000').replace(/\/$/, '') +export function associatedPhoneLabel(phone) { + if (typeof phone === 'string') return phone + return phone?.phone_number || phone?.phone || 'Phone record' +} + export function buildSearchUrl({ place, radiusMiles, query, sources, limit = 100 }, apiBase = API_BASE) { const params = new URLSearchParams({ place: place.trim(), diff --git a/src/api.test.js b/src/api.test.js index 7772ca0..8362dd3 100644 --- a/src/api.test.js +++ b/src/api.test.js @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from 'vitest' -import { buildSearchUrl, searchMap } from './api.js' +import { associatedPhoneLabel, buildSearchUrl, searchMap } from './api.js' describe('map API', () => { it('builds a canonical search URL', () => { @@ -14,4 +14,9 @@ describe('map API', () => { const fetcher = vi.fn().mockResolvedValue({ ok: false, status: 404, json: async () => ({ detail: 'place not found' }) }) await expect(searchMap({ place: 'Missing', radiusMiles: 10, query: '', sources: ['datasets'] }, fetcher)).rejects.toThrow('place not found') }) + + it('formats associated phone metadata', () => { + expect(associatedPhoneLabel({ phone_number: '+12025550111' })).toBe('+12025550111') + expect(associatedPhoneLabel('+12025550112')).toBe('+12025550112') + }) })