Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
5195 stevensc 1
/* eslint-disable camelcase */
3094 stevensc 2
/* eslint-disable react/prop-types */
5329 stevensc 3
import React, { useEffect, useRef, useState } from 'react'
5195 stevensc 4
import { axios } from '../../../utils'
5
import { Modal } from 'react-bootstrap'
6
import { useForm } from 'react-hook-form'
7
import { addNotification } from '../../../redux/notification/notification.actions'
5331 stevensc 8
import { useDispatch } from 'react-redux'
5329 stevensc 9
import styled from 'styled-components'
10
import Datetime from 'react-datetime'
4386 stevensc 11
import SearchIcon from '@mui/icons-material/Search'
5329 stevensc 12
import Emojione from './emojione/Emojione'
13
import SendFileModal from './send-file-modal/SendFileModal'
14
import ConfirmModal from '../../../shared/confirm-modal/ConfirmModal'
5206 stevensc 15
import EmptySection from '../../../shared/empty-section/EmptySection'
5329 stevensc 16
import FormErrorFeedback from '../../../shared/form-error-feedback/FormErrorFeedback'
1 www 17
 
5329 stevensc 18
import 'react-datetime/css/react-datetime.css'
5334 stevensc 19
import ChatList from '../../../components/chat/ChatList'
5329 stevensc 20
 
1 www 21
const StyledShowOptions = styled.div`
22
  height: 342px;
23
  flex-direction: column;
5195 stevensc 24
  gap: 0.5rem;
1 www 25
  overflow-y: auto;
26
  position: relative;
27
  &.show {
28
    display: flex;
29
  }
30
  &.hide {
31
    display: none;
32
  }
33
  .optionBack {
34
    margin: 1rem 0 0.5rem 1rem;
35
    cursor: pointer;
36
  }
37
  .optionsTab {
38
    &__option {
39
      padding: 0.5rem;
40
      border-bottom: 1px solid #e2e2e2;
41
      cursor: pointer;
42
      &:hover {
43
        background-color: #e2e2e2;
44
      }
45
      &__icon {
46
        margin-right: 0.3rem;
47
      }
48
    }
49
  }
50
  .addPersonToGroupTab {
51
    display: flex;
52
    flex-direction: column;
53
    &__person {
54
      display: flex;
55
      justify-content: space-between;
56
      align-items: center;
57
      padding: 0.2rem 0.5rem;
58
      border-bottom: 1px solid #e2e2e2;
59
    }
60
  }
5195 stevensc 61
`
1 www 62
 
5329 stevensc 63
const OPTIONS = {
64
  GROUP: 'group',
65
  CONFERENCE: 'conference',
66
  ADD_CONTACTS: 'addContacts',
67
  LIST_CONTACTS: 'listContacts',
68
  INITIAL: null
69
}
70
 
