From 1847dd87dc7e369505a07116ee6ea0a78dd45914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Prod=27homme?= Date: Mon, 18 Nov 2024 13:16:03 +0100 Subject: [PATCH] feat(client): Zoom the map onto the selected location --- client/package.json | 1 + client/src/components/map/index.tsx | 4 +++ client/src/hooks/use-apply-map-location.ts | 39 ++++++++++++++++++++++ client/src/hooks/use-location-by-code.ts | 22 ++++++------ client/yarn.lock | 35 ++++++++++++++++++- 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 client/src/hooks/use-apply-map-location.ts diff --git a/client/package.json b/client/package.json index 75494c6..d42722c 100644 --- a/client/package.json +++ b/client/package.json @@ -38,6 +38,7 @@ "@radix-ui/react-tooltip": "1.1.3", "@t3-oss/env-nextjs": "0.11.1", "@tanstack/react-query": "5.59.16", + "@turf/bbox": "7.1.0", "@types/mapbox-gl": "3.4.0", "apng-js": "1.1.4", "axios": "1.7.7", diff --git a/client/src/components/map/index.tsx b/client/src/components/map/index.tsx index 83cc1a4..068bd22 100644 --- a/client/src/components/map/index.tsx +++ b/client/src/components/map/index.tsx @@ -7,6 +7,7 @@ import DeckglMapboxProvider from "@/components/map/deckgl-mapbox-provider"; import LayerManager from "@/components/map/layer-manager"; import { SIDEBAR_WIDTH } from "@/components/ui/sidebar"; import { env } from "@/env"; +import useApplyMapLocation from "@/hooks/use-apply-map-location"; import useApplyMapSettings from "@/hooks/use-apply-map-settings"; import useBreakpoint from "@/hooks/use-breakpoint"; import useIsSidebarExpanded from "@/hooks/use-is-sidebar-expanded"; @@ -82,6 +83,9 @@ const Map = () => { // Apply the basemap and labels useApplyMapSettings(map); + // Zoom the map on the selected location + useApplyMapLocation(map); + return ( { + if (isLoading || data?.geometry === undefined || data?.geometry === null) { + return undefined; + } + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return bbox(data.geometry) as [number, number, number, number]; + }, [data, isLoading]); + + useEffect(() => { + const hasChangedLocation = location !== previousLocation; + if (hasChangedLocation) { + triggerFitBoundsRef.current = true; + } + + if (map && !!bounds && triggerFitBoundsRef.current) { + map.fitBounds(bounds); + triggerFitBoundsRef.current = false; + } + }, [map, location, previousLocation, data, isLoading]); +} diff --git a/client/src/hooks/use-location-by-code.ts b/client/src/hooks/use-location-by-code.ts index e8a836f..457bd31 100644 --- a/client/src/hooks/use-location-by-code.ts +++ b/client/src/hooks/use-location-by-code.ts @@ -1,19 +1,14 @@ import { useGetLocations } from "@/types/generated/location"; +import { Location } from "@/types/generated/strapi.schemas"; -type LocationByCode = { - id: number; - name: string; - code: string; -}; - -export function useLocationByCode(code: string | undefined) { +export function useLocationByCode(code: string | undefined, fields = ["name", "code"]) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-error - const { data, isLoading } = useGetLocations( + const { data, isLoading } = useGetLocations( { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-error - fields: ["name", "code"], + fields, filters: { code: { $eq: code, @@ -33,8 +28,13 @@ export function useLocationByCode(code: string | undefined) { return { id: data.data[0].id, - name: data.data[0].attributes!.name!, - code: data.data[0].attributes!.code!, + ...fields.reduce( + (res, field) => ({ + ...res, + [field]: data.data![0].attributes![field as keyof Location], + }), + {}, + ), }; }, }, diff --git a/client/yarn.lock b/client/yarn.lock index 6c6e03e..14c9519 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -4238,6 +4238,18 @@ __metadata: languageName: node linkType: hard +"@turf/bbox@npm:7.1.0": + version: 7.1.0 + resolution: "@turf/bbox@npm:7.1.0" + dependencies: + "@turf/helpers": "npm:^7.1.0" + "@turf/meta": "npm:^7.1.0" + "@types/geojson": "npm:^7946.0.10" + tslib: "npm:^2.6.2" + checksum: 10c0/901ed437ad1241b1c7cf76ee3f1dd998b32a59647074216d076a62080281693cc3f1d66d1dedd02fd5617ea57434ec059843bcc275d20f667019f3e1f378b05d + languageName: node + linkType: hard + "@turf/boolean-clockwise@npm:^5.1.5": version: 5.1.5 resolution: "@turf/boolean-clockwise@npm:5.1.5" @@ -4264,6 +4276,16 @@ __metadata: languageName: node linkType: hard +"@turf/helpers@npm:^7.1.0": + version: 7.1.0 + resolution: "@turf/helpers@npm:7.1.0" + dependencies: + "@types/geojson": "npm:^7946.0.10" + tslib: "npm:^2.6.2" + checksum: 10c0/0b07c01584d8bee977edec8752109b4f79ab5b149e55a7dbe051e412e150c0a96f2464c9647676a092b7ab4429271eee4a31400ea45e9b55095ae53ad22f43d6 + languageName: node + linkType: hard + "@turf/invariant@npm:^5.1.5": version: 5.2.0 resolution: "@turf/invariant@npm:5.2.0" @@ -4282,6 +4304,16 @@ __metadata: languageName: node linkType: hard +"@turf/meta@npm:^7.1.0": + version: 7.1.0 + resolution: "@turf/meta@npm:7.1.0" + dependencies: + "@turf/helpers": "npm:^7.1.0" + "@types/geojson": "npm:^7946.0.10" + checksum: 10c0/c7aa77ddb28ef5068b031c1b422d2d5dc1df51975f727be42e2d8d500a026a2e667242d6aa06453f757cbd5ead2db0ba6b9a5d2fcf5ab496574cd4c0ae4fe325 + languageName: node + linkType: hard + "@turf/rewind@npm:^5.1.5": version: 5.1.5 resolution: "@turf/rewind@npm:5.1.5" @@ -4329,7 +4361,7 @@ __metadata: languageName: node linkType: hard -"@types/geojson@npm:*, @types/geojson@npm:^7946.0.14, @types/geojson@npm:^7946.0.7, @types/geojson@npm:^7946.0.8": +"@types/geojson@npm:*, @types/geojson@npm:^7946.0.10, @types/geojson@npm:^7946.0.14, @types/geojson@npm:^7946.0.7, @types/geojson@npm:^7946.0.8": version: 7946.0.14 resolution: "@types/geojson@npm:7946.0.14" checksum: 10c0/54f3997708fa2970c03eeb31f7e4540a0eb6387b15e9f8a60513a1409c23cafec8d618525404573468b59c6fecbfd053724b3327f7fca416729c26271d799f55 @@ -5484,6 +5516,7 @@ __metadata: "@t3-oss/env-nextjs": "npm:0.11.1" "@tanstack/eslint-plugin-query": "npm:5.59.7" "@tanstack/react-query": "npm:5.59.16" + "@turf/bbox": "npm:7.1.0" "@types/mapbox-gl": "npm:3.4.0" "@types/node": "npm:22.7.6" "@types/react": "npm:18.3.1"