Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
3094 stevensc 1
/* eslint-disable react/prop-types */
4115 stevensc 2
import React, { Children } from "react";
1 www 3
import { useState, useRef, useEffect } from "react";
4
import styled from "styled-components";
932 stevensc 5
import { axios } from "../../../utils";
1 www 6
import Emojione from "./emojione/Emojione";
7
import SendFileModal from "./send-file-modal/SendFileModal";
8
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
9
import MessageTemplate from "./messageTemplate/MessageTemplate";
4115 stevensc 10
import { Button, Modal } from "react-bootstrap";
11
import Spinner from "../../../shared/loading-spinner/Spinner";
12
import { useForm } from "react-hook-form";
13
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
4119 stevensc 14
import 'react-datetime/css/react-datetime.css'
4116 stevensc 15
import Datetime from "react-datetime";
1 www 16
 
17
const StyledChatHead = styled.div`
18
  .notify {
19
    animation: notify 2s infinite;
20
  }
21
 
22
  @keyframes notify {
23
    0% {
24
      background-color: unset;
25
    }
26
    50% {
27
      background-color: #00b0ff;
28
    }
29
    100% {
30
      background-color: unset;
31
    }
32
  }
33
`;
34
 
35
const StyledShowOptions = styled.div`
36
  height: 342px;
37
  flex-direction: column;
38
  overflow-y: auto;
39
  position: relative;
40
  &.show {
41
    display: flex;
42
  }
43
  &.hide {
44
    display: none;
45
  }
46
  .optionBack {
47
    margin: 1rem 0 0.5rem 1rem;
48
    cursor: pointer;
49
  }
50
  .optionsTab {
51
    &__option {
52
      padding: 0.5rem;
53
      border-bottom: 1px solid #e2e2e2;
54
      cursor: pointer;
55
      &:hover {
56
        background-color: #e2e2e2;
57
      }
58
      &__icon {
59
        margin-right: 0.3rem;
60
      }
61
    }
62
  }
63
  .addPersonToGroupTab {
64
    display: flex;
65
    flex-direction: column;
66
    &__person {
67
      display: flex;
68
      justify-content: space-between;
69
      align-items: center;
70
      padding: 0.2rem 0.5rem;
71
      border-bottom: 1px solid #e2e2e2;
72
    }
73
  }
74
`;
75
 
