Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6944 | Rev 6956 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
6911 stevensc 1
import React, { useCallback, useEffect, useState } from 'react'
2
import { axios } from '../../utils'
3
import { useSelector } from 'react-redux'
6938 stevensc 4
import { Avatar, Tab, Tabs } from '@mui/material'
5
import styled from 'styled-components'
6911 stevensc 6
import SearchIcon from '@mui/icons-material/Search'
7
 
8
import Options from '../UI/Option'
9
import EmptySection from '../UI/EmptySection'
10
import ContactsModal from '../modals/ContactsModal'
11
import CreateGroupModal from '../modals/CreateGroupModal'
12
 
13
const notifyAudio = new Audio('/audio/chat.mp3')
14
 
6938 stevensc 15
const StyledContact = styled.div`
16
  align-items: center;
17
  display: flex;
18
  height: auto;
6940 stevensc 19
  padding: 0.5rem 1rem;
6938 stevensc 20
  gap: 0.5rem;
6946 stevensc 21
  cursor: pointer;
6938 stevensc 22
`
23
const StyledContactInfo = styled.div`
24
  display: flex;
25
  flex-direction: column;
26
 
27
  span {
28
    font-size: 0.9rem;
29
    font-weight: bold;
30
    white-space: nowrap;
31
    overflow: hidden;
32
    text-overflow: ellipsis;
33
    max-width: 20ch;
34
  }
35
`
6944 stevensc 36
const StyledTab = styled(Tab)`
37
  flex-grow: 1;
6946 stevensc 38
  color: var(--subtitle-color) !important;
39
  font-weight: bold !important;
40
  padding: 0.5rem 1rem !important;
41
  min-height: auto !important;
6944 stevensc 42
  &.Mui-selected {
6946 stevensc 43
    color: var(--font-color) !important;
6944 stevensc 44
  }
45
`
6938 stevensc 46
 
6911 stevensc 47
const Contacts = ({ selectedConversation, changeConversation }) => {
48
  const [showContactModal, setShowContactModal] = useState(false)
49
  const [showGroupModal, setShowGroupModal] = useState(false)
6913 stevensc 50
  const [conversations, setConversations] = useState([])
6911 stevensc 51
  const [search, setSearch] = useState('')
52
  const [tab, setTab] = useState('user')
53
 
54
  const options = [
55
    {
56
      label: 'Iniciar conversación',
57
      action: () => setShowContactModal(!showContactModal),
58
    },
6916 stevensc 59
    { label: 'Crear grupo', action: () => setShowGroupModal(!showGroupModal) },
6911 stevensc 60
  ]
61
 
62
  const onCreateConversation = (url) => {
63
    const conversation = conversations.find((user) => user.url_send === url)
64
    changeConversation(conversation)
65
  }
66
 
67
  const heartBeat = async () => {
68
    axios.get('/chat/heart-beat').then((response) => {
69
      const { data: entities, success } = response.data
70
 
71
      if (!success) {
72
        return
73
      }
74
 
75
      entities.map(
76
        (entity) =>
77
          entity.not_received_messages &&
78
          playNewMessage(entity.url_mark_received)
79
      )
80
 
81
      setConversations(entities)
82
    })
83
  }
84
 
85
  const playNewMessage = async (url) => {
86
    notifyAudio.play()
87
    const { data } = await axios.post(url)
88
    return data.success
89
  }
90
 
91
  const getConversations = useCallback(
6917 stevensc 92
    () => conversations.filter((conversation) => conversation.type === tab),
6914 stevensc 93
    [tab, conversations]
6911 stevensc 94
  )
95
 
96
  const filterConversations = useCallback(
97
    (conversations) =>
98
      conversations.filter((conversation) =>
99
        conversation.name.toLowerCase().includes(search.toLowerCase())
100
      ),
101
 
102
    [search]
103
  )
104
 
105
  useEffect(() => {
106
    const heartBeatInterval = setInterval(heartBeat, 3000)
107
    heartBeat()
108
 
109
    return () => {
110
      clearInterval(heartBeatInterval)
111
    }
112
  }, [])
113
 
114
  return (
115
    <>
116
      <aside className="chat_contacts">
117
        <div className="position-relative">
118
          <h1>Chat</h1>
119
          <Options options={options} />
120
        </div>
121
 
6940 stevensc 122
        <Tabs
123
          value={tab}
124
          onChange={(e, newValue) => setTab(newValue)}
6943 stevensc 125
          sx={{
126
            width: '100%',
6944 stevensc 127
            minHeight: 'auto',
6943 stevensc 128
            '& .MuiTabs-indicator': {
129
              backgroundColor: 'var(--font-color)',
130
            },
131
          }}
6940 stevensc 132
        >
6944 stevensc 133
          <StyledTab label="Personas" value="user" disableRipple />
134
          <StyledTab label="Grupos" value="group" disableRipple />
6917 stevensc 135
        </Tabs>
6916 stevensc 136
 
6911 stevensc 137
        <div className="contact__search show">
138
          <SearchIcon />
139
          <input
140
            type="text"
141
            placeholder="Buscar"
142
            onChange={(e) => setSearch(e.target.value)}
143
          />
144
        </div>
145
 
146
        <Contacts.List
6915 stevensc 147
          contacts={filterConversations(getConversations())}
6938 stevensc 148
          onChange={changeConversation}
149
          currentConversation={selectedConversation}
6911 stevensc 150
        />
151
      </aside>
152
      <ContactsModal
153
        show={showContactModal}
154
        onClose={() => setShowContactModal(false)}
155
        onComplete={onCreateConversation}
156
      />
157
      <CreateGroupModal
158
        isOpen={showGroupModal}
159
        onClose={() => setShowGroupModal(false)}
160
      />
161
    </>
162
  )
163
}
164
 
6938 stevensc 165
const List = ({
166
  contacts = [],
167
  onChange = () => null,
168
  currentConversation,
169
}) => {
6911 stevensc 170
  const labels = useSelector(({ intl }) => intl.labels)
171
 
172
  return (
173
    <div className="contacts-list">
174
      <ul>
175
        {!contacts.length ? (
176
          <EmptySection message={labels.datatable_szerorecords} />
177
        ) : (
178
          contacts.map((contact) => (
179
            <li key={contact.id}>
6939 stevensc 180
              <List.Item contact={contact} onClick={onChange} />
6911 stevensc 181
            </li>
182
          ))
183
        )}
184
      </ul>
185
    </div>
186
  )
187
}
188
 
189
const Item = ({ contact, onClick }) => {
190
  const labels = useSelector(({ intl }) => intl.labels)
191
 
192
  return (
6944 stevensc 193
    <StyledContact onClick={() => onClick(contact)}>
6938 stevensc 194
      <Avatar
6911 stevensc 195
        src={contact.image || '/images/users-group.png'}
196
        alt="image-image"
6938 stevensc 197
        sx={{ width: 32, height: 32 }}
6911 stevensc 198
      />
6938 stevensc 199
      <StyledContactInfo>
6944 stevensc 200
        <span>{contact.name}</span>
6911 stevensc 201
        {contact.last_message && (
202
          <p>
203
            {`${contact.count_not_seen_messages} ${labels.new_messages} |
204
            ${contact.last_message}`}
205
          </p>
206
        )}
6938 stevensc 207
      </StyledContactInfo>
208
    </StyledContact>
6911 stevensc 209
  )
210
}
211
 
212
List.Item = Item
213
Contacts.List = List
214
 
215
export default Contacts