Skip to content

Commit 89ad01c

Browse files
authored
Merge pull request #89 from CivicDataLab/52-integrate-facets-in-dataset-listing-page
Integrate facets (Search-Filters-Pagination) in dataset listing page
2 parents 8c6824a + 5c4b715 commit 89ad01c

8 files changed

Lines changed: 433 additions & 188 deletions

File tree

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,52 @@
1-
import React from 'react';
21
import Link from 'next/link';
32
import { Tag, Text } from 'opub-ui';
43

5-
import CustomTags from '@/components/CustomTags';
6-
74
interface Dataset {
8-
datasetTitle: string;
5+
tags: string[];
96
description: string;
7+
title: string;
108
id: string;
11-
metadata: Metadata;
12-
}
13-
14-
interface Metadata {
15-
update: string;
16-
category: string;
17-
tags: { title: string }[];
18-
formats: { type: string }[];
19-
accessModels: { type: string }[];
20-
accessModelsCount: string;
219
}
2210

2311
const Cards = ({ data }: { data: Dataset }) => {
24-
const { datasetTitle, description, metadata, id } = data;
2512
return (
26-
<>
27-
<div className="border-b-2 border-solid border-baseGraySlateSolid4 p-6 ">
28-
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
29-
<div className="">
30-
<Link href={`/datasets/${id}`}>
31-
<Text variant="headingMd">{datasetTitle}</Text>
32-
</Link>
33-
</div>
34-
<div className="">
35-
<Text variant="bodySm">{description}</Text>
36-
</div>
13+
<div className="border-b-2 border-solid border-baseGraySlateSolid4 p-6">
14+
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
15+
<div>
16+
<Link href={`/datasets/${data.id}`}>
17+
<Text variant="headingMd">{data.title}</Text>
18+
</Link>
19+
</div>
20+
<div className="description-container line-clamp-4">
21+
<Text variant="bodySm">{data.description}</Text>
22+
</div>
23+
{data.tags && data.tags.length > 0 && (
3724
<div className="flex flex-wrap items-center gap-2">
3825
<Text fontWeight="bold">Tags:</Text>
3926
<div className="flex gap-2">
40-
{metadata.tags.map((item, index) => (
41-
<Tag key={index}>{item.title}</Tag>
27+
{data.tags.map((item, index) => (
28+
<Tag key={index}>{item}</Tag>
4229
))}
4330
</div>
4431
</div>
45-
<div className="flex flex-wrap items-center">
32+
)}
33+
{/* <div className="flex flex-wrap items-center">
4634
<Text fontWeight="bold">Categories&nbsp;:</Text>
47-
<Text>&nbsp;{metadata.category}</Text>
35+
<Text>&nbsp;{sector}</Text>
4836
</div>
4937
<div className="flex flex-wrap items-center gap-2">
5038
<Text fontWeight="bold">Formats:</Text>
5139
<div className="flex gap-2">
52-
{metadata.formats.map((item, index) => (
53-
<Tag key={index}>{item.type}</Tag>
40+
{format.map((item, index) => (
41+
<Tag key={index}>{item}</Tag>
5442
))}
5543
</div>
5644
</div>
5745
<div className="flex flex-wrap items-center">
5846
<Text fontWeight="bold">Access Models&nbsp;:</Text>
59-
<Text>&nbsp;{metadata.accessModelsCount} in total</Text>&nbsp;
47+
<Text>&nbsp;{dataset_access_models.length} in total</Text>&nbsp;
6048
<div className="flex gap-2">
61-
{metadata.accessModels.map((item, index) => (
49+
{dataset_access_models.map((item: any, index) => (
6250
<CustomTags
6351
key={index}
6452
type={item.type}
@@ -68,10 +56,10 @@ const Cards = ({ data }: { data: Dataset }) => {
6856
/>
6957
))}
7058
</div>
71-
</div>
72-
</div>
59+
</div> */}
7360
</div>
74-
</>
61+
</div>
7562
);
7663
};
64+
7765
export default Cards;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import Footer from '@/app/[locale]/dashboard/components/GraphqlTable/footer';
3+
4+
import Card from '../Card';
5+
6+
interface DatasetCardsProps {
7+
data: any;
8+
totalCount: number;
9+
pageSize: number;
10+
currentPage: number;
11+
onPageChange: (newPage: number) => void;
12+
onPageSizeChange: (newSize: number) => void;
13+
}
14+
15+
const DatasetCards: React.FC<DatasetCardsProps> = ({
16+
data,
17+
totalCount,
18+
pageSize,
19+
currentPage,
20+
onPageChange,
21+
onPageSizeChange,
22+
}) => {
23+
return (
24+
<div>
25+
{data.map((item: any, index: any) => (
26+
<Card key={index} data={item} />
27+
))}
28+
<Footer
29+
totalRows={totalCount}
30+
pageSize={pageSize}
31+
currentPage={currentPage}
32+
onPageChange={onPageChange}
33+
onPageSizeChange={onPageSizeChange}
34+
/>
35+
</div>
36+
);
37+
};
38+
39+
export default DatasetCards;

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

Lines changed: 43 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React from 'react';
22
import {
33
Accordion,
44
AccordionContent,
@@ -10,106 +10,71 @@ import {
1010
Text,
1111
} from 'opub-ui';
1212

13+
import { toTitleCase } from '@/lib/utils';
1314
import { Icons } from '@/components/icons';
1415

1516
interface FilterProps {
1617
setOpen?: (isOpen: boolean) => void;
18+
options: Record<string, { label: string; value: string }[]>;
19+
setSelectedOptions: (category: string, values: string[]) => void;
20+
selectedOptions: Record<string, string[]>;
1721
}
1822

19-
const Filter: React.FC<FilterProps> = ({ setOpen }) => {
20-
const filtersData = [
21-
{
22-
title: 'Organization',
23-
Options: [
24-
{
25-
label: 'Option1',
26-
value: 'Option1',
27-
},
28-
{
29-
label: 'Option2',
30-
value: 'Option2',
31-
},
32-
{
33-
label: 'Option3',
34-
value: 'Option3',
35-
},
36-
],
37-
},
38-
{
39-
title: 'Sector',
40-
Options: [
41-
{
42-
label: 'Option21',
43-
value: 'Option21',
44-
},
45-
{
46-
label: 'Option22',
47-
value: 'Option22',
48-
},
49-
{
50-
label: 'Option23',
51-
value: 'Option23',
52-
},
53-
],
54-
},
55-
{
56-
title: 'Category',
57-
Options: [
58-
{
59-
label: 'Option31',
60-
value: 'Option31',
61-
},
62-
{
63-
label: 'Option32',
64-
value: 'Option32',
65-
},
66-
{
67-
label: 'Option33',
68-
value: 'Option33',
69-
},
70-
],
71-
},
72-
];
73-
const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
23+
const Filter: React.FC<FilterProps> = ({
24+
setOpen,
25+
options,
26+
setSelectedOptions,
27+
selectedOptions,
28+
}) => {
29+
const handleReset = () => {
30+
Object.keys(options).forEach((category) => {
31+
setSelectedOptions(category, []); // Reset selected options for each category
32+
});
33+
};
34+
7435
return (
75-
<div className="rounded-2 border-2 border-solid border-baseGraySlateSolid5 px-4 py-6">
76-
<div className="mb-5 flex justify-between ">
77-
<div>
78-
<Text variant="headingMd">Filters</Text>
36+
<div className="rounded-2 border-2 border-solid border-baseGraySlateSolid5 px-4 py-6">
37+
<div className="mb-5 flex justify-between">
38+
<div className="flex w-full justify-between">
39+
<div>
40+
<Text variant="headingMd">Filters</Text>
41+
</div>
42+
<div>
43+
<Button kind="tertiary" onClick={handleReset}>
44+
Reset
45+
</Button>
46+
</div>
7947
</div>
8048
{setOpen && (
81-
<div className="align-center mr-2">
82-
<Button onClick={(e) => setOpen(false)} kind="tertiary">
49+
<div className="align-center mx-3">
50+
<Button onClick={() => setOpen(false)} kind="tertiary">
8351
<Icon source={Icons.cross} size={24} color="default" />
8452
</Button>
8553
</div>
8654
)}
8755
</div>
88-
<div className="flex flex-col gap-5 ">
89-
{filtersData.map((item, index) => (
56+
<div className="flex flex-col gap-5">
57+
{Object.entries(options).map(([category, data], index) => (
9058
<div key={index}>
9159
<Accordion type="single" collapsible className="w-full">
92-
<AccordionItem value={item.title}>
93-
<AccordionTrigger className="flex w-full flex-wrap items-center gap-2 rounded-1 bg-baseIndigoSolid5 py-2 hover:no-underline ">
94-
<Text>{item.title}</Text>
60+
<AccordionItem value={category}>
61+
<AccordionTrigger className="flex w-full flex-wrap items-center gap-2 rounded-1 bg-baseIndigoSolid5 py-2 hover:no-underline">
62+
<Text>{toTitleCase(category)}</Text>
9563
</AccordionTrigger>
9664
<AccordionContent
97-
className="flex w-full flex-col px-3 pb-0 pt-2 "
65+
className="flex w-full flex-col px-3 pb-0 pt-2"
9866
style={{
99-
backgroundColor: 'var( --base-pure-white)',
100-
outline: '1px solid var( --base-pure-white)',
67+
backgroundColor: 'var(--base-pure-white)',
68+
outline: '1px solid var(--base-pure-white)',
10169
}}
10270
>
10371
<CheckboxGroup
104-
name="checkbox"
105-
options={item.Options.map((Option) => ({
106-
label: Option.label,
107-
value: Option.value,
108-
}))}
72+
name={category}
73+
options={data}
10974
title={undefined}
110-
value={selectedOptions}
111-
onChange={(e) => {
112-
setSelectedOptions(e), console.log(e);
75+
value={selectedOptions[category] || []}
76+
onChange={(values) => {
77+
setSelectedOptions(category, values as string[]);
11378
}}
11479
/>
11580
</AccordionContent>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.Search {
2+
input {
3+
width: 80%;
4+
height: 36px;
5+
}
6+
}

0 commit comments

Comments
 (0)