4119 stevensc 76
const PersonalChat = ({ entity, onClose, onMinimize, onRead, not_seen_messages, minimized, timezones }) => {
3056 stevensc 77
 
1 www 78
  // entity destructuring
79
  const {
80
    id,
81
    image,
82
    name,
83
    online,
84
    type,
85
    url_get_all_messages,
86
    url_send,
87
    url_upload,
88
    profile,
89
    // group
90
    url_leave,
91
    url_delete,
92
    url_add_user_to_group,
93
    url_get_contact_group_list,
94
    url_get_contacts_availables_for_group,
4134 stevensc 95
    url_zoom
3056 stevensc 96
  } = entity;
1 www 97
 
98
  // states
99
  const [messages, setMessages] = useState([]);
1298 stevensc 100
  const [responseMessage, setResponseMessage] = useState(null);
1 www 101
  const [oldMessages, setOldMessages] = useState([]);
102
  const [currentPage, setCurrentPage] = useState(1);
103
  const [pages, setPages] = useState(1);
104
  const [showOptions, setShowOptions] = useState(false);
105
  const [optionTab, setOptionTab] = useState("default");
106
  const [availableContactsToAdd, setAvailableContactsToAdd] = useState([]);
107
  const [groupContactsList, setGroupContactsList] = useState([]);
108
  const [confirmModalShow, setConfirmModalShow] = useState(false);
109
  const [showEmojiTab, setShowEmojiTab] = useState(false);
110
  const [shareFileModalShow, setShareFileModalShow] = useState(false);
4115 stevensc 111
  const [showConferenceModal, setShowConferenceModal] = useState(false);
3122 stevensc 112
  const [loading, setLoading] = useState(false);
1 www 113
 
114
  // refs
115
  const conversationListEl = useRef(null);
116
  const loader = useRef(null);
117
  const modalActionUrl = useRef("");
118
  const chatboxEl = useRef(null);
119
  const textAreaEl = useRef(null);
120
 
121
  // optionTabs
122
  const optionTabs = {
123
    add_person_to_group: "add_person_to_group",
124
    group_contacts_list: "group_contacts_list",
4116 stevensc 125
    meet: 'meet',
1 www 126
    default: "default",
127
  };
128
 
129
  const handleActive = () => {
3122 stevensc 130
    onRead(entity);
3123 stevensc 131
    onMinimize(entity);
1 www 132
  };
133
 
134
  const handleGetMessages = async () => {
3122 stevensc 135
    setLoading(true)
1 www 136
    const response = await axios.get(url_get_all_messages);
137
    const resData = response.data;
138
    if (!resData.success) {
932 stevensc 139
      return ("ha ocurrido un error", resData);
1 www 140
    }
141
    const updatedMessages = [...resData.data.items].reverse();
142
    const newMessages = updatedMessages.reduce((acum, updatedMessage) => {
3089 stevensc 143
      if (messages.findIndex((message) => message.id === updatedMessage.id) === -1) {
1 www 144
        acum = [...acum, updatedMessage];
145
      }
146
      return acum;
147
    }, []);
3089 stevensc 148
 
1 www 149
    if (newMessages.length > 0) {
150
      setMessages([...messages, ...newMessages]);
3122 stevensc 151
      setLoading(false)
1 www 152
      setPages(resData.data.pages);
153
      scrollToBottom();
3090 stevensc 154
    } else {
3089 stevensc 155
      setMessages([...updatedMessages]);
3122 stevensc 156
      setLoading(false)
1 www 157
    }
158
  };
159
 
160
  const handleLoadMore = async () => {
936 stevensc 161
    await axios.get(`${url_get_all_messages}?page=${currentPage}`)
1 www 162
      .then((response) => {
163
        const resData = response.data;
164
        if (resData.success) {
165
          if (resData.data.page > 1) {
166
            const updatedOldMessages = [...resData.data.items].reverse();
167
            setOldMessages([...updatedOldMessages, ...oldMessages]);
986 stevensc 168
            /* scrollDownBy(100); */
1 www 169
          }
170
        }
171
      });
172
  };
173
 
3122 stevensc 174
  const handleCloseChat = () => onClose(entity)
1 www 175
 
176
  const handleChatBoxKeyDown = async (e) => {
177
    if (e.key === "Enter") {
178
      e.preventDefault();
179
      const message = e.target.value;
180
      const formData = new FormData();
181
      formData.append("message", emojione.toShort(message));
2181 stevensc 182
      await axios.post(url_send, formData).then((response) => {
183
        const resData = response.data;
184
        if (resData.success) {
2188 stevensc 185
          let newMessage = resData.data
2186 stevensc 186
 
187
          online
2188 stevensc 188
            ? newMessage = { ...newMessage, not_received: false }
189
            : newMessage = { ...newMessage, not_received: true }
2186 stevensc 190
 
2189 stevensc 191
          setMessages([...messages, newMessage])
2181 stevensc 192
        }
193
      });
1 www 194
      e.target.value = "";
2189 stevensc 195
      /* await handleGetMessages(); */
1 www 196
      setShowEmojiTab(false);
1778 stevensc 197
      setResponseMessage(null)
1 www 198
    }
199
  };
200
 
201
  const handleShowOptions = () => {
3131 stevensc 202
    onMinimize(entity, false);
1 www 203
    setShowOptions(!showOptions);
204
  };
205
 
206
  const handleChangeTab = (tab) => {
207
    setOptionTab(tab);
208
  };
209
 
210
  const handleAddPersonToGroup = async (id) => {
211
    const formData = new FormData();
212
    formData.append("uid", id);
213
    await axios.post(url_add_user_to_group, formData).then((response) => {
214
      const resData = response.data;
215
      if (resData.success) {
216
        loadPersonsAvailable();
217
      }
218
    });
219
  };
220
 
221
  const handleConfirmModalAction = async () => {
3122 stevensc 222
    try {
3788 stevensc 223
      const { data } = await axios.post(modalActionUrl.current)
3122 stevensc 224
      if (!data.success) console.log('Error in confirm modal action')
3788 stevensc 225
      handleConfirmModalShow()
226
      onClose(entity);
227
      return
3122 stevensc 228
    } catch (error) {
229
      console.log(error)
230
    }
1 www 231
  };
232
 
233
  const handleObserver = (entities) => {
234
    const target = entities[0];
235
    if (target.isIntersecting) {
236
      setCurrentPage((prevState) => prevState + 1);
237
    }
238
  };
239
 
240
  const scrollToBottom = () => {
3056 stevensc 241
    if (conversationListEl.current) {
1 www 242
      conversationListEl.current.scrollTop =
243
        conversationListEl.current.scrollHeight * 9;
244
    }
245
  };
246
 
247
  const scrollDownBy = (scrollDistance) => {
3056 stevensc 248
    if (conversationListEl.current) {
976 stevensc 249
      conversationListEl.current.scrollTop = scrollDistance;
1 www 250
    }
251
  };
252
 
253
  const handleShowEmojiTab = () => {
254
    setShowEmojiTab(!showEmojiTab);
255
    // smiley_tpl(`${id}`);
256
  };
257
 
258
  const handleClickEmoji = (e) => {
259
    const shortname = e.currentTarget.dataset.shortname;
260
    const currentText = textAreaEl.current.value;
261
    let cursorPosition = textAreaEl.current.selectionStart;
262
    const textBehind = currentText.substring(0, cursorPosition);
263
    const textForward = currentText.substring(cursorPosition);
264
    const unicode = emojione.shortnameToUnicode(shortname);
265
    textAreaEl.current.value = `${textBehind}${unicode}${textForward}`;
266
    textAreaEl.current.focus();
267
    textAreaEl.current.setSelectionRange(
268
      cursorPosition + unicode.length,
269
      cursorPosition + unicode.length
270
    );
271
  };
272
 
273
  // useEffect(() => {
274
  //   setMessages([...oldMessages, ...newMessages]);
275
  // }, [newMessages, oldMessages]);
276
 
277
  // getMessageOnMaximize and subscribe to infinite Loader
278
  useEffect(async () => {
3090 stevensc 279
    let options = {
280
      root: null,
281
      rootMargin: "20px",
282
      treshold: 1.0,
283
    };
284
    const observer = new IntersectionObserver(handleObserver, options);
1 www 285
    if (!minimized) {
286
      await handleGetMessages();
287
      // loader observer
288
      if (loader.current) {
289
        observer.observe(loader.current);
290
      }
291
    }
292
    return () => {
293
      if (loader.current) {
294
        observer.unobserve(loader.current);
295
      }
296
    };
297
  }, [minimized]);
298
 
299
  // LoadMore on change page
300
  useEffect(() => {
932 stevensc 301
    let loadMore = () => handleLoadMore();
928 stevensc 302
    loadMore()
1 www 303
    return () => {
304
      loadMore = null;
305
    };
306
  }, [currentPage]);
307
 
308
  // getMessagesInterval
309
  useEffect(() => {
932 stevensc 310
    if (window.location.pathname === '/group/my-groups') {
38 steven 311
      const items = document.getElementsByClassName('sc-jSgupP')
932 stevensc 312
      if (items && items.length > 0)
313
        items[0].style.display = 'none';
38 steven 314
    }
3122 stevensc 315
  }, [minimized]);
316
 
317
  useEffect(() => {
318
    let timer;
3119 stevensc 319
    if (!minimized && !loading) {
3122 stevensc 320
      timer = setTimeout(() => handleGetMessages(), 1000);
1 www 321
    }
3120 stevensc 322
    return () => {
3122 stevensc 323
      clearTimeout(timer);
324
    };
3119 stevensc 325
  }, [minimized, loading]);
3122 stevensc 326
 
3788 stevensc 327
  const handleConfirmModalShow = () => setConfirmModalShow(!confirmModalShow)
1 www 328
 
3788 stevensc 329
  const handleConfirmModalAccept = () => handleConfirmModalAction()
1 www 330
 
331
  const handleShareFileModalShow = () => {
332
    setShareFileModalShow(!shareFileModalShow);
333
  };
334
 
1300 stevensc 335
  const handleResponseMessage = (element) => {
3059 stevensc 336
    element.mtype === 'text'
337
      ? setResponseMessage(element)
338
      : setResponseMessage({ ...element, m: 'Archivo adjunto' })
339
 
2765 stevensc 340
    textAreaEl.current && textAreaEl.current.focus()
1300 stevensc 341
  };
342
 
4116 stevensc 343
  const displayConferenceModal = () => setShowConferenceModal(!showConferenceModal)
4115 stevensc 344
 
1 www 345
  const messagesRender = () => {
346
    return (
347
      <React.Fragment>
348
        {currentPage < pages ? <li ref={loader}>Cargando...</li> : ""}
349
        {oldMessages.map((oldMessage) => (
3088 stevensc 350
          <MessageTemplate time={oldMessage.time} key={oldMessage.id} message={oldMessage} />
1 www 351
        ))}
1215 stevensc 352
        {messages.map((message, i) => {
353
          let currentTime = message.time;
1216 stevensc 354
          let prevMessage = messages[i - 1];
2187 stevensc 355
 
2537 stevensc 356
          const dailys = ["mes", "meses", "semana", "semanas", "dia", 'dias', "año", "años"]
1215 stevensc 357
          const date = new Date(Date.now()).toLocaleDateString()
358
 
1216 stevensc 359
          if (prevMessage !== undefined) {
360
            let prevTime = messages[i - 1].time;
2181 stevensc 361
 
1216 stevensc 362
            if (prevTime !== currentTime && dailys.includes(prevTime.split(' ')[1])) {
363
              return <>
2538 stevensc 364
                {/* <h2 className="text-center date-chat">{date}</h2> */}
1298 stevensc 365
                <MessageTemplate
3088 stevensc 366
                  key={message.id}
1298 stevensc 367
                  message={message}
3088 stevensc 368
                  time={message.time}
1300 stevensc 369
                  setResponseMessage={handleResponseMessage}
1298 stevensc 370
                  responseMessage={responseMessage}
371
                />
1216 stevensc 372
              </>
373
            }
1215 stevensc 374
          }
375
 
1300 stevensc 376
          return <MessageTemplate
3088 stevensc 377
            key={message.id}
1300 stevensc 378
            message={message}
3088 stevensc 379
            time={message.time}
1300 stevensc 380
            setResponseMessage={handleResponseMessage}
381
            responseMessage={responseMessage}
382
          />
1215 stevensc 383
        })}
1 www 384
      </React.Fragment>
385
    );
386
  };
387
 
388
  const optionRender = () => {
389
    switch (optionTab) {
390
      case optionTabs.add_person_to_group:
391
        return addPersonToGroupTab;
392
      case optionTabs.group_contacts_list:
393
        return groupContactsListTab;
4116 stevensc 394
      case optionTabs.meet:
395
        return meetingOptionsTab;
1 www 396
      default:
397
        return optionsDefaultTab;
398
    }
399
  };
400
 
401
  // useEffect for tabs changing
402
  useEffect(() => {
403
    switch (optionTab) {
404
      case optionTabs.add_person_to_group:
405
        loadPersonsAvailable();
406
        break;
407
      case optionTabs.group_contacts_list:
408
        loadGroupContacts();
409
        break;
410
    }
411
  }, [optionTab]);
412
 
413
  const loadPersonsAvailable = async () => {
414
    await axios.get(url_get_contacts_availables_for_group).then((response) => {
415
      const resData = response.data;
416
      if (resData.success) {
417
        setAvailableContactsToAdd(resData.data);
418
      }
419
    });
420
  };
421
 
422
  const loadGroupContacts = async () => {
423
    await axios.get(url_get_contact_group_list).then((response) => {
424
      const resData = response.data;
425
      if (resData.success) {
426
        setGroupContactsList(resData.data);
427
      }
428
    });
429
  };
430
 
431
  const handleDeletePersonFromGroup = async (urlDeletePersonFromGroup) => {
432
    await axios.post(urlDeletePersonFromGroup).then((response) => {
433
      const resData = response.data;
434
      if (resData.success) {
435
        loadGroupContacts();
436
      }
437
    });
438
  };
439
 
440
  const optionsDefaultTab = (
441
    <React.Fragment>
442
      <span className="optionBack" onClick={() => handleShowOptions()}>
443
        <i className="fa icon-arrow-left"></i>
444
      </span>
445
      <div className="optionsTab">
446
        <ul>
447
          {!!url_get_contact_group_list && (
448
            <li
449
              className="optionsTab__option"
450
              onClick={() => handleChangeTab(optionTabs.group_contacts_list)}
451
            >
452
              <span className="optionsTab__option__icon">
453
                <i className="fa fa-group"></i>
454
              </span>
455
              Integrantes
456
            </li>
457
          )}
458
          {!!url_add_user_to_group && (
459
            <li
460
              className="optionsTab__option"
461
              onClick={() => handleChangeTab(optionTabs.add_person_to_group)}
462
            >
463
              <span className="optionsTab__option__icon">
464
                <i className="fa fa-user-plus"></i>
465
              </span>
466
              Agregar contactos
467
            </li>
468
          )}
469
          {!!url_delete && (
470
            <li
471
              className="optionsTab__option"
472
              style={{ color: "red" }}
473
              onClick={() => {
474
                handleConfirmModalShow();
475
                modalActionUrl.current = url_delete;
476
              }}
477
            >
478
              <span className="optionsTab__option__icon">
479
                <i className="fa fa-trash"></i>
480
              </span>
481
              Eliminar grupo
482
            </li>
483
          )}
484
          {!!url_leave && (
485
            <li
486
              className="optionsTab__option"
487
              style={{ color: "red" }}
488
              onClick={() => {
489
                handleConfirmModalShow();
490
                modalActionUrl.current = url_leave;
491
              }}
492
            >
493
              <span className="optionsTab__option__icon">
494
                <i className="fa fa-user-times"></i>
495
              </span>
496
              Dejar grupo
497
            </li>
498
          )}
499
        </ul>
500
      </div>
501
    </React.Fragment>
502
  );
503
 
4115 stevensc 504
  const meetingOptionsTab = (
505
    <>
506
      <span className="optionBack" onClick={() => handleShowOptions()}>
507
        <i className="fa icon-arrow-left" />
508
      </span>
509
      <div className="optionsTab">
510
        <ul>
511
          <li
512
            className="optionsTab__option"
513
            onClick={displayConferenceModal}
514
          >
515
            <span className="optionsTab__option__icon">
516
              <i className="fa fa-user-plus" />
517
            </span>
518
            Crear conferencia
519
          </li>
520
        </ul>
521
      </div>
522
    </>
523
  );
524
 
1 www 525
  const addPersonToGroupTab = (
526
    <React.Fragment>
527
      <span
528
        className="optionBack"
529
        onClick={() => handleChangeTab(optionTabs.default)}
530
      >
531
        <i className="fa icon-arrow-left"></i>
532
      </span>
533
      <div className="addPersonToGroupTab">
534
        {availableContactsToAdd.length ? (
535
          availableContactsToAdd.map(({ image, name, id }) => (
536
            <div className="addPersonToGroupTab__person" key={id}>
2664 stevensc 537
              <div className="d-inline-flex" style={{ gap: '5px' }}>
2663 stevensc 538
                <img
539
                  className="chat-image img-circle pull-left"
540
                  height="36"
541
                  width="36"
542
                  src={image}
543
                  alt="image-image"
544
                />
545
                <div className="name">{name}</div>
546
              </div>
1 www 547
              <span
548
                style={{
549
                  cursor: "pointer",
550
                }}
551
                onClick={() => {
552
                  handleAddPersonToGroup(id);
553
                }}
554
              >
555
                <i className="fa fa-plus-circle"></i>
556
              </span>
557
            </div>
558
          ))
559
        ) : (
560
          <div className="addPersonToGroupTab__person">No hay Contactos</div>
561
        )}
562
      </div>
563
    </React.Fragment>
564
  );
565
 
566
  const groupContactsListTab = (
567
    <React.Fragment>
568
      <span
569
        className="optionBack"
570
        onClick={() => handleChangeTab(optionTabs.default)}
571
      >
572
        <i className="fa icon-arrow-left"></i>
573
      </span>
574
      <div className="addPersonToGroupTab">
575
        {groupContactsList.length ? (
576
          groupContactsList.map(
577
            ({ image, name, url_remove_from_group, id }) => (
578
              <div className="addPersonToGroupTab__person" key={id}>
579
                <div style={{ display: "flex", alignItems: "center" }}>
580
                  <img
581
                    className="chat-image img-circle pull-left"
582
                    height="36"
583
                    width="36"
584
                    src={image}
585
                    alt="image-image"
586
                  />
587
                  <div className="name">{name}</div>
588
                </div>
589
                {url_remove_from_group && (
590
                  <span
591
                    style={{
592
                      cursor: "pointer",
593
                    }}
594
                    onClick={() => {
595
                      handleDeletePersonFromGroup(url_remove_from_group);
596
                    }}
597
                  >
598
                    <i className="fa fa-user-times"></i>
599
                  </span>
600
                )}
601
              </div>
602
            )
603
          )
604
        ) : (
605
          <div className="addPersonToGroupTab__person">No hay Contactos</div>
606
        )}
607
      </div>
608
    </React.Fragment>
609
  );
610
 
611
  const shareFileModal = (
612
    <SendFileModal
613
      show={shareFileModalShow}
614
      onHide={() => {
615
        setShareFileModalShow(false);
616
      }}
617
      urlUpload={url_upload}
618
    />
619
  );
620
 
621
  const userChat = (
4116 stevensc 622
    <>
3752 stevensc 623
      <div className="chatbox active-chat" style={{ display: 'block' }}>
1 www 624
        <div className="chatbox-icon">
625
          <div className="contact-floating red">
626
            <img className="chat-image img-circle pull-left" src={image} />
627
            <small className="unread-msg">2</small>
628
          </div>
629
        </div>
630
        <div className="panel personal-chat">
631
          <StyledChatHead>
3094 stevensc 632
            <div className={`panel-heading chatboxhead ${not_seen_messages ? "notify" : ""}`}>
1 www 633
              <div className="panel-title">
634
                <img
635
                  className="chat-image img-circle pull-left"
636
                  height="36"
637
                  width="36"
638
                  src={image}
639
                  alt="avatar-image"
640
                />
641
                <div className="header-elements">
3056 stevensc 642
                  <a href={profile} target="_blank" rel="noreferrer">
1 www 643
                    {name}
644
                  </a>
645
                  <br />
1188 stevensc 646
                  <small className={`status ${online ? "Online" : "Offline"}`}>
647
                    <b>{online ? "En línea" : "Desconectado"}</b>
1 www 648
                  </small>
649
                  <div className="pull-right options">
4115 stevensc 650
                    <div className="btn-group uploadFile">
1 www 651
                      {/* <span>
652
                      <i className="fa fa-trash"></i>
653
                    </span> */}
654
                    </div>
4115 stevensc 655
                    <div className="btn-group">
1 www 656
                      {/* <span>
657
                      <i className="fa fa-trash"></i>
658
                    </span> */}
659
                    </div>
4117 stevensc 660
                    <div className="btn-group">
1 www 661
                      <span>
4117 stevensc 662
                        <i className="fa fa-camera" onClick={() => {
4116 stevensc 663
                          handleChangeTab(optionTabs.meet)
664
                          handleShowOptions()
4117 stevensc 665
                        }}
666
                        />
1 www 667
                      </span>
668
                    </div>
4115 stevensc 669
                    <div className="btn-group">
1 www 670
                      <span>
4115 stevensc 671
                        <i className={`fa fa-minus-circle`} onClick={handleActive} />
1 www 672
                      </span>
673
                    </div>
4115 stevensc 674
                    <div className="btn-group">
675
                      <span>
676
                        <i className="fa fa-times-circle" onClick={handleCloseChat} />
677
                      </span>
678
                    </div>
1 www 679
                  </div>
680
                </div>
681
              </div>
682
            </div>
683
          </StyledChatHead>
684
          <div
685
            className="panel-body"
686
            style={{ display: !minimized ? "block" : "none" }}
687
          >
4116 stevensc 688
            <StyledShowOptions className={` ${showOptions ? "show" : "hide"}`}>
689
              {optionRender()}
690
            </StyledShowOptions>
1 www 691
            <div
692
              id="uploader_'+chatboxtitle+'"
693
              style={{ display: "none", height: "342px" }}
694
            >
695
              <p>
696
                Your browser does not have Flash, Silverlight or HTML5 support.
697
              </p>
698
            </div>
4116 stevensc 699
            <div
700
              className="chat-conversation"
4118 stevensc 701
              style={{ position: "relative", display: showOptions ? 'none' : 'block' }}
4116 stevensc 702
            >
1 www 703
              <div className="reverseChatBox" ref={conversationListEl}>
704
                <ul
705
                  className="conversation-list chatboxcontent"
706
                  id="resultchat_'+chatboxtitle+'"
707
                >
708
                  {messagesRender()}
709
                </ul>
710
              </div>
3604 stevensc 711
              <div className="wchat-footer wchat-chat-footer">
1301 stevensc 712
                <div id="chatFrom" className="chatFrom">
2577 stevensc 713
                  {
714
                    responseMessage
715
                    &&
716
                    <div className={responseMessage ? "resp_messages-container active" : "resp_messages-container"}>
717
                      <span>{`Respondiendo a ${responseMessage.user_name}`}</span>
718
                      <p>{responseMessage.m}</p>
719
                    </div>
720
                  }
1 www 721
                  <div className="block-wchat">
722
                    <button
723
                      className="icon ti-clip attachment font-24 btn-attach btn-attach uploadFile"
724
                      id="uploadFile"
725
                      onClick={handleShareFileModalShow}
726
                    ></button>
727
                    <button
728
                      className="icon ti-face-smile font-24 btn-emoji"
729
                      id="toggle-emoji"
730
                      onClick={handleShowEmojiTab}
731
                    ></button>
732
                    <div className="input-container">
733
                      <div className="input-emoji">
734
                        <div
735
                          className="input-placeholder"
736
                          style={{ visibility: "hidden", display: "none" }}
737
                        >
738
                          Escribe un mensaje
739
                        </div>
740
                        <textarea
741
                          className="input chatboxtextarea"
742
                          id="chatboxtextarea"
743
                          name="chattxt"
744
                          style={{ resize: "none", height: "20px" }}
745
                          placeholder="Escribe un mensaje"
746
                          onKeyDown={handleChatBoxKeyDown}
747
                          ref={textAreaEl}
3045 stevensc 748
                          onBlur={() => responseMessage && setResponseMessage(null)}
3122 stevensc 749
                          onFocus={() => not_seen_messages && onRead(entity)}
750
                        />
1 www 751
                        <input
752
                          id="to_uname"
753
                          name="to_uname"
754
                          value="'+chatboxtitle+'"
755
                          type="hidden"
756
                        />
757
                        <input
758
                          id="from_uname"
759
                          name="from_uname"
760
                          value="Beenny"
761
                          type="hidden"
762
                        />
763
                      </div>
764
                    </div>
765
                  </div>
766
                </div>
767
                <div className="wchat-box-items-positioning-container">
768
                  <div className="wchat-box-items-overlay-container">
769
                    <div
770
                      className="target-emoji"
771
                      style={{ display: showEmojiTab ? "block" : "none" }}
772
                    >
773
                      <div id={`smileyPanel_${id}`}>
774
                        <div>
775
                          <Emojione onClickEmoji={handleClickEmoji} />
776
                        </div>
777
                      </div>
778
                    </div>
779
                  </div>
780
                </div>
781
              </div>
782
            </div>
783
          </div>
784
        </div>
785
      </div>
786
      {shareFileModal}
4134 stevensc 787
      <ConferenceModal show={showConferenceModal} timezones={timezones} zoomUrl={url_zoom} />
4116 stevensc 788
    </>
1 www 789
  );
790
 
791
  const groupChat = (
792
    <React.Fragment>
793
      <div
3752 stevensc 794
        className="chatbox active-chat "
1 www 795
        ref={chatboxEl}
796
      >
797
        <div className="chatbox-icon">
798
          <div className="contact-floating red">
799
            <img className="chat-image img-circle pull-left" src={image} />
800
            <small className="unread-msg">2</small>
801
          </div>
802
        </div>
803
        <div className="panel personal-chat">
804
          <StyledChatHead>
3752 stevensc 805
            <div className={`panel-heading chatboxhead ${not_seen_messages ? "notify" : ""}`}>
1 www 806
              <div className="panel-title-group">
807
                <img
808
                  className="chat-image img-circle pull-left"
809
                  height="36"
810
                  width="36"
811
                  src="/images/users-group.png"
812
                  alt="avatar-image"
813
                />
814
                <div className="header-elements">
815
                  <p>{name}</p>
816
                  <br />
817
                  <div className="pull-right options">
818
                    <div
819
                      className="btn-group uploadFile"
820
                      id="uploadFile"
821
                      data-client="'+chatboxtitle+'"
822
                    >
823
                    </div>
3752 stevensc 824
                    <div className="btn-group">
1 www 825
                    </div>
826
                    <div
827
                      className="btn-group addUser"
828
                      data-client="8cb2a840-56c2-4f93-9cf1-27ad598acd8f"
829
                      data-name="Grupo de jesus"
830
                    >
831
                      <span>
832
                        <i
833
                          className="fa fa-gear"
834
                          onClick={handleShowOptions}
835
                        ></i>
836
                      </span>
837
                    </div>
3752 stevensc 838
                    <div className="btn-group">
1 www 839
                      <span>
840
                        <i
841
                          className={`fa fa-minus-circle`}
842
                          onClick={handleActive}
843
                        ></i>
844
                      </span>
845
                    </div>
3752 stevensc 846
                    <div className="btn-group">
1 www 847
                      <span>
848
                        <i
849
                          className="fa fa-times-circle"
850
                          onClick={handleCloseChat}
851
                        ></i>
852
                      </span>
853
                    </div>
854
                  </div>
855
                </div>
856
              </div>
857
            </div>
858
          </StyledChatHead>
859
          <div
860
            className="panel-body"
861
            style={{ display: !minimized ? "block" : "none" }}
862
          >
863
            <StyledShowOptions className={` ${showOptions ? "show" : "hide"}`}>
864
              {optionRender()}
865
            </StyledShowOptions>
866
 
867
            <div
868
              className="chat-conversation"
869
              style={{
870
                display: showOptions ? "none" : "block",
871
                position: "relative",
872
              }}
873
            >
874
              <div className="reverseChatBox" ref={conversationListEl}>
875
                <ul
876
                  className="conversation-list chatboxcontent"
877
                  id="resultchat_'+chatboxtitle+'"
878
                >
879
                  {messagesRender()}
880
                </ul>
881
              </div>
3604 stevensc 882
              <div className="wchat-footer wchat-chat-footer">
1 www 883
                <div id="chatFrom">
884
                  <div className="block-wchat">
885
                    <button
886
                      className="icon ti-clip attachment font-24 btn-attach btn-attach uploadFile"
887
                      id="uploadFile"
888
                      onClick={handleShareFileModalShow}
889
                    ></button>
890
                    <button
891
                      className="icon ti-face-smile font-24 btn-emoji"
892
                      id="toggle-emoji"
893
                      onClick={handleShowEmojiTab}
894
                    ></button>
895
                    <div className="input-container">
896
                      <div className="input-emoji">
897
                        <div
898
                          className="input-placeholder"
899
                          style={{ visibility: "hidden", display: "none" }}
900
                        >
901
                          Escribe un mensaje
902
                        </div>
903
                        <textarea
904
                          className="input chatboxtextarea"
905
                          id="chatboxtextarea"
906
                          name="chattxt"
907
                          style={{ resize: "none", height: "20px" }}
908
                          placeholder="Escribe un mensaje"
909
                          onKeyDown={handleChatBoxKeyDown}
910
                          ref={textAreaEl}
3122 stevensc 911
                          onFocus={() => not_seen_messages && onRead(entity)}
3045 stevensc 912
                          onBlur={() => responseMessage && setResponseMessage(null)}
1 www 913
                        ></textarea>
914
                        <input
915
                          id="to_uname"
916
                          name="to_uname"
917
                          value="'+chatboxtitle+'"
918
                          type="hidden"
919
                        />
920
                        <input
921
                          id="from_uname"
922
                          name="from_uname"
923
                          value="Beenny"
924
                          type="hidden"
925
                        />
926
                      </div>
927
                    </div>
928
                  </div>
929
                </div>
930
                <div className="wchat-box-items-positioning-container">
931
                  <div className="wchat-box-items-overlay-container">
932
                    <div
933
                      className="target-emoji"
934
                      style={{ display: showEmojiTab ? "block" : "none" }}
935
                    >
936
                      <div id={`smileyPanel_${id}`}>
937
                        <div>
938
                          <Emojione onClickEmoji={handleClickEmoji} />
939
                        </div>
940
                      </div>
941
                    </div>
942
                  </div>
943
                </div>
944
              </div>
945
            </div>
946
          </div>
947
        </div>
948
      </div>
949
      <ConfirmModal
950
        show={confirmModalShow}
951
        onClose={handleConfirmModalShow}
952
        onAccept={handleConfirmModalAccept}
953
      />
954
      {shareFileModal}
955
    </React.Fragment>
956
  );
957
 
958
  switch (type) {
959
    case "user":
960
      return userChat;
961
    case "group":
962
      return groupChat;
963
    default:
964
      break;
965
  }
966
};
967
 
