From 3e48ee1aa085fb21ebc06d7208ebddbb7acd170e Mon Sep 17 00:00:00 2001 From: leonardo messias Date: Fri, 16 Apr 2021 10:31:41 -0300 Subject: [PATCH] feat(users list): implement update user with backend and delete user modal mocked --- src/DTOs/User.tsx | 3 + src/assets/warn.svg | 3 + src/contexts/index.tsx | 2 +- src/contexts/{users.tsx => user.tsx} | 19 ++++ src/pages/Users/components/UserInfo/styles.ts | 4 +- .../components/UserModal/DeleteUser/index.tsx | 56 ++++++++++ .../components/UserModal/DeleteUser/styles.ts | 93 ++++++++++++++++ .../UserModal/UpdateSuccess/index.tsx | 19 ++++ .../UserModal/UpdateSuccess/styles.ts | 45 ++++++++ .../UserModal/UserContent/index.tsx | 104 ++++++++++++++++++ .../UserModal/UserContent/styles.ts | 85 ++++++++++++++ .../Users/components/UserModal/index.tsx | 98 +++++------------ .../Users/components/UserModal/styles.ts | 72 +----------- src/pages/Users/index.tsx | 6 +- src/pages/Users/styles.ts | 2 +- 15 files changed, 465 insertions(+), 146 deletions(-) create mode 100644 src/assets/warn.svg rename src/contexts/{users.tsx => user.tsx} (66%) create mode 100644 src/pages/Users/components/UserModal/DeleteUser/index.tsx create mode 100644 src/pages/Users/components/UserModal/DeleteUser/styles.ts create mode 100644 src/pages/Users/components/UserModal/UpdateSuccess/index.tsx create mode 100644 src/pages/Users/components/UserModal/UpdateSuccess/styles.ts create mode 100644 src/pages/Users/components/UserModal/UserContent/index.tsx create mode 100644 src/pages/Users/components/UserModal/UserContent/styles.ts diff --git a/src/DTOs/User.tsx b/src/DTOs/User.tsx index acf9e30..ef668c3 100644 --- a/src/DTOs/User.tsx +++ b/src/DTOs/User.tsx @@ -14,7 +14,10 @@ interface UserData { export interface UserContextData { users: Array; + updateUserTypeSuccess: boolean; getUsers(): void; + clearUpdateStatus(): void; + updateUserType(credentials: { id: string; userType: string }): void; } export interface UserProviderProps { diff --git a/src/assets/warn.svg b/src/assets/warn.svg new file mode 100644 index 0000000..193f639 --- /dev/null +++ b/src/assets/warn.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/contexts/index.tsx b/src/contexts/index.tsx index c4a89dd..09386c2 100644 --- a/src/contexts/index.tsx +++ b/src/contexts/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { AuthProvider } from './auth'; import { MainProvider } from './main'; -import { UsersProvider } from './users'; +import { UsersProvider } from './user'; interface ContextProps { children: React.ReactNode; diff --git a/src/contexts/users.tsx b/src/contexts/user.tsx similarity index 66% rename from src/contexts/users.tsx rename to src/contexts/user.tsx index d272958..b4febac 100644 --- a/src/contexts/users.tsx +++ b/src/contexts/user.tsx @@ -16,6 +16,9 @@ const UsersProvider = ({ children }: UserProviderProps) => { const [users, setUsers] = useState([ { id: '', name: '', type: '' }, ]); + const [updateUserTypeSuccess, setUpdateUserTypeSuccess] = useState( + false, + ); const getUsers = useCallback(async () => { const response = await api.get('/users'); @@ -23,11 +26,27 @@ const UsersProvider = ({ children }: UserProviderProps) => { setUsers(response.data); }, []); + const updateUserType = useCallback(async ({ id, userType }) => { + try { + await api.patch(`/users/${id}`, { type: userType }); + setUpdateUserTypeSuccess(true); + } catch (error) { + setUpdateUserTypeSuccess(true); + } + }, []); + + const clearUpdateStatus = useCallback(() => { + setUpdateUserTypeSuccess(false); + }, []); + return ( {children} diff --git a/src/pages/Users/components/UserInfo/styles.ts b/src/pages/Users/components/UserInfo/styles.ts index 67fa521..af45c7d 100644 --- a/src/pages/Users/components/UserInfo/styles.ts +++ b/src/pages/Users/components/UserInfo/styles.ts @@ -11,8 +11,8 @@ export const Container = styled.button` font-family: Roboto; font-style: normal; font-weight: 900; - font-size: 2rem; - line-height: 28px; + font-size: 1.6rem; + line-height: 2.8rem; text-align: center; color: #373435; diff --git a/src/pages/Users/components/UserModal/DeleteUser/index.tsx b/src/pages/Users/components/UserModal/DeleteUser/index.tsx new file mode 100644 index 0000000..bbf5c9c --- /dev/null +++ b/src/pages/Users/components/UserModal/DeleteUser/index.tsx @@ -0,0 +1,56 @@ +import React, { useCallback, useState } from 'react'; + +import { ReactComponent as WarnIcon } from 'assets/warn.svg'; +import Button from 'components/Button/Button'; + +import { Container, RemoveWarnSuccess } from './styles'; + +interface DeleteUserProps { + setShowDeleteUser: Function; +} + +const DeleteUser = ({ setShowDeleteUser }: DeleteUserProps) => { + const [deleteUserSuccess, setDeleteUserSuccess] = useState(false); + + const handleGoBack = useCallback(() => { + if (setShowDeleteUser) setShowDeleteUser(false); + }, [setShowDeleteUser]); + + const handleDeleteUser = useCallback(() => { + setDeleteUserSuccess(true); + }, []); + + return ( + + {deleteUserSuccess ? ( + +
+ +

USUÁRIO REMOVIDO

+
+ +
+ ) : ( + <> +
+ +

TEM CERTEZA?

+

ESTA AÇÃO NÃO PODERÁ SER DEFEITA.

+
+
+ + +
+ + )} +
+ ); +}; + +export default DeleteUser; diff --git a/src/pages/Users/components/UserModal/DeleteUser/styles.ts b/src/pages/Users/components/UserModal/DeleteUser/styles.ts new file mode 100644 index 0000000..f2d1090 --- /dev/null +++ b/src/pages/Users/components/UserModal/DeleteUser/styles.ts @@ -0,0 +1,93 @@ +import styled from 'styled-components'; + +export const RemoveWarnSuccess = styled.section` + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + + .warn { + display: flex; + } + + button { + height: 5rem; + font-size: 2rem; + + margin: 0 5px; + pointer-events: all; + } +`; + +export const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + height: 100%; + width: 100%; + + .warn { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + margin-top: 5rem; + + svg { + width: 5.5rem; + height: 5.5rem; + margin: 0; + } + + h1 { + font-family: Roboto; + font-style: normal; + font-weight: bold; + font-size: 5rem; + line-height: 5.9rem; + text-align: center; + + color: #373435; + + margin: 1.5rem 0; + } + + p { + font-family: Roboto; + font-style: normal; + font-weight: normal; + font-size: 2rem; + line-height: 2.4rem; + text-align: center; + letter-spacing: 0.25em; + + color: #373435; + + margin: 0; + } + } + + .buttons { + display: flex; + pointer-events: all; + + button { + height: 5rem; + font-size: 2rem; + + margin: 0 5px; + } + } + + @media (max-width: 600px) { + justify-content: center; + + .warn { + margin: 2.5rem 0; + } + } +`; diff --git a/src/pages/Users/components/UserModal/UpdateSuccess/index.tsx b/src/pages/Users/components/UserModal/UpdateSuccess/index.tsx new file mode 100644 index 0000000..ca25594 --- /dev/null +++ b/src/pages/Users/components/UserModal/UpdateSuccess/index.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import { ReactComponent as Like } from 'assets/like.svg'; + +import { Container } from './styles'; + +const UpdateSuccess = () => { + return ( + + + +

ATUALIZADO!

+ +

VOLTANDO...

+
+ ); +}; + +export default UpdateSuccess; diff --git a/src/pages/Users/components/UserModal/UpdateSuccess/styles.ts b/src/pages/Users/components/UserModal/UpdateSuccess/styles.ts new file mode 100644 index 0000000..bdf508f --- /dev/null +++ b/src/pages/Users/components/UserModal/UpdateSuccess/styles.ts @@ -0,0 +1,45 @@ +import styled from 'styled-components'; + +export const Container = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; + + padding: 3rem; + + svg { + width: 5.5rem; + height: 5.5rem; + margin: 0; + } + + h1 { + font-family: Roboto; + font-style: normal; + font-weight: bold; + font-size: 5rem; + line-height: 5.9rem; + text-align: center; + + color: #373435; + + margin: 1.5rem 0; + } + + p { + font-family: Roboto; + font-style: normal; + font-weight: normal; + font-size: 2.4rem; + line-height: 2.8rem; + text-align: center; + letter-spacing: 0.25em; + + color: #373435; + + margin: 0; + } +`; diff --git a/src/pages/Users/components/UserModal/UserContent/index.tsx b/src/pages/Users/components/UserModal/UserContent/index.tsx new file mode 100644 index 0000000..10bed9d --- /dev/null +++ b/src/pages/Users/components/UserModal/UserContent/index.tsx @@ -0,0 +1,104 @@ +import React, { useCallback, useState } from 'react'; + +import { useUsers } from 'contexts/user'; +import { ReactComponent as UserIcon } from 'assets/userIcon.svg'; +import Button from 'components/Button/Button'; + +import { Container } from './styles'; + +interface UserModalProps { + selectedUser: { id: string; name: string; type: string }; + onClose: Function; + setShowDeleteUser: Function; +} + +const UserModal = ({ + selectedUser, + onClose, + setShowDeleteUser, +}: UserModalProps) => { + const { updateUserType } = useUsers(); + + const userIsAdmin = selectedUser.type === 'Admin'; + const [userType, setUserType] = useState(selectedUser.type); + + const handleClose = useCallback(() => { + if (onClose) onClose(); + }, [onClose]); + + const handleSelectUserType = useCallback((e: any) => { + setUserType(e.target.value); + }, []); + + const handleUpdateUserType = useCallback(async () => { + await updateUserType({ id: selectedUser.id, userType }); + }, [updateUserType, selectedUser, userType]); + + const handleDeleteUser = useCallback(() => { + if (setShowDeleteUser) setShowDeleteUser(true); + }, [setShowDeleteUser]); + + return ( + +
+ + +

{selectedUser.name}

+ {userIsAdmin ? ( +

{selectedUser.type}

+ ) : ( +
+ + + + + + + + +
+ )} +
+ +
+ + + {!userIsAdmin && ( + <> + + + + )} +
+
+ ); +}; + +export default UserModal; diff --git a/src/pages/Users/components/UserModal/UserContent/styles.ts b/src/pages/Users/components/UserModal/UserContent/styles.ts new file mode 100644 index 0000000..7111aa3 --- /dev/null +++ b/src/pages/Users/components/UserModal/UserContent/styles.ts @@ -0,0 +1,85 @@ +import styled from 'styled-components'; + +interface ContainerProps { + userIsAdmin: boolean; +} + +export const Container = styled.div` + margin-top: -30px; + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + + pointer-events: none; + + .userInfo { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + margin: 4rem 0; + + svg { + margin: 4rem 0; + } + + h1 { + font-size: 3.2rem; + margin: 0 0 5px 0; + } + + h2 { + color: ${props => props.userIsAdmin && 'var(--red-pink)'}; + font-size: 2.6rem; + margin: 0; + } + + .usertype { + display: flex; + align-items: center; + pointer-events: all; + + input, + label { + cursor: pointer; + } + + input { + width: 2rem; + height: 2rem; + margin: 0 0.5rem 0 2rem; + } + + label { + font-size: 2rem; + } + } + } + + .buttons { + pointer-events: all; + + width: 100%; + display: flex; + justify-content: center; + + button { + height: 5rem; + font-size: 2rem; + + margin: 0 5px; + } + } + + @media (max-width: 600px) { + justify-content: center; + + .userInfo { + text-align: center; + } + } +`; diff --git a/src/pages/Users/components/UserModal/index.tsx b/src/pages/Users/components/UserModal/index.tsx index 4e3536d..2951496 100644 --- a/src/pages/Users/components/UserModal/index.tsx +++ b/src/pages/Users/components/UserModal/index.tsx @@ -1,9 +1,11 @@ -import React, { useCallback, useState } from 'react'; +import React, { useEffect, useState } from 'react'; -import { ReactComponent as UserIcon } from 'assets/userIcon.svg'; +import { useUsers } from 'contexts/user'; import DefaultModal from 'components/DefaultModal'; -import Button from 'components/Button/Button'; +import UpdateSuccess from './UpdateSuccess'; +import UserContent from './UserContent'; +import DeleteUser from './DeleteUser'; import { Container } from './styles'; interface UserModalProps { @@ -12,77 +14,37 @@ interface UserModalProps { } const UserModal = ({ selectedUser, onClose }: UserModalProps) => { - const userIsAdmin = selectedUser.type === 'Admin'; - const [userType, setUserType] = useState(selectedUser.type); + const { updateUserTypeSuccess, clearUpdateStatus, getUsers } = useUsers(); - const handleClose = useCallback(() => { - if (onClose) onClose(); - }, [onClose]); + const [showSuccessElement, setShowSuccessElement] = useState(false); + const [showDeleteUser, setShowDeleteUser] = useState(false); - const handleSelectUserType = (e: any) => { - setUserType(e.target.value); - }; + useEffect(() => { + if (updateUserTypeSuccess) { + setShowSuccessElement(true); - const handleUpdateUserType = () => { - // eslint-disable-next-line no-console - console.log(userType); - }; + setTimeout(() => { + if (onClose) onClose(); + clearUpdateStatus(); + getUsers(); + }, 2000); + } + }, [updateUserTypeSuccess, clearUpdateStatus, onClose, getUsers]); return ( - -
- - -

{selectedUser.name}

- {userIsAdmin ? ( -

{selectedUser.type}

- ) : ( -
- - - - - - - - -
- )} -
- -
- - - {!userIsAdmin && ( - <> - - - - )} -
+ + {showDeleteUser ? ( + + ) : showSuccessElement ? ( + + ) : ( + + )}
); diff --git a/src/pages/Users/components/UserModal/styles.ts b/src/pages/Users/components/UserModal/styles.ts index 7111aa3..d6059f5 100644 --- a/src/pages/Users/components/UserModal/styles.ts +++ b/src/pages/Users/components/UserModal/styles.ts @@ -1,85 +1,15 @@ import styled from 'styled-components'; -interface ContainerProps { - userIsAdmin: boolean; -} - -export const Container = styled.div` - margin-top: -30px; +export const Container = styled.div` height: 100%; width: 100%; display: flex; flex-direction: column; justify-content: space-between; align-items: center; - pointer-events: none; - .userInfo { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - margin: 4rem 0; - - svg { - margin: 4rem 0; - } - - h1 { - font-size: 3.2rem; - margin: 0 0 5px 0; - } - - h2 { - color: ${props => props.userIsAdmin && 'var(--red-pink)'}; - font-size: 2.6rem; - margin: 0; - } - - .usertype { - display: flex; - align-items: center; - pointer-events: all; - - input, - label { - cursor: pointer; - } - - input { - width: 2rem; - height: 2rem; - margin: 0 0.5rem 0 2rem; - } - - label { - font-size: 2rem; - } - } - } - - .buttons { - pointer-events: all; - - width: 100%; - display: flex; - justify-content: center; - - button { - height: 5rem; - font-size: 2rem; - - margin: 0 5px; - } - } - @media (max-width: 600px) { justify-content: center; - - .userInfo { - text-align: center; - } } `; diff --git a/src/pages/Users/index.tsx b/src/pages/Users/index.tsx index 75252df..ba0206f 100644 --- a/src/pages/Users/index.tsx +++ b/src/pages/Users/index.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState, useEffect } from 'react'; -import { useUsers } from 'contexts/users'; +import { useUsers } from 'contexts/user'; import UserModal from './components/UserModal'; import UserInfo from './components/UserInfo'; @@ -46,8 +46,8 @@ const Users = () => {

Lista de Usuários

- - +
Nome do usuário
+
Nível de permissão
diff --git a/src/pages/Users/styles.ts b/src/pages/Users/styles.ts index ec9d04a..1938f65 100644 --- a/src/pages/Users/styles.ts +++ b/src/pages/Users/styles.ts @@ -26,7 +26,7 @@ export const Container = styled.div` max-width: 80rem; margin: 3rem 0; - button { + div { width: 100%; display: flex; align-items: center;