Skip to content

Commit

Permalink
made backend, add operations.js, made createSlice, add store.js, add …
Browse files Browse the repository at this point in the history
…selectors.js
  • Loading branch information
TkachenkoKaterina committed Mar 14, 2024
1 parent b63a2ff commit 0b2062d
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 41 deletions.
68 changes: 62 additions & 6 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@testing-library/jest-dom": "^5.16.3",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.7",
"nanoid": "^5.0.6",
"prop-types": "^15.8.1",
"react": "^18.1.0",
Expand Down
70 changes: 50 additions & 20 deletions src/store/contactsSlice.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,63 @@
import { createSlice } from '@reduxjs/toolkit';
import { addContact, deleteContact, fetchContacts } from './operations';

const initialState = {
contacts: [
{ id: 'id-1', name: 'Rosie Simpson', number: '459-12-56' },
{ id: 'id-2', name: 'Hermione Kline', number: '443-89-12' },
{ id: 'id-3', name: 'Eden Clements', number: '645-17-79' },
{ id: 'id-4', name: 'Annie Copeland', number: '227-91-26' },
],
contacts: {
items: [],
isLoading: false,
error: null,
},
filter: '',
};

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

const handleRejected = (state, action) => {
state.contacts.isLoading = false;
state.contacts.error = action.payload;
};

export const contactsSlice = createSlice({
name: 'contacts',
initialState,
reducers: {
addContact: (state, { payload }) => {
state.contacts.contacts.push(payload);
},
deleteContact: (state, { payload }) => {
state.contacts.contacts = state.contacts.contacts.filter(
contact => contact.id !== payload
);
},
updateFilter: (state, { payload }) => {
state.filter = payload;
},
extraReducers: builder => {
builder
// fetchContacts
.addCase(fetchContacts.pending, handlePending)
.addCase(fetchContacts.fulfilled, (state, action) => {
state.contacts.isLoading = false;
state.contacts.error = null;
state.contacts.items = action.payload;
})
.addCase(fetchContacts.rejected, handleRejected)
// addContact
.addCase(addContact.pending, handlePending)
.addCase(addContact.fulfilled, (state, action) => {
state.contacts.isLoading = false;
state.contacts.error = null;
state.contacts.items.push(action.payload);
})
.addCase(addContact.rejected, handleRejected)
// deleteContact
.addCase(deleteContact.pending, handlePending)
.addCase(deleteContact.fulfilled, (state, action) => {
state.contacts.isLoading = false;
state.contacts.error = null;
state.contacts.items = state.contacts.items.filter(
contact => contact.id !== action.payload
);
})
.addCase(deleteContact.rejected, handleRejected);
},
});

export const { addContact, deleteContact, updateFilter } =
contactsSlice.actions;
export const contactsReducer = contactsSlice.reducer;

// [
// { id: 'id-1', name: 'Rosie Simpson', number: '459-12-56' },
// { id: 'id-2', name: 'Hermione Kline', number: '443-89-12' },
// { id: 'id-3', name: 'Eden Clements', number: '645-17-79' },
// { id: 'id-4', name: 'Annie Copeland', number: '227-91-26' },
// ];
43 changes: 43 additions & 0 deletions src/store/operations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

axios.defaults.baseURL = 'https://65f1db4f034bdbecc763dfe4.mockapi.io';

export const fetchContacts = createAsyncThunk(
'contacts/fetchAll',
async (_, thunkAPI) => {
try {
const response = await axios.get('/contacts');
console.log('response :>> ', response);
return response.data;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
}
);

export const addContact = createAsyncThunk(
'contacts/addContact',
async (contact, thunkAPI) => {
try {
const response = await axios.post('/contacts', { contact });
console.log('response :>> ', response);
return response.data;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
}
);

export const deleteContact = createAsyncThunk(
'contacts/deleteContact',
async (contactId, thunkAPI) => {
try {
const response = await axios.delete(`/contacts/${contactId}`);
console.log('response :>> ', response);
return response.data;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
}
);
9 changes: 7 additions & 2 deletions src/store/selectors.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
export const getContacts = state => state.contacts.contacts.contacts;
export const getFilter = state => state.contacts.filter;
export const selectContacts = state => state.contacts.contacts.items;

export const selectIsLoading = state => state.contacts.contacts.isLoading;

export const selectError = state => state.contacts.contacts.error;

export const selectFilter = state => state.contacts.filter;
14 changes: 1 addition & 13 deletions src/store/store.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { contactsReducer } from './contactsSlice';

const persistConfig = {
key: 'root',
storage,
blacklist: ['filter'],
};

const persistedReducer = persistReducer(persistConfig, contactsReducer);

export const store = configureStore({
reducer: { contacts: persistedReducer },
reducer: { contacts: contactsReducer },
});

export const persistor = persistStore(store);

0 comments on commit 0b2062d

Please sign in to comment.