Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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