Skip to content

Commit a9911bc

Browse files
it api done
1 parent a157f33 commit a9911bc

File tree

14 files changed

+494
-63
lines changed

14 files changed

+494
-63
lines changed

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"prettify": "prettier --config ./.prettierrc.js -w ./src"
1111
},
1212
"dependencies": {
13+
"babel-plugin-styled-components": "^1.12.0",
14+
"beprofiler": "^0.2.3",
15+
"i18n-keys": "^1.0.8",
16+
"i18next": "^20.3.1",
1317
"@reduxjs/toolkit": "^1.5.1",
1418
"@testing-library/jest-dom": "^5.11.4",
1519
"@testing-library/react": "^11.1.0",
@@ -26,13 +30,18 @@
2630
"redux-logger": "^3.0.6",
2731
"redux-observable": "^1.2.0",
2832
"rxjs": "^6.6.7",
29-
"typescript": "^4.1.2"
33+
"typescript": "^4.1.2",
34+
"styled-components": "^5.3.0",
35+
"tailwindcss": "^2.1.4",
36+
"twin.macro": "^2.4.2"
3037
},
3138
"devDependencies": {
39+
"@types/styled-components": "^5.1.9",
3240
"@types/react-router-dom": "^5.1.7",
3341
"@types/redux-logger": "^3.0.8",
3442
"prettier": "^2.3.0"
3543
},
44+
"proxy": "https://api.itbook.store/1.0",
3645
"eslintConfig": {
3746
"extends": [
3847
"react-app",

src/app/app.route.const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export enum AppRoute {
22
Home = '/',
3-
Book = '/book/:id',
3+
Book = '/book/:isbn13',
44
NotFound = '/not-found',
55
}

src/logic/environment.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
export const isProduction = () => process.env.NODE_ENV === 'production';
2+
3+
export const getEnv = () => ({
4+
NODE_ENV: process.env.NODE_ENV,
5+
});

src/logic/operators/managed.operator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const managed: Managed = (operator) =>
88
of(action).pipe(
99
operator,
1010
catchError((error: Error) => {
11+
console.log(error);
1112
alert(error.message);
1213
return EMPTY;
1314
})

src/logic/store/book/book.api.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { Book } from './book.models';
1+
import { BookDetails, BookSearchResult } from './book.models';
22

33
export const bookApi = {
4-
fetchBooks: async () => {
5-
return [] as Book[];
6-
},
7-
fetchBook: async (id: string) => {
8-
return {} as Book;
9-
},
4+
fetchBooks: async (searchPhrase: string): Promise<BookSearchResult> =>
5+
(await fetch(`/search/${searchPhrase}`)).json(),
6+
7+
fetchBook: async (isbn13: string): Promise<BookDetails> => (await fetch(`/books/${isbn13}`)).json(),
108
};

src/logic/store/book/book.epic.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@ const fetchBooks$: RootEpic = (action$) =>
1111
action$.pipe(
1212
filter(bookSlice.actions.fetchBooks.match),
1313
throttleTime(AVOID_QUICK_MULTIPLY_API_CALLS_TIMEOUT_MS),
14-
managed(switchMap(() => from(bookApi.fetchBooks()))),
15-
map((books) => bookSlice.actions.setBooks({ books }))
14+
map((action) => action.payload.searchPhrase),
15+
managed(switchMap((searchPhrase) => from(bookApi.fetchBooks(searchPhrase)))),
16+
map((result) => bookSlice.actions.setBooks({ books: result.books }))
1617
);
1718

1819
const fetchNote$: RootEpic = (action$) =>
1920
action$.pipe(
2021
filter(bookSlice.actions.fetchBook.match),
21-
managed(switchMap((action) => from(bookApi.fetchBook(action.payload.id)))),
22+
map(action => action.payload.isbn13),
23+
managed(switchMap((isbn13) => from(bookApi.fetchBook(isbn13)))),
2224
map((book) => bookSlice.actions.setBook({ book }))
2325
);
2426

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,35 @@
11
export interface Book {
2-
id?: string;
3-
date?: string;
4-
content?: string;
2+
title?: string;
3+
subtitle?: string;
4+
isbn13?: string;
5+
price?: string;
6+
image?: string;
7+
url?: string;
8+
}
9+
10+
export interface BookSearchResult {
11+
error?: string;
12+
total?: string;
13+
page?: string;
14+
books: Book[];
15+
}
16+
17+
export interface BookDetails {
18+
error?: string;
19+
title?: string;
20+
subtitle?: string;
21+
authors?: string;
22+
publisher?: string;
23+
isbn10?: string;
24+
isbn13?: string;
25+
pages?: string;
26+
year?: string;
27+
rating?: string;
28+
desc: string;
29+
price?: string;
30+
image?: string;
31+
url?: string;
32+
pdf: {
33+
[x: string]: string;
34+
};
535
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { StoreState } from '../../../app/app.reducers';
22

3-
export const getBooks = (store: StoreState) => store.book.books;
3+
export const getBookCards = (store: StoreState) => store.book.books;
44

5-
export const getBook = (id: string) => (store: StoreState) => store.book.bookById[id];
5+
export const getBook = (id: string) => (store: StoreState) => store.book.bookById && store.book.bookById[id];

src/logic/store/book/book.slice.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,26 @@ import { Book } from './book.models';
33
import { ObjectByKey } from '../../object';
44

55
export interface BookState {
6-
books: Book[];
7-
bookById: ObjectByKey<Book>;
6+
books?: Book[];
7+
bookById?: ObjectByKey<Book>;
88
}
99

10-
const initialState: BookState = {
11-
books: [],
12-
bookById: {},
13-
};
10+
const initialState: BookState = {};
1411

1512
export const bookSlice = createSlice({
1613
name: 'book',
1714
initialState,
1815
reducers: {
1916
fetchBooks: (_state, _action: PayloadAction<{ searchPhrase: string }>) => undefined,
20-
fetchBook: (_state, _action: PayloadAction<{ id: string }>) => undefined,
17+
fetchBook: (_state, _action: PayloadAction<{ isbn13: string }>) => undefined,
2118
setBooks: (state, action: PayloadAction<{ books: Book[] }>) => {
2219
state.books = action.payload.books;
2320
},
2421
setBook: (state, action: PayloadAction<{ book: Book }>) => {
2522
const { book } = action.payload;
26-
if (book.id) {
27-
state.bookById[book.id] = book;
23+
if (!state.bookById) state.bookById = {};
24+
if (book.isbn13) {
25+
state.bookById[book.isbn13] = book;
2826
}
2927
},
3028
},

src/pages/book/book.page.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import './book.styles.css';
1111

1212
export const BookPage: React.FC = () => {
1313
const dispatch = useDispatch();
14-
const { id } =
14+
const { isbn13 } =
1515
useParams<{
16-
id: string;
16+
isbn13: string;
1717
}>();
18-
const book = useSelector(getBook(id));
18+
const book = useSelector(getBook(isbn13));
1919

2020
useEffect(() => {
21-
dispatch(bookSlice.actions.fetchBook({ id }));
22-
}, [dispatch, id]);
21+
dispatch(bookSlice.actions.fetchBook({ isbn13 }));
22+
}, [dispatch, isbn13]);
2323

2424
const handleBack = useCallback(() => navigateBack(), []);
2525

@@ -29,7 +29,7 @@ export const BookPage: React.FC = () => {
2929
<div className="note-buttons">
3030
<Button title="Back" type={ButtonType.Secondary} onClick={handleBack} />
3131
</div>
32-
<div className="note-content">{book.content || ''}</div>
32+
<div className="note-content">{book.title || ''}</div>
3333
</div>
3434
</Layout>
3535
) : null;

0 commit comments

Comments
 (0)