Skip to content

Commit

Permalink
contextual layers moved to categories menu
Browse files Browse the repository at this point in the history
  • Loading branch information
mluena committed Sep 14, 2023
1 parent accb877 commit e5292e1
Show file tree
Hide file tree
Showing 24 changed files with 401 additions and 157 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"husky": "6.0.0",
"prettier": "2.8.3",
"prettier-plugin-tailwindcss": "0.2.1",
"react-icons": "4.11.0",
"start-server-and-test": "1.12.1",
"svg-sprite-loader": "6.0.11",
"svgo": "3.0.2",
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions src/components/contextual/contextual-basemaps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import BASEMAPS from 'containers/datasets/contextual-layers/basemaps';
import Helper from 'containers/guide/helper';

import { WIDGET_CARD_WRAPPER_STYLE } from 'styles/widgets';

import CardBasemapContextual from './card';

const BasemapsContextualMapSettings = () => {
const HELPER_ID = 'mangrove_contextual_basemaps';
return (
<div className={`${WIDGET_CARD_WRAPPER_STYLE} relative flex flex-col`}>
<Helper
className={{
button: HELPER_ID ? '-bottom-3.5 -right-1.5 z-[20]' : 'hidden',
tooltip: 'w-fit-content',
}}
tooltipPosition={{ top: 120, left: -70 }}
message="Use this element to choose a different basemap. There is a choice between light, dark and satellite backgrounds"
>
{BASEMAPS.map((basemap) => (
<CardBasemapContextual key={basemap.id} {...basemap} />
))}
</Helper>
</div>
);
};

export default BasemapsContextualMapSettings;
17 changes: 17 additions & 0 deletions src/components/contextual/contextual-layers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { CONTEXTUAL_LAYERS_PLANET_SERIES_ATTRIBUTES } from 'containers/datasets/contextual-layers/constants';

import { WIDGET_CARD_WRAPPER_STYLE } from 'styles/widgets';

import CardBasemapContextual from './card';

const BasemapsContextualMapSettings = () => {
return (
<div className={`${WIDGET_CARD_WRAPPER_STYLE} relative flex flex-col`}>
{CONTEXTUAL_LAYERS_PLANET_SERIES_ATTRIBUTES.map((basemap) => (
<CardBasemapContextual key={basemap.id} {...basemap} />
))}
</div>
);
};

export default BasemapsContextualMapSettings;
File renamed without changes.
2 changes: 1 addition & 1 deletion src/containers/datasets/alerts/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useRecoilState } from 'recoil';
import { useMosaicsFromSeriesPlanetSatelliteBasemaps } from 'containers/datasets/contextual-layers/basemaps-planet/hooks';

import Chart from 'components/chart';
import DateSelect from 'components/contextual-basemaps/date-select';
import DateSelect from 'components/contextual/date-select';
import Icon from 'components/icon';
import Loading from 'components/loading';
import { Popover, PopoverContent, PopoverTrigger } from 'components/popover';
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { useMemo } from 'react';

import Image, { StaticImageData } from 'next/image';

import cn from 'lib/classnames';

import { basemapAtom } from 'store/map';
import { basemapContextualAtom } from 'store/map-settings';

import { useRecoilState } from 'recoil';

import { INFO } from 'containers/datasets';
import type { BasemapId } from 'containers/datasets/contextual-layers/basemaps';

import { Checkbox, CheckboxIndicator } from 'components/checkbox';
import Icon from 'components/icon';
import Info from 'components/widget-controls/info';
import { WIDGET_CARD_WRAPPER_STYLE } from 'styles/widgets';
import type { ContextualBasemapsId, MosaicId, WidgetSlugType } from 'types/widget';

import analyticThumb from 'images/thumbs/analytic.png';
import darkThumb from 'images/thumbs/[email protected]';
import lightThumb from 'images/thumbs/[email protected]';
import satelliteThumb from 'images/thumbs/[email protected]';
import visualThumb from 'images/thumbs/visual.png';

import CHECK_SVG from 'svgs/ui/check.svg?sprite';

import DateSelect from './date-select';

const THUMBS = {
light: lightThumb as StaticImageData,
dark: darkThumb as StaticImageData,
satellite: satelliteThumb as StaticImageData,
planet_medres_analytic_monthly: analyticThumb as StaticImageData,
planet_medres_visual_monthly: visualThumb as StaticImageData,
mangrove_tidal_flats: '/images/thumbs/contextual/tidal_flats.png',
mangrove_allen_coral_reef: '/images/thumbs/contextual/allen_coral_reef.png',
mangrove_global_tidal_wetland_change: '/images/thumbs/contextual/global_tidal_wetland_change.png',
};

type CardBasemapContextualProps = {
id: BasemapId | ContextualBasemapsId | WidgetSlugType;
mosaic_id?: MosaicId;
type: 'contextual-basemap' | 'basemap';
name?: string;
description?: string;
thumb?: string;
hasDropdown?: boolean;
};

