Skip to content

Commit d105094

Browse files
wilhel1812wilhel1812
andauthored
fix: add real-time lat/lon validation to prevent map crash (#808) (#822)
Co-authored-by: wilhel1812 <wilhelm@linksim.link>
1 parent 19d817d commit d105094

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

src/components/map/MapEditorPanel.test.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ describe("MapEditorPanel", () => {
258258
const latInput = await screen.findByLabelText("Latitude");
259259
await userEvent.clear(latInput);
260260
await userEvent.type(latInput, "956894");
261-
await userEvent.click(screen.getByRole("button", { name: "Create Site" }));
262261

263262
expect(screen.getByText(/Latitude must be between -90 and 90/)).toBeInTheDocument();
264263
expect(useAppStore.getState().mapEditor).not.toBeNull();
@@ -282,7 +281,6 @@ describe("MapEditorPanel", () => {
282281
const lonInput = await screen.findByLabelText("Longitude");
283282
await userEvent.clear(lonInput);
284283
await userEvent.type(lonInput, "956894");
285-
await userEvent.click(screen.getByRole("button", { name: "Create Site" }));
286284

287285
expect(screen.getByText(/Longitude must be between -180 and 180/)).toBeInTheDocument();
288286
expect(useAppStore.getState().mapEditor).not.toBeNull();
@@ -306,7 +304,6 @@ describe("MapEditorPanel", () => {
306304
const latInput = await screen.findByLabelText("Latitude");
307305
await userEvent.clear(latInput);
308306
await userEvent.type(latInput, " 956894");
309-
await userEvent.click(screen.getByRole("button", { name: "Create Site" }));
310307

311308
expect(screen.getByText(/Latitude must be between -90 and 90/)).toBeInTheDocument();
312309
expect(useAppStore.getState().mapEditor).not.toBeNull();

src/components/map/MapEditorPanel.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,21 +249,25 @@ function SiteEditorCard({
249249
<label className="field-grid">
250250
<span>Latitude</span>
251251
<input
252+
aria-invalid={form.latError ? true : undefined}
252253
onChange={(e) => form.setLatDraft(e.target.value)}
253254
step="0.000001"
254255
type="number"
255256
value={form.latDraft}
256257
/>
258+
{form.latError ? <p className="field-help warning-text">{form.latError}</p> : null}
257259
</label>
258260

259261
<label className="field-grid">
260262
<span>Longitude</span>
261263
<input
264+
aria-invalid={form.lonError ? true : undefined}
262265
onChange={(e) => form.setLonDraft(e.target.value)}
263266
step="0.000001"
264267
type="number"
265268
value={form.lonDraft}
266269
/>
270+
{form.lonError ? <p className="field-help warning-text">{form.lonError}</p> : null}
267271
</label>
268272

269273
<label className="field-grid">

src/components/map/useMapEditorFormState.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,11 +741,19 @@ export function useMapEditorFormState() {
741741
}
742742
};
743743

744+
const [latError, setLatError] = useState<string | null>(null);
745+
const [lonError, setLonError] = useState<string | null>(null);
746+
744747
const setSitePositionDraft = (nextLat: number | string, nextLon: number | string, nextGround = groundDraft) => {
745748
const lat = parseNumber(String(nextLat));
746749
const lon = parseNumber(String(nextLon));
747750
setLatDraft(lat);
748751
setLonDraft(lon);
752+
const latErr = validateLatitude(lat);
753+
const lonErr = validateLongitude(lon);
754+
setLatError(latErr);
755+
setLonError(lonErr);
756+
if (latErr || lonErr) return;
749757
setMapEditorSiteDraft({ lat, lon, groundElevationM: nextGround });
750758
};
751759

@@ -785,8 +793,12 @@ export function useMapEditorFormState() {
785793
canWrite,
786794
currentUser,
787795
// site
788-
latDraft, setLatDraft: (v: number | string) => setSitePositionDraft(v, lonDraft),
789-
lonDraft, setLonDraft: (v: number | string) => setSitePositionDraft(latDraft, v),
796+
latDraft,
797+
lonDraft,
798+
latError,
799+
lonError,
800+
setLatDraft: (v: number | string) => setSitePositionDraft(v, lonDraft),
801+
setLonDraft: (v: number | string) => setSitePositionDraft(latDraft, v),
790802
groundDraft, setGroundDraft: (v: number | string) => {
791803
const nextGround = parseNumber(String(v));
792804
setGroundDraft(nextGround);

0 commit comments

Comments
 (0)