Skip to content

Commit 2b1b2a2

Browse files
authored
fix: Refactor filters logic (#1164)
Refactor the filters logic by moving all of the implementation into each of the specific `ButtonGroup`, `Panels`, and `MultiSelect` components as well as separating out the filter heading description information, rather than keeping it wrapped together in `DimesionFilter`.
1 parent 034bd52 commit 2b1b2a2

11 files changed

+311
-432
lines changed

package-lock.json

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/FilterView.tsx

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,10 @@ import { PiX } from 'react-icons/pi';
55
import { ThemeButton } from './ThemeButton';
66
import { BarClickOptions } from '@/app/find-properties/[[...opa_id]]/page';
77
import { rcos, neighborhoods, zoning } from './Filters/filterOptions';
8-
import DimensionFilter from './Filters/DimensionFilter';
9-
10-
const filters = [
11-
{
12-
property: 'priority_level',
13-
display: 'Suggested Priority',
14-
options: ['Low', 'Medium', 'High'],
15-
type: 'buttonGroup',
16-
},
17-
{
18-
property: 'get_access',
19-
display: 'Get Access',
20-
options: [
21-
'TACTICAL_URBANISM',
22-
'PRIVATE_LAND_USE',
23-
'BUY_FROM_OWNER',
24-
'SIDE_YARD',
25-
'LAND_BANK',
26-
'CONSERVATORSHIP',
27-
],
28-
type: 'panels',
29-
},
30-
{
31-
property: 'neighborhood',
32-
display: 'Neighborhoods',
33-
options: neighborhoods,
34-
type: 'multiSelect',
35-
},
36-
{
37-
property: 'rco_names',
38-
display: 'Community Organizations',
39-
options: rcos,
40-
type: 'multiSelect',
41-
useIndexOfFilter: true,
42-
},
43-
{
44-
property: 'zoning_base_district',
45-
display: 'Zoning',
46-
options: zoning,
47-
type: 'multiSelect',
48-
},
49-
{
50-
property: 'parcel_type',
51-
display: 'Property Type',
52-
options: ['Land', 'Building'],
53-
type: 'buttonGroup',
54-
},
55-
];
8+
import FilterDescription from './Filters/FilterDescription';
9+
import ButtonGroup from './Filters/ButtonGroup';
10+
import MultiSelect from './Filters/MultiSelect';
11+
import Panels from './Filters/Panels';
5612

5713
interface FilterViewProps {
5814
updateCurrentView: (view: BarClickOptions) => void;
@@ -72,9 +28,62 @@ const FilterView: FC<FilterViewProps> = ({ updateCurrentView }) => {
7228
updateCurrentView('filter');
7329
}}
7430
/>
75-
{filters.map((attr) => (
76-
<DimensionFilter key={attr.property} {...attr} />
77-
))}
31+
<div className="pt-3 pb-6">
32+
<FilterDescription
33+
title="Suggested Priority"
34+
description="Find properties based on how much they can reduce gun violence considering the gun violence, cleanliness, and tree canopy nearby. "
35+
link="/methodology/#priority-method"
36+
/>
37+
<ButtonGroup
38+
property="priority_level"
39+
options={['Low', 'Medium', 'High']}
40+
aria_describedby_label="Suggested Priority"
41+
/>
42+
</div>
43+
<div className="pt-3 pb-6">
44+
<FilterDescription
45+
title="Get Access"
46+
description="Find properties based on what we think the easiest method to get legal access to them is, based on the data available to us."
47+
link="/methodology/#access-method"
48+
/>
49+
<Panels />
50+
</div>
51+
<div className="pt-3 pb-6">
52+
<FilterDescription title="Neighborhoods" />
53+
<MultiSelect
54+
property="neighborhood"
55+
options={neighborhoods}
56+
aria_describedby_label="Neighborhoods"
57+
useIndexOfFilter={false}
58+
/>
59+
</div>
60+
<div className="pt-3 pb-6">
61+
<FilterDescription title="Community Organizations" />
62+
<MultiSelect
63+
property="rco_names"
64+
options={rcos}
65+
aria_describedby_label="Community_Organizations"
66+
useIndexOfFilter={true}
67+
/>
68+
</div>
69+
70+
<div className="pt-3 pb-6">
71+
<FilterDescription title="Zoning" />
72+
<MultiSelect
73+
property="zoning_base_district"
74+
options={zoning}
75+
aria_describedby_label="Zoning"
76+
useIndexOfFilter={false}
77+
/>
78+
</div>
79+
<div className="pt-3 pb-6">
80+
<FilterDescription title="Property Type" />
81+
<ButtonGroup
82+
property="parcel_type"
83+
options={['Land', 'Building']}
84+
aria_describedby_label="Property_Type"
85+
/>
86+
</div>
7887
</div>
7988
);
8089
};

