Skip to content

Commit 9fcb436

Browse files
Merge pull request #338 from CivicDataLab/current_sector_filter
Disable current sector in sector detail page
2 parents 4ae60ad + 17a996c commit 9fcb436

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

app/[locale]/(user)/components/ListingComponent.tsx

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Text,
1515
Tray,
1616
} from 'opub-ui';
17-
import React, { useEffect, useReducer, useRef, useState } from 'react';
17+
import React, { useEffect, useMemo, useReducer, useRef, useState } from 'react';
1818

1919
import BreadCrumbs from '@/components/BreadCrumbs';
2020
import { Icons } from '@/components/icons';
@@ -149,7 +149,8 @@ const queryReducer = (state: QueryParams, action: Action): QueryParams => {
149149
const useUrlParams = (
150150
queryParams: QueryParams,
151151
setQueryParams: React.Dispatch<Action>,
152-
setVariables: (vars: string) => void
152+
setVariables: (vars: string) => void,
153+
lockedFilters: Record<string, string[]>
153154
) => {
154155
const router = useRouter();
155156

@@ -165,6 +166,13 @@ const useUrlParams = (
165166
}
166167
});
167168

169+
// Merge locked filters with URL filters
170+
Object.entries(lockedFilters).forEach(([category, values]) => {
171+
if (values.length > 0) {
172+
filters[category] = Array.from(new Set([...(filters[category] || []), ...values]));
173+
}
174+
});
175+
168176
const initialParams: QueryParams = {
169177
pageSize: sizeParam ? Number(sizeParam) : 9,
170178
currentPage: pageParam ? Number(pageParam) : 1,
@@ -173,7 +181,7 @@ const useUrlParams = (
173181
};
174182

175183
setQueryParams({ type: 'INITIALIZE', payload: initialParams });
176-
}, [setQueryParams]);
184+
}, [setQueryParams, lockedFilters]);
177185

178186
useEffect(() => {
179187
const filtersString = Object.entries(queryParams.filters)
@@ -234,6 +242,7 @@ interface ListingProps {
234242
categoryImage?: string;
235243
placeholder: string;
236244
redirectionURL: string;
245+
lockedFilters?: Record<string, string[]>;
237246
}
238247

239248
const ListingComponent: React.FC<ListingProps> = ({
@@ -245,6 +254,7 @@ const ListingComponent: React.FC<ListingProps> = ({
245254
categoryImage,
246255
placeholder,
247256
redirectionURL,
257+
lockedFilters = {},
248258
}) => {
249259
const [facets, setFacets] = useState<{
250260
results: any[];
@@ -259,7 +269,10 @@ const ListingComponent: React.FC<ListingProps> = ({
259269
const count = facets?.total ?? 0;
260270
const datasetDetails = facets?.results ?? [];
261271

262-
useUrlParams(queryParams, setQueryParams, setVariables);
272+
// Stabilize lockedFilters reference to prevent infinite loops
273+
const stableLockedFilters = useMemo(() => lockedFilters, [JSON.stringify(lockedFilters)]);
274+
275+
useUrlParams(queryParams, setQueryParams, setVariables, stableLockedFilters);
263276
const latestFetchId = useRef(0);
264277

265278
useEffect(() => {
@@ -389,6 +402,7 @@ const ListingComponent: React.FC<ListingProps> = ({
389402
options={filterOptions}
390403
setSelectedOptions={handleFilterChange}
391404
selectedOptions={queryParams.filters}
405+
lockedFilters={stableLockedFilters}
392406
/>
393407
</div>
394408

@@ -484,6 +498,7 @@ const ListingComponent: React.FC<ListingProps> = ({
484498
options={filterOptions}
485499
setSelectedOptions={handleFilterChange}
486500
selectedOptions={queryParams.filters}
501+
lockedFilters={stableLockedFilters}
487502
/>
488503
</Tray>
489504
</div>
@@ -497,14 +512,18 @@ const ListingComponent: React.FC<ListingProps> = ({
497512
([category, values]) =>
498513
values
499514
.filter((value) => category !== 'sort')
500-
.map((value) => (
501-
<Pill
502-
key={`${category}-${value}`}
503-
onRemove={() => handleRemoveFilter(category, value)}
504-
>
505-
{value}
506-
</Pill>
507-
))
515+
.map((value) => {
516+
// Check if this filter value is locked
517+
const isLocked = stableLockedFilters[category]?.includes(value);
518+
return (
519+
<Pill
520+
key={`${category}-${value}`}
521+
onRemove={isLocked ? undefined : () => handleRemoveFilter(category, value)}
522+
>
523+
{value}
524+
</Pill>
525+
);
526+
})
508527
)}
509528
</div>
510529
)}

app/[locale]/(user)/datasets/components/FIlter/Filter.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,21 @@ interface FilterProps {
1919
options: Record<string, { label: string; value: string }[]>;
2020
setSelectedOptions: (category: string, values: string[]) => void;
2121
selectedOptions: Record<string, string[]>;
22+
lockedFilters?: Record<string, string[]>;
2223
}
2324

2425
const Filter: React.FC<FilterProps> = ({
2526
setOpen,
2627
options,
2728
setSelectedOptions,
2829
selectedOptions,
30+
lockedFilters = {},
2931
}) => {
3032
const handleReset = () => {
3133
Object.keys(options).forEach((category) => {
32-
setSelectedOptions(category, []); // Reset selected options for each category
34+
// Keep locked filters when resetting
35+
const locked = lockedFilters[category] || [];
36+
setSelectedOptions(category, locked);
3337
});
3438
};
3539

@@ -97,11 +101,21 @@ const Filter: React.FC<FilterProps> = ({
97101
>
98102
<CheckboxGroup
99103
name={category}
100-
options={data}
104+
options={data.map((option) => ({
105+
...option,
106+
disabled: lockedFilters[category]?.includes(option.value) || false,
107+
}))}
101108
title={undefined}
102109
value={selectedOptions[category] || []}
103110
onChange={(values) => {
104-
setSelectedOptions(category, values as string[]);
111+
// Prevent unselecting locked filters
112+
const locked = lockedFilters[category] || [];
113+
const newValues = values as string[];
114+
115+
// Ensure all locked values remain selected
116+
const finalValues = Array.from(new Set([...locked, ...newValues]));
117+
118+
setSelectedOptions(category, finalValues);
105119
}}
106120
/>
107121
</AccordionContent>

app/[locale]/(user)/sectors/[sectorSlug]/SectorDetailsClient.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const SectorDetailsClient = ({ sector }: { sector: TypeSector }) => {
4343
categoryImage={`/Sectors/${sector.name}.svg`}
4444
redirectionURL={`/datasets`}
4545
placeholder="Start typing to search for any Dataset"
46+
lockedFilters={{ sectors: [sector.name] }}
4647
/>
4748
</>
4849
);

0 commit comments

Comments
 (0)