diff --git a/next.config.js b/next.config.js index f729383..8db71f3 100644 --- a/next.config.js +++ b/next.config.js @@ -34,7 +34,10 @@ const nextConfig = { headers: [ { key: "X-Content-Type-Options", value: "nosniff" }, { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, - { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" }, + { + key: "Permissions-Policy", + value: "camera=(), microphone=(), geolocation=()", + }, { key: "Content-Security-Policy", value: "frame-ancestors *" }, ], }, diff --git a/src/app/docs/(article)/api-usage/page.tsx b/src/app/docs/(article)/api-usage/page.tsx index 975af10..e05970f 100644 --- a/src/app/docs/(article)/api-usage/page.tsx +++ b/src/app/docs/(article)/api-usage/page.tsx @@ -24,7 +24,10 @@ export default function ApiUsagePage() {

Both{" "} - + Places API {" "} and{" "} @@ -35,14 +38,16 @@ export default function ApiUsagePage() { Competitions API {" "} are public, unauthenticated, read-only endpoints. This page is the honest answer - to "how much can I call this" - what's actually enforced, not what - might be assumed. + to "how much can I call this" - what's actually enforced, not + what might be assumed.

No API key, no rate limiting - Nothing throttles requests by IP or client today + + Nothing throttles requests by IP or client today +

@@ -50,7 +55,10 @@ export default function ApiUsagePage() { requests-per-minute style limit. What bounds them instead is pagination and caching, below. If that ever changes (a key requirement, a 429 response), it will show up on the{" "} - + changelog {" "} and this page gets updated alongside it - don't build something that @@ -62,7 +70,9 @@ export default function ApiUsagePage() { Pagination caps - The real limit is response size, not request rate + + The real limit is response size, not request rate +

    @@ -98,7 +108,9 @@ export default function ApiUsagePage() { Response caching - 6 hours - the real reason you rarely need to poll fast + + 6 hours - the real reason you rarely need to poll fast +

    @@ -107,8 +119,8 @@ export default function ApiUsagePage() { Cache-Control {" "} header with a 6-hour max age. The underlying datasets change a few times a - week at most, so polling more often than that gets you the same data, - served from cache either way. + week at most, so polling more often than that gets you the same data, served + from cache either way.

    @@ -122,13 +134,9 @@ export default function ApiUsagePage() {

    Nothing stops a tight polling loop today, but nothing has to reward it either. Respect the 6-hour cache window, page through large pulls with{" "} - - offset - {" "} + offset{" "} instead of raising{" "} - - limit - {" "} + limit{" "} past what you need, and if you're running something that calls either endpoint thousands of times a day, say so in an issue - that's exactly the kind of usage that would justify adding real rate limiting. diff --git a/src/app/docs/(article)/embedding-widget/page.tsx b/src/app/docs/(article)/embedding-widget/page.tsx index dbb4629..ea03813 100644 --- a/src/app/docs/(article)/embedding-widget/page.tsx +++ b/src/app/docs/(article)/embedding-widget/page.tsx @@ -35,9 +35,7 @@ export default function EmbeddingWidgetPage() { /embed is a second, chrome-free version of the map: no navbar, no sidebar, no sign-in - just the pins, sized to fit wherever you put it. It's meant to be put inside an{" "} - - <iframe> - {" "} + <iframe>{" "} on a school, library, or organization's own site.

    @@ -67,9 +65,7 @@ export default function EmbeddingWidgetPage() { Or build the URL yourself - - Same query parameters as a shared /map link - + Same query parameters as a shared /map link
      diff --git a/src/app/docs/(article)/privacy-data/page.tsx b/src/app/docs/(article)/privacy-data/page.tsx index 7262a83..f288979 100644 --- a/src/app/docs/(article)/privacy-data/page.tsx +++ b/src/app/docs/(article)/privacy-data/page.tsx @@ -23,7 +23,7 @@ const TABLES: { name: string; stores: string; note?: string }[] = [ }, { name: "user_home", - stores: "One lat/lng, if you've set a home location (powers \"Near me\" sorting).", + stores: 'One lat/lng, if you\'ve set a home location (powers "Near me" sorting).', }, { name: "user_events", @@ -46,8 +46,8 @@ export default function PrivacyDataPage() {

      The map, calendar, and competitions catalog are fully public and need no - account. Signing in only unlocks a handful of private, per-user features - - this page is what those store. + account. Signing in only unlocks a handful of private, per-user features - this + page is what those store.

      @@ -110,7 +110,9 @@ export default function PrivacyDataPage() { Password resets - Attempts are rate-limited, not your email itself + + Attempts are rate-limited, not your email itself +

      diff --git a/src/app/docs/(article)/roadmap/page.tsx b/src/app/docs/(article)/roadmap/page.tsx index a8a2b46..aabf87a 100644 --- a/src/app/docs/(article)/roadmap/page.tsx +++ b/src/app/docs/(article)/roadmap/page.tsx @@ -72,11 +72,11 @@ export default function RoadmapPage() {

      • - Geographic depth. Coverage is - deepest in India and a handful of other countries; most of the world has - at most a handful of entries per category, if any. Adding a real, - verifiable place in an under-covered city is one of the highest-value - single contributions anyone can make. + Geographic depth. Coverage is deepest + in India and a handful of other countries; most of the world has at most a + handful of entries per category, if any. Adding a real, verifiable place + in an under-covered city is one of the highest-value single contributions + anyone can make.
      • Re-verification. Most places have @@ -102,7 +102,9 @@ export default function RoadmapPage() { How direction actually gets decided - Issues and pull requests, not a backlog tool + + Issues and pull requests, not a backlog tool +

        diff --git a/src/app/docs/(article)/verification-process/page.tsx b/src/app/docs/(article)/verification-process/page.tsx index ce2035d..c8a7908 100644 --- a/src/app/docs/(article)/verification-process/page.tsx +++ b/src/app/docs/(article)/verification-process/page.tsx @@ -31,7 +31,9 @@ export default function VerificationProcessPage() { What the badge means - A green badge with the check date, next to the pin + + A green badge with the check date, next to the pin +

        @@ -78,15 +80,15 @@ export default function VerificationProcessPage() { >

        Confirm the address and entrance still match what's on the map, and that - the place is still open and operating. If anything has actually changed - name, - address, permanently closed - that's a correction, not a verification; - say so in the issue instead of confirming stale data. + the place is still open and operating. If anything has actually changed - + name, address, permanently closed - that's a correction, not a + verification; say so in the issue instead of confirming stale data.

        @@ -100,8 +102,9 @@ export default function VerificationProcessPage() { > Verify a place {" "} - issue with the place's id (from its dataset entry, or the map's share - link), the date you checked it, and what you found. A maintainer then adds the{" "} + issue with the place's id (from its dataset entry, or the map's + share link), the date you checked it, and what you found. A maintainer then + adds the{" "} verified {" "} diff --git a/src/components/home/city-switcher.tsx b/src/components/home/city-switcher.tsx index c9fb647..1372961 100644 --- a/src/components/home/city-switcher.tsx +++ b/src/components/home/city-switcher.tsx @@ -65,7 +65,12 @@ export function CitySwitcher({ cities, className }: CitySwitcherProps) { } return ( - +
        {children}
        ); diff --git a/src/components/map/category-icon.tsx b/src/components/map/category-icon.tsx index 919c499..7dbe949 100644 --- a/src/components/map/category-icon.tsx +++ b/src/components/map/category-icon.tsx @@ -1,4 +1,11 @@ -import { GraduationCap, Landmark, Library, MapPin, Plane, type LucideIcon } from "lucide-react"; +import { + GraduationCap, + Landmark, + Library, + MapPin, + Plane, + type LucideIcon, +} from "lucide-react"; import type { PlaceType } from "@/lib/types"; import { PLACE_TYPE_COLORS } from "@/lib/map"; @@ -29,6 +36,10 @@ export interface CategoryIconProps { export function CategoryIcon({ type, className }: CategoryIconProps) { const Icon = PLACE_TYPE_ICONS[type]; return ( - + ); } diff --git a/src/components/map/compare-places-sheet.tsx b/src/components/map/compare-places-sheet.tsx index 5851c68..119998e 100644 --- a/src/components/map/compare-places-sheet.tsx +++ b/src/components/map/compare-places-sheet.tsx @@ -45,7 +45,11 @@ function pairDistances(places: Place[]): PairDistance[] { * between each pair. Callers are expected to pass 2 or 3 places; fewer than * 2 just renders the one card with no distances. */ -export function ComparePlacesSheet({ places, open, onOpenChange }: ComparePlacesSheetProps) { +export function ComparePlacesSheet({ + places, + open, + onOpenChange, +}: ComparePlacesSheetProps) { const distances = places.length > 1 ? pairDistances(places) : []; return ( @@ -76,7 +80,9 @@ export function ComparePlacesSheet({ places, open, onOpenChange }: ComparePlaces /> {PLACE_TYPE_LABELS[place.type]}
      -

      {humanizeCity(place.city)}

      +

      + {humanizeCity(place.city)} +

      {place.address && (

      {place.address} diff --git a/src/components/map/embed-map.tsx b/src/components/map/embed-map.tsx index 57ad5b7..39e9fd9 100644 --- a/src/components/map/embed-map.tsx +++ b/src/components/map/embed-map.tsx @@ -33,7 +33,8 @@ export function EmbedMap({ places }: EmbedMapProps) { ); const visible = React.useMemo( - () => filterPlaces(places, { types: state.types, city: state.city, query: state.query }), + () => + filterPlaces(places, { types: state.types, city: state.city, query: state.query }), [places, state.types, state.city, state.query], ); @@ -53,7 +54,9 @@ export function EmbedMap({ places }: EmbedMapProps) { focusId={state.placeId} focusBounds={focusBounds} closePopupTrigger={0} - center={state.lat !== null && state.lng !== null ? [state.lat, state.lng] : undefined} + center={ + state.lat !== null && state.lng !== null ? [state.lat, state.lng] : undefined + } zoom={state.zoom ?? studyMapConfig.defaultZoom} />

@@ -63,7 +66,8 @@ export function EmbedMap({ places }: EmbedMapProps) { rel="noreferrer" className="flex h-7 shrink-0 items-center justify-center bg-card text-xs font-medium text-muted-foreground hover:text-foreground" > - {visible.length} {visible.length === 1 ? "place" : "places"} · View on {site.name} ↗ + {visible.length} {visible.length === 1 ? "place" : "places"} · View on {site.name}{" "} + ↗ ); diff --git a/src/components/map/heatmap-toggle.tsx b/src/components/map/heatmap-toggle.tsx index 9090241..1cc3553 100644 --- a/src/components/map/heatmap-toggle.tsx +++ b/src/components/map/heatmap-toggle.tsx @@ -17,7 +17,11 @@ interface HeatmapToggleProps { * layer to `map-view.tsx`, which is out of scope here. Styled to match * `NearMeButton` so both sit naturally in the same map-controls stack. */ -export function HeatmapToggle({ pressed, onPressedChange, className }: HeatmapToggleProps) { +export function HeatmapToggle({ + pressed, + onPressedChange, + className, +}: HeatmapToggleProps) { return (