Updating search functionality setup

This commit is contained in:
Sharyn 2018-07-09 16:29:57 +02:00
parent 1beebf9b9b
commit b9dc338c6d
8 changed files with 210 additions and 35 deletions

View File

@ -1,4 +1,5 @@
import React from 'react';
import _ from 'lodash';
import RelatedInterviewsList from '../interviews/relatedInterviewsList';
import InterviewsList from '../interviews/interviewsList';
import SingleInterview from '../interviews/singleInterview';
@ -6,7 +7,7 @@ import TopicsList from '../topicsList';
import ProjectsList from '../projectsList';
import SearchBar from '../searchBar';
import SearchResults from '../searchResults';
import Data from '../../data/archives/interviews';
import InterviewsData from '../../data/archives/interviews';
import './style.scss';
class BrowseArchives extends React.Component {
@ -15,18 +16,24 @@ class BrowseArchives extends React.Component {
this.state = {
term: '',
searchResults: [],
isSingleInterviewModalOpen: false,
isInterviewsListModalOpen: false,
activeSingleInterviewId: 1,
isSearchActive: false,
};
this.onInputChange = this.onInputChange.bind(this);
this.onSearchInputChange = this.onSearchInputChange.bind(this);
this.toggleSingleInterview = this.toggleSingleInterview.bind(this);
this.toggleInterviewsListModal = this.toggleInterviewsListModal.bind(this);
this.setSearchTerm = this.setSearchTerm.bind(this);
this.clearSearchInput = this.clearSearchInput.bind(this);
}
onInputChange(event) {
onSearchInputChange = (event) => {
const { term } = this.state;
const getSearchResults = _.debounce(() => { this.getSearchResults(term); }, 500);
this.setState({
term: event.target.value,
isSearchActive: true,
@ -35,15 +42,42 @@ class BrowseArchives extends React.Component {
if (event.target.value.length === 0) {
this.setState({ isSearchActive: false });
}
// Throttle search result frequency with debounce
getSearchResults(term);
}
getSelectedInterview() {
getSearchResults = (term) => {
// Edit function to do actual search based on term and update searchResults with dynamic data
// eslint-disable-next-line
console.log(`Get search results array based on searching for: ${term}`);
this.setState({
searchResults: InterviewsData,
});
}
getSelectedInterview = () => {
const { activeSingleInterviewId } = this.state;
const selectedInterview = Data.find(item => item.id === activeSingleInterviewId);
const selectedInterview = InterviewsData.find(item => item.id === activeSingleInterviewId);
return selectedInterview;
}
toggleInterviewsListModal() {
setSearchTerm = (event) => {
this.setState({
term: event.target.innerText,
isSearchActive: true,
});
}
clearSearchInput = () => {
this.setState({
isSearchActive: false,
term: '',
});
}
toggleInterviewsListModal = () => {
const { isInterviewsListModalOpen } = this.state;
this.setState({
@ -52,13 +86,19 @@ class BrowseArchives extends React.Component {
});
}
toggleSingleInterview(event) {
toggleSingleInterview = (event) => {
const { isSingleInterviewModalOpen, isInterviewsListModalOpen } = this.state;
let clickedInterview = event.target;
while (clickedInterview.id === '') {
clickedInterview = clickedInterview.parentNode;
}
const clickedSingleInterviewId = clickedInterview.id;
this.setState({
isInterviewsListModalOpen: !isInterviewsListModalOpen,
isSingleInterviewModalOpen: !isSingleInterviewModalOpen,
activeSingleInterviewId: Number(event.target.id),
activeSingleInterviewId: Number(clickedSingleInterviewId),
});
}
@ -69,32 +109,42 @@ class BrowseArchives extends React.Component {
isSearchActive,
activeSingleInterviewId,
term,
searchResults,
} = this.state;
return (
<div className="browse-wrap">
<SearchBar onInputChange={this.onInputChange} term={term} />
<SearchBar
onSearchInputChange={this.onSearchInputChange}
clearSearchInput={this.clearSearchInput}
isSearchActive={isSearchActive}
term={term}
/>
<div className="browse-content-wrap container">
<div className="browse-content-left">
{isSearchActive &&
(<RelatedInterviewsList
data={Data}
data={InterviewsData}
toggleSingleInterview={this.toggleSingleInterview}
/>)
}
</div>
<div className="browse-content-right">
{isSearchActive ? <SearchResults /> :
{isSearchActive ? (
<SearchResults
data={searchResults}
toggleSingleInterview={this.toggleSingleInterview}
/>) :
(
<React.Fragment>
<InterviewsList
data={Data}
data={InterviewsData}
isInterviewsListModalOpen={isInterviewsListModalOpen}
toggleSingleInterview={this.toggleSingleInterview}
toggleInterviewsListModal={this.toggleInterviewsListModal}
/>
<TopicsList />
<ProjectsList />
<TopicsList setSearchTerm={this.setSearchTerm} />
<ProjectsList setSearchTerm={this.setSearchTerm} />
</React.Fragment>
)
}

View File

@ -1,14 +1,26 @@
import React from 'react';
import { PropTypes } from 'prop-types';
import Data from '../../data/archives/projects';
import './style.scss';
export default () => (
const ProjectsList = props => (
<div className="projects-list">
<h4>Projects</h4>
<ul>
{
Data.map(project => <li key={project}><span>{ project }</span></li>)
Data.map(project => (
// eslint-disable-next-line
<li key={project} onClick={props.setSearchTerm}>
<span>{ project }</span>
</li>
))
}
</ul>
</div>
);
ProjectsList.propTypes = {
setSearchTerm: PropTypes.func.isRequired,
};
export default ProjectsList;

View File

@ -6,20 +6,34 @@ const SearchBar = props => (
<div className="search-bar">
<div className="container">
<h3>Browse Archives</h3>
<input
className="search-input"
type="search"
placeholder="Search archives"
value={props.term}
onChange={props.onInputChange}
/>
<form className="search-form">
<input
className="search-input"
type="search"
placeholder="Search archives"
value={props.term}
onChange={props.onSearchInputChange}
/>
{ props.isSearchActive && (
// eslint-disable-next-line
<span
className="search-clear-button"
onClick={props.clearSearchInput}
>
Clear search
</span>
)
}
</form>
</div>
</div>
);
SearchBar.propTypes = {
term: PropTypes.string.isRequired,
onInputChange: PropTypes.func.isRequired,
}
isSearchActive: PropTypes.bool.isRequired,
onSearchInputChange: PropTypes.func.isRequired,
clearSearchInput: PropTypes.func.isRequired,
};
export default SearchBar;

View File

@ -13,17 +13,40 @@
}
}
.search-form {
position: relative;
bottom: calculateRem(-24);
}
.search-input {
width: 100%;
height: calculateRem(48);
border: 5px solid #efefef;
padding: calculateRem(12);
padding: calculateRem(12) calculateRem(100) calculateRem(12) calculateRem(12);
font-size: calculateRem(16);
position: relative;
bottom: calculateRem(-24);
&:focus,
&:active {
outline: none;
}
}
.search-clear-button {
position: absolute;
top: 10%;
right: calculateRem(4);
height: 80%;
border: 0;
padding: 0 calculateRem(16);
cursor: pointer;
font-size: calculateRem(14);
background-color: #fff;
display: flex;
align-items: center;
&:focus,
&:active {
outline: none;
}
}

View File

@ -1,10 +1,40 @@
import React from 'react';
import { PropTypes } from 'prop-types';
import './style.scss';
const SearchResults = () => (
<div className="search-results">
<p>Search results go here</p>
</div>
);
const SearchResults = (props) => {
if (!props.data) {
return <div>Loading...</div>;
}
return (
<div className="search-results">
<ul>
{ props.data.map(interview => (
// eslint-disable-next-line
<li
id={interview.id}
key={interview.id}
onClick={props.toggleSingleInterview}
>
<h3>{ interview.name }</h3>
<h5>1) Question goes here</h5>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce hendrerit dolor quis
ante mollis fringilla. <span>Lorem</span> ipsum dolor sit amet, consectetur adipiscing
elit.
</p>
</li>
))
}
</ul>
</div>
);
};
SearchResults.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
toggleSingleInterview: PropTypes.func.isRequired,
};
export default SearchResults;

View File

@ -2,4 +2,37 @@
.search-results {
li {
margin-bottom: calculateRem(32);
cursor: pointer;
h3 {
font-size: calculateRem(18);
margin-bottom: calculateRem(8);
}
h5 {
font-size: calculateRem(16);
margin-bottom: calculateRem(8);
}
p {
font-size: calculateRem(14);
span {
position: relative;
&::before {
content: '';
position: absolute;
top: -10%;
left: -15%;
height: 120%;
width: 130%;
background-color: #efefef;
z-index: -1;
}
}
}
}
}

View File

@ -1,14 +1,26 @@
import React from 'react';
import { PropTypes } from 'prop-types';
import Data from '../../data/archives/topics';
import './style.scss';
export default () => (
const TopicsList = props => (
<div className="topics-list">
<h4>Topics</h4>
<ul>
{
Data.map(topic => <li key={topic}><span>{ topic }</span></li>)
Data.map(topic => (
// eslint-disable-next-line
<li key={topic} onClick={props.setSearchTerm}>
<span>{ topic }</span>
</li>
))
}
</ul>
</div>
);
TopicsList.propTypes = {
setSearchTerm: PropTypes.func.isRequired,
};
export default TopicsList;

View File

@ -38,6 +38,7 @@
"dependencies": {
"@zeit/next-sass": "^0.2.0",
"html-react-parser": "^0.4.5",
"lodash": "^4.17.10",
"next": "^6.0.3",
"node-sass": "^4.9.0",
"prop-types": "^15.6.1",