diff --git a/client/package.json b/client/package.json index 5a6ba5b..f94aba9 100644 --- a/client/package.json +++ b/client/package.json @@ -36,7 +36,7 @@ "@radix-ui/react-slot": "1.1.0", "@radix-ui/react-switch": "1.1.1", "@radix-ui/react-tabs": "1.1.1", - "@radix-ui/react-tooltip": "1.1.3", + "@radix-ui/react-tooltip": "1.1.4", "@t3-oss/env-nextjs": "0.11.1", "@tanstack/react-query": "5.59.16", "@turf/bbox": "7.1.0", @@ -57,6 +57,7 @@ "react": "18.3.1", "react-dom": "18.3.1", "react-map-gl": "7.1.7", + "react-markdown": "9.0.1", "tailwind-merge": "2.5.4", "tailwindcss-animate": "1.0.7", "tailwindcss-border-image": "1.1.2", diff --git a/client/src/components/dataset-card/index.tsx b/client/src/components/dataset-card/index.tsx index fe47819..f811411 100644 --- a/client/src/components/dataset-card/index.tsx +++ b/client/src/components/dataset-card/index.tsx @@ -6,7 +6,9 @@ import Link from "next/link"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import * as React from "react"; +import DatasetMetadata from "@/components/dataset-metadata"; import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import MonthPicker from "@/components/ui/month-picker"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; @@ -18,6 +20,7 @@ import { SelectValue, } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import useMapLayers from "@/hooks/use-map-layers"; import { cn } from "@/lib/utils"; import CalendarDaysIcon from "@/svgs/calendar-days.svg"; @@ -25,7 +28,8 @@ import ChevronDownIcon from "@/svgs/chevron-down.svg"; import DownloadIcon from "@/svgs/download.svg"; import PauseIcon from "@/svgs/pause.svg"; import PlayIcon from "@/svgs/play.svg"; -import { DatasetLayersDataItem } from "@/types/generated/strapi.schemas"; +import QuestionMarkIcon from "@/svgs/question-mark.svg"; +import { DatasetLayersDataItem, MetadataItemComponent } from "@/types/generated/strapi.schemas"; import { LayerParamsConfig } from "@/types/layer"; import { @@ -40,9 +44,10 @@ interface DatasetCardProps { name: string; defaultLayerId: number | undefined; layers: DatasetLayersDataItem[]; + metadata?: MetadataItemComponent; } -const DatasetCard = ({ id, name, defaultLayerId, layers }: DatasetCardProps) => { +const DatasetCard = ({ id, name, defaultLayerId, layers, metadata }: DatasetCardProps) => { const [layersConfiguration, { addLayer, updateLayer, removeLayer }] = useMapLayers(); const defaultSelectedLayerId = useMemo( @@ -219,21 +224,54 @@ const DatasetCard = ({ id, name, defaultLayerId, layers }: DatasetCardProps) => -
+
{!!selectedLayer?.attributes!.download_link && ( - + + + + + + Download dataset + + + )} + {!!metadata && ( + + + + + + + + + More info + + + + + + + )} + {(!!selectedLayer?.attributes!.download_link || !!metadata) && ( +
)} { + return ( + <> + + {name} + +
+ {!!metadata.full_name && ( +
+
Full name
+
{metadata.full_name}
+
+ )} + {!!metadata.source && ( +
+
Source
+
{metadata.source}
+
+ )} + {!!metadata.website && ( +
+
Website
+
+ + {metadata.website} + +
+
+ )} + {!!metadata.description && ( +
+
Description
+
{metadata.description}
+
+ )} + {!!metadata.main_applications && ( +
+
Main applications
+
+ {metadata.main_applications} +
+
+ )} + {!!metadata.temporal_resolution && ( +
+
Temporal resolution
+
+ {metadata.temporal_resolution} +
+
+ )} + {!!metadata.temporal_coverage && ( +
+
Temporal coverage
+
+ {metadata.temporal_coverage} +
+
+ )} + {!!metadata.spatial_resolution && ( +
+
Spatial resolution
+
{metadata.spatial_resolution}
+
+ )} + {!!metadata.units && ( +
+
Units
+
{metadata.units}
+
+ )} +
+ + ); +}; + +export default DatasetMetadata; diff --git a/client/src/components/markdown/index.tsx b/client/src/components/markdown/index.tsx new file mode 100644 index 0000000..79f2e13 --- /dev/null +++ b/client/src/components/markdown/index.tsx @@ -0,0 +1,32 @@ +import Link from "next/link"; +import ReactMarkdown from "react-markdown"; + +interface MarkdownProps { + children: string | null | undefined; +} + +const Markdown = ({ children }: MarkdownProps) => { + return ( +
    {children}
, + ol: ({ children }) =>
    {children}
, + a: ({ children, href }) => ( + + {children} + + ), + }} + > + {children} +
+ ); +}; + +export default Markdown; diff --git a/client/src/components/navigation/navigation-desktop/index.tsx b/client/src/components/navigation/navigation-desktop/index.tsx index 8c62e87..b8e8419 100644 --- a/client/src/components/navigation/navigation-desktop/index.tsx +++ b/client/src/components/navigation/navigation-desktop/index.tsx @@ -46,7 +46,7 @@ const NavigationDesktop = () => { - + diff --git a/client/src/components/panels/contextual-layers/index.tsx b/client/src/components/panels/contextual-layers/index.tsx index b7d9bc4..ee6965a 100644 --- a/client/src/components/panels/contextual-layers/index.tsx +++ b/client/src/components/panels/contextual-layers/index.tsx @@ -9,10 +9,12 @@ import XMarkIcon from "@/svgs/xmark.svg"; import Item from "./item"; const ContextualLayersPanel = () => { - const { data, isLoading } = useDatasetsBySubTopic("contextual", "sub_topic.name,name", [ - "layer", - "download_link", - ]); + const { data, isLoading } = useDatasetsBySubTopic( + "contextual", + "sub_topic.name,name", + ["layer", "download_link"], + true, + ); return ( <> @@ -75,6 +77,7 @@ const ContextualLayersPanel = () => { id: dataset.layers[0].id!, name: dataset.layers[0].attributes!.name!, downloadLink: dataset.layers[0].attributes!.download_link, + metadata: dataset.metadata, }))} /> ))} diff --git a/client/src/components/panels/contextual-layers/item.tsx b/client/src/components/panels/contextual-layers/item.tsx index f90cd25..d7ed59c 100644 --- a/client/src/components/panels/contextual-layers/item.tsx +++ b/client/src/components/panels/contextual-layers/item.tsx @@ -1,16 +1,25 @@ import Link from "next/link"; +import * as React from "react"; +import DatasetMetadata from "@/components/dataset-metadata"; import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import useMapLayers from "@/hooks/use-map-layers"; -import { cn } from "@/lib/utils"; import DownloadIcon from "@/svgs/download.svg"; -import { Dataset, Layer } from "@/types/generated/strapi.schemas"; +import QuestionMarkIcon from "@/svgs/question-mark.svg"; +import { Dataset, Layer, MetadataItemComponent } from "@/types/generated/strapi.schemas"; interface ItemProps { name: Dataset["name"]; - layers: { id: number; name: Layer["name"]; downloadLink?: Layer["download_link"] }[]; + layers: { + id: number; + name: Layer["name"]; + downloadLink?: Layer["download_link"]; + metadata?: MetadataItemComponent; + }[]; } const Item = ({ name, layers }: ItemProps) => { @@ -25,30 +34,55 @@ const Item = ({ name, layers }: ItemProps) => { -
- +
+ {!!layer.downloadLink && ( + + + + + + Download dataset + + + )} + {!!layer.metadata && ( + + + + + + + + + More info + + + + + + + )} + {(!!layer.downloadLink || !!layer.metadata) && ( +
+ )} id === layer.id) !== -1} diff --git a/client/src/components/panels/drought/index.tsx b/client/src/components/panels/drought/index.tsx index 478b586..2dc8c4b 100644 --- a/client/src/components/panels/drought/index.tsx +++ b/client/src/components/panels/drought/index.tsx @@ -6,11 +6,12 @@ import { Skeleton } from "@/components/ui/skeleton"; import useDatasetsBySubTopic from "@/hooks/use-datasets-by-sub-topic"; const DroughtPanel = () => { - const { data, isLoading } = useDatasetsBySubTopic("drought", "sub_topic.name:desc,name", [ - "name", - "params_config", - "download_link", - ]); + const { data, isLoading } = useDatasetsBySubTopic( + "drought", + "sub_topic.name:desc,name", + ["name", "params_config", "download_link"], + true, + ); return (
diff --git a/client/src/components/panels/flood/index.tsx b/client/src/components/panels/flood/index.tsx index 2fc9d36..597564d 100644 --- a/client/src/components/panels/flood/index.tsx +++ b/client/src/components/panels/flood/index.tsx @@ -6,11 +6,12 @@ import { Skeleton } from "@/components/ui/skeleton"; import useDatasetsBySubTopic from "@/hooks/use-datasets-by-sub-topic"; const FloodPanel = () => { - const { data, isLoading } = useDatasetsBySubTopic("flood", "sub_topic.name:desc,name", [ - "name", - "params_config", - "download_link", - ]); + const { data, isLoading } = useDatasetsBySubTopic( + "flood", + "sub_topic.name:desc,name", + ["name", "params_config", "download_link"], + true, + ); return (
diff --git a/client/src/components/panels/hydrometeorological/index.tsx b/client/src/components/panels/hydrometeorological/index.tsx index 163fd7a..b57d1c1 100644 --- a/client/src/components/panels/hydrometeorological/index.tsx +++ b/client/src/components/panels/hydrometeorological/index.tsx @@ -11,6 +11,7 @@ const HydrometeorologicalPanel = () => { "hydrometeorological", "sub_topic.name:desc,name", ["name", "params_config", "download_link"], + true, ); return ( diff --git a/client/src/components/ui/dialog.tsx b/client/src/components/ui/dialog.tsx index b12bdb8..753c255 100644 --- a/client/src/components/ui/dialog.tsx +++ b/client/src/components/ui/dialog.tsx @@ -39,12 +39,12 @@ const DialogContent = React.forwardRef< - {children} +
{children}