- Introduced a new `LocationMap` component for handling latitude and longitude inputs in forms and detail views. - Updated form and detail components to utilize the `LocationMap`, enhancing user experience by allowing map-based location selection. - Added internationalization support for map-related labels in English and Indonesian. - Developed unit tests for the `LocationMap` to ensure functionality and reliability. This commit enhances the application by providing a user-friendly interface for managing geographical locations, improving data accuracy and user interaction.
61 lines
2.1 KiB
Plaintext
61 lines
2.1 KiB
Plaintext
---
|
|
description: Entities with latitude/longitude must pick coords on OSM LocationMap in forms and render LocationMap on detail pages
|
|
globs: apps/web/src/apps/main/modules/**/*.{ts,tsx}
|
|
alwaysApply: false
|
|
---
|
|
|
|
# Location maps (lat / lng)
|
|
|
|
If an entity, DTO, or Zod schema has `latitude` and `longitude`, it is a **location entity**. Do not ship lat/lng as number fields alone.
|
|
|
|
Canonical component: `LocationMap` from `@repo/ui/map` (OpenStreetMap / Leaflet). Do not add Google Maps, Mapbox, or a second Leaflet wrapper.
|
|
|
|
Line geometry (`routeGeometry`) uses `RouteMap`, not `LocationMap`.
|
|
|
|
## Form (required)
|
|
|
|
Full-width `LocationMap` **above** the lat/lng inputs. Clicking the map writes both fields. Keep `FieldNumberInput` so values can still be typed.
|
|
|
|
```tsx
|
|
// ✅ GOOD
|
|
<LocationMap
|
|
latitude={formControl.watch('latitude')}
|
|
longitude={formControl.watch('longitude')}
|
|
helperLabel={t('common:map.pickLocation')}
|
|
onChange={(point) => {
|
|
formControl.setValue('latitude', point.latitude, { shouldDirty: true, shouldValidate: true });
|
|
formControl.setValue('longitude', point.longitude, { shouldDirty: true, shouldValidate: true });
|
|
}}
|
|
/>
|
|
|
|
// ❌ BAD — lat/lng inputs with no map picker
|
|
<FieldNumberInput name="latitude" />
|
|
<FieldNumberInput name="longitude" />
|
|
```
|
|
|
|
Layout: map is full width (form-layout compound field). Lat/lng stay a two-column pair under the map. Copy `customers` / `branches` `form-location.tsx`.
|
|
|
|
## Detail (required)
|
|
|
|
Render `LocationMap` **without** `onChange` (read-only). Pass `emptyLabel` when coords are missing. Keep `FieldValue` for the numeric pair under the map.
|
|
|
|
```tsx
|
|
// ✅ GOOD
|
|
<LocationMap
|
|
latitude={data?.latitude}
|
|
longitude={data?.longitude}
|
|
emptyLabel={t('common:map.noLocation')}
|
|
/>
|
|
|
|
// ❌ BAD — coordinates as text only
|
|
<FieldValue label={t('common:fields.latitude')} value={data?.latitude} />
|
|
```
|
|
|
|
Copy `customers` / `branches` `detail-location.tsx`.
|
|
|
|
## i18n and validation
|
|
|
|
- Helper / empty copy: `common:map.pickLocation`, `common:map.noLocation`
|
|
- Labels: `common:fields.latitude`, `common:fields.longitude`
|
|
- Keep existing Zod lat/lng range checks (`optionalLatitudeSchema` / `optionalLongitudeSchema`)
|