Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(search): Implement search feature app #37

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to resolve path to module './notifications' import/no-unresolved
Missing file extension for "./notifications" import/extensions

import {
SEARCH_BOOKS_SUCCESS,
SEARCH_BOOKS_FAILURE
} from './actiontype';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to resolve path to module './actiontype' import/no-unresolved
Missing file extension for "./actiontype" import/extensions

import api from './api';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to resolve path to module './api' import/no-unresolved
Missing file extension for "./api" import/extensions


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';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to resolve path to module '../../presentation/common/book/SearchBooks.jsx' import/no-unresolved
Unexpected use of file extension "jsx" for "../../presentation/common/book/SearchBooks.jsx" import/extensions


/**
* @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';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Icon' is defined but never used no-unused-vars
'Col' is defined but never used no-unused-vars
Missing file extension for "react-materialize" import/extensions
Unable to resolve path to module 'react-materialize' import/no-unresolved

import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import PropTypes from 'prop-types';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to resolve path to module 'prop-types' import/no-unresolved
Missing file extension for "prop-types" import/extensions

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 });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing error: Unexpected token =


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 ) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing error: Unexpected token =

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{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening curly brace { should be preceded by one space

height: 2.4rem !important;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line should be indented with spaces, not tabs
!important should not be used

}

i.medium{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid qualifying class selectors with an element.
Opening curly brace { should be preceded by one space

font-size: 2.5rem ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line should be indented with spaces, not tabs
Declaration should not have a space before the terminating semicolon

padding-top: 14px ;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line should be indented with spaces, not tabs
Declaration should not have a space before the terminating semicolon

// margin-left: -6px;
}

.react-autosuggest__container{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Selector react-autosuggest__container should be written in lowercase with hyphens
Opening curly brace { should be preceded by one space

padding-top: 5.5px;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line should be indented with spaces, not tabs

}

.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