diff --git a/src/features/Search/Filters.tsx b/src/features/Search/Filters.tsx index 55ebec18b..18cc9508c 100644 --- a/src/features/Search/Filters.tsx +++ b/src/features/Search/Filters.tsx @@ -24,47 +24,26 @@ interface IFilterProps { loading: boolean; } -class FilterComponent extends React.Component { - constructor(props: IFilterProps) { - super(props); - this.handleSubmit = this.handleSubmit.bind(this); - this.renderFormik = this.renderFormik.bind(this); - this.resetForm = this.resetForm.bind(this); - } - public render() { - return ( - - - - ); - } - private parseInitialValues(initFilters: ISearchParameter[]) { +const FilterComponent: React.FC = (props) => { + const parseInitialValues = (initFilters: ISearchParameter[]) => { const initVals = { - school: this.searchParam2List('application.general.school', initFilters), - gradYear: this.searchParam2List( + school: searchParam2List('application.general.school', initFilters), + gradYear: searchParam2List( 'application.general.graduationYear', initFilters ), - degree: this.searchParam2List('application.general.degree', initFilters), - status: this.searchParam2List('status', initFilters), - skills: this.searchParam2List( - 'application.shortAnswer.skills', - initFilters - ), - jobInterest: this.searchParam2List( + degree: searchParam2List('application.general.degree', initFilters), + status: searchParam2List('status', initFilters), + skills: searchParam2List('application.shortAnswer.skills', initFilters), + jobInterest: searchParam2List( 'application.general.jobInterest', initFilters ), }; return initVals; - } + }; - private renderFormik(fp: FormikProps) { + const renderFormik = (fp: FormikProps) => { return (
{ - )} - {account && isSponsor(account) && ( - - )} - - - - - - - - - - - - - - - - - - ); - } - public async componentDidMount() { - const account = (await Account.getSelf()).data.data; - this.setState({ account }); + if (isSponsor(account)) { + const sponsor = (await Sponsor.getSelf()).data.data; + setSponsor(sponsor); + } + await triggerSearch(); + })(); + }, []); - if (isSponsor(account)) { - const sponsor = (await Sponsor.getSelf()).data.data; - this.setState({ sponsor }); - } - await this.triggerSearch(); - } - private getSearchFromQuery(): ISearchParameter[] { + // return the parameters of the search + const getSearchFromQuery = () => { const search = getValueFromQuery('q'); if (!search) { return []; @@ -167,14 +88,15 @@ class SearchContainer extends React.Component<{}, ISearchState> { } catch (e) { return []; } - } + }; - private getSearchBarFromQuery(): string { + const getSearchBarFromQuery = () => { const search = getValueFromQuery('searchBar'); return search ? decodeURIComponent(search) : ''; - } + }; - private downloadData(): void { + // function to download the candidates file + const downloadData = () => { const headers = [ { label: CONSTANTS.FIRST_NAME_LABEL, key: 'accountId.firstName' }, { label: CONSTANTS.LAST_NAME_LABEL, key: 'accountId.lastName' }, @@ -195,10 +117,7 @@ class SearchContainer extends React.Component<{}, ISearchState> { }, ]; // Return all fields for admin, and only subset for sponsors - if ( - this.state.account && - this.state.account.accountType === UserType.STAFF - ) { + if (account && account.accountType === UserType.STAFF) { headers.push({ label: 'Resume', key: 'application.general.URL.resume' }); headers.push({ label: 'Github', key: 'application.general.URL.github' }); headers.push({ @@ -264,7 +183,7 @@ class SearchContainer extends React.Component<{}, ISearchState> { tempHeaders.push(header.label); }); const csvData: string[] = [tempHeaders.join('\t')]; - this.filter().forEach((result) => { + filter().forEach((result) => { if (result.selected) { const row: string[] = []; headers.forEach((header) => { @@ -281,11 +200,11 @@ class SearchContainer extends React.Component<{}, ISearchState> { } }); fileDownload(csvData.join('\n'), 'hackerData.tsv', 'text/tsv'); - } + }; - private async triggerSearch(): Promise { - this.setState({ loading: true }); - const { model, query } = this.state; + // function to search based on query and type of user (hacker/admin/sponsor) + const triggerSearch = async (): Promise => { + setLoading(true); try { const response = await Search.search(model, query, { expand: true, @@ -297,32 +216,31 @@ class SearchContainer extends React.Component<{}, ISearchState> { hacker: v, })) : []; - this.setState({ results: tableData, loading: false }); + setResults(tableData); + setLoading(false); } catch (e) { ValidationErrorGenerator(e.data); - this.setState({ loading: false }); + setLoading(false); } - } - private onResetForm() { - this.setState({ query: [] }); - this.updateQueryURL([], this.state.searchBar); - } + }; + const onResetForm = () => { + setQuery([]); + updateQueryURL([], searchBar); + }; - private onFilterChange(newFilters: ISearchParameter[]) { - this.setState({ - query: newFilters, - }); - this.updateQueryURL(newFilters, this.state.searchBar); - this.triggerSearch(); - } + const onFilterChange = (newFilters: ISearchParameter[]) => { + setQuery(newFilters); + updateQueryURL(newFilters, searchBar); + triggerSearch(); + }; - private onSearchBarChanged(e: any) { + const onSearchBarChanged = (e: any) => { const searchBar = e.target.value; - this.setState({ searchBar }); - this.updateQueryURL(this.state.query, searchBar); - } + setSearchBar(searchBar); + updateQueryURL(query, searchBar); + }; - private updateQueryURL(filters: ISearchParameter[], searchBar: string) { + const updateQueryURL = (filters: ISearchParameter[], searchBar: string) => { const newSearch = `?q=${encodeURIComponent( JSON.stringify(filters) )}&searchBar=${encodeURIComponent(searchBar)}`; @@ -331,11 +249,11 @@ class SearchContainer extends React.Component<{}, ISearchState> { '', window.location.href.split('?')[0] + newSearch ); - } + }; - private filter() { - const { sponsor, viewSaved, results } = this.state; - const searchBar = this.state.searchBar.toLowerCase(); + // filter to read the search bar to retrieve useful info + const filter = () => { + const currSearchBar = searchBar.toLowerCase(); return results.filter(({ hacker }) => { const { accountId } = hacker; let foundAcct; @@ -345,29 +263,31 @@ class SearchContainer extends React.Component<{}, ISearchState> { account.lastName }`.toLowerCase(); foundAcct = - fullName.includes(searchBar) || - account.email.toLowerCase().includes(searchBar) || - account.phoneNumber.toString().includes(searchBar) || - account.gender.toLowerCase().includes(searchBar) || - (account._id && account._id.includes(searchBar)); + fullName.includes(currSearchBar) || + account.email.toLowerCase().includes(currSearchBar) || + account.phoneNumber.toString().includes(currSearchBar) || + account.gender.toLowerCase().includes(currSearchBar) || + (account._id && account._id.includes(currSearchBar)); } else { - foundAcct = accountId.includes(searchBar); + foundAcct = accountId.includes(currSearchBar); } const foundHacker = - hacker.id.includes(searchBar) || - hacker.application.general.school.includes(searchBar) || - hacker.application.general.degree.includes(searchBar) || - hacker.application.general.fieldOfStudy.includes(searchBar) || + hacker.id.includes(currSearchBar) || + hacker.application.general.school.includes(currSearchBar) || + hacker.application.general.degree.includes(currSearchBar) || + hacker.application.general.fieldOfStudy.includes(currSearchBar) || hacker.application.general.graduationYear .toString() - .includes(searchBar) || - hacker.application.general.jobInterest.includes(searchBar) || - hacker.status.includes(searchBar) || - hacker.application.shortAnswer.question1.includes(searchBar) || - hacker.application.shortAnswer.question2.includes(searchBar) || - hacker.application.accommodation.shirtSize.includes(searchBar) || + .includes(currSearchBar) || + hacker.application.general.jobInterest.includes(currSearchBar) || + hacker.status.includes(currSearchBar) || + hacker.application.shortAnswer.question1.includes(currSearchBar) || + hacker.application.shortAnswer.question2.includes(currSearchBar) || + hacker.application.accommodation.shirtSize.includes(currSearchBar) || (hacker.application.shortAnswer.skills && - hacker.application.shortAnswer.skills.toString().includes(searchBar)); + hacker.application.shortAnswer.skills + .toString() + .includes(currSearchBar)); const isSavedBySponsorIfToggled = !viewSaved || @@ -375,16 +295,82 @@ class SearchContainer extends React.Component<{}, ISearchState> { return (foundAcct || foundHacker) && isSavedBySponsorIfToggled; }); - } + }; - private toggleSaved = async () => { + const toggleSaved = async () => { // Resets the sponsor if they made changes to their saved hackers const sponsor = (await Sponsor.getSelf()).data.data; - const { viewSaved } = this.state; if (sponsor) { - this.setState({ sponsor, viewSaved: !viewSaved }); + setSponsor(sponsor); + setViewSaved(!viewSaved); } }; -} + + return ( + + + + +

+ Search +

+
+ + + +

+ Hackers +

+
+ + + + + {account && account.accountType === UserType.STAFF && ( + + )} + {account && isSponsor(account) && ( + + )} + + +
+
+
+
+ + + + + + + + + + +
+ ); +}; export default withContext(WithToasterContainer(SearchContainer)); diff --git a/src/pages/Admin/Search.tsx b/src/pages/Admin/Search.tsx index 44637771c..5ddd44341 100644 --- a/src/pages/Admin/Search.tsx +++ b/src/pages/Admin/Search.tsx @@ -1,9 +1,15 @@ import React from 'react'; +import Helmet from 'react-helmet'; import SearchContainer from '../../features/Search/Search'; - +import { HACKATHON_NAME } from '../../config'; const AdminSearchPage: React.FC = () => ( - +
+ + Search | {HACKATHON_NAME} + + +
); export default AdminSearchPage; diff --git a/src/pages/Sponsor/Search.tsx b/src/pages/Sponsor/Search.tsx index 3548bdba9..cd38c456d 100644 --- a/src/pages/Sponsor/Search.tsx +++ b/src/pages/Sponsor/Search.tsx @@ -1,9 +1,15 @@ import React from 'react'; +import Helmet from 'react-helmet'; import SearchContainer from '../../features/Search/Search'; - +import { HACKATHON_NAME } from '../../config'; const SponsorSearchPage: React.FC = () => ( - +
+ + Search | {HACKATHON_NAME} + + +
); export default SponsorSearchPage;