diff --git a/src/views/CountryOngoingActivities/index.tsx b/src/views/CountryOngoingActivities/index.tsx
index 58391ff96d..6888aaf752 100644
--- a/src/views/CountryOngoingActivities/index.tsx
+++ b/src/views/CountryOngoingActivities/index.tsx
@@ -30,6 +30,7 @@ export function Component() {
countryResponsePending,
],
);
+
return (
diff --git a/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/i18n.json b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/i18n.json
new file mode 100644
index 0000000000..d357be7ffd
--- /dev/null
+++ b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/i18n.json
@@ -0,0 +1,10 @@
+{
+ "namespace": "emergencyActivities",
+ "strings": {
+ "severityLow": "Less than 2",
+ "severityMedium": "2 to 4",
+ "severityHigh": "5 to 9",
+ "severitySevere": "10 or more",
+ "numberOfProjects": "Number of Projects"
+ }
+}
diff --git a/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/index.tsx b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/index.tsx
new file mode 100644
index 0000000000..06b66b5bcb
--- /dev/null
+++ b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/index.tsx
@@ -0,0 +1,195 @@
+import { useMemo } from 'react';
+import {
+ _cs,
+ isDefined,
+ isNotDefined,
+ mapToList,
+} from '@togglecorp/fujs';
+import {
+ useOutletContext,
+} from 'react-router-dom';
+import type { FillLayer } from 'mapbox-gl';
+import {
+ MapLayer,
+ MapBounds,
+} from '@togglecorp/re-map';
+import getBbox from '@turf/bbox';
+
+import LegendItem from '#components/LegendItem';
+import MapContainerWithDisclaimer from '#components/MapContainerWithDisclaimer';
+import useTranslation from '#hooks/useTranslation';
+import type { CountryOutletContext } from '#utils/outletContext';
+import {
+ DURATION_MAP_ZOOM,
+ DEFAULT_MAP_PADDING,
+ COLOR_LIGHT_GREY,
+} from '#utils/constants';
+import BaseMap from '#components/domain/BaseMap';
+
+import i18n from './i18n.json';
+import styles from './styles.module.css';
+
+const COLOR_SEVERITY_LOW = '#ccd2d9';
+const COLOR_SEVERITY_MEDIUM = '#99a5b4';
+const COLOR_SEVERITY_HIGH = '#67788d';
+const COLOR_SEVERITY_SEVERE = '#344b67';
+
+const SEVERITY_LOW = 2;
+const SEVERITY_MEDIUM = 5;
+const SEVERITY_HIGH = 10;
+
+interface Props {
+ className?: string;
+ sidebarContent?: React.ReactNode;
+ emergencyProjectCountByDistrict: Record;
+}
+
+function ResponseActivitiesMap(props: Props) {
+ const {
+ className,
+ sidebarContent,
+ emergencyProjectCountByDistrict,
+ } = props;
+
+ const strings = useTranslation(i18n);
+ const {
+ // countryId,
+ countryResponse,
+ } = useOutletContext();
+
+ const bounds = useMemo(
+ () => (countryResponse ? getBbox(countryResponse?.bbox) : undefined),
+ [countryResponse],
+ );
+
+ const emergencyProjectCountByDistrictList = mapToList(
+ emergencyProjectCountByDistrict,
+ (value, key) => ({ district: key, count: value }),
+ );
+
+ const districtIdList = useMemo(
+ () => emergencyProjectCountByDistrictList.map(
+ (list) => Number(list.district),
+ ),
+ [emergencyProjectCountByDistrictList],
+ );
+
+ const adminOneLabelSelectedLayerOptions = useMemo>(
+ () => ({
+ type: 'fill',
+ layout: { visibility: 'visible' },
+ filter: [
+ 'in',
+ 'district_id',
+ ...districtIdList,
+ ],
+ }),
+ [districtIdList],
+ );
+
+ const adminOneHighlightLayerOptions = useMemo>(
+ () => {
+ if (isNotDefined((emergencyProjectCountByDistrictList))
+ || emergencyProjectCountByDistrictList.length < 1) {
+ return {
+ type: 'fill',
+ layout: { visibility: 'visible' },
+ paint: {
+ 'fill-color': COLOR_LIGHT_GREY,
+ },
+ };
+ }
+
+ return {
+ type: 'fill',
+ layout: { visibility: 'visible' },
+ paint: {
+ 'fill-color': [
+ 'match',
+ ['get', 'district_id'],
+ ...(emergencyProjectCountByDistrictList).flatMap(({ district, count }) => [
+ Number(district),
+ [
+ 'interpolate',
+ ['exponential', 1],
+ ['number', count],
+ 0,
+ COLOR_SEVERITY_LOW,
+ SEVERITY_LOW,
+ COLOR_SEVERITY_MEDIUM,
+ SEVERITY_MEDIUM,
+ COLOR_SEVERITY_HIGH,
+ SEVERITY_HIGH,
+ COLOR_SEVERITY_SEVERE,
+ ],
+ ]),
+ COLOR_LIGHT_GREY,
+ ],
+ },
+ };
+ },
+ [emergencyProjectCountByDistrictList],
+ );
+
+ return (
+
+
+
+
+
+ >
+ )}
+ >
+
+
+ {strings.numberOfProjects}
+
+
+
+
+
+
+ )}
+ />
+ {isDefined(bounds) && (
+
+ )}
+
+
+ {sidebarContent && (
+
+ {sidebarContent}
+
+ )}
+
+ );
+}
+
+export default ResponseActivitiesMap;
diff --git a/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/styles.module.css b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/styles.module.css
new file mode 100644
index 0000000000..7168c3fa49
--- /dev/null
+++ b/src/views/CountryOngoingActivitiesThreeWActivities/ResponseActivitiesMap/styles.module.css
@@ -0,0 +1,53 @@
+.map {
+ display: flex;
+ gap: var(--go-ui-spacing-md);
+ height: 40rem;
+ overflow: auto;
+
+ .map-with-legend {
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+
+ .map-container {
+ flex-grow: 1;
+ }
+
+ .legend {
+ display: flex;
+ flex-wrap: wrap;
+ background-color: var(--go-ui-color-background);
+ gap: var(--go-ui-spacing-sm) var(--go-ui-spacing-md);
+ padding: var(--go-ui-spacing-md);
+
+ .label {
+ font-weight: var(--go-ui-font-weight-medium);
+ }
+ }
+ }
+
+ .sidebar {
+ flex-basis: calc(14vw + 12rem);
+ background-color: var(--go-ui-color-background);
+ overflow: auto;
+ }
+
+ @media screen and (max-width: 50rem) {
+ flex-direction: column;
+ height: initial;
+
+ .sidebar {
+ flex-basis: unset;
+ }
+
+ .map-with-legend {
+ height: min(40rem, 60vh);
+ }
+ }
+}
+
+.map-popup-content {
+ display: flex;
+ flex-direction: column;
+ gap: var(--go-ui-spacing-md);
+}
diff --git a/src/views/CountryOngoingActivitiesThreeWActivities/i18n.json b/src/views/CountryOngoingActivitiesThreeWActivities/i18n.json
index 6938c6316e..de69740195 100644
--- a/src/views/CountryOngoingActivitiesThreeWActivities/i18n.json
+++ b/src/views/CountryOngoingActivitiesThreeWActivities/i18n.json
@@ -2,10 +2,26 @@
"namespace": "countryOngoingActivitiesThreeWActivities",
"strings": {
"pageTitle": "Country Ongoing 3W Activities",
+
+ "addThreeWActivity": "Add 3W Activity",
+ "chartDescription": "The data represents the added projects and may not reflect all of the ongoing projects.",
"uniqueEruAndNationalSocietyCount": "Active National Societies / ERUs",
+ "failedToCreateExport": "Failed to generate export.",
"peopleInNeedReached": "Services Provided to People in Need",
"peopleReachedTooltip": "The figure displayed here is a sum of all individual services or interventions delivered as part of this emergency operation to people in need. Some people may have received more than one service or intervention.",
+ "activitySectors": "Activity Sectors",
"uniqueSectorCount": "Sectors",
- "totalActivities": "Total Activities"
+ "totalActivities": "Total Activities",
+ "activityStatus": "Activity Status",
+ "emergencyProjectNationalSociety": "National Society / ERU",
+ "emergencyProjectTitle": "Title",
+ "emergencyProjectStartDate": "Start Date",
+ "emergencyProjectCountry": "Country",
+ "emergencyProjectDistrict": "Province / Region",
+ "emergencyProjectStatus": "Status",
+ "emergencyProjectPeopleReached": "Services Provided to People in Need",
+ "responseActivities": "Response Activities",
+ "activitiesBySector": "Activities by Sector",
+ "dataNotAvailable": "No Activities"
}
}
diff --git a/src/views/CountryOngoingActivitiesThreeWActivities/index.tsx b/src/views/CountryOngoingActivitiesThreeWActivities/index.tsx
index 9cfb4ed9fb..21d70b2edb 100644
--- a/src/views/CountryOngoingActivitiesThreeWActivities/index.tsx
+++ b/src/views/CountryOngoingActivitiesThreeWActivities/index.tsx
@@ -1,12 +1,19 @@
import { useMemo } from 'react';
import { useOutletContext } from 'react-router-dom';
-import { compareNumber, isDefined, isNotDefined } from '@togglecorp/fujs';
+import {
+ compareNumber,
+ isDefined,
+ isNotDefined,
+ mapToList,
+} from '@togglecorp/fujs';
import PieChart from '#components/PieChart';
import BlockLoading from '#components/BlockLoading';
import Container from '#components/Container';
import KeyFigure from '#components/KeyFigure';
import InfoPopup from '#components/InfoPopup';
+import Pager from '#components/Pager';
+import Message from '#components/Message';
import useTranslation from '#hooks/useTranslation';
import useFilterState from '#hooks/useFilterState';
@@ -19,9 +26,11 @@ import {
stringTitleSelector,
} from '#utils/selectors';
-import { type FilterValue } from '#views/EmergencyActivities/Filters';
+import Filters, { type FilterValue } from '#views/EmergencyActivities/Filters';
import useEmergencyProjectStats from '#views/EmergencyActivities/useEmergencyProjectStats';
+import ActivityDetail from '#views/EmergencyActivities/ActivityDetail';
+import ResponseActivitiesMap from './ResponseActivitiesMap';
import i18n from './i18n.json';
import styles from './styles.module.css';
@@ -98,7 +107,14 @@ export function Component() {
const strings = useTranslation(i18n);
const {
+ rawFilter,
filter: filters,
+ setFilter: setFilters,
+ page: activePage,
+ setPage: setActivePage,
+ filtered: isFiltered,
+ limit,
+ offset,
} = useFilterState({
filter: {
reporting_ns: [],
@@ -130,8 +146,10 @@ export function Component() {
);
const {
+ emergencyProjectCountByDistrict,
emergencyProjectCountListBySector,
emergencyProjectCountListByStatus,
+ sectorGroupedEmergencyProjects,
peopleReached,
uniqueEruCount,
uniqueNsCount,
@@ -149,6 +167,25 @@ export function Component() {
getAggregatedValues(emergencyProjectCountListByStatus)
), [emergencyProjectCountListByStatus]);
+ const paginatedEmergencyProjectList = useMemo(() => (
+ filteredProjectList.slice(offset, offset + limit)
+ ), [filteredProjectList, offset, limit]);
+
+ const sectorGroupedEmergencyProjectList = useMemo(() => (
+ mapToList(
+ sectorGroupedEmergencyProjects,
+ (value, key) => ({
+ sector: key,
+ projects: value.projects,
+ sectorDetails: value.sectorDetails,
+ }),
+ )
+ ), [sectorGroupedEmergencyProjects]);
+
+ const noActivitiesBySector = (isNotDefined(sectorGroupedEmergencyProjectList)
+ || (isDefined(sectorGroupedEmergencyProjectList)
+ && (sectorGroupedEmergencyProjectList.length < 1)));
+
return (
@@ -210,6 +247,53 @@ export function Component() {
)}
+
+ )}
+ footerActions={(
+
+ )}
+ >
+
+ {noActivitiesBySector && (
+
+ )}
+ {/* FIXME: use List, add pending, filtered state */}
+ {sectorGroupedEmergencyProjectList.map((sectorGroupedProject) => (
+
+ ))}
+
+ )}
+ />
+
);
}