4119 stevensc 71
const PersonalChat = ({ entity, onClose, onMinimize, onRead, not_seen_messages, minimized, timezones }) => {
1 www 72
  const {
73
    id,
74
    image,
75
    name,
76
    online,
77
    type,
78
    url_get_all_messages,
79
    url_send,
80
    url_upload,
81
    profile,
82
    url_leave,
83
    url_delete,
84
    url_add_user_to_group,
85
    url_get_contact_group_list,
86
    url_get_contacts_availables_for_group,
4134 stevensc 87
    url_zoom
5195 stevensc 88
  } = entity
1 www 89
 
5329 stevensc 90
  const [optionTab, setOptionTab] = useState(OPTIONS.INITIAL)
5311 stevensc 91
 
5195 stevensc 92
  const [availableContactsToAdd, setAvailableContactsToAdd] = useState([])
93
  const [groupContactsList, setGroupContactsList] = useState([])
5311 stevensc 94
 
5195 stevensc 95
  const [confirmModalShow, setConfirmModalShow] = useState(false)
96
  const [showEmojiTab, setShowEmojiTab] = useState(false)
97
  const [shareFileModalShow, setShareFileModalShow] = useState(false)
98
  const [showConferenceModal, setShowConferenceModal] = useState(false)
5311 stevensc 99
 
5195 stevensc 100
  const [search, setSearch] = useState('')
1 www 101
 
5331 stevensc 102
  const [messages, setMessages] = useState([])
103
  const [oldMessages, setOldMessages] = useState([])
104
  const [currentPage, setCurrentPage] = useState(1)
105
  const [lastPage, setLastPage] = useState(1)
106
 
107
  const [loading, setLoading] = useState(false)
108
 
4390 stevensc 109
  const filtredGroupList = groupContactsList.filter((conversation) => conversation.name.toLowerCase().includes(search.toLowerCase()))
4386 stevensc 110
 
1 www 111
  // refs
5195 stevensc 112
  const conversationListEl = useRef(null)
113
  const loader = useRef(null)
114
  const modalActionUrl = useRef('')
115
  const textAreaEl = useRef(null)
1 www 116
 
117
  const handleActive = () => {
5195 stevensc 118
    onRead(entity)
119
    onMinimize(entity)
120
  }
1 www 121
 
122
  const handleGetMessages = async () => {
5331 stevensc 123
    setLoading(true)
124
    const response = await axios.get(url_get_all_messages)
125
    const resData = response.data
126
    if (!resData.success) {
127
      return ('ha ocurrido un error', resData)
128
    }
129
    const updatedMessages = [...resData.data.items].reverse()
130
    const newMessages = updatedMessages.reduce((acum, updatedMessage) => {
131
      if (messages.findIndex((message) => message.id === updatedMessage.id) === -1) {
132
        acum = [...acum, updatedMessage]
133
      }
134
      return acum
135
    }, [])
136
 
137
    if (newMessages.length > 0) {
138
      setMessages([...messages, ...newMessages])
139
      setLoading(false)
140
      setLastPage(resData.data.pages)
141
      scrollToBottom()
142
    } else {
143
      setMessages([...updatedMessages])
144
      setLoading(false)
145
    }
5195 stevensc 146
  }
1 www 147
 
148
  const handleLoadMore = async () => {
936 stevensc 149
    await axios.get(`${url_get_all_messages}?page=${currentPage}`)
1 www 150
      .then((response) => {
5195 stevensc 151
        const resData = response.data
1 www 152
        if (resData.success) {
153
          if (resData.data.page > 1) {
5195 stevensc 154
            const updatedOldMessages = [...resData.data.items].reverse()
5331 stevensc 155
            setOldMessages([...updatedOldMessages, ...oldMessages])
986 stevensc 156
            /* scrollDownBy(100); */
1 www 157
          }
158
        }
5195 stevensc 159
      })
160
  }
1 www 161
 
3122 stevensc 162
  const handleCloseChat = () => onClose(entity)
1 www 163
 
164
  const handleChatBoxKeyDown = async (e) => {
5195 stevensc 165
    if (e.key === 'Enter') {
166
      e.preventDefault()
167
      const message = e.target.value
168
      const formData = new FormData()
169
      formData.append('message', emojione.toShort(message))
2181 stevensc 170
      await axios.post(url_send, formData).then((response) => {
5195 stevensc 171
        const resData = response.data
2181 stevensc 172
        if (resData.success) {
2188 stevensc 173
          let newMessage = resData.data
2186 stevensc 174
 
175
          online
2188 stevensc 176
            ? newMessage = { ...newMessage, not_received: false }
177
            : newMessage = { ...newMessage, not_received: true }
2186 stevensc 178
 
5311 stevensc 179
          // setMessages([...messages, newMessage])
2181 stevensc 180
        }
5195 stevensc 181
      })
182
      e.target.value = ''
2189 stevensc 183
      /* await handleGetMessages(); */
5195 stevensc 184
      setShowEmojiTab(false)
5311 stevensc 185
      // setResponseMessage(null)
1 www 186
    }
5195 stevensc 187
  }
1 www 188
 
5329 stevensc 189
  const showOptions = (tab = OPTIONS.INITIAL) => {
5195 stevensc 190
    onMinimize(entity, false)
191
    setOptionTab(tab)
192
  }
1 www 193
 
194
  const handleAddPersonToGroup = async (id) => {
5195 stevensc 195
    const formData = new FormData()
196
    formData.append('uid', id)
1 www 197
    await axios.post(url_add_user_to_group, formData).then((response) => {
5195 stevensc 198
      const resData = response.data
1 www 199
      if (resData.success) {
5195 stevensc 200
        loadPersonsAvailable()
1 www 201
      }
5195 stevensc 202
    })
203
  }
1 www 204
 
205
  const handleConfirmModalAction = async () => {
3122 stevensc 206
    try {
3788 stevensc 207
      const { data } = await axios.post(modalActionUrl.current)
3122 stevensc 208
      if (!data.success) console.log('Error in confirm modal action')
3788 stevensc 209
      handleConfirmModalShow()
5195 stevensc 210
      onClose(entity)
3788 stevensc 211
      return
3122 stevensc 212
    } catch (error) {
213
      console.log(error)
214
    }
5195 stevensc 215
  }
1 www 216
 
217
  const handleObserver = (entities) => {
5195 stevensc 218
    const target = entities[0]
1 www 219
    if (target.isIntersecting) {
5331 stevensc 220
      setCurrentPage((prevState) => prevState + 1)
1 www 221
    }
5195 stevensc 222
  }
1 www 223
 
224
  const scrollToBottom = () => {
3056 stevensc 225
    if (conversationListEl.current) {
1 www 226
      conversationListEl.current.scrollTop =
5195 stevensc 227
        conversationListEl.current.scrollHeight * 9
1 www 228
    }
5195 stevensc 229
  }
1 www 230
 
231
  const handleShowEmojiTab = () => {
5195 stevensc 232
    setShowEmojiTab(!showEmojiTab)
1 www 233
    // smiley_tpl(`${id}`);
5195 stevensc 234
  }
1 www 235
 
236
  const handleClickEmoji = (e) => {
5195 stevensc 237
    const shortname = e.currentTarget.dataset.shortname
238
    const currentText = textAreaEl.current.value
239
    const cursorPosition = textAreaEl.current.selectionStart
240
    const textBehind = currentText.substring(0, cursorPosition)
241
    const textForward = currentText.substring(cursorPosition)
242
    const unicode = emojione.shortnameToUnicode(shortname)
243
    textAreaEl.current.value = `${textBehind}${unicode}${textForward}`
244
    textAreaEl.current.focus()
1 www 245
    textAreaEl.current.setSelectionRange(
246
      cursorPosition + unicode.length,
247
      cursorPosition + unicode.length
5195 stevensc 248
    )
249
  }
1 www 250
 
3788 stevensc 251
  const handleConfirmModalShow = () => setConfirmModalShow(!confirmModalShow)
1 www 252
 
3788 stevensc 253
  const handleConfirmModalAccept = () => handleConfirmModalAction()
1 www 254
 
255
  const handleShareFileModalShow = () => {
5195 stevensc 256
    setShareFileModalShow(!shareFileModalShow)
257
  }
1 www 258
 
5311 stevensc 259
  /* const handleResponseMessage = (element) => {
3059 stevensc 260
    element.mtype === 'text'
261
      ? setResponseMessage(element)
262
      : setResponseMessage({ ...element, m: 'Archivo adjunto' })
263
 
2765 stevensc 264
    textAreaEl.current && textAreaEl.current.focus()
5311 stevensc 265
  } */
1300 stevensc 266
 
4116 stevensc 267
  const displayConferenceModal = () => setShowConferenceModal(!showConferenceModal)
4115 stevensc 268
 
1 www 269
  const loadPersonsAvailable = async () => {
270
    await axios.get(url_get_contacts_availables_for_group).then((response) => {
5195 stevensc 271
      const resData = response.data
1 www 272
      if (resData.success) {
5195 stevensc 273
        setAvailableContactsToAdd(resData.data)
1 www 274
      }
5195 stevensc 275
    })
276
  }
1 www 277
 
278
  const loadGroupContacts = async () => {
279
    await axios.get(url_get_contact_group_list).then((response) => {
5195 stevensc 280
      const resData = response.data
1 www 281
      if (resData.success) {
5195 stevensc 282
        setGroupContactsList(resData.data)
1 www 283
      }
5195 stevensc 284
    })
285
  }
1 www 286
 
287
  const handleDeletePersonFromGroup = async (urlDeletePersonFromGroup) => {
288
    await axios.post(urlDeletePersonFromGroup).then((response) => {
5195 stevensc 289
      const resData = response.data
1 www 290
      if (resData.success) {
5195 stevensc 291
        loadGroupContacts()
1 www 292
      }
5195 stevensc 293
    })
294
  }
1 www 295
 
5320 stevensc 296
  const tabsOptions = {
5328 stevensc 297
    group:
5320 stevensc 298
      <ul>
299
        {url_get_contact_group_list &&
5329 stevensc 300
          <li className="optionsTab__option" onClick={() => showOptions(OPTIONS.LIST_CONTACTS)}>
5320 stevensc 301
            <span className="optionsTab__option__icon">
302
              <i className="fa fa-group" />
1 www 303
              Integrantes
5320 stevensc 304
            </span>
305
          </li>
306
        }
307
        {url_add_user_to_group &&
5329 stevensc 308
          <li className="optionsTab__option" onClick={() => showOptions(OPTIONS.ADD_CONTACTS)}>
4115 stevensc 309
            <span className="optionsTab__option__icon">
5320 stevensc 310
              <i className="fa fa-user-plus"></i>
311
            </span>
312
            {CHAT_LABELS.ADD_CONTACTS}
313
          </li>
314
        }
315
        {url_zoom &&
316
          <li
317
            className="optionsTab__option"
318
            onClick={displayConferenceModal}
319
          >
320
            <span className="optionsTab__option__icon">
4115 stevensc 321
              <i className="fa fa-user-plus" />
322
            </span>
5206 stevensc 323
            {CHAT_LABELS.CREATE_CONFERENCE}
4115 stevensc 324
          </li>
5320 stevensc 325
        }
326
        {url_delete &&
327
          <li
328
            className="optionsTab__option"
329
            style={{ color: 'red' }}
330
            onClick={() => {
331
              handleConfirmModalShow()
332
              modalActionUrl.current = url_delete
333
            }}
334
          >
335
            <span className="optionsTab__option__icon">
336
              <i className="fa fa-trash"></i>
337
            </span>
338
            Eliminar grupo
339
          </li>
340
        }
341
        {!!url_leave &&
342
          <li
343
            className="optionsTab__option"
344
            style={{ color: 'red' }}
345
            onClick={() => {
346
              handleConfirmModalShow()
347
              modalActionUrl.current = url_leave
348
            }}
349
          >
350
            <span className="optionsTab__option__icon">
351
              <i className="fa fa-user-times"></i>
352
            </span>
353
            Dejar grupo
354
          </li>
355
        }
5328 stevensc 356
      </ul>,
357
    conference:
5320 stevensc 358
      <ul>
359
        <li className="optionsTab__option" onClick={displayConferenceModal}>
360
          <span className="optionsTab__option__icon">
361
            <i className="fa fa-user-plus" />
362
          </span>
363
          {CHAT_LABELS.CREATE_CONFERENCE}
364
        </li>
5328 stevensc 365
      </ul>,
366
    addContacts:
5320 stevensc 367
      <>
368
        {availableContactsToAdd.length
369
          ? <EmptySection message={CHAT_LABELS.NOT_CONTACTS} align='left' />
370
          : availableContactsToAdd.map(({ image, name, id }) =>
1 www 371
            <div className="addPersonToGroupTab__person" key={id}>
2664 stevensc 372
              <div className="d-inline-flex" style={{ gap: '5px' }}>
2663 stevensc 373
                <img
374
                  className="chat-image img-circle pull-left"
375
                  height="36"
376
                  width="36"
377
                  src={image}
378
                  alt="image-image"
379
                />
380
                <div className="name">{name}</div>
381
              </div>
5206 stevensc 382
              <span className='cursor-pointer' onClick={() => handleAddPersonToGroup(id)}>
383
                <i className="fa fa-plus-circle" />
1 www 384
              </span>
385
            </div>
5320 stevensc 386
          )}
5328 stevensc 387
      </>,
388
    listContacts:
5320 stevensc 389
      <>
390
        <div className='group__search'>
391
          <SearchIcon />
392
          <input
393
            type='text'
394
            placeholder={CHAT_LABELS.SEARCH}
395
            onChange={(e) => setSearch(e.target.value)}
396
          />
397
        </div>
4389 stevensc 398
        {filtredGroupList.length
399
          ? filtredGroupList.map(({ image, name, url_remove_from_group, id }) => {
400
            return (
1 www 401
              <div className="addPersonToGroupTab__person" key={id}>
5195 stevensc 402
                <div style={{ display: 'flex', alignItems: 'center' }}>
1 www 403
                  <img
404
                    className="chat-image img-circle pull-left"
405
                    height="36"
406
                    width="36"
407
                    src={image}
408
                    alt="image-image"
409
                  />
410
                  <div className="name">{name}</div>
411
                </div>
4389 stevensc 412
                {url_remove_from_group &&
413
                  <span className="cursor-pointer" onClick={() => handleDeletePersonFromGroup(url_remove_from_group)}>
414
                    <i className="fa fa-user-times" />
1 www 415
                  </span>
4389 stevensc 416
                }
1 www 417
              </div>
418
            )
4389 stevensc 419
          })
5206 stevensc 420
          : <div className="addPersonToGroupTab__person">{CHAT_LABELS.NOT_CONTACTS}</div>
4389 stevensc 421
        }
5320 stevensc 422
      </>
423
  }
1 www 424
 
5329 stevensc 425
  // getMessageOnMaximize and subscribe to infinite Loader
426
  useEffect(async () => {
427
    const options = {
428
      root: null,
429
      rootMargin: '20px',
430
      treshold: 1.0
431
    }
432
    const observer = new IntersectionObserver(handleObserver, options)
433
    if (!minimized) {
434
      await handleGetMessages()
435
      // loader observer
436
      if (loader.current) {
437
        observer.observe(loader.current)
438
      }
439
    }
440
    return () => {
441
      if (loader.current) {
442
        observer.unobserve(loader.current)
443
      }
444
    }
445
  }, [minimized])
446
 
447
  // LoadMore on change page
448
  useEffect(() => {
449
    let loadMore = () => handleLoadMore()
450
    loadMore()
451
    return () => {
452
      loadMore = null
453
    }
454
  }, [currentPage])
455
 
456
  // getMessagesInterval
457
  useEffect(() => {
458
    if (window.location.pathname === '/group/my-groups') {
459
      const items = document.getElementsByClassName('sc-jSgupP')
460
      if (items && items.length > 0) { items[0].style.display = 'none' }
461
    }
462
  }, [minimized])
463
 
464
  useEffect(() => {
465
    let timer
466
    if (!minimized && !loading) {
467
      timer = setTimeout(() => handleGetMessages(), 1000)
468
    }
469
    return () => {
470
      clearTimeout(timer)
471
    }
472
  }, [minimized, loading])
473
 
474
  // useEffect for tabs changing
475
  useEffect(() => {
476
    if (optionTab === 'addContacts') loadPersonsAvailable()
477
    if (optionTab === 'listContacts') loadGroupContacts()
478
  }, [optionTab])
479
 
5328 stevensc 480
  return (
4116 stevensc 481
    <>
5320 stevensc 482
      <div className="personal-chat">
5206 stevensc 483
 
5320 stevensc 484
        <div className={`chat-header ${not_seen_messages ? 'notify' : ''}`}>
5326 stevensc 485
          <img src={image} alt="avatar-image" />
486
          <div className="info-content">
487
            <a href={profile} target="_blank" rel="noreferrer">{name}</a>
5328 stevensc 488
            {type === 'user' && <small className={online ? 'online' : 'offline'} >{online ? 'En línea' : 'Desconectado'}</small>}
5326 stevensc 489
          </div>
5334 stevensc 490
          <div className="options ml-auto">
5328 stevensc 491
            <i className="cursor-pointer fa fa-gear"
5329 stevensc 492
              onClick={() => showOptions(type === 'user' ? OPTIONS.CONFERENCE : OPTIONS.GROUP)} />
5328 stevensc 493
            <i className={'cursor-pointer fa fa-minus-circle'} onClick={handleActive} />
494
            <i className="cursor-pointer fa fa-times-circle" onClick={handleCloseChat} />
5320 stevensc 495
          </div>
496
        </div>
497
 
498
        <div className="panel-body" style={{ display: !minimized ? 'block' : 'none' }}>
5323 stevensc 499
 
5334 stevensc 500
          {optionTab
501
            ? <StyledShowOptions>
502
              <span className="optionBack" onClick={() => showOptions()}>
503
                <i className="fa icon-arrow-left" />
504
              </span>
505
              <div className="optionsTab">
506
                {tabsOptions[optionTab]}
507
              </div>
508
            </StyledShowOptions>
509
            : <>
510
            <ChatList
511
              messages={[...oldMessages, ...messages]}
512
              currentPage={currentPage}
513
              lastPage={lastPage}
514
              conversationList={conversationListEl}
515
              loader={loader}
516
            />
5320 stevensc 517
            <div className="wchat-footer wchat-chat-footer">
518
              <div id="chatFrom" className="chatFrom">
5312 stevensc 519
 
5320 stevensc 520
                <div className="block-wchat">
521
                  <button
522
                    className="icon ti-clip attachment font-24 btn-attach btn-attach uploadFile"
523
                    id="uploadFile"
524
                    onClick={handleShareFileModalShow}
525
                  ></button>
526
                  <button
527
                    className="icon ti-face-smile font-24 btn-emoji"
528
                    id="toggle-emoji"
529
                    onClick={handleShowEmojiTab}
530
                  ></button>
531
                  <div className="input-container">
532
                    <div className="input-emoji">
533
                      <div
534
                        className="input-placeholder"
535
                        style={{ visibility: 'hidden', display: 'none' }}
536
                      >
537
                        {CHAT_LABELS.WRITE_A_MESSAGE}
1 www 538
                      </div>
5320 stevensc 539
                      <textarea
540
                        className="input chatboxtextarea"
541
                        id="chatboxtextarea"
542
                        name="chattxt"
543
                        style={{ resize: 'none', height: '20px' }}
544
                        placeholder={CHAT_LABELS.WRITE_A_MESSAGE}
545
                        onKeyDown={handleChatBoxKeyDown}
546
                        ref={textAreaEl}
547
                        onFocus={() => not_seen_messages && onRead(entity)}
548
                      />
1 www 549
                    </div>
550
                  </div>
551
                </div>
5058 stevensc 552
 
553
                <div className="wchat-box-items-overlay-container">
5195 stevensc 554
                  <div className="target-emoji" style={{ display: showEmojiTab ? 'block' : 'none' }} id={`smileyPanel_${id}`}>
5058 stevensc 555
                    <Emojione onClickEmoji={handleClickEmoji} />
1 www 556
                  </div>
557
                </div>
5058 stevensc 558
 
1 www 559
              </div>
560
            </div>
5334 stevensc 561
            </>
562
          }
1 www 563
        </div>
5329 stevensc 564
 
1 www 565
      </div>
566
      <ConfirmModal
567
        show={confirmModalShow}
568
        onClose={handleConfirmModalShow}
569
        onAccept={handleConfirmModalAccept}
570
      />
4152 stevensc 571
      <ConferenceModal
572
        show={showConferenceModal}
573
        timezones={timezones}
574
        zoomUrl={url_zoom}
575
        onCreate={() => {
5329 stevensc 576
          showOptions()
4152 stevensc 577
          displayConferenceModal()
578
        }}
579
      />
5052 stevensc 580
      <SendFileModal
581
        show={shareFileModalShow}
582
        onHide={() => setShareFileModalShow(false)}
583
        urlUpload={url_upload}
584
      />
5206 stevensc 585
    </>
5195 stevensc 586
  )
587
}
1 www 588
 
