diff --git a/src/components/GlobalFooter/styles.module.css b/src/components/GlobalFooter/styles.module.css index a8bdacb8..1da81718 100644 --- a/src/components/GlobalFooter/styles.module.css +++ b/src/components/GlobalFooter/styles.module.css @@ -18,7 +18,6 @@ display: flex; flex-direction: column; gap: var(--go-ui-spacing-sm); - .footer-link { text-decoration: none; color: var(--go-ui-color-white); @@ -50,4 +49,4 @@ @media print { display: none; } -} \ No newline at end of file +} diff --git a/src/utils/map.ts b/src/utils/map.ts index 6d709788..4db792b9 100644 --- a/src/utils/map.ts +++ b/src/utils/map.ts @@ -17,7 +17,7 @@ export const defaultNavControlPosition: ControlPosition = 'top-right'; export const defaultMapOptions: Omit = { logoPosition: 'bottom-left' as const, - zoom: 1.5, + zoom: 1, minZoom: 1, maxZoom: 18, scrollZoom: false, @@ -26,7 +26,6 @@ export const defaultMapOptions: Omit>; - -export interface AlertProps { - data: CountryAlertType; - onExpandClick: (alertId: string | undefined) => void; -} - -function AlertDetail(props: AlertProps) { - const { - data, - onExpandClick, - } = props; - - return ( - - {data?.infos?.map((alert) => ( - -
- {alert?.event} -
-
- {alert?.category} -
- - ))} -
- ) -} - -export default AlertDetail; diff --git a/src/views/Home/AlertMap/AlertListItem/i18n.json b/src/views/Home/AlertMap/AlertListItem/i18n.json deleted file mode 100644 index d15e35b0..00000000 --- a/src/views/Home/AlertMap/AlertListItem/i18n.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "namespace": "alertDetails", - "strings": { - "alertViewDetails": "Alert List Details" - } -} \ No newline at end of file diff --git a/src/views/Home/AlertMap/AlertListItem/index.tsx b/src/views/Home/AlertMap/AlertListItem/index.tsx deleted file mode 100644 index 97dfacc8..00000000 --- a/src/views/Home/AlertMap/AlertListItem/index.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import { - useCallback, - useMemo, - useState, -} from 'react'; -import { isDefined } from '@togglecorp/fujs'; -import { gql, useQuery } from '@apollo/client'; -import { useTranslation } from '@ifrc-go/ui/hooks'; -import { - Button, - Container, - Pager, - TextOutput, -} from '@ifrc-go/ui'; - -import { - CountryAlertsListQuery, - CountryAlertsListQueryVariables, -} from '#generated/types'; - -import i18n from './i18n.json'; -import styles from './styles.module.css'; -import { ChevronLeftLineIcon } from '@ifrc-go/icons'; - -const COUNTRY_ALERTS_LIST = gql` - query CountryAlertsList( - $country: ID!, - $pagination: OffsetPaginationInput - ) { - public { - alerts( - filters: { - country: { - pk: $country - } - } - pagination: $pagination - ) { - items { - id - info { - event - category - alertId - } - } - } - } - } -`; - -const defaultMaxItemsPerPage = 10; - -type CountryAlertType = NonNullable>; - -const countryAlertKeySelector = (alert: CountryAlertType) => alert.id; - -export interface Props { - countryId: string; - handleAlertClick: (countryId: string | undefined) => void; - activeAlertId: string | undefined; -} - -function AlertDetail(props: Props) { - const { - countryId, - handleAlertClick, - activeAlertId, - } = props; - - const strings = useTranslation(i18n); - - const [activePage, setActivePage] = useState(1); - - const variables = useMemo(() => ({ - country: countryId, - pagination: { - offset: (activePage - 1) * defaultMaxItemsPerPage, - limit: defaultMaxItemsPerPage, - }, - }), [activePage]); - - const { - data: countryAlertsResponse, - loading: countryAlertsLoading, - } = useQuery( - COUNTRY_ALERTS_LIST, { - variables, - }); - - // const setActiveCountryIdSafe = useCallback( - // (countryId: string | undefined) => { - // setActiveCountryId(countryId); - // onActiveCountryChange(countryId); - // }, - // [onActiveCountryChange, setActiveCountryId], - // ); - - // const alertListRendererParams = useCallback( - // (_: string | number, alert: CountryAlertType): Props => ({ - // countryId: activeCountryId, - // onActiveCountryChange: setActiveCountryIdSafe, - // }), - // [activeCountryId, setActiveCountryIdSafe], - // ); - - console.log('alert', activeAlertId); - - return ( - - )} - contentViewType="vertical" - // actions={isDefined(countryId) && ( - // - // )} - > - {/* - {alert.event} - {alert.category} - */} - {countryAlertsResponse?.public?.alerts?.items?.map((alerts) => ( -
- -
- ))} - {/* {countryAlertsLoading && } - {isDefined(countryAlertsResponse) && ( - - )} */} -
- ); -} - -export default AlertDetail; diff --git a/src/views/Home/AlertMap/AlertListItem/styles.module.css b/src/views/Home/AlertMap/AlertListItem/styles.module.css deleted file mode 100644 index e7f2d20d..00000000 --- a/src/views/Home/AlertMap/AlertListItem/styles.module.css +++ /dev/null @@ -1,3 +0,0 @@ -.alerts { - display: flex; -} diff --git a/src/views/Home/AlertMap/CountryListItem/i18n.json b/src/views/Home/AlertMap/CountryListItem/i18n.json deleted file mode 100644 index 4f648d37..00000000 --- a/src/views/Home/AlertMap/CountryListItem/i18n.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "namespace": "countryDetails", - "strings": { - "countryViewDetails": "View Details" - } -} \ No newline at end of file diff --git a/src/views/Home/AlertMap/CountryListItem/index.tsx b/src/views/Home/AlertMap/CountryListItem/index.tsx deleted file mode 100644 index 75892cb6..00000000 --- a/src/views/Home/AlertMap/CountryListItem/index.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { ChevronRightLineIcon } from '@ifrc-go/icons'; -import { - Button, - Container, -} from '@ifrc-go/ui'; -import { useTranslation } from '@ifrc-go/ui/hooks'; - -import { CountryListQuery } from '#generated/types'; - -import i18n from './i18n.json'; -import styles from './styles.module.css'; - -type CountryType = NonNullable['allCountries']>[number]; - -export interface CountryProps { - data: CountryType; - onExpandClick: (alertId: string | undefined) => void; - bbox?: number[][] | undefined; -} - -function CountryListItem(props: CountryProps) { - const { - data, - onExpandClick, - bbox, - } = props; - - const strings = useTranslation(i18n); - - return ( - - - - )} - /> - ); -} - -export default CountryListItem; diff --git a/src/views/Home/AlertMap/CountryListItem/styles.module.css b/src/views/Home/AlertMap/CountryListItem/styles.module.css deleted file mode 100644 index 14ee0020..00000000 --- a/src/views/Home/AlertMap/CountryListItem/styles.module.css +++ /dev/null @@ -1,32 +0,0 @@ -.country-info { - .country-list-item { - gap: 0; - - .icon { - align-self: flex-end; - font-size: var(--go-ui-height-icon-multiplier); - }:hover { - .icon { - animation: wiggle var(--go-ui-duration-transition-slow) ease-in-out; - } - } - } - - @keyframes wiggle { - 0% { - transform: translateX(0); - } - - 25% { - transform: translateX(-0.1rem); - } - - 50% { - transform: translateX(0.1rem); - } - - 100% { - transform: translateX(0); - } - } -} \ No newline at end of file diff --git a/src/views/Home/AlertMap/Filters/i18n.json b/src/views/Home/AlertMap/Filters/i18n.json deleted file mode 100644 index f9dadf6b..00000000 --- a/src/views/Home/AlertMap/Filters/i18n.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "namespace": "alertFilters", - "strings": { - "alertCountries": "All countries", - "alertUrgency": "Select Urgency type", - "alertSeverity": "Select Severity type", - "alertCertainty": "Select Certainty type" - } -} diff --git a/src/views/Home/AlertMap/Filters/index.tsx b/src/views/Home/AlertMap/Filters/index.tsx deleted file mode 100644 index 1df4e838..00000000 --- a/src/views/Home/AlertMap/Filters/index.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { useCallback } from 'react'; -import { MultiSelectInput } from '@ifrc-go/ui'; -import { useTranslation } from '@ifrc-go/ui/hooks'; -import { stringNameSelector } from '@ifrc-go/ui/utils'; -import { EntriesAsList } from '@togglecorp/toggle-form'; - -import { - AlertEnumsQuery, - CountryListQuery, -} from '#generated/types'; - -import i18n from './i18n.json'; -import styles from './styles.module.css'; - -type CountryType = NonNullable['countries']>['items']>[number]; - -interface AlertFilters { - key: string; - label: string; -} - -const countryKeySelector = (country: CountryType) => country?.id; - -const keySelector = (alert: AlertFilters) => alert?.key; -const labelSelector = (alert: AlertFilters) => alert?.label; - -export interface FilterValue { - countries: string[]; - regions: string[]; - urgencyList: string[]; - severityList: string[]; - certaintyList: string[]; -} - -interface Props { - value: FilterValue; - onChange: React.Dispatch>; - countries?: NonNullable; - urgencyList?: NonNullable; - severityList?: NonNullable; - certaintyList?: NonNullable; -} - -function Filters(props: Props) { - const { - value, - onChange, - countries, - urgencyList, - severityList, - certaintyList, - } = props; - - const strings = useTranslation(i18n); - - const handleChange = useCallback( - (...args: EntriesAsList) => { - const [val, key] = args; - onChange((prevValue): FilterValue => ({ - ...prevValue, - [key]: val, - })); - }, - [onChange], - ); - - return ( -
- - - - -
- ); -} - -export default Filters; diff --git a/src/views/Home/AlertMap/Filters/styles.module.css b/src/views/Home/AlertMap/Filters/styles.module.css deleted file mode 100644 index 07a3bfcd..00000000 --- a/src/views/Home/AlertMap/Filters/styles.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.filters { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); - grid-gap: var(--go-ui-spacing-md); -} diff --git a/src/views/Home/AlertMap/RegionListItem/i18n.json b/src/views/Home/AlertMap/RegionListItem/i18n.json deleted file mode 100644 index fd58cb69..00000000 --- a/src/views/Home/AlertMap/RegionListItem/i18n.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "namespace": "ongoingAlertRegion", - "strings": { - "regionList": "Region List" - } -} diff --git a/src/views/Home/AlertMap/RegionListItem/index.tsx b/src/views/Home/AlertMap/RegionListItem/index.tsx deleted file mode 100644 index 879fe4f9..00000000 --- a/src/views/Home/AlertMap/RegionListItem/index.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { useMemo } from 'react'; -import { - gql, - useQuery, -} from '@apollo/client'; -import { - BlockLoading, - Container, -} from '@ifrc-go/ui'; -import { useTranslation } from '@ifrc-go/ui/hooks'; - -import { - Admin1ListQuery, - Admin1ListQueryVariables, -} from '#generated/types'; - -import i18n from './i18n.json'; -import styles from './styles.module.css'; - -const ADMIN1_LIST = gql` -query Admin1List { - public { - admin1s { - items { - countryId - name - } - } - } - } -`; - -export interface RegionProps { - countryId: string | undefined; -} - -function RegionListItem(props: RegionProps) { - const { - countryId, - } = props; - - const strings = useTranslation(i18n); - - const { - data: admin1ListResponse, - loading: admin1ListLoading, - } = useQuery( - ADMIN1_LIST, - ); - - const filteredAdmins = useMemo(() => { - if (!countryId || !admin1ListResponse?.public?.admin1s?.items) return []; - - return admin1ListResponse.public.admin1s.items - .filter((item) => countryId.includes(item.countryId)) - .map((item) => item.name); - }, [countryId, admin1ListResponse]); - - return ( - - {admin1ListLoading && } -
- {filteredAdmins.map((name) => ( -
- {name} -
- ))} -
-
- ); -} - -export default RegionListItem; diff --git a/src/views/Home/AlertMap/RegionListItem/styles.module.css b/src/views/Home/AlertMap/RegionListItem/styles.module.css deleted file mode 100644 index 1fbd139c..00000000 --- a/src/views/Home/AlertMap/RegionListItem/styles.module.css +++ /dev/null @@ -1,13 +0,0 @@ -.alerts { - .content { - display: flex; - flex-direction: column; - gap: var(--go-ui-spacing-lg); - - .alert-details { - display: flex; - flex-direction: column; - gap: var(--go-ui-spacing-2xs); - } - } -} diff --git a/src/views/Home/AlertMap/index.tsx b/src/views/Home/AlertMap/index.tsx deleted file mode 100644 index 01b9e5ad..00000000 --- a/src/views/Home/AlertMap/index.tsx +++ /dev/null @@ -1,384 +0,0 @@ -import { - useCallback, - useMemo, - useState, -} from 'react'; -import { Link } from 'react-router-dom'; -import { - gql, - useQuery, -} from '@apollo/client'; -import { ChevronLeftLineIcon } from '@ifrc-go/icons'; -import { - Button, - Container, - List, - Tab, - TabList, - TabPanel, - Tabs, -} from '@ifrc-go/ui'; -import { useTranslation } from '@ifrc-go/ui/hooks'; -import { - _cs, - isDefined, - isNotDefined, - unique, -} from '@togglecorp/fujs'; -import { - MapBounds, - MapContainer, - MapLayer, -} from '@togglecorp/re-map'; -import type { - FillLayer, - LngLatBoundsLike, -} from 'mapbox-gl'; - -import BaseMap from '#components/domain/BaseMap'; -import MapPopup from '#components/MapPopup'; -import { - AlertEnumsQuery, - AlertEnumsQueryVariables, - CountryListQuery, - CountryListQueryVariables, -} from '#generated/types'; -import useDebouncedValue from '#hooks/useDebouncedValue'; -import useInputState from '#hooks/useInputState'; -import { - COLOR_LIGHT_GREY, - COLOR_PRIMARY_RED, - DEFAULT_MAP_PADDING, - DURATION_MAP_ZOOM, -} from '#utils/constants'; - -import CountryListItem, { CountryProps } from './CountryListItem'; -import Filters, { FilterValue } from './Filters'; -import RegionListItem from './RegionListItem'; -import AlertListItem from './AlertListItem'; - -import i18n from './i18n.json'; -import styles from './styles.module.css'; - -const COUNTRIES_LIST = gql` -query CountryList { - public { - allCountries { - alertCount - name - id - iso3 - } - } -}`; - -const ALERT_ENUMS = gql` -query AlertEnums { - enums { - AlertInfoCertainty { - key - label - } - AlertInfoUrgency { - label - key - } - AlertInfoSeverity { - key - label - } - } -}`; - -const defaultFilterValue: FilterValue = { - countries: [], - regions: [], - urgencyList: [], - severityList: [], - certaintyList: [], -}; - -type CountryType = NonNullable['allCountries']>[number]; - -export type AlertPointFeature = GeoJSON.Feature; - -type AlertPointProperties = { - id: string | number, -} - -type Props = { - className?: string; - bbox: LngLatBoundsLike | undefined; - onActiveCountryChange: (countryId: string | undefined) => void; - activeCountryId: string | undefined; -} - -const countryKeySelector = (country: CountryType) => country?.id; - -interface ClickedPoint { - feature: GeoJSON.Feature; - lngLat: mapboxgl.LngLatLike; -} - -function OngoingAlertMap(props: Props) { - const { - className, - bbox, - activeCountryId, - onActiveCountryChange, - } = props; - - const strings = useTranslation(i18n); - const [filters, setFilters] = useInputState(defaultFilterValue); - const [activeAlertId, setActiveAlertId] = useState(); - const [activeLearnOption, setActiveLearnOption] = useState('admin-1'); - - const { - data: countryResponse, - loading: countryLoading, - } = useQuery( - COUNTRIES_LIST, - ); - - const { - data: alertEnumsResponse, - } = useQuery( - ALERT_ENUMS, - ); - - const filteredCountries = countryResponse?.public.allCountries.filter( - country => country.alertCount > 0 - ); - - const [ - clickedPointProperties, - setClickedPointProperties, - ] = useState(); - - const handlePointClose = useCallback( - () => { - setClickedPointProperties(undefined); - }, - [setClickedPointProperties], - ); - - const setActiveCountryIdSafe = useCallback( - (countryId: string | undefined) => { - onActiveCountryChange(countryId); - }, - [onActiveCountryChange], - ); - - const countryListRendererParams = useCallback( - (_: string | number, country: CountryType): CountryProps => ({ - data: country, - onExpandClick: setActiveCountryIdSafe, - }), - [setActiveCountryIdSafe], - ); - - const handleCountryClick = useCallback(( - feature: mapboxgl.MapboxGeoJSONFeature, - lngLat: mapboxgl.LngLatLike, - ) => { - setClickedPointProperties({ - feature: feature as unknown as ClickedPoint['feature'], - lngLat, - }); - return false; - }, []); - - const [bounds, setBounds] = useState(bbox); - const boundsSafe = useDebouncedValue(bounds); - - const countryFillOptions = useMemo>(() => { - if (isNotDefined(filteredCountries)) { - return { - type: 'fill', - layout: { - visibility: 'visible', - }, - }; - } - const uniqueCountries = unique( - filteredCountries, - (item) => item.iso3, - ); - - return { - type: 'fill', - paint: { - 'fill-opacity': 1, - 'fill-color': [ - 'match', - ['get', 'iso3'], - ...uniqueCountries.flatMap( - (country) => [ - country.iso3.toUpperCase(), - COLOR_PRIMARY_RED, - ], - ), - COLOR_LIGHT_GREY, - ], - }, - layout: { - visibility: 'visible', - }, - }; - }, [countryResponse]); - - const handleAlertClick = useCallback( - (id: string | undefined) => { - setActiveAlertId(id); - onActiveCountryChange(undefined); - }, [onActiveCountryChange], - ); - - return ( - - {strings.mapViewAllSources} - - )} - filters={( - - )} - > - - )} - > - - {clickedPointProperties?.lngLat && ( - - Map - - )} - {boundsSafe && ( - - )} - - - )} - > - {strings.backToAlertsLabel} - - )} - > - {isDefined(countryResponse) && isNotDefined(activeCountryId) && isNotDefined(activeAlertId) && ( - - )} - - {isDefined(activeCountryId) && ( - - - - Admin-1 - - - Alerts - - - -
- - {isDefined(activeCountryId) && ( - - )} - - - {isDefined(activeCountryId) && ( - - )} - - - )} - - - ); -} - -export default OngoingAlertMap; diff --git a/src/views/Home/AlertMap/styles.module.css b/src/views/Home/AlertMap/styles.module.css deleted file mode 100644 index 102837bc..00000000 --- a/src/views/Home/AlertMap/styles.module.css +++ /dev/null @@ -1,66 +0,0 @@ -.alert-map { - display: flex; - flex-direction: column; - - .sources { - color: var(--go-ui-color-text); - font-weight: var(--go-ui-font-weight-medium); - } - - .sources:hover { - color: var(--go-ui-color-primary-red); - } - - .countries { - display: flex; - flex-basis: calc(14vw + 16rem); - flex-direction: column; - gap: var(--go-ui-spacing-md); - background-color: var(--go-ui-color-background); - - .content { - overflow: auto; - } - } - - .main-content { - display: flex; - gap: var(--go-ui-spacing-md); - height: 40rem; - - .map-container { - flex-grow: 1; - } - - .country-list { - display: flex; - flex-basis: calc(14vw + 16rem); - flex-direction: column; - gap: var(--go-ui-spacing-md); - background-color: var(--go-ui-color-background); - - .content { - overflow: auto; - - .country { - .name { - font-size: var(--go-ui-font-size-sm); - } - } - } - } - - @media screen and (max-width: 50rem) { - flex-direction: column; - height: initial; - - .map-container { - height: min(40rem, 60vh); - } - - .country-list { - flex-basis: unset; - } - } - } -} \ No newline at end of file diff --git a/src/views/Home/Alerts/AlertsAside/CountryListItem/index.tsx b/src/views/Home/Alerts/AlertsAside/CountryListItem/index.tsx new file mode 100644 index 00000000..235157e2 --- /dev/null +++ b/src/views/Home/Alerts/AlertsAside/CountryListItem/index.tsx @@ -0,0 +1,45 @@ +import { + Button, + Container, +} from '@ifrc-go/ui'; + +import { CountryListQuery } from '#generated/types'; + +import styles from './styles.module.css'; + +type CountryType = NonNullable['allCountries']>[number]; + +export interface CountryProps { + data: CountryType; + onCountryClick: (id: string) => void; +} + +function CountryListItem(props: CountryProps) { + const { + data, + onCountryClick, + } = props; + + return ( + + {data.name} + + )} + headingDescription={`(${data.filteredAlertCount})`} + headingLevel={5} + key={data.id} + /> + ); +} + +export default CountryListItem; diff --git a/src/views/Home/Alerts/AlertsAside/CountryListItem/styles.module.css b/src/views/Home/Alerts/AlertsAside/CountryListItem/styles.module.css new file mode 100644 index 00000000..20396ba9 --- /dev/null +++ b/src/views/Home/Alerts/AlertsAside/CountryListItem/styles.module.css @@ -0,0 +1,12 @@ +.country-list-item { + display: flex; + .header { + display: flex; + .heading-container { + display: flex; + .heading { + flex-grow: 0; + } + } + } +} diff --git a/src/views/Home/Alerts/AlertsAside/i18n.json b/src/views/Home/Alerts/AlertsAside/i18n.json new file mode 100644 index 00000000..4460965d --- /dev/null +++ b/src/views/Home/Alerts/AlertsAside/i18n.json @@ -0,0 +1,6 @@ +{ + "namespace": "alertsAside", + "strings": { + "heading": "Countries" + } +} diff --git a/src/views/Home/Alerts/AlertsAside/index.tsx b/src/views/Home/Alerts/AlertsAside/index.tsx new file mode 100644 index 00000000..317b0ab6 --- /dev/null +++ b/src/views/Home/Alerts/AlertsAside/index.tsx @@ -0,0 +1,72 @@ +import { useCallback } from 'react'; +import { + Container, + List, +} from '@ifrc-go/ui'; +import { useTranslation } from '@ifrc-go/ui/hooks'; +import { _cs } from '@togglecorp/fujs'; + +import { CountryListQuery } from '#generated/types'; +import { stringIdSelector } from '#utils/selectors'; + +import CountryListItem from './CountryListItem'; + +import i18n from './i18n.json'; +import styles from './styles.module.css'; + +type CountryType = NonNullable['allCountries']>[number]; + +interface Props { + className?: string; + countriesWithAlert?: CountryType[]; + alertsPending: boolean; + alertsFetchError: boolean; + alertsFiltered: boolean; +} + +function AlertsAside(props: Props) { + const { + className, + countriesWithAlert, + alertsPending, + alertsFetchError, + alertsFiltered, + } = props; + + const strings = useTranslation(i18n); + + const handleCountryClick = useCallback((id: string) => { + console.warn('id', id); + }, []); + + const rendererParams = useCallback( + (_: string, value: CountryType) => ({ + data: value, + onCountryClick: handleCountryClick, + }), + [handleCountryClick], + ); + + return ( + + + + ); +} + +export default AlertsAside; diff --git a/src/views/Home/Alerts/AlertsAside/styles.module.css b/src/views/Home/Alerts/AlertsAside/styles.module.css new file mode 100644 index 00000000..4c8637dd --- /dev/null +++ b/src/views/Home/Alerts/AlertsAside/styles.module.css @@ -0,0 +1,13 @@ +.alert-aside { + display: flex; + + .main-content { + display: flex; + + .country-list { + display: flex; + flex-direction: column; + gap: var(--go-ui-spacing-xs); + } + } +} diff --git a/src/views/Home/Alerts/AlertsMap/index.tsx b/src/views/Home/Alerts/AlertsMap/index.tsx new file mode 100644 index 00000000..5064fb61 --- /dev/null +++ b/src/views/Home/Alerts/AlertsMap/index.tsx @@ -0,0 +1,88 @@ +import { useMemo } from 'react'; +import { + _cs, + isNotDefined, + unique, +} from '@togglecorp/fujs'; +import { + MapContainer, + MapLayer, +} from '@togglecorp/re-map'; +import type { FillLayer } from 'mapbox-gl'; + +import BaseMap from '#components/domain/BaseMap'; +import { CountryListQuery } from '#generated/types'; +import { + COLOR_LIGHT_GREY, + COLOR_PRIMARY_RED, +} from '#utils/constants'; + +import styles from './styles.module.css'; + +type CountryType = NonNullable['allCountries']>[number]; + +interface Props { + className?: string; + countriesWithAlert?: CountryType[]; +} + +function AlertsMap(props: Props) { + const { countriesWithAlert, className } = props; + + const countryFillOptions = useMemo>(() => { + if (isNotDefined(countriesWithAlert)) { + return { + type: 'fill', + layout: { + visibility: 'visible', + }, + }; + } + + const uniqueCountries = unique( + countriesWithAlert, + (item) => item.iso3, + ); + + return { + type: 'fill', + paint: { + 'fill-opacity': 1, + 'fill-color': [ + 'match', + ['get', 'iso3'], + ...uniqueCountries.flatMap( + (country) => [ + country.iso3.toUpperCase(), + COLOR_PRIMARY_RED, + ], + ), + COLOR_LIGHT_GREY, + ], + }, + layout: { + visibility: 'visible', + }, + }; + }, [countriesWithAlert]); + + return ( +
+ + )} + > + + +
+ ); +} + +export default AlertsMap; diff --git a/src/views/Home/Alerts/AlertsMap/styles.module.css b/src/views/Home/Alerts/AlertsMap/styles.module.css new file mode 100644 index 00000000..36d04f43 --- /dev/null +++ b/src/views/Home/Alerts/AlertsMap/styles.module.css @@ -0,0 +1,8 @@ +.alerts-map { + display: flex; + + .map-container { + flex-grow: 1; + } +} + diff --git a/src/views/Home/AlertMap/i18n.json b/src/views/Home/Alerts/i18n.json similarity index 87% rename from src/views/Home/AlertMap/i18n.json rename to src/views/Home/Alerts/i18n.json index 7a7cf09a..7627d8cf 100644 --- a/src/views/Home/AlertMap/i18n.json +++ b/src/views/Home/Alerts/i18n.json @@ -1,5 +1,5 @@ { - "namespace": "ongoingAlertMap", + "namespace": "alerts", "strings": { "mapHeading": "All Ongoing Alerts", "mapViewAllSources": "View All Sources", @@ -7,4 +7,4 @@ "backToAlertsLabel": "Back to Alerts", "alertViewDetails": "View Details" } -} \ No newline at end of file +} diff --git a/src/views/Home/Alerts/index.tsx b/src/views/Home/Alerts/index.tsx new file mode 100644 index 00000000..019d582b --- /dev/null +++ b/src/views/Home/Alerts/index.tsx @@ -0,0 +1,91 @@ +import { Link } from 'react-router-dom'; +import { + gql, + useQuery, +} from '@apollo/client'; +import { Container } from '@ifrc-go/ui'; +import { useTranslation } from '@ifrc-go/ui/hooks'; +import { _cs } from '@togglecorp/fujs'; + +import { + CountryListQuery, + CountryListQueryVariables, +} from '#generated/types'; + +import AlertsAside from './AlertsAside'; +import AlertsMap from './AlertsMap'; + +import i18n from './i18n.json'; +import styles from './styles.module.css'; + +const COUNTRIES_LIST = gql` +query CountryList { + public { + allCountries(alertFilters: {}) { + name + id + iso3 + filteredAlertCount + } + } +} +`; + +export type AlertPointFeature = GeoJSON.Feature; + +type AlertPointProperties = { + id: string | number, +} + +interface Props { + className?: string; +} + +function Alerts(props: Props) { + const { className } = props; + + const strings = useTranslation(i18n); + + const { + data: countryResponse, + loading: countryLoading, + } = useQuery( + COUNTRIES_LIST, + ); + + const countriesWithAlert = countryResponse?.public.allCountries.filter( + (country) => (country?.filteredAlertCount ?? 0) > 0, + ); + + return ( + + {strings.mapViewAllSources} + + )} + > + + + + ); +} + +export default Alerts; diff --git a/src/views/Home/Alerts/styles.module.css b/src/views/Home/Alerts/styles.module.css new file mode 100644 index 00000000..b4bb4b1d --- /dev/null +++ b/src/views/Home/Alerts/styles.module.css @@ -0,0 +1,34 @@ +.alert-map { + display: flex; + flex-direction: column; + + .main-content { + display: flex; + flex-grow: 1; + height: 45rem; + gap: var(--go-ui-spacing-md); + + .alerts-map { + flex-grow: 1; + } + + .alerts-aside { + display: flex; + flex-basis: 30%; + overflow: auto; + } + + @media screen and (max-width: 50rem) { + flex-direction: column; + height: initial; + + .alerts-map { + height: min(40rem, 60vh); + } + + .alerts-aside { + flex-basis: unset; + } + } + } +} diff --git a/src/views/Home/i18n.json b/src/views/Home/i18n.json index 85373a1c..18960eb5 100644 --- a/src/views/Home/i18n.json +++ b/src/views/Home/i18n.json @@ -5,4 +5,4 @@ "homeHeading": "IFRC Alert Hub", "homeDescription": "IFRC Alert Hub provides global emergency alerts, empowering communities to protect lives and livelihoods." } -} \ No newline at end of file +} diff --git a/src/views/Home/index.tsx b/src/views/Home/index.tsx index b8526d48..97508ba3 100644 --- a/src/views/Home/index.tsx +++ b/src/views/Home/index.tsx @@ -1,9 +1,8 @@ -import { useState } from 'react'; import { useTranslation } from '@ifrc-go/ui/hooks'; import Page from '#components/Page'; -import OngoingAlertMap from './AlertMap'; +import Alerts from './Alerts'; import i18n from './i18n.json'; import styles from './styles.module.css'; @@ -12,8 +11,6 @@ import styles from './styles.module.css'; export function Component() { const strings = useTranslation(i18n); - const [activeCountryId, setActiveCountryId] = useState(); - return ( - + ); }