· 4 years ago · Jun 20, 2021, 10:48 AM
1import React, {useState, useEffect} from 'react';
2// material ui components
3import Grid from '@material-ui/core/Grid';
4import Accordion from '@material-ui/core/Accordion';
5import AccordionSummary from '@material-ui/core/AccordionSummary';
6import AccordionDetails from '@material-ui/core/AccordionDetails';
7import Typography from '@material-ui/core/Typography';
8import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
9import Chip from '@material-ui/core/Chip';
10import Button from '@material-ui/core/Button';
11import AccordionActions from '@material-ui/core/AccordionActions';
12import Divider from '@material-ui/core/Divider';
13import TextField from '@material-ui/core/TextField';
14import FaceIcon from '@material-ui/icons/Face';
15import DoneIcon from '@material-ui/icons/Done';
16import Link from '@material-ui/core/Link';
17import FormControlLabel from '@material-ui/core/FormControlLabel';
18import FormGroup from '@material-ui/core/FormGroup';
19import Checkbox from '@material-ui/core/Checkbox';
20import RadioGroup from '@material-ui/core/RadioGroup';
21import FormControl from '@material-ui/core/FormControl';
22import FormLabel from '@material-ui/core/FormLabel';
23import Radio from '@material-ui/core/Radio';
24import Autocomplete from '@material-ui/lab/Autocomplete'
25import Axios from "axios";
26import ProjectPreviewComponent from "../../components/project.preview.block"
27/*import DatePicker from '@material-ui/lab/DatePicker';
28import AdapterDateFns from '@material-ui/lab/AdapterDateFns';
29import LocalizationProvider from '@material-ui/lab/LocalizationProvider';
30import DateFnsUtils from '@date-io/date-fns';*/
31import { connect } from "react-redux"
32// redux actions
33import {projectdata} from '../../redux/projectscreen/single.project.actions';
34// react router
35import {useHistory} from 'react-router-dom';
36
37
38
39const SearchProjectsPg = (props)=>{
40 // router hoook
41 const history = useHistory()
42 const [dateValue, setDateValue] = React.useState(null);
43 const [searchDefaultData, setSearchDefaultData] = useState(null)
44 const [queryParams, setQueryParams] = useState({})
45 const [queryResData, setqueryResData] = useState(null);
46 const [filteredQuery, setfilteredQuery] = useState(null);
47 const [clearInputs, setclearInputs] = useState(false);
48
49
50 // get default autocomplete data
51 useEffect(() => {
52 Axios.get("http://localhost:5001/react-auth-test-bd5be/us-central1/projectsSearchData")
53 .then((res)=>{
54 console.log(res.data)
55 setSearchDefaultData(res.data)
56 })
57 .catch(e=>console.log(e))
58 }, []);
59
60 const yearsGenerator = () => {
61 var currentYear = new Date().getFullYear(), years = [];
62 let startYear = 1980;
63 while ( startYear <= currentYear ) {
64 years.push(`${startYear++}`);
65 }
66 return years;
67 }
68
69 const searchEventHandler = (fieldKey, e)=>{
70 e.preventDefault()
71 setclearInputs(false)
72 console.log("am the text value thats been crashing your script", e.target.value)
73
74 if(fieldKey === 'keyword' || fieldKey === 'category'){
75 console.log("the filed key fo an arr", fieldKey)
76 // u cant iterate queryparams[filedkey] the first time as it dont exist.
77 let updatedArr = queryParams[fieldKey] || [e.target.value]
78 console.log(...updatedArr)
79 setQueryParams({
80 ...queryParams,
81 [fieldKey]: [
82 ...updatedArr,
83 e.target.value
84 ]
85 })
86 }else{
87 setQueryParams({
88 ...queryParams,
89 [fieldKey]: e.target.value
90 })
91 }
92 }
93
94 //find similarity between mutliple choice input (categories and keywords) and existing filter
95 const query_userInputed_Arr = (queryResArr, userInputedArr)=>{
96 let filteredQueryArr = [];
97 let sharedArrValue;
98 queryResArr?.forEach(queryArrvalue=>{
99 sharedArrValue = userInputedArr.find(Bvalue => Bvalue === queryArrvalue)
100 if(sharedArrValue){
101 filteredQueryArr.push(sharedArrValue)
102 }
103 });
104 return filteredQueryArr;
105 }
106
107 useEffect(() => {
108 console.log(queryParams)
109 //console.log("object length", Object.keys(queryParams)?.length)
110
111 // query only if queryParams length is 1
112 if(Object.keys(queryParams)?.length === 1 ){
113 console.log("object length", Object.keys(queryParams)?.length)
114 Axios.post("http://localhost:5001/react-auth-test-bd5be/us-central1/dynamicDbSearch",{
115 ...queryParams
116 })
117 .then(res=>{
118 console.log(res)
119 // if only one argument is present, query the db and get push the res to state
120 setqueryResData(res.data)
121 setfilteredQuery(res.data)
122 })
123 .catch(e=>console.log(e))
124 }else{
125 // check the docs that satisfy the args instead of querying the db each time a new arg is entered
126 let filteredArrOfDocs = [];
127 // queryResData containes the docs of the first and only api query
128 queryResData?.map((doc)=>{
129 let fileMeetsCriteria = 0;
130 //console.log(doc)
131 console.log("query params args", Object.keys(queryParams).length)
132 Object.keys(queryParams)?.map(key=>{
133 // console.log(key)
134
135 if(typeof queryParams[key] === 'string' && (key !== 'pushDateFrom' || key !== 'pushDateTill')){
136 if(queryParams[key] === doc[key]){
137 fileMeetsCriteria++;
138 }
139 }
140 if(key === 'pushDateFrom'){
141 if(doc.pushDate >= queryParams[key]){
142 fileMeetsCriteria ++;
143 }
144 }
145 if(key === 'pushDateTill'){
146 if(doc.pushDate <= queryParams[key]){
147 fileMeetsCriteria ++;
148 }
149 }
150 if(typeof queryParams[key] === "object" && key === "keyword"){
151 let arrMatch = query_userInputed_Arr(queryParams[key], doc.keywords)
152 if(arrMatch.length > 0){
153 fileMeetsCriteria ++;
154 }
155 }
156 if(typeof queryParams[key] === "object" && key === "category"){
157 let arrMatch = query_userInputed_Arr(queryParams[key], doc.categories)
158 if(arrMatch.length > 0){
159 fileMeetsCriteria ++;
160 }
161 }
162 })
163
164 console.log("files meet criteria ", fileMeetsCriteria)
165 if(Object.keys(queryParams).length === fileMeetsCriteria){
166 filteredArrOfDocs.push(doc)
167 }
168 })
169 setfilteredQuery(filteredArrOfDocs)
170 }
171
172 }, [queryParams]);
173
174 // set default autocomplete values upon first render
175 useEffect(()=>{
176 console.log(yearsGenerator())
177 setDateValue(yearsGenerator)
178 },[])
179
180 // get project data and go to project screen
181 const projectAddMoreHandler = () => (obj) => {
182 console.log(obj)
183 props.projectdata(obj)
184 console.log("i should now go to projecct page")
185 history.push('/project')
186 }
187
188
189 const projectsPreviews = (objArr) =>{
190 console.log(objArr)
191 return objArr?.map((dataObj)=>{
192 return(
193 <ProjectPreviewComponent seeProject={projectAddMoreHandler()} data={dataObj}/>
194 );
195 })
196 }
197
198 return(
199 <Grid container md={12} xs={12}>
200 <Grid container item xs={12} md={12} className={'search-component-container'}
201 justify="center">
202 <Grid md={2} lg={2} xs={12} className={'search-side-bar'} item container>
203 <Grid md={11} xs={12} lg={12} className={'search-res-sub-container'} item container
204 >
205
206 <Grid item container lg={12} xs={12} md={12}
207 alignItems="center"
208 justify="center"
209 className={'search-container'}
210 >
211 <Grid xs={12} md={12} lg={12} item container
212 className={"side-bar-search-title"}>
213 <p>search by title</p>
214 </Grid>
215 <Grid xs={12} md={12} lg={12} container item>
216 <Autocomplete
217
218 options={searchDefaultData?.titles ?? ["xxx", "xxx"]}
219 onBlur={(e)=>searchEventHandler("title", e)}
220 getOptionLabel={(option) => option}
221 value={queryParams?.title || ""}
222 defaultValue={''}
223 classes={{
224 root: 'multi-choice-textfield'
225 }}
226 renderInput={(params) => <TextField {...params} label="title" variant="outlined" />}
227 />
228 </Grid>
229 </Grid>
230 <Grid item container lg={12} xs={12} md={12}
231 alignItems="center"
232 justify="center"
233 className={'search-container'}
234 >
235 <Grid xs={12} md={12} lg={12} item container
236 className={"side-bar-search-title"}>
237 <Grid xs={12} md={12} lg={12} item container
238 className={"side-bar-search-title"}>
239 <p>search by date</p>
240 </Grid>
241 <Grid xs={6} md={12} lg={12} item container>
242 <Autocomplete
243 id="datePickerFrom"
244 options={dateValue ?? ["xxx", "xxx"]}
245 onBlur={(e)=>searchEventHandler("pushDateFrom", e)}
246 getOptionLabel={(option) => option}
247 value={queryParams.pushDateFrom || 1980}
248 defaultValue={''}
249 classes={{
250 root: 'multi-choice-textfield'
251 }}
252 renderInput={(params) => <TextField {...params} label="from" variant="outlined" type="number"/>}
253 />
254 </Grid>
255 <Grid xs={6} md={12} lg={12} item container>
256 <Autocomplete
257 id="datePickerTill"
258 options={dateValue ?? ["xxx", "xxx"]}
259 onBlur={(e)=>searchEventHandler("pushDateTill", e)}
260 value={queryParams.pushDateTill || 2021}
261 getOptionLabel={(option) => option}
262 defaultValue={''}
263 classes={{
264 root: 'multi-choice-textfield'
265 }}
266 renderInput={(params) => <TextField {...params} label="till" variant="outlined" type="number"/>}
267 />
268 </Grid>
269 </Grid>
270 </Grid>
271 <Grid xs={12} md={12} lg={12}
272 className={'radio-btn-form search-container'}
273 container item
274 >
275 {/* <Grid xs={12} md={12} lg={12} item container
276 className={"side-bar-search-title"}>
277 <p>University</p>
278
279 <input type="serch" placeholder="search by university" className={"search-input"} />
280 </Grid> */}
281 <Grid xs={12} md={12} lg={12} item container
282 className={"side-bar-search-title"}>
283 <p>search by university</p>
284 </Grid>
285 {/* <input
286 type="serch"
287 placeholder="search by title"
288 className={"search-input"}
289 onBlur={(e)=>searchEventHandler(e)}
290 /> */}
291 <Grid xs={12} md={12} lg={12} container item>
292 <Autocomplete
293 id="universitiesSearchIpt"
294 options={searchDefaultData?.universities ?? ["xxx", "xxx"]}
295 onBlur={(e)=>searchEventHandler("university", e)}
296 getOptionLabel={(option) => option}
297 value={queryParams.university || ""}
298 defaultValue={''}
299 classes={{
300 root: 'multi-choice-textfield'
301 }}
302 renderInput={(params) => <TextField {...params} label="university" variant="outlined" />}
303 />
304 </Grid>
305 </Grid>
306 {/* search by author */}
307 <Grid xs={12} md={12} lg={12}
308 className={'radio-btn-form search-container'}
309 container item
310 >
311 <Grid xs={12} md={12} lg={12} item container
312 className={"side-bar-search-title"}>
313 <p>search by author</p>
314 </Grid>
315 {/* <input
316 type="serch"
317 placeholder="search by title"
318 className={"search-input"}
319 onBlur={(e)=>searchEventHandler(e)}
320 /> */}
321 <Grid xs={12} md={12} lg={12} container item>
322 <Autocomplete
323 id="datePickerFrom"
324 options={searchDefaultData?.authors ?? ["xxx", "xxx"]}
325 onBlur={(e)=>searchEventHandler("author", e)}
326 getOptionLabel={(option) => option}
327 value={queryParams.author || ""}
328 defaultValue={''}
329 classes={{
330 root: 'multi-choice-textfield'
331 }}
332 renderInput={(params) => <TextField {...params} label="title" variant="outlined" />}
333 />
334 </Grid>
335 </Grid>
336 {/* search by teacher */}
337 <Grid xs={12} md={12} lg={12}
338 className={'radio-btn-form search-container'}
339 container item
340 >
341 <Grid xs={12} md={12} lg={12} item container
342 className={"side-bar-search-title"}>
343 <p>search by categorie</p>
344 </Grid>
345 {/* <input
346 type="serch"
347 placeholder="search by title"
348 className={"search-input"}
349 onBlur={(e)=>searchEventHandler(e)}
350 /> */}
351 <Grid xs={12} md={12} lg={12} container item>
352 <Autocomplete
353 id="datePickerFrom"
354 options={searchDefaultData?.categories ?? ["xxx", "xxx"]}
355 onBlur={(e)=>searchEventHandler("category", e)}
356 getOptionLabel={(option) => option}
357 value={queryParams.category ? queryParams.category[queryParams.category?.length - 1] : ""}
358 defaultValue={''}
359 classes={{
360 root: 'multi-choice-textfield'
361 }}
362 renderInput={(params) => <TextField {...params} label="title" variant="outlined" />}
363 />
364 </Grid>
365
366 </Grid>
367 <Grid xs={12} md={12} lg={12}
368 className={'radio-btn-form search-container'}
369 container item
370 >
371 <Grid xs={12} md={12} lg={12} item container
372 className={"side-bar-search-title"}>
373 <p>search by keyword</p>
374 </Grid>
375 {/* <input
376 type="serch"
377 placeholder="search by title"
378 className={"search-input"}
379 onBlur={(e)=>searchEventHandler(e)}
380 /> */}
381 <Grid xs={12} md={12} lg={12} container item>
382 <Autocomplete
383 id="datePickerFrom"
384 options={searchDefaultData?.keywords ?? ["xxx", "xxx"]}
385 onBlur={(e)=>searchEventHandler("keyword", e)}
386 getOptionLabel={(option) => option}
387 value={queryParams.keyword ? queryParams.keyword[queryParams.keyword?.length - 1] : ""}
388 defaultValue={''}
389 classes={{
390 root: 'multi-choice-textfield'
391 }}
392 renderInput={(params) => <TextField {...params} label="title" variant="outlined" />}
393 />
394 </Grid>
395
396 </Grid>
397 {/* */}
398
399 <Grid xs={12} md={12} lg={12}
400 container item
401 className={'side-bar-btn'}>
402 <Button size="small" variant='outlined' color='primary'
403 disableElevation
404 classes={{
405 root: 'custom-search-btn',
406 label: 'custom-search-btn-label'
407 }}
408 onClick={()=>{
409 setclearInputs(true)
410 setQueryParams({})
411 setqueryResData(null)
412 }}>
413 delete filters
414 </Button>
415 </Grid>
416 </Grid>
417 </Grid>
418 {/* main search block */}
419 <Grid md={10} lg={10} xs={12} className={'search-result-top-container'}
420 justify="center" spacing={2} container item
421 style={{
422 border: "1px solid green"
423 }}>
424 {
425 filteredQuery?.length > 0 ?
426 projectsPreviews(filteredQuery)
427 :
428 <>
429 nothing to show!
430 </>
431 }
432 </Grid>
433
434 </Grid>
435 </Grid>
436 );
437}
438
439const mapStateToProps = (state) => {
440 return {
441 projectscreendata: state.projectscreendata
442 };
443 };
444 const mapDispatchToProps = dispatch => {
445 return {
446 projectdata : (obj) => dispatch(projectdata(obj))
447 };
448 };
449
450 export default connect(mapStateToProps, mapDispatchToProps)(SearchProjectsPg);
451
452//export default SearchProjectsPg;