4115 stevensc 589
const StyleModal = ({
590
  title = 'Crea una conferencia',
591
  size = 'md',
592
  show = false,
593
  children
594
}) => {
595
  const [isShow, setIsShow] = useState(show)
596
 
4118 stevensc 597
  useEffect(() => {
598
    setIsShow(show)
599
  }, [show])
600
 
4115 stevensc 601
  const closeModal = () => setIsShow(false)
602
 
603
  return (
604
    <Modal
605
      show={isShow}
606
      onHide={closeModal}
5195 stevensc 607
      style={{ overflowY: 'scroll' }}
4115 stevensc 608
    >
609
      <Modal.Header closeButton>
610
        <Modal.Title>{title}</Modal.Title>
611
      </Modal.Header>
612
      <Modal.Body>
613
        {children}
614
      </Modal.Body>
615
    </Modal>
616
  )
617
}
618
 
5021 stevensc 619
export const ConferenceModal = ({
4128 stevensc 620
  show = false,
4134 stevensc 621
  timezones = {},
4147 stevensc 622
  zoomUrl = '',
623
  onCreate = () => null
4115 stevensc 624
}) => {
4130 stevensc 625
  const dt = new Date()
4136 stevensc 626
  const { handleSubmit, register, errors, reset } = useForm({ mode: 'all' })
4128 stevensc 627
  const [date, setDate] = useState({
5195 stevensc 628
    year: dt.toLocaleString('default', { year: 'numeric' }),
629
    month: dt.toLocaleString('default', { month: '2-digit' }),
630
    day: dt.toLocaleString('default', { day: '2-digit' })
4128 stevensc 631
  })
5195 stevensc 632
  const [time, setTime] = useState(dt.toLocaleString('es', { hour: 'numeric', minute: '2-digit', second: '2-digit' }))
4120 stevensc 633
  const [coferenceType, setConferenceType] = useState(1)
4140 stevensc 634
  const dispatch = useDispatch()
4115 stevensc 635
 
4120 stevensc 636
  const handleChange = (value) => setConferenceType(value)
637
 
4128 stevensc 638
  const handleDateTime = (value) => {
639
    setDate({
640
      ...date,
4134 stevensc 641
      year: new Intl.DateTimeFormat('es', { year: 'numeric' }).format(value),
642
      month: new Intl.DateTimeFormat('es', { month: '2-digit' }).format(value),
5195 stevensc 643
      day: new Intl.DateTimeFormat('es', { day: '2-digit' }).format(value)
4128 stevensc 644
    })
4143 stevensc 645
    setTime(new Intl.DateTimeFormat('es', { hour: 'numeric', minute: '2-digit', second: 'numeric' }).format(value))
4128 stevensc 646
  }
647
 
4139 stevensc 648
  const onSubmit = async (data) => {
649
    try {
650
      const formData = new FormData()
4134 stevensc 651
 
4139 stevensc 652
      Object.entries(data).forEach(([key, value]) => formData.append(key, value))
653
      formData.append('date', `${date.year}-${date.month}-${date.day}`)
4144 stevensc 654
      formData.append('time', time)
4139 stevensc 655
 
656
      const { data: response } = await axios.post(zoomUrl, formData)
657
 
4140 stevensc 658
      if (!response.success && typeof response.data === 'string') {
659
        dispatch(addNotification({ msg: response.data, style: 'danger' }))
660
        return
4139 stevensc 661
      }
662
 
4140 stevensc 663
      if (!response.success && typeof response.data === 'object') {
664
        Object.entries(response.data)
665
          .forEach(([key, value]) => {
666
            dispatch(addNotification({ msg: `${key}: ${value[0]}`, style: 'danger' }))
667
          })
668
        return
669
      }
670
 
4147 stevensc 671
      dispatch(addNotification({ msg: response.data, style: 'success' }))
672
      onCreate()
4139 stevensc 673
      reset()
674
    } catch (error) {
675
      console.log(`Error: ${error.message}`)
4140 stevensc 676
      return dispatch(addNotification({ msg: 'Ha ocurrido un error', style: 'danger' }))
4139 stevensc 677
    }
4115 stevensc 678
  }
679
 
680
  return (
5052 stevensc 681
    <StyleModal title='Crea una conferencia' show={show}>
4145 stevensc 682
      <form onSubmit={handleSubmit(onSubmit)} autoComplete="new-password">
4128 stevensc 683
        <div className="form-group">
684
          <label htmlFor="first_name">Título</label>
685
          <input
686
            type="text"
687
            name="title"
688
            className="form-control"
4133 stevensc 689
            maxLength={128}
5195 stevensc 690
            ref={register({ required: 'Por favor ingrese un título' })}
4128 stevensc 691
          />
5052 stevensc 692
          {errors.title && <FormErrorFeedback>{errors.title.message}</FormErrorFeedback>}
4128 stevensc 693
        </div>
694
        <div className="form-group">
4133 stevensc 695
          <label htmlFor="first_name">Descripción</label>
696
          <input
697
            type="text"
698
            name="description"
699
            className="form-control"
5195 stevensc 700
            ref={register({ required: 'Por favor ingrese una descripción' })}
4133 stevensc 701
          />
5052 stevensc 702
          {errors.description && <FormErrorFeedback>{errors.description.message}</FormErrorFeedback>}
4133 stevensc 703
        </div>
704
        <div className="form-group">
4134 stevensc 705
          <label htmlFor="timezone">Tipo de conferencia</label>
706
          <select
707
            name="type"
708
            className="form-control"
709
            onChange={({ target }) => handleChange(target.value)}
4137 stevensc 710
            ref={register}
4134 stevensc 711
          >
712
            <option value='i'>
713
              Inmediata
714
            </option>
715
            <option value='s'>
716
              Programada
717
            </option>
718
          </select>
719
        </div>
720
        {
721
          coferenceType === 's' &&
722
          <div className="form-group">
723
            <label htmlFor="timezone">Horario</label>
724
            <Datetime
725
              dateFormat="DD-MM-YYYY"
5017 stevensc 726
              onChange={(e) => {
5019 stevensc 727
                if (e.toDate) {
728
                  handleDateTime(e.toDate())
5017 stevensc 729
                }
730
              }}
4134 stevensc 731
              inputProps={{ className: 'form-control' }}
4138 stevensc 732
              initialValue={Date.parse(new Date())}
4134 stevensc 733
              closeOnSelect
734
            />
735
          </div>
736
        }
737
        <div className="form-group">
4128 stevensc 738
          <label htmlFor="timezone">Zona horaria</label>
739
          <select
740
            className="form-control"
741
            name="timezone"
5195 stevensc 742
            ref={register({ required: 'Por favor elige una Zona horaria' })}
4128 stevensc 743
          >
744
            <option value="" hidden>
745
              Zona horaria
746
            </option>
747
            {Object.entries(timezones).map(([key, value]) => (
748
              <option value={key} key={key}>
749
                {value}
4116 stevensc 750
              </option>
4128 stevensc 751
            ))}
752
          </select>
753
          {errors.timezone && <FormErrorFeedback>{errors.timezone.message}</FormErrorFeedback>}
4116 stevensc 754
        </div>
4133 stevensc 755
        <div className="form-group">
756
          <label htmlFor="timezone">Duración</label>
757
          <select
758
            className="form-control"
759
            name="duration"
4137 stevensc 760
            ref={register}
4133 stevensc 761
          >
762
            <option value={5}>5-min</option>
763
            <option value={10}>10-min</option>
764
            <option value={15}>15-min</option>
765
            <option value={20}>20-min</option>
766
            <option value={25}>25-min</option>
767
            <option value={30}>30-min</option>
768
            <option value={35}>35-min</option>
769
            <option value={40}>40-min</option>
770
            <option value={45}>45-min</option>
771
          </select>
772
        </div>
773
        <div className="form-group">
774
          <label htmlFor="first_name">Contraseña de ingreso</label>
775
          <input
776
            type="password"
777
            name="password"
778
            className="form-control"
4137 stevensc 779
            ref={register({
5195 stevensc 780
              required: 'Por favor ingrese una contraseña',
781
              maxLength: { value: 6, message: 'La contraseña debe tener al menos 6 digitos' }
4137 stevensc 782
            })}
4133 stevensc 783
          />
5052 stevensc 784
          {errors.password && <FormErrorFeedback>{errors.password.message}</FormErrorFeedback>}
4115 stevensc 785
        </div>
5052 stevensc 786
        <button className="btn btn-primary" type="submit">
4116 stevensc 787
          Crear
788
        </button>
4115 stevensc 789
      </form>
5206 stevensc 790
    </StyleModal>
4115 stevensc 791
  )
792
}
793
 
5195 stevensc 794
export default React.memo(PersonalChat)