Skip to content

Commit 0dffd52

Browse files
shreeyash07frozenhelium
authored andcommitted
Add tab for map view and list view for Ns local units
- Add Table component in local units - Add common files in NS local units
1 parent ef63617 commit 0dffd52

File tree

14 files changed

+533
-269
lines changed

14 files changed

+533
-269
lines changed

.changeset/chilly-mails-type.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"go-web-app": minor
3+
---
4+
5+
Add table view in NS local units
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"namespace": "nationalSocietyLocalUnits",
3+
"strings": {
4+
"localUnitDetailAddress": "Address",
5+
"localUnitDetailPhoneNumber": "Phone Number",
6+
"localUnitDetailLastUpdate": "Last Updated",
7+
"localUnitDetailFocalPerson": "Focal Person",
8+
"localUnitDetailEmail": "Email"
9+
}
10+
}

app/src/views/CountryNsOverviewContextAndStructure/NationalSocietyLocalUnitsMap/index.tsx renamed to app/src/views/CountryNsOverviewContextAndStructure/NationalSocietyLocalUnits/LocalUnitsMap/index.tsx

Lines changed: 64 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,14 @@ import { useOutletContext } from 'react-router-dom';
77
import {
88
LocationIcon,
99
MailIcon,
10-
SearchLineIcon,
1110
} from '@ifrc-go/icons';
1211
import {
13-
Button,
1412
Container,
1513
List,
16-
SelectInput,
17-
TextInput,
1814
TextOutput,
1915
} from '@ifrc-go/ui';
2016
import { useTranslation } from '@ifrc-go/ui/hooks';
2117
import {
22-
stringLabelSelector,
23-
stringNameSelector,
24-
} from '@ifrc-go/ui/utils';
25-
import {
26-
_cs,
2718
isDefined,
2819
isNotDefined,
2920
isTruthyString,
@@ -44,22 +35,18 @@ import BaseMap from '#components/domain/BaseMap';
4435
import Link, { type Props as LinkProps } from '#components/Link';
4536
import MapContainerWithDisclaimer from '#components/MapContainerWithDisclaimer';
4637
import MapPopup from '#components/MapPopup';
47-
import { adminUrl } from '#config';
48-
import { type components } from '#generated/types';
49-
import useAuth from '#hooks/domain/useAuth';
50-
import useFilterState from '#hooks/useFilterState';
5138
import {
5239
COLOR_RED,
5340
DEFAULT_MAP_PADDING,
5441
DURATION_MAP_ZOOM,
5542
} from '#utils/constants';
5643
import { type CountryOutletContext } from '#utils/outletContext';
57-
import { resolveUrl } from '#utils/resolveUrl';
58-
import { useRequest } from '#utils/restRequest';
44+
import { type GoApiResponse } from '#utils/restRequest';
5945

6046
import i18n from './i18n.json';
6147
import styles from './styles.module.css';
6248

49+
type GetLocalUnitResponseType = GoApiResponse<'/api/v2/local-units/'>;
6350
const basePointPaint: CirclePaint = {
6451
'circle-radius': 5,
6552
'circle-color': COLOR_RED,
@@ -73,38 +60,29 @@ const basePointLayerOptions: Omit<CircleLayer, 'id'> = {
7360
type: 'circle',
7461
paint: basePointPaint,
7562
};
63+
7664
const sourceOption: mapboxgl.GeoJSONSourceRaw = {
7765
type: 'geojson',
7866
};
7967

80-
type LocalUnitType = components<'read'>['schemas']['LocalUnitType'];
81-
82-
const localUnitCodeSelector = (localUnit: LocalUnitType) => localUnit.code;
83-
84-
interface Validation {
85-
label: string;
86-
}
87-
8868
interface ClickedPoint {
8969
id: string;
9070
lngLat: mapboxgl.LngLatLike;
9171
}
9272

93-
interface Props {
94-
className?: string;
95-
}
96-
9773
function emailKeySelector(email: string) {
9874
return email;
9975
}
10076

101-
function NationalSocietyLocalUnitsMap(props: Props) {
102-
const {
103-
className,
104-
} = props;
77+
interface Props {
78+
localUnitListResponse?: GetLocalUnitResponseType;
79+
}
80+
81+
function LocalUnitsMap(props: Props) {
82+
const { localUnitListResponse } = props;
83+
const { countryResponse } = useOutletContext<CountryOutletContext>();
10584

10685
const strings = useTranslation(i18n);
107-
const { countryId, countryResponse } = useOutletContext<CountryOutletContext>();
10886
const [
10987
clickedPointProperties,
11088
setClickedPointProperties,
@@ -114,45 +92,6 @@ function NationalSocietyLocalUnitsMap(props: Props) {
11492
countryResponse ? getBbox(countryResponse.bbox) : undefined
11593
), [countryResponse]);
11694

117-
const { isAuthenticated } = useAuth();
118-
119-
const {
120-
rawFilter,
121-
filter,
122-
filtered,
123-
setFilter,
124-
setFilterField,
125-
} = useFilterState<{
126-
type?: number;
127-
search?: string;
128-
isValidated?: string;
129-
}>({
130-
filter: {},
131-
pageSize: 9999,
132-
});
133-
134-
const {
135-
response: localUnitListResponse,
136-
} = useRequest({
137-
skip: isNotDefined(countryResponse?.iso3),
138-
url: '/api/v2/local-units/',
139-
query: {
140-
limit: 9999,
141-
type__code: filter.type,
142-
validated: isDefined(filter.isValidated)
143-
? filter.isValidated === strings.validated : undefined,
144-
search: filter.search,
145-
country__iso3: isDefined(countryResponse?.iso3) ? countryResponse?.iso3 : undefined,
146-
},
147-
});
148-
149-
const {
150-
response: localUnitsOptionsResponse,
151-
pending: localUnitsOptionsResponsePending,
152-
} = useRequest({
153-
url: '/api/v2/local-units/options/',
154-
});
155-
15695
const localUnitsGeoJson = useMemo((): GeoJSON.FeatureCollection<GeoJSON.Geometry> => ({
15796
type: 'FeatureCollection' as const,
15897
features: isDefined(localUnitListResponse)
@@ -203,15 +142,6 @@ function NationalSocietyLocalUnitsMap(props: Props) {
203142
[clickedPointProperties, localUnitListResponse?.results],
204143
);
205144

206-
const validationOptions: Validation[] = useMemo(() => ([
207-
{
208-
label: strings.validated,
209-
},
210-
{
211-
label: strings.notValidated,
212-
},
213-
]), [strings.validated, strings.notValidated]);
214-
215145
const handlePointClick = useCallback(
216146
(feature: mapboxgl.MapboxGeoJSONFeature, lngLat: mapboxgl.LngLat) => {
217147
setClickedPointProperties({
@@ -230,13 +160,6 @@ function NationalSocietyLocalUnitsMap(props: Props) {
230160
[setClickedPointProperties],
231161
);
232162

233-
const handleClearFilter = useCallback(
234-
() => {
235-
setFilter({});
236-
},
237-
[setFilter],
238-
);
239-
240163
const emailRendererParams = useCallback(
241164
(_: string, email: string): LinkProps => ({
242165
className: styles.email,
@@ -249,65 +172,7 @@ function NationalSocietyLocalUnitsMap(props: Props) {
249172
);
250173

251174
return (
252-
<Container
253-
className={_cs(styles.nationalSocietyLocalUnitsMap, className)}
254-
heading={strings.localUnitsMapTitle}
255-
childrenContainerClassName={styles.content}
256-
withGridViewInFilter
257-
withHeaderBorder
258-
actions={isAuthenticated && (
259-
<Link
260-
external
261-
href={resolveUrl(adminUrl, `local_units/localunit/?country=${countryId}`)}
262-
variant="secondary"
263-
>
264-
{strings.editLocalUnitLink}
265-
</Link>
266-
)}
267-
filters={(
268-
<>
269-
<SelectInput
270-
placeholder={strings.localUnitsFilterTypePlaceholder}
271-
label={strings.localUnitsFilterTypeLabel}
272-
name="type"
273-
value={rawFilter.type}
274-
onChange={setFilterField}
275-
keySelector={localUnitCodeSelector}
276-
labelSelector={stringNameSelector}
277-
disabled={localUnitsOptionsResponsePending}
278-
options={localUnitsOptionsResponse?.type}
279-
/>
280-
<SelectInput
281-
placeholder={strings.localUnitsFilterValidatedPlaceholder}
282-
label={strings.localUnitsFilterValidatedLabel}
283-
name="isValidated"
284-
value={rawFilter.isValidated}
285-
onChange={setFilterField}
286-
keySelector={stringLabelSelector}
287-
labelSelector={stringLabelSelector}
288-
options={validationOptions}
289-
/>
290-
<TextInput
291-
name="search"
292-
label={strings.localUnitsFilterSearchLabel}
293-
placeholder={strings.localUnitsFilterSearchPlaceholderLabel}
294-
value={rawFilter.search}
295-
onChange={setFilterField}
296-
icons={<SearchLineIcon />}
297-
/>
298-
<div className={styles.clearButton}>
299-
<Button
300-
name={undefined}
301-
variant="secondary"
302-
onClick={handleClearFilter}
303-
disabled={!filtered}
304-
>
305-
{strings.localUnitsFilterClear}
306-
</Button>
307-
</div>
308-
</>
309-
)}
310-
>
175+
<>
311176
<BaseMap
312177
baseLayers={(
313178
<MapLayer
@@ -372,54 +237,60 @@ function NationalSocietyLocalUnitsMap(props: Props) {
372237
)}
373238
</BaseMap>
374239
{isDefined(countryResponse)
375-
&& (isDefined(countryResponse.address_1) || isDefined(countryResponse.emails)) && (
376-
<Container
377-
className={styles.mapDetail}
378-
childrenContainerClassName={styles.infoContainer}
379-
>
380-
{isDefined(countryResponse) && isDefined(countryResponse.address_1) && (
381-
<TextOutput
382-
className={styles.info}
383-
labelClassName={styles.label}
384-
label={(
385-
<LocationIcon className={styles.icon} />
386-
)}
387-
withoutLabelColon
388-
value={(
389-
<>
390-
<div>{countryResponse.address_1}</div>
391-
<div>{countryResponse.address_2}</div>
392-
</>
393-
)}
394-
/>
395-
)}
396-
{isDefined(countryResponse) && isDefined(countryResponse.emails) && (
397-
<TextOutput
398-
className={styles.info}
399-
labelClassName={styles.label}
400-
label={(
401-
<MailIcon className={styles.icon} />
402-
)}
403-
withoutLabelColon
404-
value={(
405-
<List
406-
data={countryResponse.emails.filter(isDefined)}
407-
renderer={Link}
408-
rendererParams={emailRendererParams}
409-
keySelector={emailKeySelector}
410-
withoutMessage
411-
compact
412-
pending={false}
413-
errored={false}
414-
filtered={false}
415-
/>
416-
)}
417-
/>
240+
&& (isDefined(countryResponse.address_1)
241+
|| isDefined(countryResponse.emails))
242+
&& (
243+
<Container
244+
className={styles.mapDetail}
245+
childrenContainerClassName={styles.infoContainer}
246+
>
247+
{isDefined(countryResponse)
248+
&& isDefined(countryResponse.address_1)
249+
&& (
250+
<TextOutput
251+
className={styles.info}
252+
labelClassName={styles.label}
253+
label={(
254+
<LocationIcon className={styles.icon} />
255+
)}
256+
withoutLabelColon
257+
value={(
258+
<>
259+
<div>{countryResponse.address_1}</div>
260+
<div>{countryResponse.address_2}</div>
261+
</>
262+
)}
263+
/>
264+
)}
265+
{isDefined(countryResponse)
266+
&& isDefined(countryResponse.emails)
267+
&& (
268+
<TextOutput
269+
className={styles.info}
270+
labelClassName={styles.label}
271+
label={(
272+
<MailIcon className={styles.icon} />
273+
)}
274+
withoutLabelColon
275+
value={(
276+
<List
277+
data={countryResponse.emails.filter(isDefined)}
278+
renderer={Link}
279+
rendererParams={emailRendererParams}
280+
keySelector={emailKeySelector}
281+
withoutMessage
282+
compact
283+
pending={false}
284+
errored={false}
285+
filtered={false}
286+
/>
287+
)}
288+
/>
289+
)}
290+
</Container>
418291
)}
419-
</Container>
420-
)}
421-
</Container>
292+
</>
422293
);
423294
}
424295

425-
export default NationalSocietyLocalUnitsMap;
296+
export default LocalUnitsMap;

0 commit comments

Comments
 (0)