src/components/Filters/ButtonGroup.tsx

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,36 @@
11
'use client';
22

3-
import React, { FC } from 'react';
3+
import React, { FC, useState } from 'react';
44
import { Button } from '@nextui-org/react';
55
import { Check } from '@phosphor-icons/react';
6+
import { useFilter } from '@/context/FilterContext';
67

78
type ButtonGroupProps = {
9+
property: string;
810
options: string[];
9-
selectedKeys: string[];
1011
aria_describedby_label?: string;
11-
toggleDimension: (dimension: string) => void;
12-
displayOptions?: { [key: string]: string };
1312
};
1413

15-
const ButtonGroup: FC<ButtonGroupProps> = ({
14+
const ButtonGroup = ({
15+
property,
1616
options,
17-
selectedKeys,
18-
toggleDimension,
1917
aria_describedby_label,
20-
displayOptions = {},
21-
}) => {
18+
}: ButtonGroupProps): JSX.Element => {
19+
const { dispatch, appFilter } = useFilter();
20+
const currentFilterKeys = appFilter[property]?.values || [];
21+
22+
const toggleDimension = (dimension: string) => {
23+
const updatedKeys = currentFilterKeys.includes(dimension)
24+
? currentFilterKeys.filter((item) => item !== dimension)
25+
: [...currentFilterKeys, dimension];
26+
27+
dispatch({
28+
type: 'SET_DIMENSIONS',
29+
property,
30+
dimensions: updatedKeys,
31+
});
32+
};
33+
2234
return (
2335
<div className="flex flex-wrap gap-x-2 min-h-[33.5px]">
2436
{options.map((option, index) => (
@@ -28,23 +40,25 @@ const ButtonGroup: FC<ButtonGroupProps> = ({
2840
role="checkbox"
2941
onPress={() => toggleDimension(option)}
3042
size="sm"
31-
color={selectedKeys.includes(option) ? 'success' : 'default'}
43+
color={currentFilterKeys.includes(option) ? 'success' : 'default'}
3244
className={
33-
(selectedKeys.includes(option) ? 'tagSelected' : 'tagDefault') +
45+
(currentFilterKeys.includes(option)
46+
? 'tagSelected'
47+
: 'tagDefault') +
3448
(option === 'Private Land Use Agreement'
3549
? ' max-[475px]:mt-2 sm:max-[1103px]:mt-2'
3650
: '')
3751
}
3852
radius="full"
39-
aria-checked={selectedKeys.includes(option)}
53+
aria-checked={currentFilterKeys.includes(option)}
4054
aria-describedby={aria_describedby_label}
4155
startContent={
42-
selectedKeys.includes(option) ? (
43-
<Check className="w-3 w-3.5 max-h-6" />
56+
currentFilterKeys.includes(option) ? (
57+
<Check className="w-3 max-h-6" />
4458
) : undefined
4559
}
4660
>
47-
{displayOptions[option] || option}
61+
{option}
4862
</Button>
4963
))}
5064
</div>

0 commit comments

Comments
 (0)