11'use client' ;
22
3+ import { useEffect , useState } from 'react' ;
34import Image from 'next/image' ;
45import Link from 'next/link' ;
56import { graphql } from '@/gql' ;
7+ import {
8+ Ordering ,
9+ SectorOrder ,
10+ SectorsListsQuery ,
11+ } from '@/gql/generated/graphql' ;
612import { 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
915import { GraphQL } from '@/lib/api' ;
1016import { cn } from '@/lib/utils' ;
1117import BreadCrumbs from '@/components/BreadCrumbs' ;
1218import { ErrorPage } from '@/components/error' ;
13- import { Loading } from '@/components/loading' ;
1419import Styles from '../datasets/dataset.module.scss' ;
1520
1621const 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
2833const 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