Skip to content

Commit f0543d9

Browse files
committed
style: eslint
1 parent 0155395 commit f0543d9

File tree

6 files changed

+146
-18
lines changed

6 files changed

+146
-18
lines changed

src/components/Hotjar.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const Hotjar = () => {
1313
r=o.createElement('script');
1414
r.async=1;
1515
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
16+
r.onerror = function() {
17+
console.warn('Hotjar script failed to load');
18+
};
1619
a.appendChild(r);
1720
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
1821
`;

src/components/PropertyAccessOptionContainer.tsx

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,43 @@ const determineCardEnums = (property: any) => {
77
const available = new Set<PropertyAccess>();
88
const unavailable = new Set<PropertyAccess>();
99

10+
// Debug logging for Boolean fields
11+
console.log('Property Boolean fields:', {
12+
side_yard_eligible: {
13+
value: property.side_yard_eligible,
14+
type: typeof property.side_yard_eligible,
15+
isTrue: property.side_yard_eligible === true,
16+
isYes: property.side_yard_eligible === 'Yes',
17+
isTrueString: property.side_yard_eligible === 'True',
18+
willMatch:
19+
property.side_yard_eligible === true ||
20+
property.side_yard_eligible === 'Yes' ||
21+
property.side_yard_eligible === 'True',
22+
},
23+
tactical_urbanism: {
24+
value: property.tactical_urbanism,
25+
type: typeof property.tactical_urbanism,
26+
isTrue: property.tactical_urbanism === true,
27+
isYes: property.tactical_urbanism === 'Yes',
28+
isTrueString: property.tactical_urbanism === 'True',
29+
willMatch:
30+
property.tactical_urbanism === true ||
31+
property.tactical_urbanism === 'Yes' ||
32+
property.tactical_urbanism === 'True',
33+
},
34+
conservatorship: {
35+
value: property.conservatorship,
36+
type: typeof property.conservatorship,
37+
isTrue: property.conservatorship === true,
38+
isYes: property.conservatorship === 'Yes',
39+
isTrueString: property.conservatorship === 'True',
40+
willMatch:
41+
property.conservatorship === true ||
42+
property.conservatorship === 'Yes' ||
43+
property.conservatorship === 'True',
44+
},
45+
});
46+
1047
if (property.access_process === 'Private Land Use Agreement') {
1148
best = 'PRIVATE_LAND_USE';
1249
}
@@ -30,19 +67,31 @@ const determineCardEnums = (property: any) => {
3067
unavailable.add('LAND_BANK');
3168
}
3269

33-
if (property.side_yard_eligible === 'Yes') {
70+
if (
71+
property.side_yard_eligible === true ||
72+
property.side_yard_eligible === 'Yes' ||
73+
property.side_yard_eligible === 'True'
74+
) {
3475
neighbor = 'SIDE_YARD';
3576
} else {
3677
unavailable.add('SIDE_YARD');
3778
}
3879

39-
if (property.tactical_urbanism === 'Yes') {
80+
if (
81+
property.tactical_urbanism === true ||
82+
property.tactical_urbanism === 'Yes' ||
83+
property.tactical_urbanism === 'True'
84+
) {
4085
available.add('TACTICAL_URBANISM');
4186
} else {
4287
unavailable.add('TACTICAL_URBANISM');
4388
}
4489

45-
if (property.conservatorship === 'Yes') {
90+
if (
91+
property.conservatorship === true ||
92+
property.conservatorship === 'Yes' ||
93+
property.conservatorship === 'True'
94+
) {
4695
available.add('CONSERVATORSHIP');
4796
} else {
4897
unavailable.add('CONSERVATORSHIP');

src/components/PropertyCard.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ function getPriorityClass(priorityLevel: string) {
2121
}
2222

2323
const PropertyCard = ({ feature, setSelectedProperty }: PropertyCardProps) => {
24-
const { address, gun_crimes_density_label, priority_level, opa_id } =
25-
feature.properties;
24+
const {
25+
standardized_street_address,
26+
gun_crimes_density_label,
27+
priority_level,
28+
opa_id,
29+
} = feature.properties;
2630

2731
const image = `https://storage.googleapis.com/cleanandgreenphl/${opa_id}.jpg`;
28-
const formattedAddress = toTitleCase(address);
32+
const formattedAddress = toTitleCase(standardized_street_address);
2933
const priorityClass = getPriorityClass(priority_level);
3034

3135
const handleClick = () => setSelectedProperty(feature);
@@ -59,7 +63,7 @@ const PropertyCard = ({ feature, setSelectedProperty }: PropertyCardProps) => {
5963
className="font-bold heading-lg focus:bg-gray-100"
6064
onKeyDown={handleKeyDown}
6165
>
62-
{formattedAddress}
66+
{formattedAddress ?? 'Address not available'}
6367
</button>
6468
<div className="text-gray-700 body-sm">
6569
{gun_crimes_density_label} Gun Crime Rate

src/components/PropertyMap.tsx

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ const PropertyMap: FC<PropertyMapProps> = ({
241241

242242
const features = map.queryRenderedFeatures(bbox, { layers });
243243

244-
//Get count of features if they are clustered
244+
// Get count of features if they are clustered
245245
const clusteredFeatureCount = features.reduce(
246246
(acc: number, feature: MapGeoJSONFeature) => {
247247
if (feature.properties?.clustered) {
@@ -361,14 +361,20 @@ const PropertyMap: FC<PropertyMapProps> = ({
361361
const updateFilter = () => {
362362
if (!map) return;
363363

364+
// If no filters are applied (appFilter is empty), show all properties
365+
if (Object.keys(appFilter).length === 0) {
366+
map.setFilter('vacant_properties_tiles_points', null);
367+
map.setFilter('vacant_properties_tiles_polygons', null);
368+
return;
369+
}
370+
364371
const isAnyFilterEmpty = Object.values(appFilter).some((filterItem) => {
365372
return filterItem.values.length === 0;
366373
});
367374

368375
if (isAnyFilterEmpty) {
369376
map.setFilter('vacant_properties_tiles_points', ['==', ['id'], '']);
370377
map.setFilter('vacant_properties_tiles_polygons', ['==', ['id'], '']);
371-
372378
return;
373379
}
374380

@@ -384,7 +390,24 @@ const PropertyMap: FC<PropertyMapProps> = ({
384390
0,
385391
]);
386392
} else {
387-
thisFilterGroup.push(['in', ['get', property], item]);
393+
// Handle Boolean fields that might be mixed format
394+
if (
395+
[
396+
'tactical_urbanism',
397+
'conservatorship',
398+
'side_yard_eligible',
399+
].includes(property)
400+
) {
401+
// For Boolean fields, check Boolean true, string 'Yes', and string 'True'
402+
thisFilterGroup.push([
403+
'any',
404+
['==', ['get', property], true],
405+
['==', ['get', property], 'Yes'],
406+
['==', ['get', property], 'True'],
407+
]);
408+
} else {
409+
thisFilterGroup.push(['in', ['get', property], item]);
410+
}
388411
}
389412
if (Object.keys(subZoning).includes(item)) {
390413
subZoning[item].forEach((subZone: string) => {
@@ -408,8 +431,49 @@ const PropertyMap: FC<PropertyMapProps> = ({
408431
[] as any[]
409432
);
410433

411-
map.setFilter('vacant_properties_tiles_points', ['all', ...mapFilter]);
412-
map.setFilter('vacant_properties_tiles_polygons', ['all', ...mapFilter]);
434+
// Check if we have access-related filters
435+
const accessProperties = [
436+
'tactical_urbanism',
437+
'conservatorship',
438+
'side_yard_eligible',
439+
'access_process',
440+
];
441+
const hasAccessFilters = Object.keys(appFilter).some(
442+
(property) =>
443+
accessProperties.includes(property) &&
444+
appFilter[property].values.length > 0
445+
);
446+
447+
let finalFilter: any;
448+
if (hasAccessFilters && mapFilter.length > 1) {
449+
// If we have access filters and other filters, use OR for access filters
450+
const accessFilterIndices = Object.keys(appFilter)
451+
.map((property, index) => ({ property, index }))
452+
.filter(
453+
({ property }) =>
454+
accessProperties.includes(property) &&
455+
appFilter[property].values.length > 0
456+
)
457+
.map(({ index }) => index);
458+
459+
const accessFilters = accessFilterIndices.map((i) => mapFilter[i]);
460+
const otherFilters = mapFilter.filter(
461+
(_, i) => !accessFilterIndices.includes(i)
462+
);
463+
464+
if (otherFilters.length > 0) {
465+
finalFilter = ['all', ['any', ...accessFilters], ...otherFilters];
466+
} else {
467+
finalFilter = ['any', ...accessFilters];
468+
}
469+
} else {
470+
// Use original logic for all other cases
471+
finalFilter =
472+
mapFilter.length > 0 ? ['all', ...mapFilter] : ['==', ['id'], ''];
473+
}
474+
475+
map.setFilter('vacant_properties_tiles_points', finalFilter);
476+
map.setFilter('vacant_properties_tiles_polygons', finalFilter);
413477
};
414478

415479
if (map) {
@@ -528,7 +592,10 @@ const PropertyMap: FC<PropertyMapProps> = ({
528592
onClose={handlePopupClose}
529593
>
530594
<div className="flex flex-row items-center nowrap space-x-1">
531-
<span>{toTitleCase(popupInfo.feature.address)}</span>
595+
<span>
596+
{toTitleCase(popupInfo.feature.standardized_street_address) ??
597+
'Address not available'}
598+
</span>
532599
{/* keeping invisible to maintain spacing for built-in close button */}
533600
<X size={16} className="invisible" />
534601
</div>

src/components/SinglePropertyDetail.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const SinglePropertyDetail = ({
8888
if (!properties) return null;
8989

9090
const {
91-
address,
91+
standardized_street_address,
9292
council_district,
9393
gun_crimes_density_label,
9494
market_value,
@@ -106,7 +106,9 @@ const SinglePropertyDetail = ({
106106
phs_care_program,
107107
} = properties;
108108
const image = `https://storage.googleapis.com/cleanandgreenphl/${opa_id}.jpg`;
109-
const atlasUrl = `https://atlas.phila.gov/${address}`;
109+
const atlasUrl = standardized_street_address
110+
? `https://atlas.phila.gov/${standardized_street_address}`
111+
: '#';
110112
const priorityClass = getPriorityClass(priority_level);
111113

112114
const priorityBgClassName = priority_level.includes('High')
@@ -247,7 +249,7 @@ const SinglePropertyDetail = ({
247249
<div className="relative h-48 w-full rounded-lg overflow-hidden">
248250
<Image
249251
src={image}
250-
alt={`Property at ${address}`}
252+
alt={`Property at ${standardized_street_address}`}
251253
layout="fill"
252254
objectFit="cover"
253255
unoptimized
@@ -281,7 +283,8 @@ const SinglePropertyDetail = ({
281283
textTransform: 'capitalize',
282284
}}
283285
>
284-
{address.toLowerCase()}
286+
{standardized_street_address?.toLowerCase() ||
287+
'Address not available'}
285288
</h2>
286289
<div>
287290
<Tooltip

src/utilities/toTitleCase.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// exported this function to be used in other files (PropertyMap.tsx)
22

3-
export function toTitleCase(str: string) {
3+
export function toTitleCase(str: string | undefined | null) {
4+
if (str === null || str === undefined) return null;
5+
46
return str
57
.toLowerCase()
68
.split(' ')

0 commit comments

Comments
 (0)