Skip to content

Commit

Permalink
feature(search): Implement search feature app
Browse files Browse the repository at this point in the history
- Implemented search function for app utilising search books api
- Implemented search component and strategy on reducer
[Delivers #153149549]
  • Loading branch information
Benny Ogidan authored and Benny Ogidan committed Nov 29, 2017
1 parent da0988c commit 953ea00
Show file tree
Hide file tree
Showing 15 changed files with 184 additions and 35 deletions.
6 changes: 4 additions & 2 deletions client/src/app/actions/actiontype.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export const USER_LOG_IN_FAILURE = 'USER_LOG_IN_FAILURE';

export const USER_LOGGED_OUT = 'USER_LOGGED_OUT';

export const FETCHING_BOOKS = 'FETCHING_BOOKS';

export const SIGN_UP_USER_FAILURE = 'SIGN_UP_USER_FAILURE';

export const SIGNUP_USER_SUCCESS = 'SIGNUP_USER_SUCCESS';
Expand All @@ -27,6 +25,10 @@ export const UPLOAD_TO_CLOUD_IMAGE_SUCCESS = 'UPLOAD_TO_CLOUD_IMAGE_SUCCESS';

export const UPLOAD_TO_CLOUD_IMAGE_FAILURE = 'UPLOAD_TO_CLOUD_IMAGE_FAILURE';

export const SEARCH_BOOKS_SUCCESS = 'SEARCH_BOOKS_SUCCESS';

export const SEARCH_BOOKS_FAILURE = 'SEARCH_BOOKS_FAILURE';

export const CLOUDINARY_UPLOAD_PRESET = 'yn0wpv0n';

export const CLOUDINARY_UPLOAD_URL = 'https://api.cloudinary.com/v1_1/digpnxufx/upload';
Expand Down
3 changes: 3 additions & 0 deletions client/src/app/actions/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export default {
.then(res => res.data),
loanhistory: (offset, limit) => axios
.get(`api/v1/users/getloanhistory?offset=${offset}&limit=${limit}`)
.then(res => res.data),
searchBooks: value => axios
.get(`api/v1/books/search?searchTerm=${value}`)
.then(res => res.data)
}
};
7 changes: 1 addition & 6 deletions client/src/app/actions/fetchbooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
FETCH_ALL_BOOKS,
FETCH_BOOKS_REJECTED,
FETCH_BOOKS_BY_USER_ID,
FETCHING_BOOKS,

