@@ -7,23 +7,14 @@ import { useOutletContext } from 'react-router-dom';
77import {
88 LocationIcon ,
99 MailIcon ,
10- SearchLineIcon ,
1110} from '@ifrc-go/icons' ;
1211import {
13- Button ,
1412 Container ,
1513 List ,
16- SelectInput ,
17- TextInput ,
1814 TextOutput ,
1915} from '@ifrc-go/ui' ;
2016import { useTranslation } from '@ifrc-go/ui/hooks' ;
2117import {
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';
4435import Link , { type Props as LinkProps } from '#components/Link' ;
4536import MapContainerWithDisclaimer from '#components/MapContainerWithDisclaimer' ;
4637import 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' ;
5138import {
5239 COLOR_RED ,
5340 DEFAULT_MAP_PADDING ,
5441 DURATION_MAP_ZOOM ,
5542} from '#utils/constants' ;
5643import { 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
6046import i18n from './i18n.json' ;
6147import styles from './styles.module.css' ;
6248
49+ type GetLocalUnitResponseType = GoApiResponse < '/api/v2/local-units/' > ;
6350const 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+
7664const 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-
8868interface ClickedPoint {
8969 id : string ;
9070 lngLat : mapboxgl . LngLatLike ;
9171}
9272
93- interface Props {
94- className ?: string ;
95- }
96-
9773function 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