Skip to content

Commit 09f0e3c

Browse files
committed
feat: Enhance location handling in forms and components with incident coordinates
1 parent 3800b4b commit 09f0e3c

File tree

7 files changed

+63
-10
lines changed

7 files changed

+63
-10
lines changed

src/components/AssignmentBoard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const AssignmentBoard: React.FC<AssignmentBoardProps> = ({ unitId, orgId, readOn
6464
function markerSvg(color: string, label: string) {
6565
const initial = label ? label.toUpperCase() : '';
6666
const len = initial.length;
67-
let width = 32, height = 28, rectX = 0, rectY = 0, rectRx = 6, fontSize = 16, textX = 16, textY = 16;
67+
let width = 32, height = 28, rectX = 0, rectY = 0, rectRx = 6, fontSize = 16, textX = 16;
6868
if (len === 2) {
6969
width = 40; textX = 20;
7070
} else if (len === 3) {

src/components/fields/LocationField.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useState } from 'react';
22
import { Form, FloatingLabel, InputGroup } from 'react-bootstrap';
3-
43
import LocationPickerModal from './LocationPickerModal';
54

65
interface LocationFieldProps {
@@ -9,6 +8,8 @@ interface LocationFieldProps {
98
address: string;
109
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
1110
readOnly?: boolean;
11+
incidentLat?: number;
12+
incidentLng?: number;
1213
}
1314

1415

@@ -18,6 +19,8 @@ const LocationField: React.FC<LocationFieldProps> = ({
1819
address,
1920
onChange,
2021
readOnly = false,
22+
incidentLat,
23+
incidentLng,
2124
}) => {
2225
const [showPicker, setShowPicker] = useState(false);
2326

@@ -102,6 +105,8 @@ const LocationField: React.FC<LocationFieldProps> = ({
102105
onPick={handlePick}
103106
initialLat={hasCoords ? latNum : undefined}
104107
initialLng={hasCoords ? lngNum : undefined}
108+
incidentLat={incidentLat}
109+
incidentLng={incidentLng}
105110
/>
106111
</>
107112
);

src/components/fields/LocationPickerModal.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ interface LocationPickerModalProps {
88
onPick: (lat: number, lng: number) => void;
99
initialLat?: number;
1010
initialLng?: number;
11+
incidentLat?: number;
12+
incidentLng?: number;
1113
}
1214

1315
const mapContainerStyle = { width: '100%', height: '300px' };
14-
const defaultCenter = { lat: 28.5383, lng: -81.3792 }; // Orlando, FL
1516

16-
const LocationPickerModal: React.FC<LocationPickerModalProps> = ({ show, onHide, onPick, initialLat, initialLng }) => {
17+
// Default fallback center (Orlando, FL)
18+
const defaultCenter = { lat: 28.5383, lng: -81.3792 };
19+
20+
21+
const LocationPickerModal: React.FC<LocationPickerModalProps> = ({ show, onHide, onPick, initialLat, initialLng, incidentLat, incidentLng }) => {
1722
const [marker, setMarker] = useState<{ lat: number; lng: number } | null>(
1823
initialLat != null && initialLng != null
1924
? { lat: Number(initialLat), lng: Number(initialLng) }
@@ -43,6 +48,14 @@ const LocationPickerModal: React.FC<LocationPickerModalProps> = ({ show, onHide,
4348
}
4449
};
4550

51+
// Determine the map center: marker > incident location > default
52+
let mapCenter = defaultCenter;
53+
if (marker) {
54+
mapCenter = marker;
55+
} else if (incidentLat != null && incidentLng != null) {
56+
mapCenter = { lat: Number(incidentLat), lng: Number(incidentLng) };
57+
}
58+
4659
return (
4760
<Modal show={show} onHide={onHide} centered>
4861
<Modal.Header closeButton>
@@ -51,8 +64,8 @@ const LocationPickerModal: React.FC<LocationPickerModalProps> = ({ show, onHide,
5164
<Modal.Body>
5265
<GoogleMap
5366
mapContainerStyle={mapContainerStyle}
54-
center={marker || defaultCenter}
55-
zoom={marker ? 16 : 4}
67+
center={mapCenter}
68+
zoom={marker ? 18 : (incidentLat && incidentLng) ? 15 : 10}
5669
mapTypeId="hybrid"
5770
onClick={handleMapClick}
5871
>

src/pages/Incidents/IncidentForm.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
22
import { Form, Button, Modal } from 'react-bootstrap';
33
import NoteField from '../../components/fields/NoteField';
44
import DescriptorField from '../../components/fields/DescriptorField';
5+
import LocationField from '../../components/fields/LocationField';
56

67
interface IncidentFormProps {
78
show: boolean;
@@ -15,6 +16,9 @@ const IncidentForm: React.FC<IncidentFormProps> = ({ show, onHide, onSubmit, ini
1516
name: initial?.name || '',
1617
description: initial?.description || '',
1718
notes: initial?.notes || '',
19+
latitude: initial?.latitude || '',
20+
longitude: initial?.longitude || '',
21+
address: initial?.address || '',
1822
});
1923

2024
React.useEffect(() => {
@@ -23,12 +27,24 @@ const IncidentForm: React.FC<IncidentFormProps> = ({ show, onHide, onSubmit, ini
2327
name: initial?.name || '',
2428
description: initial?.description || '',
2529
notes: initial?.notes || '',
30+
latitude: initial?.latitude || '',
31+
longitude: initial?.longitude || '',
32+
address: initial?.address || '',
2633
});
2734
}
2835
}, [initial, show]);
2936

30-
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
31-
setForm({ ...form, [e.target.name]: e.target.value });
37+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | any) => {
38+
// Support batched lat/lng event from map picker
39+
if (e.target.name === 'latitude-longitude' && e.target.value) {
40+
setForm(f => ({
41+
...f,
42+
latitude: e.target.value.latitude,
43+
longitude: e.target.value.longitude,
44+
}));
45+
} else {
46+
setForm({ ...form, [e.target.name]: e.target.value });
47+
}
3248
};
3349

3450
const handleSubmit = (e: React.FormEvent) => {
@@ -48,6 +64,14 @@ const IncidentForm: React.FC<IncidentFormProps> = ({ show, onHide, onSubmit, ini
4864
description={form.description}
4965
onChange={handleChange}
5066
/>
67+
<LocationField
68+
latitude={form.latitude}
69+
longitude={form.longitude}
70+
address={form.address}
71+
onChange={handleChange}
72+
incidentLat={form.latitude !== '' ? Number(form.latitude) : undefined}
73+
incidentLng={form.longitude !== '' ? Number(form.longitude) : undefined}
74+
/>
5175
<NoteField
5276
notes={form.notes}
5377
onChange={handleChange}

src/pages/Locations/LocationForm.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ interface LocationFormProps {
1313
initial?: any;
1414
units: Unit[];
1515
unitsLoading?: boolean;
16+
incidentLat?: number;
17+
incidentLng?: number;
1618
}
1719

18-
const LocationForm: React.FC<LocationFormProps> = ({ show, onHide, onSubmit, initial, units, unitsLoading }) => {
20+
const LocationForm: React.FC<LocationFormProps> = ({ show, onHide, onSubmit, initial, units, unitsLoading, incidentLat, incidentLng }) => {
1921
const [form, setForm] = useState({
2022
name: initial?.name || '',
2123
label: initial?.label || '',
@@ -87,6 +89,8 @@ const LocationForm: React.FC<LocationFormProps> = ({ show, onHide, onSubmit, ini
8789
longitude={form.longitude}
8890
address={form.address}
8991
onChange={handleChange}
92+
incidentLat={incidentLat}
93+
incidentLng={incidentLng}
9094
/>
9195
<ContextSelect
9296
label='Unit'

src/pages/Locations/LocationsPage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Container, Card, Table, Button, Alert, Placeholder, Row, Col, Spinner }
77
import { ArchiveFill, CheckCircleFill, DashCircleFill } from 'react-bootstrap-icons';
88
import { Location, LocationStatus } from '../../types/Location';
99
import LocationForm from './LocationForm';
10+
import { useIncident } from '../../context/IncidentContext';
1011
import LocationViewModal from './LocationViewModal';
1112
import { ALERT_NOT_LOGGED_IN } from '../../constants/messages';
1213
import { useUnit } from '../../context/UnitContext';
@@ -30,6 +31,7 @@ const LocationsPage: React.FC = () => {
3031
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc');
3132
const [selectedLocation, setSelectedLocation] = useState<Location | null>(null);
3233
const { units, loading: unitsLoading } = useUnit();
34+
const { selectedIncident } = useIncident();
3335

3436
const handleAdd = () => {
3537
setEditLocation(null);
@@ -190,7 +192,9 @@ const LocationsPage: React.FC = () => {
190192
onSubmit={handleFormSubmit}
191193
initial={editLocation}
192194
units={units}
193-
unitsLoading={unitsLoading} // Assuming unitsLoading is passed as a prop
195+
unitsLoading={unitsLoading}
196+
incidentLat={selectedIncident?.latitude}
197+
incidentLng={selectedIncident?.longitude}
194198
/>
195199
<LocationViewModal
196200
show={showView}

src/types/Incident.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ export interface Incident {
44
name: string;
55
description?: string;
66
notes?: string;
7+
latitude?: number;
8+
longitude?: number;
9+
address?: string;
710
// ...other fields as needed
811
}

0 commit comments

Comments
 (0)