Bladeren bron

finished right lists in credentials

unknown 3 jaren geleden
bovenliggende
commit
dd72e6754b
20 gewijzigde bestanden met toevoegingen van 245 en 92 verwijderingen
  1. 1 1
      .eslintcache
  2. 22 0
      src/api-data/index.ts
  3. 4 8
      src/components/HomePage/LeftBar/ChatsList/index.tsx
  4. 9 6
      src/components/HomePage/LeftBar/ContactsList/index.tsx
  5. 79 0
      src/components/HomePage/RightBar/HeaderBar/Buttons/DeleteModal/index.tsx
  6. 3 3
      src/components/HomePage/RightBar/HeaderBar/Buttons/MenuList/index.tsx
  7. 7 2
      src/components/HomePage/RightBar/HeaderBar/Buttons/index.tsx
  8. 3 2
      src/components/HomePage/RightBar/HeaderBar/Credentials/index.tsx
  9. 3 1
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ProfileLists/index.tsx
  10. 4 3
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ProfileMenu/index.tsx
  11. 14 7
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ToolBar/index.tsx
  12. 2 5
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/index.tsx
  13. 6 7
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/Delete/index.tsx
  14. 18 35
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/EditList/index.tsx
  15. 27 0
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/SubmitBtn/index.tsx
  16. 34 9
      src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/index.tsx
  17. 1 0
      src/redux/chat/reducer/index.ts
  18. 6 3
      src/redux/contacts/selector/index.ts
  19. 1 0
      src/typescript/redux/chat/types.ts
  20. 1 0
      src/typescript/redux/chats/types.ts

File diff suppressed because it is too large
+ 1 - 1
.eslintcache


+ 22 - 0
src/api-data/index.ts

@@ -119,6 +119,16 @@ const addContact = async <T>(number:string): Promise<T | undefined> => {
   }
 };
 
