Skip to content

Commit c25f23c

Browse files
committed
add solution
1 parent 92eaae4 commit c25f23c

File tree

7 files changed

+250
-190
lines changed

7 files changed

+250
-190
lines changed

src/components/About.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react'
2+
3+
function About() {
4+
return (
5+
<section id="about" className="success">
6+
<div className="container">
7+
<div className="row">
8+
<div className="col-lg-12 text-center">
9+
<h2>About The Library</h2>
10+
<hr className="star-light" />
11+
</div>
12+
</div>
13+
<div className="row">
14+
<div className="col-lg-4 col-lg-offset-2">
15+
<p>
16+
This library is an exercise for building UI in a{' '}
17+
<strong style={{ textDecoration: 'underline' }}>
18+
declarative way
19+
</strong>
20+
. This web site will help you understand the fundamental piece of
21+
ReactJS, components. You'll learn how to break an app in
22+
components (AKA componentization) and flow data accross them.
23+
</p>
24+
</div>
25+
<div className="col-lg-4">
26+
<p>
27+
This ReactJS web site works, but it's not well implemented. The
28+
problem, the developer didn't think in React and there aren't many
29+
components. We challenge you to fork the repo an componentizise
30+
the app to unleash the power of ReactJS.
31+
</p>
32+
</div>
33+
<div className="col-lg-8 col-lg-offset-2 text-center">
34+
<a
35+
target="_blank"
36+
rel="noopener noreferrer"
37+
href="https://github.com/reactgraphqlacademy/thinking-in-react"
38+
className="btn btn-lg btn-outline"
39+
>
40+
<i className="fa fa-code-fork" /> Fork me on Github
41+
</a>
42+
</div>
43+
</div>
44+
</div>
45+
</section>
46+
)
47+
}
48+
49+
export default About

src/components/App.js

+8-190
Original file line numberDiff line numberDiff line change
@@ -1,213 +1,31 @@
11
import React, { useState } from 'react'
22

33
import Menu from './Navigations/Menu'
4+
import Navbar from './Navigations/Navbar'
45
import Header from './Header'
5-
import booksMockData from '../mocks/books'
6+
import Books from './Books'
7+
import Footer from './Footer'
8+
import About from './About'
69

710
function App() {
8-
const [books, setBooks] = useState(booksMockData)
911
const [isMenuOpen, setIsMenuOpen] = useState(false)
10-
const [selectedFilter, setSelectedFilter] = useState('All')
1112

1213
const toggleMenu = () => {
1314
setIsMenuOpen(!isMenuOpen)
1415
}
1516

16-
const selectFilter = (filter) => {
17-
setSelectedFilter(filter)
18-
setBooks(
19-
filter === 'All'
20-
? booksMockData
21-
: booksMockData.filter((book) => book.category === filter)
22-
)
23-
}
24-
25-
const filters = ['All', 'Design', 'Mobile', 'DevOps', 'Essentials']
26-
27-
const tabItems = filters.map((filter) => (
28-
<li
29-
className={filter === selectedFilter ? 'active' : ''}
30-
key={filter}
31-
onClick={() => selectFilter(filter)}
32-
>
33-
<a href="#0">{filter}</a>
34-
</li>
35-
))
36-
3717
return (
3818
<div id="page-wrap">
3919
<Menu
4020
pageWrapId="page-wrap"
4121
isOpen={isMenuOpen}
4222
toggleMenu={toggleMenu}
4323
/>
44-
45-
<nav className="navbar navbar-default navbar-fixed-top navbar-custom">
46-
<div className="container">
47-
<div className="navbar-header">
48-
<a className="navbar-brand" href="/">
49-
Library
50-
</a>
51-
</div>
52-
<ul className="nav navbar-nav pull-right">
53-
<li className="hidden-xs">
54-
<a href="#about">About us</a>
55-
</li>
56-
<li>
57-
<button onClick={toggleMenu} className="btn btn-lg btn-outline">
58-
<i className="fa fa-graduation-cap" /> <span>Training</span>
59-
</button>
60-
</li>
61-
</ul>
62-
</div>
63-
</nav>
64-
24+
<Navbar toggleMenu={toggleMenu} />
6525
<Header title="By React GraphQL Academy" />
66-
67-
<section id="books">
68-
<div className="container">
69-
<div className="row">
70-
<div className="col-lg-12 text-center">
71-
<h2>Books</h2>
72-
<hr className="star-primary" />
73-
</div>
74-
</div>
75-
<div className="row">
76-
<div className="col-lg-12">
77-
<ul className="nav nav-pills text-center">{tabItems}</ul>
78-
</div>
79-
</div>
80-
<div className="row book-list">
81-
{books.map((book) => (
82-
<div className="col-xs-6 col-sm-3" key={book.id}>
83-
<div className="thumbnail">
84-
<img alt="" className="img-responsive" src={book.cover} />
85-
</div>
86-
</div>
87-
))}
88-
</div>
89-
</div>
90-
</section>
91-
92-
<section id="about" className="success">
93-
<div className="container">
94-
<div className="row">
95-
<div className="col-lg-12 text-center">
96-
<h2>About The Library</h2>
97-
<hr className="star-light" />
98-
</div>
99-
</div>
100-
<div className="row">
101-
<div className="col-lg-4 col-lg-offset-2">
102-
<p>
103-
This library is an exercise for building UI in a{' '}
104-
<strong style={{ textDecoration: 'underline' }}>
105-
declarative way
106-
</strong>
107-
. This web site will help you understand the fundamental piece
108-
of ReactJS, components. You'll learn how to break an app in
109-
components (AKA componentization) and flow data accross them.
110-
</p>
111-
</div>
112-
<div className="col-lg-4">
113-
<p>
114-
This ReactJS web site works, but it's not well implemented. The
115-
problem, the developer didn't think in React and there aren't
116-
many components. We challenge you to fork the repo an
117-
componentizise the app to unleash the power of ReactJS.
118-
</p>
119-
</div>
120-
<div className="col-lg-8 col-lg-offset-2 text-center">
121-
<a
122-
target="_blank"
123-
rel="noopener noreferrer"
124-
href="https://github.com/leanjscom/thinking-in-react"
125-
className="btn btn-lg btn-outline"
126-
>
127-
<i className="fa fa-code-fork" /> Fork me on Github
128-
</a>
129-
</div>
130-
</div>
131-
</div>
132-
</section>
133-
134-
<footer className="text-center">
135-
<div className="footer-above">
136-
<div className="container">
137-
<div className="row">
138-
<div className="footer-col col-md-4">
139-
<h3>Main Location</h3>
140-
<p>
141-
<span>1 St. Katharine's Way</span>
142-
<br />
143-
<span>London, E1W 1UN</span>
144-
</p>
145-
</div>
146-
<div className="footer-col col-md-4">
147-
<h3>Around the Web</h3>
148-
<ul className="list-inline">
149-
<li>
150-
<a
151-
target="_blank"
152-
rel="noopener noreferrer"
153-
href="https://github.com/leanjscom"
154-
className="btn-social btn-outline"
155-
>
156-
<i className="fa fa-fw fa-github" />
157-
</a>
158-
</li>
159-
<li>
160-
<a
161-
target="_blank"
162-
rel="noopener noreferrer"
163-
href="https://twitter.com/leanjscom"
164-
className="btn-social btn-outline"
165-
>
166-
<i className="fa fa-fw fa-twitter" />
167-
</a>
168-
</li>
169-
<li>
170-
<a
171-
target="_blank"
172-
rel="noopener noreferrer"
173-
href="https://www.instagram.com/leanjscom/"
174-
className="btn-social btn-outline"
175-
>
176-
<i className="fa fa-fw fa-instagram" />
177-
</a>
178-
</li>
179-
</ul>
180-
</div>
181-
<div className="footer-col col-md-4">
182-
<h3>About ReactJS Academy</h3>
183-
<p>
184-
<a href="https://reactjs.academy/">ReactJS Academy</a>
185-
<span>
186-
ReactJS Academy is Europes longest running dedicated React,
187-
Redux, and GraphQL training.
188-
</span>
189-
</p>
190-
</div>
191-
</div>
192-
</div>
193-
</div>
194-
<div className="footer-below">
195-
<div className="container">
196-
<div className="row">
197-
<div className="col-lg-12">
198-
<span>Copyright &copy;</span>{' '}
199-
<a
200-
href="https://leanjs.com/"
201-
target="_blank"
202-
rel="noopener noreferrer"
203-
>
204-
LeanJS
205-
</a>
206-
</div>
207-
</div>
208-
</div>
209-
</div>
210-
</footer>
26+
<Books />
27+
<About />
28+
<Footer />
21129
</div>
21230
)
21331
}

