Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 57x 57x 57x 57x 57x 15x 15x 15x 14x 1x 15x 57x 22x 22x 16x 16x 6x 6x 5x 1x 22x 57x 6x 6x 57x 3x 1x 2x 2x 2x 3x 2x 1x 1x 1x 1x 57x | import { useState, useEffect, useCallback } from "react";
import { taxonomyApi, type City, type Locality } from "../lib/api";
export function useLocationCascade() {
const [cities, setCities] = useState<City[]>([]);
const [localities, setLocalities] = useState<Locality[]>([]);
const [selectedCityId, setSelectedCityId] = useState("");
const [localityId, setLocalityId] = useState("");
// Load cities on mount
useEffect(() => {
const loadCities = async () => {
try {
const response = await taxonomyApi.getCities();
setCities(response.data || []);
} catch (err) {
console.error("Failed to load cities:", err);
}
};
loadCities();
}, []);
// Load localities when city changes (skip zone)
useEffect(() => {
const loadLocalities = async () => {
if (!selectedCityId) {
setLocalities([]);
return;
}
try {
const response = await taxonomyApi.getLocalitiesByCity(selectedCityId);
setLocalities(response.data || []);
} catch (err) {
console.error("Failed to load localities:", err);
}
};
loadLocalities();
}, [selectedCityId]);
const handleCityChange = useCallback((cityId: string) => {
setSelectedCityId(cityId);
setLocalityId("");
}, []);
// Initialize from an existing locality ID (for edit forms)
// Finds the city that contains this locality, sets city + locality
const initializeFromLocality = useCallback(
async (targetLocalityId: string) => {
if (!targetLocalityId || cities.length === 0) return;
// Try each city until we find the one containing this locality
for (const city of cities) {
try {
const response = await taxonomyApi.getLocalitiesByCity(city.id);
const cityLocalities = response.data || [];
const match = cityLocalities.find((l) => l.id === targetLocalityId);
if (match) {
setSelectedCityId(city.id);
setLocalities(cityLocalities);
setLocalityId(targetLocalityId);
return;
}
} catch {
// Continue to next city
}
}
},
[cities],
);
return {
cities,
localities,
selectedCityId,
localityId,
setLocalityId,
handleCityChange,
initializeFromLocality,
};
}
|