import React from 'react';
import { withState, pure, branch, renderComponent, compose } from 'recompose';
import { gql, graphql } from 'react-apollo';
// Define a very basic loading state component - you could make this
// a nice animation or something
const Loading = () => (
<div>Loading</div>
);
// Define an HoC that displays the Loading component instead of the
// wrapped component when props.data.loading is true
const displayLoadingState = branch(
(props) => props.data.loading,
renderComponent(Loading),
);
// The pure component that renders UI
const BookSearchResultsPure = ({ data: { allBooks } }) => (
<ul className="bookName">
{allBooks.map(book =>
<li key={book.id}>
{book.title} by {book.author[0].name}
</li>
)}
</ul>
);
const data = graphql(gql`
query BookSearchQuery($filter: BookFilter) {
allBooks(filter: $filter) {
id
title
author {
id
name
}
}
}
`, {
// note: this variables object is the same object as in Graphiql so if it works
// there, copy/paste that object here. Query Variables Winodw in Graphiql = the
// value of the variable key below.
options: ({ filter }) => ({ variables: { filter: {title_contains:filter }} }),
});
// Put everything together!
const BookSearchResults = compose(
data,
displayLoadingState,
pure,
)(BookSearchResultsPure);
// Use recompose to keep the state of the input so that we
// can use functional component syntax
// See: <https://github.com/acdlite/recompose/blob/master/docs/API.md#withstate>
const filter = withState('filter', 'setFilter', '');
const BookSearchPure = ({ filter, setFilter }) => (
<div className="bookList">
<input
type="text"
placeholder="Search Book Here"
value={ filter }
onChange={(e) => setFilter(e.target.value)}
/>
<BookSearchResults filter={filter} />
</div>
);
// Attach the state to the pure component
const BookSearch = compose(
filter,
pure,
)(BookSearchPure);
export default BookSearch;