FETCH_ALL_OVERDUE_BOOKS
} from './actiontype';
import api from './api';
Expand All @@ -13,7 +13,6 @@ export const fetchBooksRejected = error => ({ type: FETCH_BOOKS_REJECTED, error
export const fetchRecentBooks = books => ({ type: FETCH_ALL_RECENT_BOOKS, books });
export const fetchBooks = books => ({ type: FETCH_ALL_BOOKS, books });
export const fetchBooksByUserId = books => ({ type: FETCH_BOOKS_BY_USER_ID, books });
export const fetchingBooks = state => ({ type: FETCHING_BOOKS, state });
export const fetchOverdueBooks = books => ({ type: FETCH_ALL_OVERDUE_BOOKS, books });

/**
Expand All @@ -28,13 +27,11 @@ export const fetchAllBooks = (offset, limit) => dispatch => api
.fetch(offset, limit)
.then((response) => {
dispatch(fetchBooks(response));
dispatch(fetchingBooks(false));
return response;
})
.catch((error) => {
dispatch(showErrorNotification({ error }));
dispatch(fetchBooksRejected({ error }));
dispatch(fetchingBooks(false));
});

/**
Expand Down Expand Up @@ -69,13 +66,11 @@ export const fetchAllRecentBooks = (offset, limit) => dispatch => api
.fetchRecentBooks(offset, limit)
.then((response) => {
dispatch(fetchRecentBooks(response));
dispatch(fetchingBooks(false));
return response;
})
.catch((error) => {
dispatch(showErrorNotification({ error }));
dispatch(fetchBooksRejected({ error }));
dispatch(fetchingBooks(false));
});

/**
Expand Down
29 changes: 29 additions & 0 deletions client/src/app/actions/searchbooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { showErrorNotification } from './notifications';
import {
SEARCH_BOOKS_SUCCESS,
SEARCH_BOOKS_FAILURE
} from './actiontype';
import api from './api';

export const SearchBookSuccess = books => ({ type: SEARCH_BOOKS_SUCCESS, books });
export const SearchBookFailure = error => ({ type: SEARCH_BOOKS_FAILURE, error });


/**
* async helper function: search Books
* @function SearchBooks
* @param {object} value
* @returns {function} asynchronous action
*/
export const searchAllBooks = value => dispatch => api
.book
.searchBooks(value)
.then((response) => {
dispatch(SearchBookSuccess(response.booksFound));
return (response);
})
.catch((error) => {
dispatch(showErrorNotification({ error }));
dispatch(SearchBookFailure({ error }));
return error;
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Row, Preloader, Col } from 'react-materialize';
import Book from '../../presentation/common/book/DisplayBook.jsx';
import { fetchAllBooks } from '../../../actions/fetchbooks';
import PaginationWrapper from '../common/Pagination.jsx';
import SearchBooks from '../../presentation/common/book/SearchBooks.jsx';

/**
* @description Component for Display Books on the Landing page for all users
Expand Down Expand Up @@ -65,6 +66,9 @@ this.props.allBooksList.books.map(book => (
};
return (
<div>
<Row>
<SearchBooks />
</Row>
<Row>
<Col l={12}>
{
Expand Down
35 changes: 26 additions & 9 deletions client/src/app/components/presentation/Dashboard.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import React from 'react';
import { Row } from 'react-materialize';
import { Row, Icon, Col } from 'react-materialize';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import PropTypes from 'prop-types';
import SideNav from '../presentation/common/SideNav/index.jsx';
import DisplayAllBorrowedBooks from '../container/booklist/DisplayBorrowedBooks.jsx';
import DisplayAllBooks from '../container/booklist/DisplayAllBooks.jsx';
import LoanHistoryTable from '../container/loanhistory/LoanHistory.jsx';
import DisplayOverdueBooks from '../container/booklist/DisplayOverdueBooks.jsx';


/**
* @description Show User Dashboard
* @class DashboardView
* @param {object} props
*/
const Dashoard = props =>
const Dashboard = props =>
(
<div>
<div className="main-wrapper">
Expand All @@ -24,12 +26,19 @@ const Dashoard = props =>
/>
<div className="main-text">
<Tabs>
<TabList>
<Tab>DASHBOARD</Tab>
<Tab>ALL BOOKS</Tab>
<Tab>BOOKS OVERDUE</Tab>
<Tab>LOAN HISTORY</Tab>
</TabList>
<Row>

<TabList>
<Tab>DASHBOARD</Tab>
<Tab>ALL BOOKS</Tab>
<Tab>BOOKS OVERDUE</Tab>
<Tab>LOAN HISTORY</Tab>
</TabList>


{/* <Icon tiny>search
</Icon> */}
</Row>
<Row>
<TabPanel>
<DisplayAllBorrowedBooks />
Expand All @@ -51,4 +60,12 @@ const Dashoard = props =>
</div>
);

export default Dashoard;
Dashboard.propTypes = {
firstname: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
profilePic: PropTypes.string.isRequired,
};


export default Dashboard;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactTooltip from 'react-tooltip';

import DisplayBookModal from './DisplayBookModal.jsx';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class DisplayBookModal extends React.Component {
}
}

handleChange = date => this.setState({ returndate: date });
handleChange = date => this.setState({ returnDate: date });

handleReturnClick = (event) =>{
this.
Expand Down
74 changes: 74 additions & 0 deletions client/src/app/components/presentation/common/book/SearchBooks.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Col, Icon,Autocomplete } from 'react-materialize';
import { searchAllBooks } from '../../../../actions/searchbooks';
import { fetchAllBooks } from '../../../../actions/fetchbooks';


/**
*
*
* @class SearchBooks
* @extends {React.Component}
*/
class SearchBooks extends React.Component {
/**
* Creates an instance of SearchBooks.
* @param {any} props
*
* @memberOf SearchBooks
*/
constructor(props) {
super(props);

this.state = {
searchTerm:'',
offset: 0,
limit:8,
dataSource: {}
};
this.onChange = this.onChange.bind(this)
}

onChange = (event, value ) => {
event.preventDefault();
this.setState({
searchTerm: value
});
if(value.length> 1){
this.props.searchAllBooks(value)
}
else{
this.props.fetchAllBooks(this.state.offset, this.state.limit);
}

};

render() {
return (
<Col s={12} m={3} l={3}>
<div className='autocomplete'>
<Col s={2}>
<div className='autocomplete-icon'>
<Icon medium>search
</Icon>
</div>
</Col>
<Col s={10}>
<Autocomplete
placeholder='Search.....'
data ={this.state.dataSource}
onChange= {this.onChange}
/>
</Col>

</div>
</Col>

);
}
}


export default connect(null, { fetchAllBooks, searchAllBooks })(SearchBooks);
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Row } from 'react-materialize';
*/
const MessageforNoBooks = () => (
<Row>
<h3 className='center bold-text nobooks-message'>
<h3 className="center bold-text nobooks-message">
You have not borrowed any books.
</h3>
</Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { Row } from 'react-materialize';
*/
const MessageforNoBooksHistory = () => (
<Row>
<h3 className='center bold-text nobooks-message'>
<h3 className="center bold-text nobooks-message">
You have no loan history. Go and search our collection and loan some books
</h3>
</h3>
</Row>
);
export default MessageforNoBooksHistory
export default MessageforNoBooksHistory;

Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import React from 'react';
* @class MessageforNoOverdueBooks
*/
const MessageforNoOverdueBooks = () => (
<h3 className='center bold-text nobooks-message'>
<h3 className="center bold-text nobooks-message">
You have no overdue books at present
</h3>
);
export default MessageforNoOverdueBooks
export default MessageforNoOverdueBooks;
14 changes: 14 additions & 0 deletions client/src/app/css/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,20 @@ footer {
color: $base-white;
}

.autocomplete{
height: 2.4rem !important;
}

i.medium{
font-size: 2.5rem ;
padding-top: 14px ;
// margin-left: -6px;
}

.react-autosuggest__container{
padding-top: 5.5px;
}

.btn {
background-color: black;
font-family: $font-stack2;
Expand Down
19 changes: 15 additions & 4 deletions client/src/app/reducers/bookReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {
RETURN_BOOKS_SUCCESS,
LOAN_HISTORY_FAILURE,
LOAN_HISTORY_SUCCESS,
FETCHING_BOOKS,
FETCH_ALL_OVERDUE_BOOKS
FETCH_ALL_OVERDUE_BOOKS,
SEARCH_BOOKS_SUCCESS,
SEARCH_BOOKS_FAILURE
} from '../actions/actiontype';

/**
Expand All @@ -25,11 +26,21 @@ import {
export default function bookReducer(state = {
}, action) {
switch (action.type) {
case FETCHING_BOOKS:
case SEARCH_BOOKS_SUCCESS:
{
return {
...state,
fetchingBooks: action.state
allBooksList:
action.books
};
}
case SEARCH_BOOKS_FAILURE:
{
return {
...state,
error: action.message
};
}
case FETCH_ALL_OVERDUE_BOOKS:
{
return {
Expand Down
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"test": "export NODE_ENV=test && mocha server/dist/test/index.spec.js --timeout 10000 && export NODE_ENV=development",
"client:test": "jest client/ --coverage",
"coverage": "export NODE_ENV=test && npm run pretest && nyc --reporter=lcov --reporter=text --reporter=lcovonly mocha --compilers js:babel-register server/src/test/*",
"start:migrate": "sequelize db:migrate ",
"undo:migrate": "sequelize db:migrate:undo:all",
"seed:all":"sequelize db:seed:all",
"undo:seed":"sequelize db:seed:undo:all",
"start:migrate": "sequelize db:migrate ",
"undo:migrate": "sequelize db:migrate:undo:all",
"seed:all": "sequelize db:seed:all",
"undo:seed": "sequelize db:seed:undo:all",
"start:dev": "babel-node server/dist/bin/www.js",
"start:webdev": "webpack -d && webpack-dev-server && --content-base client/src/ --inline --hot",
"start-prod": "babel server/src --out-dir server/dist --presets es2015 && npm run heroku-postbuild",
Expand Down Expand Up @@ -89,14 +89,15 @@
"morgan": "^1.8.2",
"muicss": "^0.9.25",
"node-cron": "^1.2.1",
"node-sass": "^4.5.3",
"nodemailer": "^4.4.0",
"node-sass": "^4.5.3",
"nodemailer": "^4.4.0",
"nodemailer-mailgun-transport": "^1.3.5",
"nodemon": "^1.11.0",
"pg": "^7.0.2",
"pg-hstore": "^2.3.2",
"prop-types": "^15.5.10",
"react": "^15.6.1",
"react-autosuggest": "^9.3.2",
"react-cookie": "^2.0.8",
"react-datepicker": "^0.61.0",
"react-dom": "^15.6.1",
Expand Down

0 comments on commit 953ea00

Please sign in to comment.