src/components/Books/BookFilter.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from 'react'
2+
3+
function BookFilter(props) {
4+
const filters = ['All', 'Design', 'Mobile', 'DevOps', 'Essentials']
5+
const tabItems = filters.map((filter) => (
6+
<li
7+
className={filter === props.selectedFilter ? 'active' : ''}
8+
key={filter}
9+
onClick={() => props.selectFilter(filter)}
10+
>
11+
<a href="#0">{filter}</a>
12+
</li>
13+
))
14+
15+
return <ul className="nav nav-pills text-center">{tabItems}</ul>
16+
}
17+
18+
export default BookFilter

src/components/Books/BookList.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react'
2+
3+
function BookList(props) {
4+
return (
5+
<div className="row book-list">
6+
{props.books.map((book) => (
7+
<div className="col-xs-6 col-sm-3" key={book.id}>
8+
<div className="thumbnail">
9+
<img alt="" className="img-responsive" src={book.cover} />
10+
</div>
11+
</div>
12+
))}
13+
</div>
14+
)
15+
}
16+
17+
export default BookList

src/components/Books/index.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { useState } from 'react'
2+
import booksMockData from '../../mocks/books'
3+
import BookList from './BookList'
4+
import BookFilter from './BookFilter'
5+
6+
function Books() {
7+
// It's probably better to combine these two states into a useReducer. For simplicity at this point, we keep into two different useState
8+
const [books, setBooks] = useState(booksMockData)
9+
const [selectedFilter, setSelectedFilter] = useState('All')
10+
11+
const selectFilter = (filter) => {
12+
setSelectedFilter(filter)
13+
setBooks(
14+
filter === 'All'
15+
? booksMockData
16+
: booksMockData.filter((book) => book.category === filter)
17+
)
18+
}
19+
20+
return (
21+
<section id="books">
22+
<div className="container">
23+
<div className="row">
24+
<div className="col-lg-12 text-center">
25+
<h2>Books</h2>
26+
<hr className="star-primary" />
27+
</div>
28+
</div>
29+
<div className="row">
30+
<div className="col-lg-12">
31+
<BookFilter
32+
selectFilter={selectFilter}
33+
selectedFilter={selectedFilter}
34+
/>
35+
</div>
36+
</div>
37+
<BookList books={books} />
38+
</div>
39+
</section>
40+
)
41+
}
42+
43+
export default Books

0 commit comments

Comments
 (0)