4115 stevensc 968
const StyleModal = ({
969
  title = 'Crea una conferencia',
970
  size = 'md',
971
  show = false,
972
  children
973
}) => {
974
 
975
  const [isShow, setIsShow] = useState(show)
976
 
4118 stevensc 977
  useEffect(() => {
978
    setIsShow(show)
979
  }, [show])
980
 
4115 stevensc 981
  const closeModal = () => setIsShow(false)
982
 
983
  return (
984
    <Modal
985
      size={size}
986
      show={isShow}
987
      onHide={closeModal}
988
      style={{ overflowY: "scroll" }}
989
    >
990
      <Modal.Header closeButton>
991
        <Modal.Title>{title}</Modal.Title>
992
      </Modal.Header>
993
      <Modal.Body>
994
        {children}
995
      </Modal.Body>
996
    </Modal>
997
  )
998
}
999
 
1000
const ConferenceModal = ({
4128 stevensc 1001
  show = false,
4134 stevensc 1002
  timezones = {},
1003
  zoomUrl = ''
4115 stevensc 1004
}) => {
1005
 
4130 stevensc 1006
  const dt = new Date()
4136 stevensc 1007
  const { handleSubmit, register, errors, reset } = useForm({ mode: 'all' })
4128 stevensc 1008
  const [date, setDate] = useState({
4130 stevensc 1009
    year: dt.toLocaleString("default", { year: "numeric" }),
1010
    month: dt.toLocaleString("default", { month: "2-digit" }),
1011
    day: dt.toLocaleString("default", { day: "2-digit" })
4128 stevensc 1012
  })
1013
  const [time, setTime] = useState({
4130 stevensc 1014
    hour: dt.toLocaleString("default", { hour: "numeric" }),
1015
    minute: dt.toLocaleString("default", { minute: "2-digit" }),
1016
    second: dt.toLocaleString("default", { second: "2-digit" })
4128 stevensc 1017
  })
4120 stevensc 1018
  const [coferenceType, setConferenceType] = useState(1)
4115 stevensc 1019
 
4120 stevensc 1020
  const handleChange = (value) => setConferenceType(value)
1021
 
4128 stevensc 1022
  const handleDateTime = (value) => {
1023
    setDate({
1024
      ...date,
4134 stevensc 1025
      year: new Intl.DateTimeFormat('es', { year: 'numeric' }).format(value),
1026
      month: new Intl.DateTimeFormat('es', { month: '2-digit' }).format(value),
1027
      day: new Intl.DateTimeFormat('es', { day: '2-digit' }).format(value),
4128 stevensc 1028
    })
1029
    setTime({
1030
      ...time,
4134 stevensc 1031
      hour: new Intl.DateTimeFormat('es', { hour: 'numeric' }).format(value),
1032
      minute: new Intl.DateTimeFormat('es', { minute: '2-digit' }).format(value),
1033
      second: new Intl.DateTimeFormat('es', { second: '2-digit' }).format(value),
4128 stevensc 1034
    })
1035
  }
1036
 
4134 stevensc 1037
  const onSubmit = (data) => {
1038
    Object.entries(data)
4136 stevensc 1039
      .forEach(([key, value]) => console.log(`${key}: ${value}`))
4134 stevensc 1040
 
4115 stevensc 1041
    reset()
1042
  }
1043
 
1044
  return (
1045
    <StyleModal
1046
      title='Crea una conferencia'
1047
      size='md'
1048
      show={show}
1049
    >
1050
      <form onSubmit={handleSubmit(onSubmit)}>
4128 stevensc 1051
        <div className="form-group">
1052
          <label htmlFor="first_name">Título</label>
1053
          <input
1054
            type="text"
1055
            name="title"
1056
            className="form-control"
4133 stevensc 1057
            maxLength={128}
4137 stevensc 1058
            ref={register({ required: "Por favor ingrese un título" })}
4128 stevensc 1059
          />
1060
          {errors.title && <FormErrorFeedback> {errors.title.message}</FormErrorFeedback>}
1061
        </div>
1062
        <div className="form-group">
4133 stevensc 1063
          <label htmlFor="first_name">Descripción</label>
1064
          <input
1065
            type="text"
1066
            name="description"
1067
            className="form-control"
4137 stevensc 1068
            ref={register({ required: "Por favor ingrese una descripción" })}
4133 stevensc 1069
          />
1070
          {errors.title && <FormErrorFeedback> {errors.description.message}</FormErrorFeedback>}
1071
        </div>
1072
        <div className="form-group">
4134 stevensc 1073
          <label htmlFor="timezone">Tipo de conferencia</label>
1074
          <select
1075
            name="type"
1076
            className="form-control"
1077
            onChange={({ target }) => handleChange(target.value)}
4137 stevensc 1078
            ref={register}
4134 stevensc 1079
          >
1080
            <option value='i'>
1081
              Inmediata
1082
            </option>
1083
            <option value='s'>
1084
              Programada
1085
            </option>
1086
          </select>
1087
        </div>
1088
        {
1089
          coferenceType === 's' &&
1090
          <div className="form-group">
1091
            <label htmlFor="timezone">Horario</label>
1092
            <Datetime
1093
              dateFormat="DD-MM-YYYY"
1094
              onChange={(e) => handleDateTime(e.toDate())}
1095
              inputProps={{ className: 'form-control' }}
1096
              initialValue={Date.parse(date)}
1097
              closeOnSelect
1098
            />
1099
          </div>
1100
        }
1101
        <div className="form-group">
4128 stevensc 1102
          <label htmlFor="timezone">Zona horaria</label>
1103
          <select
1104
            className="form-control"
1105
            name="timezone"
4137 stevensc 1106
            ref={register({ required: "Por favor elige una Zona horaria" })}
4128 stevensc 1107
          >
1108
            <option value="" hidden>
1109
              Zona horaria
1110
            </option>
1111
            {Object.entries(timezones).map(([key, value]) => (
1112
              <option value={key} key={key}>
1113
                {value}
4116 stevensc 1114
              </option>
4128 stevensc 1115
            ))}
1116
          </select>
1117
          {errors.timezone && <FormErrorFeedback>{errors.timezone.message}</FormErrorFeedback>}
4116 stevensc 1118
        </div>
4133 stevensc 1119
        <div className="form-group">
1120
          <label htmlFor="timezone">Duración</label>
1121
          <select
1122
            className="form-control"
1123
            name="duration"
4137 stevensc 1124
            ref={register}
4133 stevensc 1125
          >
1126
            <option value={5}>5-min</option>
1127
            <option value={10}>10-min</option>
1128
            <option value={15}>15-min</option>
1129
            <option value={20}>20-min</option>
1130
            <option value={25}>25-min</option>
1131
            <option value={30}>30-min</option>
1132
            <option value={35}>35-min</option>
1133
            <option value={40}>40-min</option>
1134
            <option value={45}>45-min</option>
1135
          </select>
1136
          {errors.timezone && <FormErrorFeedback>{errors.timezone.message}</FormErrorFeedback>}
1137
        </div>
1138
        <div className="form-group">
1139
          <label htmlFor="first_name">Contraseña de ingreso</label>
1140
          <input
1141
            type="password"
1142
            name="password"
1143
            className="form-control"
4137 stevensc 1144
            ref={register({
1145
              required: "Por favor ingrese una contraseña",
1146
              minLength: { value: 6, message: "La contraseña debe tener al menos 6 digitos" }
1147
            })}
4133 stevensc 1148
          />
1149
          {errors.title && <FormErrorFeedback> {errors.password.message}</FormErrorFeedback>}
4115 stevensc 1150
        </div>
4136 stevensc 1151
        <button
1152
          className="btn btn-primary"
1153
          type="submit"
1154
        >
4116 stevensc 1155
          Crear
1156
        </button>
4115 stevensc 1157
      </form>
4133 stevensc 1158
    </StyleModal >
4115 stevensc 1159
  )
1160
}
1161
 
1162
export default React.memo(PersonalChat);