Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6942 | Rev 6944 | 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)}
6943 stevensc 115
          sx={{
116
            width: '100%',
117
            '& .MuiTabs-indicator': {
118
              backgroundColor: 'var(--font-color)',
119
            },
120
          }}
6940 stevensc 121
        >
6942 stevensc 122
          <Tab
123
            label="Personas"
124
            value="user"
125
            disableRipple
126
            sx={{
127
              flexGrow: 1,
128
              color: 'var(--subtitle-color)',
6943 stevensc 129
              fontWeight: 'bold',
130
              padding: '.5rem 1rem',
6942 stevensc 131
              '&.Mui-selected': {
132
                color: 'var(--font-color)',
133
              },
134
            }}
135
          />
136
          <Tab
137
            label="Grupos"
138
            value="group"
139
            disableRipple
140
            sx={{
141
              flexGrow: 1,
142
              color: 'var(--subtitle-color)',
6943 stevensc 143
              padding: '.5rem 1rem',
6942 stevensc 144
              '&.Mui-selected': {
145
                color: 'var(--font-color)',
146
              },
147
            }}
148
          />
6917 stevensc 149
        </Tabs>
6916 stevensc 150
 
6911 stevensc 151
        <div className="contact__search show">
152
          <SearchIcon />
153
          <input
154
            type="text"
155
            placeholder="Buscar"
156
            onChange={(e) => setSearch(e.target.value)}
157
          />
158
        </div>
159
 
160
        <Contacts.List
6915 stevensc 161
          contacts={filterConversations(getConversations())}
6938 stevensc 162
          onChange={changeConversation}
163
          currentConversation={selectedConversation}
6911 stevensc 164
        />
165
      </aside>
166
      <ContactsModal
167
        show={showContactModal}
168
        onClose={() => setShowContactModal(false)}
169
        onComplete={onCreateConversation}
170
      />
171
      <CreateGroupModal
172
        isOpen={showGroupModal}
173
        onClose={() => setShowGroupModal(false)}
174
      />
175
    </>
176
  )
177
}
178
 
6938 stevensc 179
const List = ({
180
  contacts = [],
181
  onChange = () => null,
182
  currentConversation,
183
}) => {
6911 stevensc 184
  const labels = useSelector(({ intl }) => intl.labels)
185
 
186
  return (
187
    <div className="contacts-list">
188
      <ul>
189
        {!contacts.length ? (
190
          <EmptySection message={labels.datatable_szerorecords} />
191
        ) : (
192
          contacts.map((contact) => (
193
            <li key={contact.id}>
6939 stevensc 194
              <List.Item contact={contact} onClick={onChange} />
6911 stevensc 195
            </li>
196
          ))
197
        )}
198
      </ul>
199
    </div>
200
  )
201
}
202
 
203
const Item = ({ contact, onClick }) => {
204
  const labels = useSelector(({ intl }) => intl.labels)
205
 
206
  return (
6938 stevensc 207
    <StyledContact>
208
      <Avatar
6911 stevensc 209
        src={contact.image || '/images/users-group.png'}
210
        alt="image-image"
6938 stevensc 211
        sx={{ width: 32, height: 32 }}
6911 stevensc 212
      />
6938 stevensc 213
      <StyledContactInfo>
6911 stevensc 214
        <span onClick={() => onClick(contact)}>{contact.name}</span>
215
        {contact.last_message && (
216
          <p>
217
            {`${contact.count_not_seen_messages} ${labels.new_messages} |
218
            ${contact.last_message}`}
219
          </p>
220
        )}
6938 stevensc 221
      </StyledContactInfo>
222
    </StyledContact>
6911 stevensc 223
  )
224
}
225
 
226
List.Item = Item
227
Contacts.List = List
228
 
229
export default Contacts