From 89c98815016db74402035a41addbf4b3444be0ba Mon Sep 17 00:00:00 2001
From: IrynaSlavinska <133566139+IrynaSlavinska@users.noreply.github.com>
Date: Sat, 6 Jan 2024 17:04:15 +0200
Subject: [PATCH] groups
---
src/components/App.jsx | 60 ++++++++--------
src/components/ContactForm/ContactForm.jsx | 69 +++++++++++++------
.../ContactForm/ContactForm.styled.jsx | 3 +-
src/components/ContactsList/ContactsList.jsx | 3 +-
src/components/Filter/Filter.jsx | 56 ++++++++++++++-
src/components/Filter/Filter.styled.jsx | 14 ++++
src/components/Layout/Layout.jsx | 3 +-
src/hooks/useAuth.js | 2 +
src/redux/auth/authSelectors.js | 1 +
src/redux/group/groupFilters.js | 7 ++
src/redux/group/groupSlice.js | 17 +++++
src/redux/reducer.js | 2 +
src/redux/selectors.js | 6 +-
13 files changed, 183 insertions(+), 60 deletions(-)
create mode 100644 src/redux/group/groupFilters.js
create mode 100644 src/redux/group/groupSlice.js
diff --git a/src/components/App.jsx b/src/components/App.jsx
index 2cd575e..2af6b8a 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -8,8 +8,6 @@ import { PublicRoute } from '../routes/PublicRoute';
import { useAuth } from '../hooks/useAuth';
import operations from '../redux/auth/authOperations';
-import { HourglassLoader } from './Loader/Loader';
-
const HomePage = lazy(() => import('pages/HomePage/HomePage'));
const LoginPage = lazy(() => import('pages/LoginPage/LoginPage'));
const ContactsPage = lazy(() => import('pages/ContactsPage/ContactsPage'));
@@ -25,35 +23,35 @@ const App = () => {
dispatch(operations.refreshUser());
}, [dispatch]);
- return isRefreshing ? (
-
- ) : (
-
- }>
- } />
-
- } />}
- />
- } />}
- />
- } />
- }
- />
- }
- />
-
- }>
-
-
+ return (
+ !isRefreshing && (
+
+ }>
+ } />
+
+ } />}
+ />
+ } />}
+ />
+ } />
+ }
+ />
+ }
+ />
+
+ }>
+
+
+ )
);
};
diff --git a/src/components/ContactForm/ContactForm.jsx b/src/components/ContactForm/ContactForm.jsx
index f412f79..1a97615 100644
--- a/src/components/ContactForm/ContactForm.jsx
+++ b/src/components/ContactForm/ContactForm.jsx
@@ -10,28 +10,28 @@ import {
Label,
Input,
SubmitButton,
- // Group,
- // RadioContainer,
- // RaioDiv,
- // RadioInput,
+ Group,
+ RadioContainer,
+ RadioInput,
} from './ContactForm.styled';
export const ContactForm = () => {
const [name, setName] = useState('');
const [number, setNumber] = useState('');
+ const [group, setGroup] = useState('others');
const contacts = useSelector(selectContacts);
const dispatch = useDispatch();
const handleSubmit = e => {
e.preventDefault();
+ const form = e.currentTarget;
+ dispatch(addContactAction({ name, number, group }));
const isExist = contacts.some(contact => contact.name === name);
if (isExist) {
Notiflix.Notify.warning(`${name} is already in your phonebook`);
return;
}
- dispatch(addContactAction({ name, number }));
- setName('');
- setNumber('');
+ form.reset();
};
const handleChange = e => {
@@ -43,6 +43,9 @@ export const ContactForm = () => {
case 'number':
setNumber(value);
break;
+ case 'group':
+ setGroup(value);
+ break;
default:
break;
}
@@ -72,28 +75,52 @@ export const ContactForm = () => {
/>
- {/* Group
+ Group
-
+
+
+
-
+
+
+
-
+
+
+
-
+
- */}
+
+
+
Add contact
diff --git a/src/components/ContactForm/ContactForm.styled.jsx b/src/components/ContactForm/ContactForm.styled.jsx
index 89ae3cd..472b86e 100644
--- a/src/components/ContactForm/ContactForm.styled.jsx
+++ b/src/components/ContactForm/ContactForm.styled.jsx
@@ -49,6 +49,7 @@ export const Group = styled.p`
export const RadioContainer = styled.div`
display: flex;
justify-content: space-between;
+ margin-bottom: 16px;
`;
export const RaioDiv = styled.div`
@@ -81,5 +82,5 @@ export const RaioDiv = styled.div`
`;
export const RadioInput = styled.input`
- display: none;
+ margin-left: 6px;
`;
diff --git a/src/components/ContactsList/ContactsList.jsx b/src/components/ContactsList/ContactsList.jsx
index 5a12f7f..33d21e9 100644
--- a/src/components/ContactsList/ContactsList.jsx
+++ b/src/components/ContactsList/ContactsList.jsx
@@ -55,7 +55,7 @@ export const ContactsList = () => {
{error &&
Something went wrong!. Try again later
}
{visibleContacts.length > 0 && (
- {visibleContacts.map(({ id, name, number }) => (
+ {visibleContacts.map(({ id, name, number, group }) => (
-
@@ -63,6 +63,7 @@ export const ContactsList = () => {
{name}
{number}
+ {group}
{
- const { filter } = useSelector(selectFilterValue);
const dispatch = useDispatch();
+ const { filter } = useSelector(selectFilterValue);
+
+ const group = useSelector(selectGroupFilters);
+
+ const handleGroupChange = group => dispatch(setGroupFilters(group));
const filterChange = e => {
dispatch(setSearchFilterAction(e.target.value));
@@ -24,6 +38,44 @@ export const Filter = () => {
onChange={filterChange}
/>
+
+
+ handleGroupChange(groupFilters.all)}
+ >
+ All
+
+ handleGroupChange(groupFilters.family)}
+ >
+ Family
+
+ handleGroupChange(groupFilters.friends)}
+ >
+ Friends
+
+ handleGroupChange(groupFilters.work)}
+ >
+ Work
+
+ handleGroupChange(groupFilters.others)}
+ >
+ Oters
+
+
);
};
diff --git a/src/components/Filter/Filter.styled.jsx b/src/components/Filter/Filter.styled.jsx
index d17a4d6..666cc7e 100644
--- a/src/components/Filter/Filter.styled.jsx
+++ b/src/components/Filter/Filter.styled.jsx
@@ -13,6 +13,7 @@ export const Label = styled.label`
display: flex;
align-items: center;
gap: 20px;
+ margin-bottom: 10px;
`;
export const Input = styled.input`
@@ -29,3 +30,16 @@ export const Input = styled.input`
border-color: #e9af3d;
}
`;
+
+export const SortContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+ gap: 6px;
+`;
+
+export const SortButton = styled.button`
+ padding: 8px 12px;
+ font-size: 16px;
+ color: #000000;
+ background-color: #e9af3d;
+`;
diff --git a/src/components/Layout/Layout.jsx b/src/components/Layout/Layout.jsx
index 933400d..ac30d49 100644
--- a/src/components/Layout/Layout.jsx
+++ b/src/components/Layout/Layout.jsx
@@ -2,13 +2,14 @@ import { Outlet } from 'react-router-dom';
import { Suspense } from 'react';
import { AppBar } from 'components/AppBar/AppBar';
import { Container, Main } from './Layout.styled';
+import { HourglassLoader } from 'components/Loader/Loader';
const Layout = () => {
return (
-
+ }>
diff --git a/src/hooks/useAuth.js b/src/hooks/useAuth.js
index 019e308..98d2c7d 100644
--- a/src/hooks/useAuth.js
+++ b/src/hooks/useAuth.js
@@ -4,9 +4,11 @@ import { authSelectors } from '../redux/auth/authSelectors';
export const useAuth = () => {
const isLoggedIn = useSelector(authSelectors.selectIsLoggedIn);
const user = useSelector(authSelectors.selectUserName);
+ const isRefreshing = useSelector(authSelectors.selectIsRefreshing);
return {
isLoggedIn,
user,
+ isRefreshing,
};
};
diff --git a/src/redux/auth/authSelectors.js b/src/redux/auth/authSelectors.js
index 160c542..c67f7ba 100644
--- a/src/redux/auth/authSelectors.js
+++ b/src/redux/auth/authSelectors.js
@@ -7,4 +7,5 @@ export const selectIsRefreshing = state => state.auth.isRefreshing;
export const authSelectors = {
selectIsLoggedIn,
selectUserName,
+ selectIsRefreshing,
};
diff --git a/src/redux/group/groupFilters.js b/src/redux/group/groupFilters.js
new file mode 100644
index 0000000..71cbe62
--- /dev/null
+++ b/src/redux/group/groupFilters.js
@@ -0,0 +1,7 @@
+export const groupFilters = Object.freeze({
+ all: 'all',
+ family: 'family',
+ friends: 'friends',
+ work: 'work',
+ others: 'others',
+});
diff --git a/src/redux/group/groupSlice.js b/src/redux/group/groupSlice.js
new file mode 100644
index 0000000..e1dd5a2
--- /dev/null
+++ b/src/redux/group/groupSlice.js
@@ -0,0 +1,17 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { groupFilters } from './groupFilters';
+
+const groupSlice = createSlice({
+ name: 'group',
+ initialState: {
+ group: groupFilters.all,
+ },
+ reducers: {
+ setGroupFilters(state, action) {
+ state.group = action.payload;
+ },
+ },
+});
+
+export const { setGroupFilters } = groupSlice.actions;
+export const sortReducer = groupSlice.reducer;
diff --git a/src/redux/reducer.js b/src/redux/reducer.js
index a6ca202..a67b962 100644
--- a/src/redux/reducer.js
+++ b/src/redux/reducer.js
@@ -4,6 +4,7 @@ import storage from 'redux-persist/lib/storage';
import { contactsReducer } from './contacts/contactsSlice';
import { filterReducer } from './filter/filterSlice';
import { authReducer } from './auth/authSlice';
+import { sortReducer } from './group/groupSlice.js';
const authPersistConfig = {
key: 'auth',
@@ -14,5 +15,6 @@ const authPersistConfig = {
export const reducer = {
contacts: contactsReducer,
filter: filterReducer,
+ sort: sortReducer,
auth: persistReducer(authPersistConfig, authReducer),
};
diff --git a/src/redux/selectors.js b/src/redux/selectors.js
index 78ffa42..06ec274 100644
--- a/src/redux/selectors.js
+++ b/src/redux/selectors.js
@@ -1,7 +1,7 @@
export const selectContacts = state => state.contacts.contacts;
+export const selectError = state => state.contacts.error;
+export const selectIsLoading = state => state.contacts.isLoading;
export const selectFilterValue = state => state.filter.filter;
-export const selectError = state => state.contacts.error;
-
-export const selectIsLoading = state => state.contacts.isLoading;
+export const selectGroupFilters = state => state.filter.status;