Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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