1- /* eslint-disable sort-keys */
1+ /* eslint-disable max-lines-per-function */
22/* eslint-disable react-hooks/exhaustive-deps */
33import React , { useCallback , useEffect , useState } from 'react' ;
44import Box from '@material-ui/core/Box' ;
@@ -8,7 +8,7 @@ import useMediaQuery from '@material-ui/core/useMediaQuery';
88import { makeStyles , useTheme } from '@material-ui/core/styles' ;
99import axios from 'axios' ;
1010import _ from 'lodash' ;
11-
11+ import { ArrayParam , NumberParam , StringParam , useQueryParam , withDefault } from 'use-query-params' ;
1212import { GetStartedCard , GenericHeaderSection } from '../../components' ;
1313import SearchBar from '../SearchProjects/SearchBar' ;
1414import FAQCard from '../../components/FAQCard' ;
@@ -20,51 +20,80 @@ const useStyles = makeStyles({
2020} ) ;
2121
2222const Faq = ( ) => {
23- const breadCrumbLinks = [
24- { name : 'Home' , href : '/home' } ,
25- { name : 'FAQ' , href : '/about/faq' } ,
26- ] ;
27- const [ data , setData ] = useState ( [ ] ) ;
28- const [ pageNum , setPageNum ] = useState ( 1 ) ;
29- const [ query , setQuery ] = useState ( '' ) ;
30- const [ status , setStatus ] = useState ( 'fetchedFaq' ) ;
31- const [ totalCount , setTotalCount ] = useState ( 0 ) ;
3223 const classes = useStyles ( ) ;
33- const apiUrl = `${ process . env . REACT_APP_API_URL } /api/faqs/` ;
34-
3524 const theme = useTheme ( ) ;
3625 const largeScreen = useMediaQuery ( theme . breakpoints . up ( 'sm' ) , {
3726 noSsr : true ,
3827 } ) ;
28+ const apiUrl = `${ process . env . REACT_APP_API_URL } /api/faqs/` ;
29+ const [ faqs , setFaqs ] = useState ( [ ] ) ;
30+ const [ status , setStatus ] = useState ( 'fetchedFaq' ) ;
31+ const [ totalCount , setTotalCount ] = useState ( 0 ) ;
32+ const [ expandedFaqs , setExpandedFaqs ] = useQueryParam (
33+ 'opened' ,
34+ withDefault ( ArrayParam , [ ] )
35+ ) ;
36+ const [ pageNum , setPageNum ] = useQueryParam (
37+ 'page' ,
38+ withDefault ( NumberParam , 1 )
39+ ) ;
40+ const [ query , setQuery ] = useQueryParam (
41+ 'query' ,
42+ withDefault ( StringParam , '' )
43+ ) ;
3944
40- const getFAQData = async ( currentQuery , resetPageNum ) => {
45+ const breadCrumbLinks = [
46+ { name : 'Home' , href : '/home' } ,
47+ { name : 'FAQ' , href : '/about/faq' } ,
48+ ] ;
49+
50+ const getFaqData = async ( currentQuery , resetState ) => {
4151 const params = {
42- page : resetPageNum ? 1 : pageNum ,
52+ page : resetState ? 1 : pageNum ,
4353 page_size : largeScreen ? 10 : 5 ,
4454 search : currentQuery ,
4555 } ;
46- // reset pagination current page to 1 in certain cases such as new search query input
47- if ( resetPageNum ) {
56+ if ( resetState ) {
57+ setExpandedFaqs ( [ ] ) ;
4858 setPageNum ( 1 ) ;
4959 }
5060 const res = await axios . get ( apiUrl , { params : params } ) ;
51- setData ( res . data . results ) ;
61+ setFaqs ( res . data . results ) ;
5262 setTotalCount ( res . data . count ) ;
5363 setStatus ( params . search ? 'fetchedSearch' : 'fetchedFaq' ) ;
5464 } ;
5565
5666 const debounce = useCallback (
5767 _ . debounce ( ( value ) => {
58- getFAQData ( value , true ) ;
68+ getFaqData ( value , true ) ;
5969 } , 300 ) ,
6070 [ ]
6171 ) ;
6272
6373 useEffect ( ( ) => {
64- getFAQData ( query , false ) ;
65- // eslint-disable-next-line react-hooks/exhaustive-deps
74+ getFaqData ( query , false ) ;
6675 } , [ pageNum , largeScreen ] ) ;
6776
77+ const handleFaqClick = ( faq ) => {
78+ const expanded = [ ...expandedFaqs ] ;
79+ const idx = expanded . indexOf ( faq . id . toString ( ) ) ;
80+ if ( idx > - 1 ) {
81+ expanded . splice ( idx , 1 ) ;
82+ } else {
83+ const requestBody = {
84+ question : faq . question ,
85+ answer : faq . answer ,
86+ view_count : faq . view_count ,
87+ } ;
88+ axios . post (
89+ `${ process . env . REACT_APP_API_URL } /api/faqs/${ faq . id } /increment_count/` ,
90+ requestBody
91+ ) ;
92+ expanded . push ( faq . id . toString ( ) ) ;
93+ }
94+ setExpandedFaqs ( expanded ) ;
95+ } ;
96+
6897 const handleInput = ( event ) => {
6998 setQuery ( event . target . value ) ;
7099 debounce ( event . target . value ) ;
@@ -87,17 +116,20 @@ const Faq = () => {
87116 dataCy = 'search-faq'
88117 onInput = { handleInput }
89118 placeholder = 'Search the Civic Tech Index'
119+ value = { query }
90120 />
91121 </ Grid >
92122 </ Grid >
93123 </ GenericHeaderSection >
94124 </ Container >
95125 < FAQCard
96- title = { status === 'fetchedFaq' ? 'Top Asked Questions' : `Search results (${ totalCount } )` }
97- faqs = { data }
98- pages = { Math . ceil ( totalCount / ( largeScreen ? 10 : 5 ) ) }
99126 currentPageNum = { pageNum }
127+ expandedFaqs = { expandedFaqs }
128+ faqs = { faqs }
129+ onFaqClick = { handleFaqClick }
100130 onPageChange = { handlePageNumChange }
131+ pages = { Math . ceil ( totalCount / ( largeScreen ? 10 : 5 ) ) }
132+ title = { status === 'fetchedFaq' ? 'Top Asked Questions' : `Search results (${ totalCount } )` }
101133 />
102134 < GetStartedCard
103135 headerTitle = 'Can’t find an answer?'
@@ -107,5 +139,4 @@ const Faq = () => {
107139 </ Box >
108140 ) ;
109141} ;
110-
111142export default Faq ;
0 commit comments