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

feat: emotion with styles #1

Merged
merged 2 commits into from Aug 16, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -3,7 +3,11 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/core": "^10.0.15",
"@emotion/styled": "^10.0.15",
"axios": "^0.19.0",
"emotion-theming": "^10.0.14",
"normalize.css": "^8.0.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
@@ -1,6 +1,10 @@
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { Global, css } from "@emotion/core";
import normalize from "normalize.css";
import { ThemeProvider } from "emotion-theming";

import theme from "./components/theme";
import SearchPage from "./pages/searchPage.js";
import BookDetailPage from "./pages/bookDetailPage";
import "./App.css";
@@ -9,13 +13,23 @@ const NoMatchRoute = () => <div>404 Page</div>;

const App = () => {
return (
<Router>
<Switch>
<Route path="/" exact component={SearchPage} />
<Route path="/book/:bookId" exact component={BookDetailPage} />
<Route component={NoMatchRoute} />
</Switch>
</Router>
<ThemeProvider theme={theme}>
<Global
styles={css`
${normalize}
body {
background-color: #fafafa;
}
`}
/>
<Router>
<Switch>
<Route path="/" exact component={SearchPage} />
<Route path="/book/:bookId" exact component={BookDetailPage} />
<Route component={NoMatchRoute} />
</Switch>
</Router>
</ThemeProvider>
);
};

@@ -1,4 +1,37 @@
import React from "react";
import styled from "@emotion/styled";

import ErrorText from "./errorText";

const Input = styled.input`
outline: 0;
padding: 0.6rem 1rem;
border: 1px solid rgba(34, 36, 38, 0.15);
border-radius: 3px;
min-width: 280px;
&:focus,
&:active {
border-color: #85b7d9;
}
@media (max-width: 778px) {
margin-top: 10px;
}
`;

const Button = styled.button`
background-color: #2185d0;
color: #ffffff;
text-shadow: none;
background-image: none;
padding: 0.6rem 1.5rem;
margin-left: 15px;
border-radius: 3px;
cursor: pointer;
@media (max-width: 778px) {
margin-left: 0;
margin-top: 10px;
}
`;

const BookSearchForm = ({
onSubmitHandler,
@@ -8,21 +41,16 @@ const BookSearchForm = ({
}) => {
return (
<form onSubmit={onSubmitHandler}>
<label>
<span>Search for books</span>
<input
type="search"
placeholder="microservice, restful design, etc.,"
value={searchTerm}
onChange={onInputChange}
required
/>
<button type="submit">Search</button>
</label>
<Input
type="search"
placeholder="Search for books"
value={searchTerm}
onChange={onInputChange}
required
/>
<Button type="submit">Search</Button>
{error && (
<div style={{ color: `red` }}>
some error occurred, while fetching api
</div>
<ErrorText>Some error occurred, while fetching books API</ErrorText>
)}
</form>
);
@@ -0,0 +1,9 @@
import styled from "@emotion/styled";

const ErrorText = styled.div`
color: red;
text-align: center;
padding: 20px 0;
`;

export default ErrorText;
@@ -1,13 +1,23 @@
import React from 'react';
/** @jsx jsx */
import { css, jsx } from "@emotion/core";
import React from "react";

const Loader = ({ loading, searchTerm }) => {
return (
<>
{
loading && <div style={{color: `green`}}>fetching books for "<strong>{searchTerm}</strong>"</div>
}
</>
);
const Loader: React.FunctionComponent<{}> = ({ loading, children }) => {
return (
<>
{loading && (
<div
css={css`
color: green;
text-align: center;
padding: 20px 0;
`}
>
{children}
</div>
)}
</>
);
};

export default Loader;
export default Loader;
@@ -0,0 +1,11 @@
import styled from "@emotion/styled";

export const Header = styled.header`
background-color: ${props => props.theme.colors.white};
`;

export const Container = styled.div`
max-width: 960px;
padding: 15px;
margin: 0 auto;
`;
@@ -0,0 +1,9 @@
const theme = {
colors: {
success: "green",
error: "red",
white: "white"
}
};

export default theme;
@@ -1,47 +1,48 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from 'axios';
import axios from "axios";

import BookDetail from '../components/bookDetail';
import BookDetail from "../components/bookDetail";
import Loader from "../components/loader";
import ErrorText from "../components/errorText";

const BookDetailPage = ({ match }) => {
const { params: { bookId } } = match;
const [book, setBook] = useState(null);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const {
params: { bookId }
} = match;
const [book, setBook] = useState(null);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);

useEffect(() => {
const API_BASE_URL = `https://www.googleapis.com/books/v1/volumes`;
const fetchBook = async () => {
setLoading(true);
setError(false);
try {
const result = await axios.get(`${API_BASE_URL}/${bookId}`);
setBook(result.data);
}
catch(error) {
setError(true);
}
setLoading(false);
}
// Call the API
fetchBook();
}, [bookId]);
useEffect(() => {
const API_BASE_URL = `https://www.googleapis.com/books/v1/volumes`;
const fetchBook = async () => {
setLoading(true);
setError(false);
try {
const result = await axios.get(`${API_BASE_URL}/${bookId}`);
setBook(result.data);
} catch (error) {
setError(true);
}
setLoading(false);
};
// Call the API
fetchBook();
}, [bookId]);

return (
<>
<Link to={`/`}>Go back to search books</Link>
{
loading && <div style={{ color: `green` }}>loading book detail for book ID: <strong>{bookId}</strong></div>
}
{
error && <div style={{ color: `red` }}>some error occurred, while fetching api</div>
}
{
book && <BookDetail book={book} />
}
</>
);
return (
<>
<Link to={`/`}>Go back to search books</Link>
<Loader loading={loading}>
loading book detail for book ID <strong>{bookId}</strong>
</Loader>
{error && (
<ErrorText>Some error occurred, while fetching books API</ErrorText>
)}
{book && <BookDetail book={book} />}
</>
);
};

export default BookDetailPage;
export default BookDetailPage;
@@ -1,10 +1,29 @@
import React, { useState } from "react";
import axios from "axios";
import styled from "@emotion/styled";

import { Container, Header } from "../components/shared";
import BookSearchForm from "../components/bookSearchForm";
import Loader from "../components/loader";
import BooksList from "../components/booksList";

const HeaderContainer = styled(Container)`
display: flex;
align-items: center;
@media (max-width: 778px) {
flex-direction: column;
align-items: flex-start;
}
`;

const LogoText = styled.h3`
margin: 0;
`;

const HeaderSearchForm = styled.div`
margin-left: auto;
`;

const SearchPage = () => {
const [searchTerm, setSearchTerm] = useState("");
const [books, setBooks] = useState({ items: [] });
@@ -36,14 +55,25 @@ const SearchPage = () => {

return (
<>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
<Loader searchTerm={searchTerm} loading={loading} />
<BooksList books={books} />
<Header>
<HeaderContainer>
<LogoText>Bookie</LogoText>
<HeaderSearchForm>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
</HeaderSearchForm>
</HeaderContainer>
</Header>
<Container>
<Loader loading={loading}>
fetching books for "<strong>{searchTerm}</strong>"
</Loader>
<BooksList books={books} />
</Container>
</>
);
};
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.