const CardBasemapContextual = ({
id,
mosaic_id,
type,
name,
description,
hasDropdown,
}: CardBasemapContextualProps) => {
const [basemapStored, setBasemap] = useRecoilState(basemapAtom);
const [basemapContextualSelected, setBasemapContextual] = useRecoilState(basemapContextualAtom);

const isActive = useMemo(() => {
if (type === 'contextual-basemap') return basemapContextualSelected === id;
if (type === 'basemap') return basemapStored === id;
}, [basemapContextualSelected, basemapStored, type, id]);
const info = INFO[id];
const handleClick = () => {
if (type === 'contextual-basemap') {
const updatedContextualBasemap = basemapContextualSelected === id ? null : id;
setBasemapContextual(updatedContextualBasemap as ContextualBasemapsId);
}

if (type === 'basemap') {
setBasemap(id as BasemapId);
}
};
return (
<div className="flex flex-1 flex-col border-b-2 border-dashed border-b-brand-800 border-opacity-50 last-of-type:border-none">
<div className="flex w-full items-center justify-between">
{name && (
<h2 className="flex-1 cursor-pointer py-1 text-xs font-bold uppercase -tracking-tighter text-black/85">
{name}
</h2>
)}

{!!info && <Info id={id} content={false} />}
</div>

<div className={`${WIDGET_CARD_WRAPPER_STYLE} flex`}>
<button
type="button"
onClick={handleClick}
data-testid={id}
className={cn({
[`relative mr-10 h-24 w-24 shrink-0 rounded-xl border-4 border-transparent bg-cover bg-center`]:
true,
'border-brand-800': isActive,
})}
>
<Image src={THUMBS[id]} alt={name} fill className="rounded-lg shadow-soft" />

<Checkbox
className={cn({
'absolute bottom-2 right-2 h-6 w-6 rounded-full border-none': true,
})}
checked={isActive}
>
<CheckboxIndicator className="text-white">
<Icon
icon={CHECK_SVG}
className="h-full w-full fill-current text-white"
description="Checkmark"
/>
</CheckboxIndicator>
</Checkbox>
</button>

<div>
<h4>{name}</h4>
{description && <p>{description}</p>}
</div>
</div>
{isActive && hasDropdown && (
<div className="pb-4">
<DateSelect mosaic_id={mosaic_id} id={id} />
</div>
)}
</div>
);
};

export default CardBasemapContextual;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { useMemo, useEffect } from 'react';

import cn from 'lib/classnames';

import { basemapContextualVisualMonthlyDateAtom } from 'store/map-settings';
import { basemapContextualAnalyticMonthlyDateAtom } from 'store/map-settings';

import { orderBy } from 'lodash-es';
import { useRecoilState } from 'recoil';

import type { BasemapId } from 'containers/datasets/contextual-layers/basemaps';
import { useMosaicsFromSeriesPlanetSatelliteBasemaps } from 'containers/datasets/contextual-layers/basemaps-planet/hooks';

import Icon from 'components/icon';
import { Popover, PopoverContent, PopoverTrigger } from 'components/popover';
import type { ContextualBasemapsId, MosaicId, WidgetSlugType } from 'types/widget';

import ARROW_SVG from 'svgs/ui/arrow.svg?sprite';

const DateSelect = ({
id,
mosaic_id,
}: {
id: ContextualBasemapsId | BasemapId | WidgetSlugType;
mosaic_id: MosaicId;
}) => {
const { data: dates } = useMosaicsFromSeriesPlanetSatelliteBasemaps(mosaic_id);
const datesState =
id === 'planet_medres_visual_monthly'
? basemapContextualVisualMonthlyDateAtom
: basemapContextualAnalyticMonthlyDateAtom;
const [date, setDate] = useRecoilState(datesState);
const selectedDate = useMemo(() => date || dates?.[dates.length - 1], [date]);

useEffect(() => {
if (!date?.value) {
setDate(dates?.[dates?.length - 1]);
}
}, [dates]);

const orderedDates = useMemo(() => orderBy(dates, ['value'], ['desc']), [dates]);

return (
<Popover>
<PopoverTrigger asChild>
<div className="flex w-full cursor-pointer items-center justify-between rounded-3xl border-2 border-brand-800 border-opacity-50 py-1 px-4">
<p className="first-line:after">
Period: <span className="text-sm font-bold">{selectedDate?.label}</span>
</p>
<Icon
icon={ARROW_SVG}
className={cn({
'[data-state=closed]:rotate-180 relative inline-block h-1.5 w-2.5 font-bold': true,
})}
description="Arrow"
/>
</div>
</PopoverTrigger>

<PopoverContent>
<ul className="max-h-56 space-y-2">
{orderedDates?.map((d) => (
<li key={d.value} className="whitespace-nowrap last-of-type:pb-4">
<button
className="font-bold hover:text-brand-800"
type="button"
role="button"
onClick={() => setDate(d)}
aria-label={`Select date ${d.label}`}
>
{d.label}
</button>
</li>
))}
</ul>
</PopoverContent>
</Popover>
);
};

export default DateSelect;
Loading

0 comments on commit e5292e1

Please sign in to comment.