Rev 6944 | Rev 6960 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useCallback, useEffect, useState } from 'react'
import { axios } from '../../utils'
import { useSelector } from 'react-redux'
import { Avatar, Tab, Tabs } from '@mui/material'
import styled from 'styled-components'
import SearchIcon from '@mui/icons-material/Search'
import Options from '../UI/Option'
import EmptySection from '../UI/EmptySection'
import ContactsModal from '../modals/ContactsModal'
import CreateGroupModal from '../modals/CreateGroupModal'
const notifyAudio = new Audio('/audio/chat.mp3')
const StyledContact = styled.div`
align-items: center;
display: flex;
height: auto;
padding: 0.5rem 1rem;
gap: 0.5rem;
cursor: pointer;
`
const StyledContactInfo = styled.div`
display: flex;
flex-direction: column;
span {
font-size: 0.9rem;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 20ch;
}
`
const StyledTab = styled(Tab)`
flex-grow: 1;
color: var(--subtitle-color) !important;
font-weight: bold !important;
padding: 0.5rem 1rem !important;
min-height: auto !important;
&.Mui-selected {
color: var(--font-color) !important;
}
`
const Contacts = ({ selectedConversation, changeConversation }) => {
const [showContactModal, setShowContactModal] = useState(false)
const [showGroupModal, setShowGroupModal] = useState(false)
const [conversations, setConversations] = useState([])
const [search, setSearch] = useState('')
const [tab, setTab] = useState('user')
const options = [
{
label: 'Iniciar conversación',
action: () => setShowContactModal(!showContactModal),
},
{ label: 'Crear grupo', action: () => setShowGroupModal(!showGroupModal) },
]
const onCreateConversation = (url) => {
const conversation = conversations.find((user) => user.url_send === url)
changeConversation(conversation)
}
const heartBeat = async () => {
axios.get('/chat/heart-beat').then((response) => {
const { data: entities, success } = response.data
if (!success) {
return
}
entities.map(
(entity) =>
entity.not_received_messages &&
playNewMessage(entity.url_mark_received)
)
setConversations(entities)
})
}
const playNewMessage = async (url) => {
notifyAudio.play()
const { data } = await axios.post(url)
return data.success
}
const getConversations = useCallback(
() => conversations.filter((conversation) => conversation.type === tab),
[tab, conversations]
)
const filterConversations = useCallback(
(conversations) =>
conversations.filter((conversation) =>
conversation.name.toLowerCase().includes(search.toLowerCase())
),
[search]
)
useEffect(() => {
const heartBeatInterval = setInterval(heartBeat, 3000)
heartBeat()
return () => {
clearInterval(heartBeatInterval)
}
}, [])
return (
<>
<aside className="chat_contacts">
<div className="position-relative">
<h1>Chat</h1>
<Options options={options} />
</div>
<Tabs
value={tab}
onChange={(e, newValue) => setTab(newValue)}
sx={{
width: '100%',
minHeight: 'auto',
'& .MuiTabs-indicator': {
backgroundColor: 'var(--font-color)',
},
}}
>
<StyledTab label="Personas" value="user" disableRipple />
<StyledTab label="Grupos" value="group" disableRipple />
</Tabs>
<div className="contact__search show">
<SearchIcon />
<input
type="text"
placeholder="Buscar"
onChange={(e) => setSearch(e.target.value)}
/>
</div>
<Contacts.List
contacts={filterConversations(getConversations())}
onChange={changeConversation}
currentConversation={selectedConversation}
/>
</aside>
<ContactsModal
show={showContactModal}
onClose={() => setShowContactModal(false)}
onComplete={onCreateConversation}
/>
<CreateGroupModal
isOpen={showGroupModal}
onClose={() => setShowGroupModal(false)}
/>
</>
)
}
const List = ({
contacts = [],
onChange = () => null,
currentConversation,
}) => {
const labels = useSelector(({ intl }) => intl.labels)
return (
<div className="contacts-list">
<ul>
{!contacts.length ? (
<EmptySection message={labels.datatable_szerorecords} />
) : (
contacts.map((contact) => (
<li key={contact.id}>
<List.Item contact={contact} onClick={onChange} />
</li>
))
)}
</ul>
</div>
)
}
const Item = ({ contact, onClick }) => {
const labels = useSelector(({ intl }) => intl.labels)
return (
<StyledContact onClick={() => onClick(contact)}>
<Avatar
src={contact.image || '/images/users-group.png'}
alt="image-image"
sx={{ width: 32, height: 32 }}
/>
<StyledContactInfo>
<span>{contact.name}</span>
{contact.last_message && (
<p>
{`${contact.count_not_seen_messages} ${labels.new_messages} |
${contact.last_message}`}
</p>
)}
</StyledContactInfo>
</StyledContact>
)
}
List.Item = Item
Contacts.List = List
export default Contacts