Skip to content

Commit

Permalink
Task completed, code refactored to thunk
Browse files Browse the repository at this point in the history
  • Loading branch information
anettgor committed Apr 30, 2023
1 parent 7b270a3 commit c59ee9e
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 79 deletions.
72 changes: 64 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "goit-react-hw-06-phonebook",
"name": "goit-react-hw-07-phonebook",
"version": "0.1.0",
"private": true,
"homepage": "https://anettgor.github.io/goit-react-hw-06-phonebook/",
"homepage": "https://anettgor.github.io/goit-react-hw-07-phonebook/",
"dependencies": {
"@redux-devtools/extension": "^3.2.5",
"@reduxjs/toolkit": "^1.9.5",
"@testing-library/jest-dom": "^5.16.3",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.4.0",
"nanoid": "^4.0.2",
"notiflix": "^3.2.6",
"react": "^18.1.0",
Expand Down
17 changes: 4 additions & 13 deletions src/components/App.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import { useEffect } from 'react';
import { ContactList } from './ContactList/ContactList';
import { AddContact } from './ContactForm/ContactForm';
import { ContactForm } from './ContactForm/ContactForm';
import { Filter } from './Filter/Filter';
import css from './App.module.css';
import { useSelector, useDispatch } from 'react-redux';
import { getContacts } from './../redux/selectors';
import { loadContacts } from './../redux/actions';
import { fetchContacts } from './../redux/operations';

export const App = () => {
const dispatch = useDispatch();
const contacts = useSelector(getContacts);

useEffect(() => {
if (contacts.length > 0) {
localStorage.setItem('contacts', JSON.stringify(contacts));
}
}, [contacts]);

useEffect(() => {
const localStorageContacts = localStorage.getItem('contacts');
if (localStorageContacts) {
dispatch(loadContacts(JSON.parse(localStorageContacts)));
}
dispatch(fetchContacts());
}, [dispatch]);

return (
<div className={css.container}>
<h1> Phonebook</h1>
<AddContact />
<ContactForm />

<h2> Contacts </h2>
{contacts.length > 1 && <Filter />}
Expand Down
8 changes: 3 additions & 5 deletions src/components/ContactForm/ContactForm.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import css from './ContactForm.module.css';
import { getContacts } from './../../redux/selectors';
import { addContact } from './../../redux/actions';
import { addContact } from './../../redux/operations';
import { useDispatch, useSelector } from 'react-redux';
import { nanoid } from 'nanoid';
import { Notify } from 'notiflix';
export const AddContact = () => {
export const ContactForm = () => {
const contacts = useSelector(getContacts);
const dispatch = useDispatch();

const handleSubmit = e => {
e.preventDefault();

const form = e.currentTarget;
const name = form.elements.name.value;
const number = form.elements.number.value;
const newContact = {
id: nanoid(),
name: name,
number: number,
};

if (
contacts.find(
contact => contact.name.toLowerCase() === name.toLowerCase()
Expand Down
20 changes: 9 additions & 11 deletions src/components/ContactList/ContactList.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import css from './ContactList.module.css';
import { removeContact } from './../../redux/actions';

import { deleteContact } from './../../redux/operations';
import { useSelector, useDispatch } from 'react-redux';
import { getValue, getContacts } from './../../redux/selectors';
import { getStatusFilter, getContacts } from './../../redux/selectors';

export const ContactList = () => {
// const contacts = useSelector(loadContacts);
const filter = useSelector(getValue);
const filter = useSelector(getStatusFilter);

const filteredContacts = useSelector(getContacts).filter(contact => {
return contact.name.toLowerCase().includes(filter.toLowerCase());
});
const dispatch = useDispatch();

const deleteContact = id => {
dispatch(removeContact(id));
};

return (
<ul className={css.items}>
{filteredContacts.map(contact => {
return (
<li key={contact.id}>
<p>
{' '}
<b>Name: </b> {contact.name}{' '}
<b>Name: </b>
{contact.name}
</p>
<p>
<b>Number: </b>
{contact.number}
{contact.phone}
</p>
<button
type="button"
id={contact.id}
onClick={() => deleteContact(contact.id)}
onClick={() => dispatch(deleteContact(contact.id))}
>
Delete
</button>
Expand Down
8 changes: 4 additions & 4 deletions src/components/ContactList/ContactList.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
.items > li {
width: 80vw;
padding: 5px 20px;
display: flex;
display: grid;
grid-template-columns: 1fr 1fr auto;
grid-template-rows: 100%;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.items > li:nth-last-of-type(even) {
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.15);
box-shadow: -20px 0px 20px rgba(0, 0, 0, 0.15);
}
li > button {
all: unset;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Filter/Filter.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import css from './../ContactForm/ContactForm.module.css';
import { useDispatch } from 'react-redux';
import { setStatusFilter } from './../../redux/actions';
import { setStatusFilter } from './../../redux/filterSlice';
export const Filter = () => {
const dispatch = useDispatch();

Expand Down
8 changes: 4 additions & 4 deletions src/redux/actions.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const { createAction } = require('@reduxjs/toolkit');

export const addContact = createAction('contacts/addContact');
export const getContact = createAction('contacts/addContact');

export const removeContact = createAction('contacts/removeContact');
// export const removeContact = createAction('contacts/removeContact');

export const getContacts = createAction('contacts/getContacts');
// export const getContacts = createAction('contacts/getContacts');

export const loadContacts = createAction('contacts/loadContacts');
// export const loadContacts = createAction('contacts/loadContacts');

export const setStatusFilter = createAction('filter/setStatusFilter');
48 changes: 48 additions & 0 deletions src/redux/contactsSlice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createSlice } from '@reduxjs/toolkit';
// Importujemy operację
import { fetchContacts, addContact, deleteContact } from './operations';
const handleRejected = (state, action) => {
state.error = action.payload;
state.isLoading = false;
};

const handlePending = state => {
state.isLoading = true;
};

const contactsSlice = createSlice({
name: 'contacts',
initialState: {
items: [],
isLoading: true,
error: null,
},
extraReducers: {
[fetchContacts.pending]: handlePending,
[fetchContacts.fulfilled](state, action) {
state.isLoading = false;
state.items = action.payload;
state.error = null;
},
[fetchContacts.rejected]: handleRejected,
[addContact.pending]: handlePending,
[addContact.fulfilled](state, action) {
state.isLoading = false;
state.error = null;
state.items.push(action.payload);
},
[addContact.rejected]: handleRejected,
[deleteContact.pending]: handlePending,
[deleteContact.fulfilled](state, action) {
state.isLoading = false;
state.error = null;
const index = state.items.findIndex(
item => item.id === action.payload.id
);
state.items.splice(index, 1);
},
[deleteContact.rejected]: handleRejected,
},
});

export const contactsReducer = contactsSlice.reducer;
15 changes: 15 additions & 0 deletions src/redux/filterSlice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createSlice } from '@reduxjs/toolkit';

const filterSlice = createSlice({
name: 'filter',
initialState: '',

reducers: {
setStatusFilter(_, action) {
return action.payload;
},
},
});

export const { setStatusFilter } = filterSlice.actions;
export const filterReducer = filterSlice.reducer;
Loading

0 comments on commit c59ee9e

Please sign in to comment.