Open add-city form only via the Add city button, not map clicks
Map clicks were navigating straight to the new-city form, which made it easy to open by accident while panning/zooming.
This commit is contained in:
parent
ce16de8504
commit
3555972bfd
4 changed files with 5 additions and 20 deletions
|
|
@ -69,7 +69,7 @@ export function CitySearchInput({ onSelect }: CitySearchInputProps) {
|
||||||
)}
|
)}
|
||||||
{open && !loading && results.length === 0 && query.trim().length >= 3 && (
|
{open && !loading && results.length === 0 && query.trim().length >= 3 && (
|
||||||
<div className="search-empty">
|
<div className="search-empty">
|
||||||
No results — you can still enter details manually or click the map.
|
No results — try a different search.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'leaflet/dist/leaflet.css';
|
import 'leaflet/dist/leaflet.css';
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { MapContainer, TileLayer, Marker, Popup, useMap, useMapEvents } from 'react-leaflet';
|
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import type { City } from '@citytracker/shared';
|
import type { City } from '@citytracker/shared';
|
||||||
import { cityMarkerIcon } from './CityMarker';
|
import { cityMarkerIcon } from './CityMarker';
|
||||||
|
|
@ -8,16 +8,6 @@ import { cityMarkerIcon } from './CityMarker';
|
||||||
interface CityMapProps {
|
interface CityMapProps {
|
||||||
cities: City[];
|
cities: City[];
|
||||||
focusCity?: City;
|
focusCity?: City;
|
||||||
onMapClick?: (lat: number, lng: number) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ClickHandler({ onMapClick }: { onMapClick?: (lat: number, lng: number) => void }) {
|
|
||||||
useMapEvents({
|
|
||||||
click(e) {
|
|
||||||
onMapClick?.(e.latlng.lat, e.latlng.lng);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Roughly bounds a `radiusKm` circle around a point, for an initial "zoomed to this area" view. */
|
/** Roughly bounds a `radiusKm` circle around a point, for an initial "zoomed to this area" view. */
|
||||||
|
|
@ -42,7 +32,7 @@ function InitialFocus({ focusCity }: { focusCity?: City }) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CityMap({ cities, focusCity, onMapClick }: CityMapProps) {
|
export function CityMap({ cities, focusCity }: CityMapProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -51,7 +41,6 @@ export function CityMap({ cities, focusCity, onMapClick }: CityMapProps) {
|
||||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
/>
|
/>
|
||||||
<ClickHandler onMapClick={onMapClick} />
|
|
||||||
<InitialFocus focusCity={focusCity} />
|
<InitialFocus focusCity={focusCity} />
|
||||||
{cities.map((city) => (
|
{cities.map((city) => (
|
||||||
<Marker key={city.id} position={[city.lat, city.lng]} icon={cityMarkerIcon(city)}>
|
<Marker key={city.id} position={[city.lat, city.lng]} icon={cityMarkerIcon(city)}>
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ export function CityDetailPage({ mode }: CityDetailPageProps) {
|
||||||
{saveStatus === 'error' && 'Could not save — check your connection'}
|
{saveStatus === 'error' && 'Could not save — check your connection'}
|
||||||
{saveStatus === 'idle' &&
|
{saveStatus === 'idle' &&
|
||||||
!isEditing &&
|
!isEditing &&
|
||||||
'Search for a city or click the map, then add a name and country to save'}
|
'Search for a city, then add a name and country to save'}
|
||||||
</span>
|
</span>
|
||||||
<button type="button" className="btn btn-ghost" onClick={() => navigate('/')}>
|
<button type="button" className="btn btn-ghost" onClick={() => navigate('/')}>
|
||||||
Back to map
|
Back to map
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,6 @@ export function MapDashboardPage() {
|
||||||
// Cities are returned newest-first, so the first entry is the most recently added one.
|
// Cities are returned newest-first, so the first entry is the most recently added one.
|
||||||
const latestCity = allCities?.[0];
|
const latestCity = allCities?.[0];
|
||||||
|
|
||||||
function handleMapClick(lat: number, lng: number) {
|
|
||||||
navigate('/cities/new', { state: { lat, lng } });
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="map-dashboard">
|
<div className="map-dashboard">
|
||||||
<MapFilters filters={filters} countries={countries} years={years} onChange={setFilters} />
|
<MapFilters filters={filters} countries={countries} years={years} onChange={setFilters} />
|
||||||
|
|
@ -44,7 +40,7 @@ export function MapDashboardPage() {
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="page-loading">Loading map…</div>
|
<div className="page-loading">Loading map…</div>
|
||||||
) : (
|
) : (
|
||||||
<CityMap cities={cities ?? []} focusCity={latestCity} onMapClick={handleMapClick} />
|
<CityMap cities={cities ?? []} focusCity={latestCity} />
|
||||||
)}
|
)}
|
||||||
<button type="button" className="btn btn-primary fab" onClick={() => navigate('/cities/new')}>
|
<button type="button" className="btn btn-primary fab" onClick={() => navigate('/cities/new')}>
|
||||||
+ Add city
|
+ Add city
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue