Skip to content

Commit

Permalink
configs search suggestions and so on
Browse files Browse the repository at this point in the history
  • Loading branch information
SummySumanth committed Sep 10, 2019
1 parent 4de30ab commit e2bae85
Show file tree
Hide file tree
Showing 26 changed files with 385 additions and 190 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ An simple version of the Flickr website using the Flickr API.

[click here](https://google.com) - _**Refreshing page would not work here**_ as they are just static files (without served from a server) and because of frontend routing, it wont be able to resolve files and you would get a 404 on refreshing and that is expected.

## Configurations
Following are the configurations that can be made to this project, all the configurations exist in route directory configs.js (./configs.js)
1. flickerApiKey - Define your own flicker api key here _**[params - api key in string]**_
2. searchNetworkCallDelay - Define the delay to be present before making network call for search auto-complete suggestions _**[params - Milliseconds key in number]**_

## NPM Scripts

#### To install the required npm packages ( Required only once )
Expand Down
4 changes: 4 additions & 0 deletions configs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
flickerApiKey : '19047cf8f892417333e03b550bd901a6',
searchNetworkCallDelay : 500,
}
12 changes: 12 additions & 0 deletions src/actions/searchBar/searchBarActionTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const searchBarActionTypes = {
ON_CHANGE : 'searchBarActions/ON_CHANGE',
ON_BLUR : 'searchBarActions/ON_BLUR',
TRIGGER_SEARCH : 'searchBarActions/TRIGGER_SEARCH',
HIDE_SUGGESTIONS: 'searchBarActions/HIDE_SUGGESTIONS',
SHOW_SUGGESTIONS: 'searchBarActions/SHOW_SUGGESTIONS',
SELECT_SUGGESTION: 'searchBarActions/SELECT_SUGGESTION',
SET_SUGGESTIONS: 'searchBarActions/SET_SUGGESTIONS',
SET_SEARCH_PARAM: 'searchBarActions/SET_SEARCH_PARAM',
};

export default searchBarActionTypes;
14 changes: 14 additions & 0 deletions src/actions/searchBar/searchBarActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import services from '../../services/flicker'
import debounce from '../../scripts/debounce';
const searchBarActions = {
showSuggestions: (payload) => () => {
console.log('searching for suggestions with param: ', payload);

services.searchForGroups(payload)
.then(response =>{
console.log('Response received is: ', response);
});
}
};

export default searchBarActions;
2 changes: 2 additions & 0 deletions src/assets/images/common/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import rightArrow from './right-arrow.png';
import searchIcon from './search.png';

export {
rightArrow,
searchIcon
}
Binary file added src/assets/images/common/search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { withRouter } from 'react-router-dom'
import PropTypes from 'prop-types';
import '../../styles/landingPage/landingPage.scss';

class LandingPage extends Component{

class GroupsPage extends Component{

static propTypes = {
onNavChange: PropTypes.func.isRequired,

}

onClickHandler (direction) {
Expand All @@ -23,4 +22,4 @@ class LandingPage extends Component{
}
}

export default withRouter(LandingPage);
export default withRouter(GroupsPage);
71 changes: 71 additions & 0 deletions src/components/searchBar/searchBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React,{ Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import searchBarActions from '../../actions/searchBar/searchBarActions';
import { searchIcon } from '../../assets/images/common/';
import configs from '../../../configs';

import '../../styles/components/searchBar.scss';


class SearchBar extends Component{

static propTypes = {
showSuggestions: PropTypes.func.isRequired,
};

constructor(props){
super(props);
this.state = {
callNetworkFlag : true,
}
}

onChangeHandler = (e) =>{
if(this.state.callNetworkFlag){
this.props.showSuggestions(e.target.value);
this.setState({
callNetworkFlag: false
});
}
setTimeout(() =>{
this.setState({
callNetworkFlag: true
});
}, configs.searchNetworkCallDelay);
};

onEnterHandler = () =>{

};

render(){
return(
<div className={'FF_searchbar-wrapper'}>
<div className={'FF_searchbar-suggestions-wrapper'}>
<div className={'FF_searchbar-suggestions-container'}>
<div></div>
</div>
</div>

<div className={'FF_searchbar-container'}>
<div className={'FF_searchbar-icon-container'}>
<img className={'FF_searchbar-icon'} src={searchIcon} />
</div>

<input className={'FF_searchbar-input'} type={'text'} onChange={this.onChangeHandler} placeholder={'Search Group !'}/>
</div>
</div>
);
}
}

const mapStateToProps = state =>({
searchBar : state.searchBar,
});

const mapDispatchToProps = dispatch =>({
showSuggestions : searchParam => dispatch(searchBarActions.showSuggestions(searchParam)),
});
export default connect(mapStateToProps, mapDispatchToProps)(SearchBar);
22 changes: 22 additions & 0 deletions src/components/topBar/topBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React,{ Component } from 'react';
import PropTypes from 'prop-types';
import '../../styles/components/topBar.scss';

class TopBar extends Component{

static propTypes = {

};

render(){
return(
<div className={'FF_topBar-wrapper'}>
<div className={'FF_topBar-container'}>
{this.props.children}
</div>
</div>
);
}
}

export default TopBar;
3 changes: 0 additions & 3 deletions src/configs.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { combineReducers } from 'redux';

import landingPageReducer from './landingPage/landingPageReducer';
import searchBarReducer from './searchBar/searchBarReducer';

const allReducers = combineReducers({
landingPage : landingPageReducer,
searchBar : searchBarReducer,
});

export default allReducers;
4 changes: 2 additions & 2 deletions src/reducers/landingPage/landingPageReducer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// import SignupPageActionTypes from "../../actions/signupPage/signupPageActionTypes";
import searchBarActionTypes from "../../actions/searchBar/searchBarActionTypes";

const intialState = {

}

const landingPageReducer = (state = intialState, action) => {
switch(action.type){

default: return state;
};
}
Expand Down
17 changes: 17 additions & 0 deletions src/reducers/searchBar/searchBarReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import searchBarActionTypes from "../../actions/searchBar/searchBarActionTypes";

const intialState = {
searchParam : '',
showSuggestions: 'false',
suggestionsList : []
}

const searchBarReducer = (state = intialState, action) => {
switch(action.type){
case searchBarActionTypes.SET_SUGGESTIONS : return {...state, suggestionsList: action.payload};
case searchBarActionTypes.SET_SEARCH_PARAM : return {...state, searchParam: action.payload};
default: return state;
};
}

export default searchBarReducer;
30 changes: 23 additions & 7 deletions src/routes.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import React,{ Component } from 'react';
import { Router, Switch, Route, Redirect } from 'react-router-dom';
import { useRouterHistory } from 'react-router';
import Loadable from 'react-loadable';

import services from './services/flicker';

import TopBar from './components/topBar/topBar.jsx';
import SearchBar from './components/searchBar/searchBar.jsx';

import history from './routes/history';
import WelcomeScreen from './routes/WelcomeScreen.jsx';
import Loadable from 'react-loadable';

import './styles/index.scss';
import './styles/index.scss';

function MyLoadingComponent() {
return <div>Loading...</div>;
}

const LandingPage = Loadable({
const GroupsPage = Loadable({
loader: () => import('./routes/landingPage/LandingPageContainer.jsx'),
loading: MyLoadingComponent,
});
Expand All @@ -32,13 +38,23 @@ class Routes extends Component{
};

render(){
services.searchForGroups('Hello World')
.then(response =>{
console.log('Response received is :', response);
});
return(
<Router history={history} >
{ this.state.showModal ? <WelcomeScreen onModalClose={this.onModalClose} /> : <div></div> }
{/*{ this.state.showModal ? <WelcomeScreen onModalClose={this.onModalClose} /> : <div></div> }*/}

<TopBar>
<div></div>
<SearchBar/>
<div>Show Stats</div>
</TopBar>
<Switch>
<Route exact path='/' render={() => ( <Redirect to="/home" /> )}/>
<Route exact path='/home' component={LandingPage}/>
<Route exact path='/*' render={() => ( <Redirect to="/home" /> )}/>
<Route exact path='/' render={() => ( <Redirect to="/groups" /> )}/>
<Route exact path='/groups' component={GroupsPage}/>
<Route exact path='/*' render={() => ( <Redirect to="/groups" /> )}/>
</Switch>
</Router>
)
Expand Down
1 change: 1 addition & 0 deletions src/routes/WelcomeScreen.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class WelcomeScreen extends Component{
<li style={{padding: '6px 0px'}}>This project was built from scratch, using personally built boilerplate. No create-react-app used !</li>
<li style={{padding: '6px 0px'}}>Lazing loading of images for performance optimisation and cost reduction !</li>
<li style={{padding: '6px 0px'}}>Code splitting in order to make the static script files light weight and load only on need!</li>
<li style={{padding: '6px 0px'}}>Search suggestion network calls are throttled!</li>
<li style={{padding: '6px 0px'}}>No css frameworks used, all the styles and animations are handwritten !</li>
</ul>
</div>
Expand Down
28 changes: 28 additions & 0 deletions src/routes/groupsPage/GroupsPageContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React,{ Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import GroupsPage from '../../components/groupsPage/groupsPage.jsx';
class GroupsPageContainer extends Component{

componentDidMount(){

}

render(){
return(
<div className={'BCN-landingPage'}>
<GroupsPage/>
</div>
);
}
}

const mapStateToProps = state =>({

});

const mapDispatchToProps = dispatch => ({
});

export default connect(mapStateToProps, mapDispatchToProps)(GroupsPageContainer);
34 changes: 0 additions & 34 deletions src/routes/landingPage/LandingPageContainer.jsx

This file was deleted.

44 changes: 44 additions & 0 deletions src/scripts/debounce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function debounce(func, wait, immediate) {
// 'private' variable for instance
// The returned function will be able to reference this due to closure.
// Each call to the returned function will share this common timer.
var timeout;

// Calling debounce returns a new anonymous function
return function() {
// reference the context and args for the setTimeout function
var context = this,
args = arguments;

// Should the function be called now? If immediate is true
// and not already in a timeout then the answer is: Yes
var callNow = immediate && !timeout;

// This is the basic debounce behaviour where you can call this
// function several times, but it will only execute once
// [before or after imposing a delay].
// Each time the returned function is called, the timer starts over.
clearTimeout(timeout);

// Set the new timeout
timeout = setTimeout(function() {

// Inside the timeout function, clear the timeout variable
// which will let the next execution run when in 'immediate' mode
timeout = null;

// Check if the function already ran with the immediate flag
if (!immediate) {
// Call the original function with apply
// apply lets you define the 'this' object as well as the arguments
// (both captured before setTimeout)
func.apply(context, args);
}
}, wait);

// Immediate mode and no wait timer? Execute the function..
if (callNow) func.apply(context, args);
}
}

export default debounce;
Loading

0 comments on commit e2bae85

Please sign in to comment.