b8934f531d
Three domain services (mirroring the patients/nurse template): services/geography (cached province→city→district lookups; Infinity staleTime + shared geographyKeys), services/addresses (address book CRUD + set-primary; single-primary invariant), and services/serviceAreas (coverage add/remove; areaExists dup-guard, districtId=null = whole city). Four tested composites in src/components/geography: CascadingRegionSelect (drives the cascade queries), AddressMapPicker (map-pin stand-in emitting real lat/lng), AddressForm, AddressCard. Screens: customer address book (/addresses, reached from the profile hub) and nurse coverage editor (/nurse/coverage, new sidebar tab, inline duplicate block + 409). Adds geo/address/coverage i18n namespaces (both locales), location/delete/coverage icons, ADDRESSES/NURSE_COVERAGE routes. Consumes the b4 geography-addresses contract; filed REQ-008 (accept the map pin on create/update) and REQ-009 (provinceId on CustomerAddressDto) for gaps. Gate: npm run check + npm run test:ci (129, +17) + npm run build all green. A 5-dimension adversarial review fixed 3 findings (map-marker RTL transform, page_size→pageSize pagination casing, coverage districts-scope dead-end on district-less cities). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 lines
794 B
TypeScript
20 lines
794 B
TypeScript
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { serviceAreasApi } from '../apis';
|
|
import { serviceAreaKeys } from '../keys';
|
|
import type { AddServiceAreaInput } from '../types';
|
|
|
|
/**
|
|
* Adds a coverage area, then invalidates the list. A duplicate `(cityId, districtId)` returns
|
|
* `409` — surfaced via `mutation.error` so the screen shows the inline "already covered" message
|
|
* (the client-side check is the fast path; this 409 is the belt-and-braces server truth).
|
|
*/
|
|
export function useAddServiceArea() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (input: AddServiceAreaInput) => serviceAreasApi.add(input),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: serviceAreaKeys.lists() });
|
|
},
|
|
});
|
|
}
|