Skip to content

Commit 9d6badd

Browse files
committed
refactor SectorsListingPage to improve sorting and search functionality
1 parent 9ad9d59 commit 9d6badd

File tree

1 file changed

+176
-140
lines changed

1 file changed

+176
-140
lines changed

app/[locale]/(user)/sectors/page.tsx

Lines changed: 176 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
'use client';
22

3+
import { useEffect, useState } from 'react';
34
import Image from 'next/image';
45
import Link from 'next/link';
56
import { graphql } from '@/gql';
7+
import {
8+
Ordering,
9+
SectorOrder,
10+
SectorsListsQuery,
11+
} from '@/gql/generated/graphql';
612
import { useQuery } from '@tanstack/react-query';
7-
import { Divider, SearchInput, Select, Text } from 'opub-ui';
13+
import { Divider, SearchInput, Select, Spinner, Text } from 'opub-ui';
814

915
import { GraphQL } from '@/lib/api';
1016
import { cn } from '@/lib/utils';
1117
import BreadCrumbs from '@/components/BreadCrumbs';
1218
import { ErrorPage } from '@/components/error';
13-
import { Loading } from '@/components/loading';
1419
import Styles from '../datasets/dataset.module.scss';
1520

1621
const sectorsListQueryDoc: any = graphql(`
17-
query SectorsList {
18-
sectors {
22+
query SectorsLists($order: SectorOrder, $filters: SectorFilter) {
23+
sectors(order: $order, filters: $filters) {
1924
id
2025
name
2126
description
@@ -26,28 +31,38 @@ const sectorsListQueryDoc: any = graphql(`
2631
`);
2732

2833
const SectorsListingPage = () => {
29-
const getSectorsList: {
30-
data: any;
31-
isLoading: boolean;
32-
error: any;
33-
isError: boolean;
34-
} = useQuery([`sectors_list_page`], () =>
35-
GraphQL(
36-
sectorsListQueryDoc,
37-
{
38-
// Entity Headers if present
39-
},
40-
[]
41-
)
34+
const [sort, setSort] = useState<SectorOrder>({ name: Ordering.Asc });
35+
const [searchText, setSearchText] = useState('');
36+
37+
const { data, isLoading, isError, refetch } = useQuery<SectorsListsQuery>(
38+
['sectors_list_page', sort],
39+
() =>
40+
GraphQL(
41+
sectorsListQueryDoc,
42+
{},
43+
{ filters: searchText ? { search: searchText } : {}, order: sort }
44+
) as Promise<SectorsListsQuery>
4245
);
4346

4447
function capitalizeWords(name: any) {
4548
return name
46-
.split('-') // Split by '-'
47-
.map((word: any) => word.charAt(0).toUpperCase() + word.slice(1)) // Capitalize each word
48-
.join('+'); // Join with '+'
49+
.split('-')
50+
.map((word: any) => word.charAt(0).toUpperCase() + word.slice(1))
51+
.join('+');
4952
}
5053

54+
useEffect(() => {
55+
refetch();
56+
}, [searchText]);
57+
58+
const handleSortChange = (e: string) => {
59+
const [field, direction] = e.split('_');
60+
const formattedSort: SectorOrder = {
61+
[field]: direction.toUpperCase() as Ordering,
62+
};
63+
setSort(formattedSort);
64+
};
65+
5166
return (
5267
<main className="bg-baseGraySlateSolid2">
5368
<BreadCrumbs
@@ -57,137 +72,158 @@ const SectorsListingPage = () => {
5772
]}
5873
/>
5974
<>
60-
{getSectorsList.isLoading ? (
61-
<Loading />
62-
) : getSectorsList.data?.sectors.length > 0 ? (
63-
<>
64-
<div className="w-full">
65-
<div className=" bg-primaryBlue">
66-
<div className=" container flex flex-col-reverse items-center gap-8 py-10 lg:flex-row ">
67-
<div className="flex flex-col gap-6 ">
68-
<Text variant="heading3xl" color="onBgDefault">
69-
Our Sectors
70-
</Text>
75+
<>
76+
<div className="w-full">
77+
<div className=" bg-primaryBlue">
78+
<div className=" container flex flex-col-reverse items-center gap-8 py-10 lg:flex-row ">
79+
<div className="flex flex-col gap-6 ">
80+
<Text variant="heading3xl" color="onBgDefault">
81+
Our Sectors
82+
</Text>
83+
<Text
84+
variant="headingLg"
85+
color="onBgDefault"
86+
fontWeight="regular"
87+
>
88+
We try to enable our users to create and participate in
89+
sectoral data collaboratives, amplifying the reach and
90+
impact of high-value datasets and sectoral use cases at
91+
various levels, including national, sub-national, and
92+
regional.
93+
</Text>
94+
</div>
95+
<div className="flex items-center justify-center gap-2 px-3 ">
96+
<Image
97+
src={'/s2.png'}
98+
alt={'s1'}
99+
width={130}
100+
height={100}
101+
className="h-auto w-[80px] sm:w-[100px] md:w-[120px] lg:w-[130px]"
102+
priority
103+
/>
104+
<Image
105+
src={'/s3.png'}
106+
alt={'s1'}
107+
width={230}
108+
height={100}
109+
className="h-auto w-[140px] sm:w-[180px] md:w-[200px] lg:w-[230px]"
110+
priority
111+
/>
112+
<Image
113+
src={'/s1.png'}
114+
alt={'s1'}
115+
width={130}
116+
height={100}
117+
className="h-auto w-[80px] sm:w-[100px] md:w-[120px] lg:w-[130px]"
118+
priority
119+
/>
120+
</div>
121+
</div>
122+
</div>
123+
<div className="container flex flex-col gap-5 py-10 lg:gap-10">
124+
<Text variant="heading3xl">Explore Sectors</Text>
125+
<div className="flex w-full flex-col justify-center gap-6">
126+
<div className="flex flex-wrap gap-6 lg:flex-nowrap">
127+
<SearchInput
128+
label={''}
129+
className={cn('w-full', Styles.Search)}
130+
onSubmit={(e) => {
131+
setSearchText(e);
132+
}}
133+
onClear={() => {
134+
setSearchText('');
135+
}}
136+
name={'Start typing to search for any sector'}
137+
/>
138+
<div className="flex items-center gap-2">
71139
<Text
72-
variant="headingLg"
73-
color="onBgDefault"
74-
fontWeight="regular"
140+
variant="bodyLg"
141+
fontWeight="semibold"
142+
className="whitespace-nowrap text-secondaryOrange"
75143
>
76-
We try to enables our users to create and participate in
77-
sectoral data collaboratives, amplifying the reach and
78-
impact of high-value datasets and sectoral use cases at
79-
various levels, including national, sub-national, and
80-
regional.
81-
</Text>{' '}
82-
</div>
83-
<div className="flex items-center justify-center gap-2 px-3 ">
84-
<Image
85-
src={'/s2.png'}
86-
alt={'s1'}
87-
width={130}
88-
height={100}
89-
className="h-auto w-[80px] sm:w-[100px] md:w-[120px] lg:w-[130px]"
90-
priority
91-
/>
92-
<Image
93-
src={'/s3.png'}
94-
alt={'s1'}
95-
width={230}
96-
height={100}
97-
className="h-auto w-[140px] sm:w-[180px] md:w-[200px] lg:w-[230px]"
98-
priority
99-
/>
100-
<Image
101-
src={'/s1.png'}
102-
alt={'s1'}
103-
width={130}
104-
height={100}
105-
className="h-auto w-[80px] sm:w-[100px] md:w-[120px] lg:w-[130px]"
106-
priority
144+
Sort :
145+
</Text>
146+
<Select
147+
label=""
148+
labelInline
149+
name="sort-select"
150+
options={[
151+
{
152+
label: 'Name Asc',
153+
value: 'name_asc',
154+
},
155+
{
156+
label: 'Name Desc',
157+
value: 'name_desc',
158+
},
159+
{
160+
label: 'Dataset Count Asc',
161+
value: 'datasetCount_asc',
162+
},
163+
{
164+
label: 'Dataset Count Desc',
165+
value: 'datasetCount_desc',
166+
},
167+
]}
168+
onChange={(e: any) => {
169+
handleSortChange(e);
170+
}}
107171
/>
108172
</div>
109173
</div>
110174
</div>
111-
<div className="container flex flex-col gap-5 py-10 lg:gap-10">
112-
<div className="flex w-full flex-col justify-center gap-6">
113-
<Text variant="heading3xl">Explore Sectors</Text>
114-
<div className="flex flex-wrap gap-6 lg:flex-nowrap">
115-
<SearchInput
116-
label={''}
117-
className={cn('w-full', Styles.Search)}
118-
name={'Start typing to search for any sector'}
119-
/>
120-
<div className="flex items-center gap-2">
121-
<Text
122-
variant="bodyLg"
123-
fontWeight="semibold"
124-
className="whitespace-nowrap text-secondaryOrange"
125-
>
126-
Sort :
127-
</Text>
128-
<Select
129-
label=""
130-
labelInline
131-
name="select"
132-
options={[
133-
{
134-
label: 'Recent',
135-
value: 'recent',
136-
},
137-
{
138-
label: 'Alphabetical',
139-
value: 'alphabetical',
140-
},
141-
]}
142-
/>
143-
</div>
144-
</div>
175+
{isLoading ? (
176+
<div className="m-4 flex justify-center">
177+
<Spinner />
145178
</div>
146-
<div className="grid w-full grid-cols-1 gap-10 md:grid-cols-2 lg:grid-cols-3">
147-
{getSectorsList.data?.sectors.map((sectors: any) => (
148-
<Link
149-
href={`/sectors/${sectors.slug}?sectors=${capitalizeWords(sectors.slug)}`}
150-
key={sectors.id}
151-
>
152-
<div className="flex w-full items-center gap-5 rounded-4 bg-surfaceDefault p-7 shadow-card">
153-
<div className="flex gap-4">
154-
<Image
155-
src={`/Sectors/${sectors.name}.svg`}
156-
width={80}
157-
height={80}
158-
alt={'Sectors Logo'}
159-
/>
160-
</div>
161-
<div className="flex w-full flex-col gap-3">
162-
<div className="flex flex-col gap-2">
163-
<Text variant="headingLg" fontWeight="semibold">
164-
{sectors.name}
165-
</Text>
166-
<Divider />
179+
) : data && data?.sectors?.length > 0 ? (
180+
<>
181+
<div className="grid w-full grid-cols-1 gap-10 md:grid-cols-2 lg:grid-cols-3">
182+
{data?.sectors.map((sectors: any) => (
183+
<Link
184+
href={`/sectors/${sectors.slug}?sectors=${capitalizeWords(sectors.slug)}`}
185+
key={sectors.id}
186+
>
187+
<div className="flex w-full items-center gap-5 rounded-4 bg-surfaceDefault p-7 shadow-card">
188+
<div className="flex gap-4">
189+
<Image
190+
src={`/Sectors/${sectors.name}.svg`}
191+
width={80}
192+
height={80}
193+
alt={'Sectors Logo'}
194+
/>
167195
</div>
168-
<div className="flex gap-1">
169-
<Text
170-
variant="bodyMd"
171-
fontWeight="bold"
172-
className=" text-primaryBlue"
173-
>
174-
{sectors.datasetCount}
175-
</Text>
176-
<Text variant="bodyMd">Datasets</Text>
196+
<div className="flex w-full flex-col gap-3">
197+
<div className="flex flex-col gap-2">
198+
<Text variant="headingLg" fontWeight="semibold">
199+
{sectors.name}
200+
</Text>
201+
<Divider />
202+
</div>
203+
<div className="flex gap-1">
204+
<Text
205+
variant="bodyMd"
206+
fontWeight="bold"
207+
className=" text-primaryBlue"
208+
>
209+
{sectors.datasetCount}
210+
</Text>
211+
<Text variant="bodyMd">Datasets</Text>
212+
</div>
177213
</div>
178214
</div>
179-
</div>
180-
</Link>
181-
))}
182-
</div>
183-
</div>
215+
</Link>
216+
))}
217+
</div>
218+
</>
219+
) : isError ? (
220+
<ErrorPage />
221+
) : (
222+
<></>
223+
)}
184224
</div>
185-
</>
186-
) : getSectorsList.isError ? (
187-
<ErrorPage />
188-
) : (
189-
<></>
190-
)}
225+
</div>
226+
</>
191227
</>
192228
</main>
193229
);

0 commit comments

Comments
 (0)