+const removeContact = async <T>(id:string): Promise<T | undefined> => {
+  try {
+    const { data : {data} } = await axios.delete(`/contacts/${id}`);
+    return data
+  } catch (e) {
+    forbidden(e)
+    return undefined
+  }
+};
+
 const updateContact = async <T>(id:string,_id:string,name:string,lastName:string): Promise<T | undefined> => {
   try {
     const { data: { data } } = await axios.patch('/contacts', { id, _id, name, lastName });
@@ -169,6 +179,16 @@ const muteChat = async <T>(id:string): Promise<T | undefined> => {
   }
 };
 
+const sortChat = async <T>(id:string): Promise<T | undefined> => {
+  try {
+    const { data: { data } } = await axios.patch('/chats/sort', {id});
+    return data
+  } catch (e) {
+    forbidden(e)
+    return undefined
+  }
+};
+
 const seenChat = async <T>(id:string): Promise<T | undefined> => {
   try {
     const { data: { data } } = await axios.patch('/chats/seen', { id });
@@ -271,11 +291,13 @@ export {
   updateUserAvatar,
   currentUser,
   addContact,
+  removeContact,
   updateContact,
   getContacts,
   startChat,
   getChat,
   muteChat,
+  sortChat,
   seenChat,
   typingChat,
   getChats,

+ 4 - 8
src/components/HomePage/LeftBar/ChatsList/index.tsx

@@ -12,7 +12,7 @@ import { useSelector, useDispatch } from 'react-redux';
 
 import AlertInfo from '../../../reusableComponents/AlertInfo'
 import DoneAllIcon from '@mui/icons-material/DoneAll';
-import { firstLetter, slicedWord, timeStamp,notification,playNotificationWithoutPermission } from '../../../../helpers'
+import { firstLetter, slicedWord, timeStampEU,notification,playNotificationWithoutPermission } from '../../../../helpers'
 import { getState } from '../../../../redux/chats/selector'
 import { asyncGetChats } from '../../../../redux/chats/operations'
 import { asyncStartChatById } from '../../../../redux/chat/operations'
@@ -179,7 +179,6 @@ const ChatsList = () => {
   const ref = useRef<any>(null)
   const [selectedIndex, setSelectedIndex] = useState<number>(1);
   const { total, chats , lastMessages,lastOnline } = useSelector(getState)
- 
 
   const handleListItemClick = (i: number, companionId: string) => {
     dispatch(asyncStartChatById(companionId))
@@ -195,14 +194,11 @@ const ChatsList = () => {
   }
 
   useEffect(() => {
+    dispatch(asyncGetChats())
     const handleReset = () => dispatch(asyncGetChats())
     const idInterval = setInterval(handleReset, 3000);
     return () => clearInterval(idInterval);
   }, [dispatch]);
-  
-  useEffect(() => {
-    dispatch(asyncGetChats())
-  }, [dispatch])
 
   useEffect(() => {
     const handleNotification= (companionId: string) => {
@@ -253,8 +249,8 @@ const ChatsList = () => {
                <div className={classes.listItem_iconTimeChecked}>
                  {watched&& <DoneAllIcon style={{ color: '#18bd03' }} fontSize='small' />}
               <Typography className={classes.listItem_icon_time} variant="h6" color="initial">
-                {lastMessages[i] ? timeStamp(lastMessages[i].updatedAt) :
-                timeStamp(updatedAt)}</Typography>
+                {lastMessages[i] ? timeStampEU(lastMessages[i].updatedAt) :
+                timeStampEU(updatedAt)}</Typography>
                </div>
             {lastMessages[i] && total > seen ? <button onClick={(e) => handleNewMsgs(e, i,companionId)}
               className={mute?classes.listItem_iconRightBtnMute:classes.listItem_iconRightBtn}>{total-seen}</button> :

+ 9 - 6
src/components/HomePage/LeftBar/ContactsList/index.tsx

@@ -10,7 +10,7 @@ import { useSelector,useDispatch } from 'react-redux';
 import AlertInfo from '../../../reusableComponents/AlertInfo'
 import { getState } from '../../../../redux/contacts/selector'
 import { asyncGetContacts } from '../../../../redux/contacts/operations'
-import { firstLetter, slicedWord, timeStamp } from '../../../../helpers'
+import { firstLetter, slicedWord, timeStampEU } from '../../../../helpers'
 import { asyncStartChatById } from '../../../../redux/chat/operations'
 
 const useStyles = makeStyles({
@@ -54,15 +54,18 @@ const  ContactsList = ({value} : IContactList) => {
      await dispatch(asyncStartChatById(companionId))
   }
 
-  useEffect(() => {
-    dispatch(asyncGetContacts())
-  }, [dispatch])
-
   const filteredContacts = () => contacts.filter((el) => {
     const credentials = el.name + ' ' + el.lastName
     if(credentials.toLowerCase().includes(value.toLowerCase())) return el
   })
 
+  useEffect(() => {
+    dispatch(asyncGetContacts())
+    const handleReset = () => dispatch(asyncGetContacts())
+    const idInterval = setInterval(handleReset, 3000);
+    return () => clearInterval(idInterval);
+  }, [dispatch]);
+
   const arr = filteredContacts()
   
   return total !== '0' ? (
@@ -83,7 +86,7 @@ const  ContactsList = ({value} : IContactList) => {
           </ListItemIcon> 
           <ListItemText primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
                ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
-               secondary={`Registered since ${timeStamp(createdAt)}`} />
+               secondary={`Registered since ${timeStampEU(createdAt)}`} />
         </ListItemButton>) :
         <AlertInfo name={`Can not find contact by request : ${value}`} />}
       </List>

+ 79 - 0
src/components/HomePage/RightBar/HeaderBar/Buttons/DeleteModal/index.tsx

@@ -0,0 +1,79 @@
+import Button from '@mui/material/Button';
+import Avatar from '@mui/material/Avatar';
+import { makeStyles } from '@material-ui/core'
+import { useSelector } from 'react-redux';
+
+import { getChat } from '../../../../../../redux/chat/selector';
+import { firstLetter,slicedWord } from '../../../../../../helpers';
+
+const useStyles = makeStyles({
+  modalDelete: {
+    background: '#ffffff',
+    position: 'absolute',
+    content:'',
+    width: '20%',
+    height:'auto',
+    left: '40%',
+    bottom: '48.5%',
+    borderRadius: 10,
+    padding: 10,
+    display: 'flex',
+    flexDirection:'column'
+  },  
+  overlay: {
+    position: 'fixed',
+    top: 0,
+    left: 0,
+    width: '100vw',
+    height: '100vh',
+    zIndex: 100,
+    backgroundColor: 'rgba(104, 105, 104, 0.6)',
+    overflowY: 'hidden',
+  },
+  titleWrapper: {
+    display: 'flex',
+    justifyContent: 'flex-start',
+    alignContent: 'center',
+    alignItems:'center'
+  },
+})
+
+const DeleteModal = ({setModal}:{setModal:any}) => {
+  const classes = useStyles()
+  const {name,lastName,avatarUrl,color} = useSelector(getChat)
+
+  const handleDeleteModal = (e: any) => {
+    const id = e.target.id
+    if (id === 'overlay' || id === 'cancel')  return setModal(false)
+    if (id === 'deleteForMeAnd') console.log('deleteForMeAnd')
+    if (id === 'deleteForMe') console.log('deleteForMeAnd')
+  }  
+  return (
+    <div onClick={handleDeleteModal} className={classes.overlay} id='overlay'>
+      <div className={classes.modalDelete}>
+        <div className={classes.titleWrapper}>
+          <Avatar alt={name} src={avatarUrl?`http://localhost:3000/${avatarUrl}`:undefined}
+            sx={{ background: color, width: 38, height: 38,marginRight:2}}>
+            {`${firstLetter(name)}${firstLetter(lastName)}`}
+          </Avatar>
+          <h3 style={{color: '#2c2c2c'}}>Delete chat</h3>
+         </div>
+         <p style={{color: '#050505'}}>{`Are you sure you want to delete the
+          chat with ${`${firstLetter(name)}${slicedWord(name, 15, 1)} 
+            ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}?`}</p>
+          <Button id='deleteForMeAnd' variant="text" color="error" style={{fontWeight:500,fontSize:18}}>
+            {`DELETE FOR ME AND ${`${firstLetter(name)}${slicedWord(name, 15, 1)} 
+            ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}`}
+          </Button>
+          <Button id='deleteForMe' variant="text" color="error" style={{fontWeight:500,fontSize:18}}>
+            DELETE FOR ME
+          </Button>         
+          <Button id='cancel' variant="text" style={{fontWeight:500,fontSize:18}}>
+             CANCEL
+          </Button>
+        </div>
+      </div>      
+   )
+}
+
+export default DeleteModal

+ 3 - 3
src/components/HomePage/RightBar/HeaderBar/Buttons/MenuList/index.tsx

@@ -51,7 +51,7 @@ const StyledMenu = styled((props:any) => (
 }));
 
 
-const MenuList = () => {
+const MenuList = ({setModal}:{setModal:any}) => {
   const dispatch = useDispatch()
   const [anchorEl, setAnchorEl] = useState<any>(null);
   const open = Boolean(anchorEl);
@@ -62,8 +62,8 @@ const MenuList = () => {
   }
 
   const handleClose = (i:number|undefined):void => {
-    console.log('chosen one element from small menu by id', i)
-    if(i === 0) muteChat(companionId)
+    if (i === 0) muteChat(companionId)
+    if (i === 2) setModal(true)
     dispatch(actionIsOpen(''))
     setAnchorEl(null)
   }

+ 7 - 2
src/components/HomePage/RightBar/HeaderBar/Buttons/index.tsx

@@ -3,25 +3,30 @@ import IconButton from '@mui/material/IconButton';
 import SearchIcon from '@mui/icons-material/Search';
 import { makeStyles } from '@material-ui/core'
 import { useDispatch } from 'react-redux';
+import { useState } from 'react';
 
 import MenuList from './MenuList'
+import DeleteModal from './DeleteModal';
 import { actionIsOpen } from '../../../../../redux/control/action'
 
 const useStyles = makeStyles({
   container: {
     marginLeft:20
-  }
+  }, 
 })
 
 const Buttons = () => {
   const classes = useStyles()
   const dispatch = useDispatch()
+  const [modal,setModal] = useState<boolean>(false)
+
   return (
     <Stack className={classes.container} direction="row" spacing={1}>
       <IconButton onClick={() => dispatch(actionIsOpen('search'))} aria-label="delete" size="medium">
         <SearchIcon fontSize='medium'/>
       </IconButton>
-      <MenuList/>
+      <MenuList setModal={setModal}/>
+       {modal&&<DeleteModal setModal={setModal}/>}      
     </Stack>
   );
 }

+ 3 - 2
src/components/HomePage/RightBar/HeaderBar/Credentials/index.tsx

@@ -8,7 +8,7 @@ import { useEffect,useRef } from 'react';
 import { actionIsOpen } from '../../../../../redux/control/action'
 import { getChat } from '../../../../../redux/chat/selector'
 import { asyncGetChatById } from '../../../../../redux/chat/operations'
-import { firstLetter,slicedWord,timeStamp } from '../../../../../helpers'
+import { firstLetter,slicedWord,timeStampEU } from '../../../../../helpers'
 
 const Credentials = () => {
   const dispatch = useDispatch()
@@ -37,7 +37,8 @@ const Credentials = () => {
       </ListItemIcon> 
       <ListItemText primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
         ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
-        secondaryTypographyProps={{ color: '#0379af' }} secondary={online === 'true'?'online':`last seen ${timeStamp(online)}`} />
+        secondaryTypographyProps={{ color: '#0379af' }} secondary={online === 'true' ?
+          'online' : `last seen ${timeStampEU(online)}`} />
     </ListItemButton>
   )
 }

+ 3 - 1
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ProfileLists/index.tsx

@@ -11,6 +11,7 @@ import TextList from './TextList';
 import VideoList from './VideoList'
 import { getMessagesMemo } from '../../../../../../../redux/messages/selector'
 import { handleSort } from '../../../../../../../helpers';
+import { getChat } from '../../../../../../../redux/chat/selector'
 import { TMessages } from '../../../../../../../typescript/redux/messages/types'
 
 const useStyles = makeStyles({
@@ -29,8 +30,9 @@ const useStyles = makeStyles({
     },
 })
 
-const ProfileLists = ({sort}:{sort:boolean}) => {
+const ProfileLists = () => {
     const classes = useStyles()
+    const { sort } = useSelector(getChat)
     const messagesMemo = useSelector(getMessagesMemo)
     const [isActive, setIsActive] = useState<number>(0)
     const handleIsActive = (_e: React.SyntheticEvent<Element, Event>, newValue: number): void => setIsActive(newValue)

+ 4 - 3
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ProfileMenu/index.tsx

@@ -13,7 +13,7 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { makeStyles } from '@material-ui/core'
 
 import { getChat } from '../../../../../../../redux/chat/selector'
-import { muteChat } from '../../../../../../../api-data'
+import { muteChat,sortChat } from '../../../../../../../api-data'
 import { copied } from '../../../../../../../helpers';
 
 const useStyles = makeStyles({
@@ -30,10 +30,11 @@ const useStyles = makeStyles({
 
 const label = { inputProps: { 'aria-label': 'Switch demo' } };
 
-const ProfileMenu = ({sort,handleSort}:{sort:boolean,handleSort: () => void}) => {
+const ProfileMenu = () => {
   const classes = useStyles()
-  const { number, mute, companionId } = useSelector(getChat)
+  const { number, mute,sort,companionId } = useSelector(getChat)
   const handleMute = () => muteChat(companionId)
+  const handleSort = () => sortChat(companionId)
   return (
     <Paper className={classes.container}>
       <MenuList className={classes.list}>

+ 14 - 7
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/ToolBar/index.tsx

@@ -7,7 +7,7 @@ import { makeStyles, Typography } from '@material-ui/core'
 import { useDispatch, useSelector } from 'react-redux';
 import { useState,useEffect } from 'react';
 import { actionIsOpen } from '../../../../../../../redux/control/action'
-import { getContacts } from '../../../../../../../redux/contacts/selector'
+import { getContactsMemo } from '../../../../../../../redux/contacts/selector'
 import { getChat } from '../../../../../../../redux/chat/selector'
 import { asyncGetContacts,asyncAddContact } from '../../../../../../../redux/contacts/operations';
 
@@ -31,19 +31,26 @@ const useStyles = makeStyles({
 const ToolBar = () => {
   const dispatch = useDispatch()
   const classes = useStyles()
-  const contacts = useSelector(getContacts)
+  const contactsMemo = useSelector(getContactsMemo)
   const { number } = useSelector(getChat)
   const [isContact, setIsContact] = useState<boolean>(false)
 
   useEffect(() => {
     dispatch(asyncGetContacts())
-  }, [dispatch])
+    const handleReset = () => dispatch(asyncGetContacts())
+    const idInterval = setInterval(handleReset, 3000);
+    return () => clearInterval(idInterval);
+  }, [dispatch]);
 
   useEffect(() => {
-    const isExist = contacts.some((el) => el.number === number)
-    isExist&&setIsContact(true)
-  }, [contacts,number])
-
+    const contact = contactsMemo.find((el) => el.number === number)
+     if (contact) {
+      setIsContact(true)
+     } else {
+       setIsContact(false)
+    }    
+  }, [contactsMemo,number])
+  
   return (
     <Stack className={classes.container} direction="row" spacing={40}>
       <IconButton onClick={() => dispatch(actionIsOpen(''))} aria-label="delete" size="medium">

+ 2 - 5
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/CredentialsList/index.tsx

@@ -1,5 +1,4 @@
 import { makeStyles } from '@material-ui/core'
-import { useState } from 'react'
 import ToolBar from './ToolBar'
 import ProfilePicture from './ProfilePicture'
 import ProfileMenu from './ProfileMenu'
@@ -20,15 +19,13 @@ const useStyles = makeStyles({
 
 const CredentialsList= () => {
   const classes = useStyles()
-  const [sort, setSort] = useState<boolean>(false)
-  const handleSort = () => setSort(!sort)
     return (
     <div>
         <ToolBar />
         <div className={classes.containerAbsolute}>
           <ProfilePicture />
-          <ProfileMenu sort={sort} handleSort={handleSort}/>
-          <ProfileLists sort={sort}/>
+          <ProfileMenu />
+          <ProfileLists />
      </div>
    </div>
   )

+ 6 - 7
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/Delete/index.tsx

@@ -5,13 +5,14 @@ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
 import { useState } from 'react';
 import { useDispatch } from 'react-redux';
 import { actionIsOpen } from '../../../../../../../redux/control/action'
-
+import { removeContact } from '../../../../../../../api-data';
 
 const useStyles = makeStyles({
   container: {
     width: '100%',
     padding: '20px 10px 20px 10px',
-    backgroundColor:'#ffffff'
+    backgroundColor: '#ffffff',
+    marginBottom: '280px',
   },
   modalDelete: {
     background: '#ffffff',
@@ -37,18 +38,16 @@ const useStyles = makeStyles({
     overflowY: 'hidden',
   },  
 })
-const Delete = ({id}:{id:string}) => {
+const Delete = ({_id}:{_id:string}) => {
   const classes = useStyles()
   const dispatch = useDispatch()
   const [modal,setModal] = useState<boolean>(false)
   const handleDeleteModal = (e: any) => {
     const id = e.target.id
-    if (id === 'overlay' || id === 'cancel') {
-      return setModal(false)
-    }
+    if (id === 'overlay' || id === 'cancel')  return setModal(false)
     if (id === 'delete') {
       dispatch(actionIsOpen('credentials'))
-      //here make delete fetch
+      removeContact(_id)
     }
   }
   const handleOpenModal = () => setModal(true)

+ 18 - 35
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/EditList/index.tsx

@@ -3,12 +3,8 @@ import ListItemAvatar from '@mui/material/ListItemAvatar';
 import Avatar from '@mui/material/Avatar';
 import Checkbox from '@mui/material/Checkbox';
 import ListItemText from '@mui/material/ListItemText';
-import DoneIcon from '@mui/icons-material/Done';
-import { useState,useEffect } from 'react';
 import { format,firstLetter,slicedWord } from '../../../../../../../helpers'
-import { muteChat, updateContact } from '../../../../../../../api-data';
 import { TChat } from '../../../../../../../typescript/redux/chat/types'
-import { TContact } from '../../../../../../../typescript/redux/contacts/types'
 
 const useStyles = makeStyles({
   container: {
@@ -21,7 +17,7 @@ const useStyles = makeStyles({
     padding: 20,
     marginBottom:15,
     position: 'relative',
-    backgroundColor:'#ffffff'
+    backgroundColor: '#ffffff',
   },
   textField: {
     marginBottom:20
@@ -45,13 +41,22 @@ const useStyles = makeStyles({
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
 
-const EditList = ({chat,isContact}:{chat:TChat,isContact:TContact}) => {
-  const classes = useStyles()  
-  const [name, setName] = useState<string>('')
-  const [lastName, setLastName] = useState<string>('')
-  const [mute, setMute] = useState<boolean>(true)
-  const [openBtn, setOpenBtn] = useState<boolean>(false)
-  const { avatarUrl,color,mute:Mute,name:Name,lastName:LastName,companionId,_id } = chat
+interface IEditList {
+  chat: TChat,
+  name: string,
+  setName: any,
+  lastName: string,
+  setLastName: any,
+  mute: boolean,
+  setMute: any,
+  openBtn: boolean,
+  setOpenBtn: any,  
+}
+
+const EditList = (props: IEditList) => {
+  const classes = useStyles()
+  const {chat,name,setName,lastName,setLastName,mute,setMute,openBtn,setOpenBtn} = props
+  const { avatarUrl,color,name:Name,lastName:LastName } = chat
   const handleNotifications = () => {
     setMute(!mute)
     !openBtn&&setOpenBtn(true)
@@ -71,22 +76,6 @@ const EditList = ({chat,isContact}:{chat:TChat,isContact:TContact}) => {
         break;
     }
   }
-  
-  const handleSubmit = () => {
-    if (mute !== !Mute) {
-      muteChat(companionId)
-    }
-    if (name !== Name || lastName !== LastName) {
-      updateContact(isContact._id,_id,name,lastName)
-    }    
-    openBtn&&setOpenBtn(false)
-  }  
-    
-  useEffect(() => {
-    Name&&setName(Name)
-    LastName && setLastName(LastName)
-    setMute(!Mute)
-  }, [Name, LastName, Mute])
  
   return (
     <div className={classes.container} >     
@@ -110,7 +99,6 @@ const EditList = ({chat,isContact}:{chat:TChat,isContact:TContact}) => {
         variant='outlined'
         onChange={handleTextField}
         className={classes.textField}
-        required
         />
       <TextField
         id="lastName"
@@ -121,17 +109,12 @@ const EditList = ({chat,isContact}:{chat:TChat,isContact:TContact}) => {
         variant='outlined'
         onChange={handleTextField}
         className={classes.textField}
-        required
       />
       <div className={classes.notifications}>
         <Checkbox onChange={handleNotifications} {...label} checked={mute} style={{marginRight:20}} />
         <ListItemText primary="Notifications" primaryTypographyProps={{ color: "#0e0d0d" }}
           secondary={!mute ? 'Disabled':'Enabled'} />
-      </div>
-      {openBtn&&<Avatar onClick={handleSubmit} className={classes.avatarArrow}
-        sx={{width: 56, height: 56,backgroundColor: 'rgb(41, 139, 231)',color: '#ffffff'}}>
-        <DoneIcon fontSize="medium" />  
-      </Avatar>}        
+      </div>        
     </div>
   )
 };

+ 27 - 0
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/SubmitBtn/index.tsx

@@ -0,0 +1,27 @@
+import { makeStyles} from '@material-ui/core'
+import Avatar from '@mui/material/Avatar';
+import DoneIcon from '@mui/icons-material/Done';
+
+const useStyles = makeStyles({
+  avatarArrow: {
+    cursor: 'pointer',
+    marginLeft: 'auto',
+    marginRight: 20,
+    '&:hover': {
+      backgroundColor: 'rgb(62, 149, 231)'
+    }
+  }
+})
+
+const SubmitBtn = ({handleSubmit}:{handleSubmit:() => void}) => {
+  const classes = useStyles()  
+
+  return (
+    <Avatar onClick={handleSubmit} className={classes.avatarArrow}
+      sx={{width: 56, height: 56,backgroundColor: 'rgb(41, 139, 231)',color: '#ffffff'}}>
+      <DoneIcon fontSize="medium" />  
+    </Avatar>        
+  )
+};
+
+export default SubmitBtn;

+ 34 - 9
src/components/HomePage/RightBar/HeaderBar/RightListsAndBars/EditBar/index.tsx

@@ -4,9 +4,10 @@ import { useSelector } from 'react-redux';
 import ToolBar from './ToolBar'
 import EditList from './EditList'
 import Delete from './Delete'
-import { getContacts } from '../../../../../../redux/contacts/selector'
+import SubmitBtn from './SubmitBtn';
+import { getContactsMemo } from '../../../../../../redux/contacts/selector'
 import { getChat } from '../../../../../../redux/chat/selector'
-
+import { muteChat,updateContact } from '../../../../../../api-data';
 
 const useStyles = makeStyles({
     containerAbsolute: {
@@ -16,27 +17,51 @@ const useStyles = makeStyles({
         maxHeight: '905px',
         minHeight: '905px',
         overflow: 'hidden',
-        backgroundColor:'#f3f2f2'
+        backgroundColor: '#f3f2f2',
     }
 })
 
 const EditBar= () => {
   const classes = useStyles()
-  const contacts = useSelector(getContacts)
+  const contactsMemo = useSelector(getContactsMemo)
   const chat = useSelector(getChat)
   const [isContact, setIsContact] = useState<any>(false)
+  const [name, setName] = useState<string>('')
+  const [lastName, setLastName] = useState<string>('')
+  const [mute, setMute] = useState<boolean>(true)
+  const [openBtn, setOpenBtn] = useState<boolean>(false)
+  const {name:Name,lastName:LastName,mute:Mute,companionId,_id} = chat
+
+  const handleSubmit = () => {
+    if (mute !== !Mute) {
+      muteChat(companionId)
+    }
+    if (name !== Name || lastName !== LastName) {
+      updateContact(isContact._id,_id,name,lastName)
+    }    
+    openBtn&&setOpenBtn(false)
+  }
+
+  useEffect(() => {
+    const contact = contactsMemo.find((el) => el.number === chat.number)
+    contact && setIsContact(contact)    
+  }, [contactsMemo, chat.number])
   
   useEffect(() => {
-    const contact = contacts.find((el) => el.number === chat.number)
-    contact && setIsContact(contact)
-  }, [contacts, chat.number])  
+    Name&&setName(Name)
+    LastName && setLastName(LastName)
+    setMute(!Mute)
+  }, [Name, LastName, Mute])  
 
     return (
     <div>
       <ToolBar />
       <div className={classes.containerAbsolute}>
-        <EditList chat={chat} isContact={isContact}/>
-        <Delete id={chat._id}/>
+          <EditList chat={chat} name={name} setName={setName} lastName={lastName}
+            setLastName={setLastName} mute={mute} setMute={setMute}
+            openBtn={openBtn} setOpenBtn={setOpenBtn} />
+          <Delete _id={isContact._id} />
+          {openBtn&&<SubmitBtn handleSubmit={handleSubmit}/>}
       </div>
    </div>
   )

+ 1 - 0
src/redux/chat/reducer/index.ts

@@ -14,6 +14,7 @@ const initialState: IChatState = {
      color: '',
      online: '',
      mute: false,
+     sort:false,
      seen: 0,
      total: 0,
      watched: false,

+ 6 - 3
src/redux/contacts/selector/index.ts

@@ -1,9 +1,12 @@
-import {IState} from '../../../typescript/redux/interfaces'
+import { createSelector } from 'reselect';
+import { IState } from '../../../typescript/redux/interfaces'
 
 const getTotal = (state: IState) => state.contacts.total;
 const getLimit = (state:IState) => state.contacts.limit;
 const getPage = (state: IState) => state.contacts.page;
 const getContacts = (state: IState) => state.contacts.contacts;
-const getState= (state:IState) => state.contacts;
+const getState = (state: IState) => state.contacts;
 
-export { getTotal,getLimit,getPage,getContacts,getState };
+const getContactsMemo = createSelector([getContacts], state => state);
+
+export { getTotal,getLimit,getPage,getContacts,getState,getContactsMemo };

+ 1 - 0
src/typescript/redux/chat/types.ts

@@ -5,6 +5,7 @@ export type TChat = {
   color: string,
   online: string,
   mute: boolean,
+  sort:boolean,
   seen: number,
   total: number,
   watched: boolean,

+ 1 - 0
src/typescript/redux/chats/types.ts

@@ -5,6 +5,7 @@ export type TChat = {
   color: string,
   online: string,
   mute: boolean,
+  sort:boolean,
   seen: number,
   total: number,
   watched: boolean,