Skip to content

Commit

Permalink
Merge pull request #3 from AsumVictor/ft-react-redux
Browse files Browse the repository at this point in the history
React Redux
  • Loading branch information
AsumVictor authored Jul 27, 2023
2 parents 26cf96f + 89abbfa commit 647640d
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 36 deletions.
32 changes: 21 additions & 11 deletions src/components/Book.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
/* eslint-disable no-unused-vars */
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
import { useDispatch } from 'react-redux';
import { RemoveBook } from '../redux/book/bookSlice';

const Book = ({ title, author }) => (
<div>
<h3>{title}</h3>
<p>
By
{author}
</p>
<Button name="Remove" />
</div>
);
const Book = ({ id, title, author }) => {
const dispatch = useDispatch();

const handleRemove = (id) => {
dispatch(RemoveBook(id));
};

return (
<div className="border-b-4">
<h3>{title}</h3>
<p>
By
{author}
</p>
<button type="button" className="px-3 py-1 bg-red-400" onClick={() => handleRemove(id)}> Remove Book </button>
</div>
);
};

Book.propTypes = {
title: PropTypes.string,
author: PropTypes.string,
id: PropTypes.string.isRequired,
};

Book.defaultProps = {
Expand Down
9 changes: 4 additions & 5 deletions src/components/Books.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React from 'react';
import { useSelector } from 'react-redux';
import Book from './Book';
import Form from './Form';

const Books = () => {
const books = [
{ id: 1, title: 'Book 1', author: 'Author 1' },
{ id: 2, title: 'Book 2', author: 'Author 2' },
];
const { books } = useSelector((state) => state.book);

return (
<div>
{books.map((book) => (
<Book key={book.id} title={book.title} author={book.author} />
<Book key={book.item_id} id={book.item_id} title={book.title} author={book.author} />
))}
<Form />
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/components/Button.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';

const Button = ({ name }) => <button type="button">{name}</button>;
const Button = ({ name }) => (
<button type="button">
{name}
</button>
);

Button.propTypes = {
name: PropTypes.string,
Expand Down
66 changes: 55 additions & 11 deletions src/components/Form.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,57 @@
import React from 'react';
import Button from './Button';

const Form = () => (
<form>
<h3>ADD NEW BOOK</h3>
<input type="text" placeholder="Book title" />
<input type="text" placeholder="Author" />
<Button name="Submit" />
</form>
);
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { toast } from 'react-toastify';
import { AddBook } from '../redux/book/bookSlice';

const Form = () => {
const { books } = useSelector((state) => state.book);
const dispatch = useDispatch();
const [author, setAuthor] = useState('');
const [title, setTitle] = useState('');

const handleSubmit = (e) => {
e.preventDefault();
if (title.trim() === '' || author.trim() === '') {
toast.error('All fileds must be completed');
return null;
}

dispatch(
AddBook({
item_id: `item${books.length + 1}`,
author,
title,
}),

);
setAuthor('');
setTitle('');

return null;
};

return (
<form className="flex flex-col gap-2" onSubmit={handleSubmit}>
<h3>ADD NEW BOOK</h3>
<input
type="text"
placeholder="Book title"
className="border outline-none border-blue-300"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<input
type="text"
placeholder="Author"
className="border outline-none border-blue-300"
value={author}
onChange={(e) => setAuthor(e.target.value)}
/>
<button type="submit" className="px-3 py-1 bg-blue-700 text-white mx-4 rounded-md">
Add book
</button>
</form>
);
};

export default Form;
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { Provider } from 'react-redux';
import App from './App';
import store from './redux/store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
);
31 changes: 26 additions & 5 deletions src/redux/book/bookSlice.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { createReducer } from '@reduxjs/toolkit';

const initialState = {
books: [],
books: [
{
item_id: 'item1',
title: 'The Great Gatsby',
author: 'John Smith',
category: 'Fiction',
},
{
item_id: 'item2',
title: 'Anna Karenina',
author: 'Leo Tolstoy',
category: 'Fiction',
},
{
item_id: 'item3',
title: 'The Selfish Gene',
author: 'Richard Dawkins',
category: 'Nonfiction',
},
],
};

// Reducers
Expand All @@ -10,21 +29,23 @@ export const bookReducer = createReducer(initialState, {
state.books.push(action.payload);
},
remove: (state, action) => {
const { id } = action.payload;
const newState = state.books.filter((i) => i.id !== id);
const id = action.payload;
const newState = state.books.filter((i) => i.item_id !== id);
state.books = newState;
},
});

// Actions
export const AddBook = (dispatch) => {
export const AddBook = (book) => (dispatch) => {
dispatch({
type: 'add',
payload: book,
});
};

export const RemoveBook = (dispatch) => {
export const RemoveBook = (id) => (dispatch) => {
dispatch({
type: 'remove',
payload: id,
});
};
3 changes: 1 addition & 2 deletions src/redux/category/categorySlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const initialState = {
};

// Reducers
export const categoriesReducer = createReducer({
initialState,
export const categoriesReducer = createReducer(initialState, {
checkstatus: (state) => ({ ...state, status: 'Under Construction' }),
});

Expand Down

0 comments on commit 647640d

Please sign in to comment.