From 198c513e88ae451f6a868c40f054ab089fcdd223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Prod=27homme?= Date: Thu, 10 Oct 2024 10:11:14 +0200 Subject: [PATCH] Change the bounds when changing tab --- .../main-panel/panels/details/index.tsx | 44 ++++++++++++++++++- frontend/src/lib/utils/geo.ts | 16 +++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 frontend/src/lib/utils/geo.ts diff --git a/frontend/src/containers/map/sidebar/main-panel/panels/details/index.tsx b/frontend/src/containers/map/sidebar/main-panel/panels/details/index.tsx index 5ac50b14..c9fcb2f2 100644 --- a/frontend/src/containers/map/sidebar/main-panel/panels/details/index.tsx +++ b/frontend/src/containers/map/sidebar/main-panel/panels/details/index.tsx @@ -2,16 +2,22 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; import { useRouter } from 'next/router'; +import { BBox } from '@turf/turf'; +import { useAtom } from 'jotai'; import { useLocale, useTranslations } from 'next-intl'; +import { CustomMapProps } from '@/components/map/types'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { PAGES } from '@/constants/pages'; import { useMapSearchParams } from '@/containers/map/content/map/sync-settings'; +import { bboxLocationAtom } from '@/containers/map/store'; import { useSyncMapContentSettings } from '@/containers/map/sync-settings'; import useScrollPosition from '@/hooks/use-scroll-position'; import { cn } from '@/lib/classnames'; +import { combineBoundingBoxes } from '@/lib/utils/geo'; import { FCWithMessages } from '@/types'; import { useGetLocations } from '@/types/generated/location'; +import { Location } from '@/types/generated/strapi.schemas'; import LocationSelector from '../../location-selector'; @@ -35,13 +41,23 @@ const SidebarDetails: FCWithMessages = () => { const searchParams = useMapSearchParams(); const [{ tab }, setSettings] = useSyncMapContentSettings(); + const [, setLocationBBox] = useAtom(bboxLocationAtom); const { data: locationsData } = useGetLocations({ locale, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + fields: ['name', 'name_es', 'name_fr', 'marine_bounds', 'terrestrial_bounds'], filters: { code: locationCode, }, - populate: 'members', + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + populate: { + members: { + fields: ['code', 'name', 'name_es', 'name_fr'], + }, + }, }); const locationNameField = useMemo(() => { @@ -55,6 +71,25 @@ const SidebarDetails: FCWithMessages = () => { return res; }, [locale]); + const locationBounds = useMemo(() => { + const { terrestrial_bounds, marine_bounds } = + locationsData?.data[0]?.attributes ?? ({} as Location); + + if (tab === 'terrestrial') { + return terrestrial_bounds; + } + + if (tab === 'marine') { + return marine_bounds; + } + + if (terrestrial_bounds === undefined || marine_bounds === undefined) { + return null; + } + + return combineBoundingBoxes(terrestrial_bounds as BBox, marine_bounds as BBox); + }, [locationsData, tab]); + const memberCountries = useMemo(() => { return locationsData?.data[0]?.attributes?.members?.data?.map(({ attributes }) => ({ code: attributes?.code, @@ -80,6 +115,13 @@ const SidebarDetails: FCWithMessages = () => { containerRef.current?.scrollTo({ top: 0 }); }, [tab, locationCode]); + // Zoom the map to the location's bounds (terrestrial bounds, marine bounds or both) + useEffect(() => { + if (locationBounds) { + setLocationBBox(locationBounds as CustomMapProps['bounds']['bbox']); + } + }, [setLocationBBox, locationBounds]); + return (
{ + return [ + Math.min(bbox1[0], bbox2[0]), + Math.min(bbox1[1], bbox2[1]), + Math.max(bbox1[2], bbox2[2]), + Math.max(bbox1[3], bbox2[3]), + ]; +};