Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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