Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 7102 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
6618 stevensc 1
import React, { useEffect, useState, useRef } from 'react'
2
import { useDispatch, useSelector } from 'react-redux'
3
import { axios } from '../../../utils'
4
import {
5
  EmailIcon,
6
  EmailShareButton,
7
  FacebookIcon,
8
  FacebookShareButton,
9
  RedditIcon,
10
  RedditShareButton,
11
  TelegramIcon,
12
  TelegramShareButton,
13
  TwitterIcon,
14
  TwitterShareButton,
15
  WhatsappIcon,
16
  WhatsappShareButton,
17
} from 'react-share'
18
import parse from 'html-react-parser'
19
import GroupsRoundedIcon from '@mui/icons-material/GroupsRounded'
20
 
21
import { feedTypes } from '../../redux/feed/feed.types'
22
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'
23
 
24
import { deleteFeed } from '../../redux/feed/feed.actions'
25
import { openShareModal } from '../../../redux/share-modal/shareModal.actions'
26
import { addNotification } from '../../../redux/notification/notification.actions'
27
 
28
import FeedCommentSection from './CommentSection'
29
import useOutsideClick from '../../hooks/useOutsideClick'
30
 
31
import FeedModal from './FeedModal'
32
import ConfirmModal from '../modals/ConfirmModal'
6623 stevensc 33
import SurveyForm from '../survey-form/SurveyForm'
6625 stevensc 34
import ReactionsButton from '../UI/buttons/ReactionsButton'
6618 stevensc 35
 
36
const Feed = ({ feed, owner_shared, image }) => {
37
  const {
38
    feed_unique,
39
    owner_name,
40
    owner_url,
41
    owner_image,
42
    owner_time_elapse,
43
    owner_file_image,
44
    owner_file_video,
45
    owner_file_document,
46
    owner_feed_type,
47
    feed_highlighted,
48
    feed_share_url,
49
    feed_delete_url,
50
    comments,
51
    comment_add_url,
52
    feed_share_external_url,
53
  } = feed
6624 stevensc 54
  const [totalComments, setTotalComments] = useState(0)
6618 stevensc 55
  const [sharedState, setSharedState] = useState(owner_shared)
56
  const [shareUrl, setShareUrl] = useState('')
57
 
58
  const [showComments, setShowComments] = useState(false)
59
  const [shareOptions, setShareOptions] = useState(false)
60
  const [show, setShow] = useState(false)
61
 
62
  const shareContainer = useRef(null)
63
  const dispatch = useDispatch()
6625 stevensc 64
 
6618 stevensc 65
  useOutsideClick(shareContainer, () => setShareOptions(false))
66
 
67
  const getShareUrl = new Promise((resolve, reject) => {
68
    if (shareOptions) {
69
      axios
70
        .get(feed_share_external_url)
71
        .then(({ data }) => {
72
          if (!data.success) {
73
            dispatch(addNotification({ style: 'danger', msg: data.data }))
74
            setShareOptions(false)
75
            return reject(data.data)
76
          }
77
          setShareUrl(data.data)
78
          return resolve(data.data)
79
        })
80
        .catch((err) => reject(err))
81
    }
82
  })
83
 
6625 stevensc 84
  const displayComments = () => {
85
    setShowComments(!showComments)
6618 stevensc 86
  }
87
 
88
  const btnShareHandler = () => {
89
    dispatch(
90
      openShareModal(
91
        feed_share_url,
92
        shareModalTypes.SHARE,
93
        feedTypes.DASHBOARD,
94
        feed_unique
95
      )
96
    )
97
  }
98
 
99
  useEffect(() => setSharedState(owner_shared), [owner_shared])
100
 
101
  return (
102
    <>
103
      <FeedModal isShow={show} handleClose={() => setShow(false)} feed={feed} />
104
      <div className={`feed ${feed_highlighted ? 'highlighted' : ''}`}>
105
        <FeedHeader
106
          ownerName={owner_name}
107
          ownerImage={owner_image}
108
          ownerTimeElapse={owner_time_elapse}
109
          ownerUrl={owner_url}
110
          feedDeleteUrl={feed_delete_url}
111
          feedUnique={feed_unique}
112
          feedType={owner_feed_type}
113
        />
114
        <div
115
          onClick={() =>
116
            (owner_file_image || owner_file_video || owner_file_document) &&
117
            setShow(true)
118
          }
119
        >
120
          <Feed.Content
121
            isShare={!!feed.shared_name}
6623 stevensc 122
            image={feed.owner_file_image}
123
            fileVideo={feed.owner_file_video}
124
            imagePreview={feed.owner_file_image_preview}
125
            document={feed.owner_file_document}
126
            description={feed.owner_description}
127
            type={feed.feed_content_type}
128
            voteUrl={feed.feed_vote_url}
6618 stevensc 129
            sharedItem={{
130
              name: feed.shared_name,
131
              image: feed.shared_image,
132
              time_elapse: feed.shared_time_elapse,
133
              description: feed.shared_description,
134
              file_video: feed.shared_file_video,
135
              file_image_preview: feed.shared_file_image_preview,
136
              file_image: feed.shared_file_image,
137
              file_document: feed.shared_file_document,
138
            }}
139
          />
140
        </div>
141
        <ul className="reactions-list">
142
          <li>
6625 stevensc 143
            <ReactionsButton
7101 stevensc 144
              onChange={() => null}
6625 stevensc 145
              currentReaction={feed.feed_my_reaction}
146
              withLabel
147
              deleteUrl={feed.feed_delete_reaction_url}
7106 stevensc 148
              saveUrl={feed.feed_save_reaction_url}
6625 stevensc 149
            />
6618 stevensc 150
          </li>
151
          <li>
152
            <button
153
              type="button"
154
              id={`btn-comments-${feed_unique}`}
155
              className="btn-indicator"
156
              onClick={displayComments}
157
            >
158
              <img src="/images/icons/message.png" className="mr-1 img-icon" />
159
              {totalComments}
160
            </button>
161
          </li>
162
          <li>
163
            <button
164
              type="button"
165
              id={`btn-share-${feed_unique}`}
166
              className="btn-indicator"
167
              onClick={btnShareHandler}
168
            >
169
              <img src="/images/icons/share.png" className="mr-1 img-icon" />
170
              {sharedState}
171
            </button>
172
          </li>
173
          <li className="position-relative">
174
            <button
175
              type="button"
176
              className="btn-indicator"
177
              onClick={() => setShareOptions(!shareOptions)}
178
            >
179
              <i className="mr-1 far fa-share-square" />
180
            </button>
181
            {shareOptions && (
182
              <div className="ext_share" ref={shareContainer}>
183
                <FacebookShareButton
184
                  beforeOnClick={() => getShareUrl}
185
                  url={shareUrl}
186
                >
187
                  <FacebookIcon size={32} round />
188
                </FacebookShareButton>
189
                <TwitterShareButton
190
                  beforeOnClick={() => getShareUrl}
191
                  url={shareUrl}
192
                >
193
                  <TwitterIcon size={32} round />
194
                </TwitterShareButton>
195
                <TelegramShareButton
196
                  beforeOnClick={() => getShareUrl}
197
                  url={shareUrl}
198
                >
199
                  <TelegramIcon size={32} round />
200
                </TelegramShareButton>
201
                <WhatsappShareButton
202
                  beforeOnClick={() => getShareUrl}
203
                  url={shareUrl}
204
                >
205
                  <WhatsappIcon size={32} round />
206
                </WhatsappShareButton>
207
                <RedditShareButton
208
                  beforeOnClick={() => getShareUrl}
209
                  url={shareUrl}
210
                >
211
                  <RedditIcon size={32} round />
212
                </RedditShareButton>
213
                <EmailShareButton
214
                  beforeOnClick={() => getShareUrl}
215
                  url={shareUrl}
216
                >
217
                  <EmailIcon size={32} round />
218
                </EmailShareButton>
219
              </div>
220
            )}
221
          </li>
222
        </ul>
223
        <FeedCommentSection
6625 stevensc 224
          isShow={showComments}
6618 stevensc 225
          image={image}
226
          addUrl={comment_add_url}
227
          currentComments={comments}
6625 stevensc 228
          updateTotalComments={(totalComments) =>
229
            setTotalComments(totalComments)
230
          }
6618 stevensc 231
        />
232
      </div>
233
    </>
234
  )
235
}
236
 
237
export const FeedContent = ({
238
  showDescription = true,
6623 stevensc 239
  image,
240
  video,
241
  imagePreview,
242
  document,
243
  description,
6618 stevensc 244
  isShare,
245
  sharedItem,
6623 stevensc 246
  type,
247
  voteUrl,
6618 stevensc 248
}) => {
249
  return (
250
    <div className="job_descp">
6623 stevensc 251
      {type !== 'fast-survey' && showDescription ? (
252
        <Feed.Description description={description} />
253
      ) : (
254
        <SurveyForm
255
          active={description.active}
256
          question={description.question}
257
          answers={[
258
            description.answer1,
259
            description.answer2,
260
            description.answer3,
261
            description.answer4,
262
            description.answer5,
263
          ]}
264
          votes={
265
            description.votes1 && [
266
              description.votes1,
267
              description.votes2,
268
              description.votes3,
269
              description.votes4,
270
              description.votes5,
271
            ]
272
          }
273
          time={description.time_remaining}
274
          voteUrl={voteUrl}
275
          resultType={description.result_type}
276
        />
6618 stevensc 277
      )}
6623 stevensc 278
 
279
      {image && <img src={image} className="Entradas" loading="lazy" />}
280
      {video && (
281
        <video src={video} controls poster={imagePreview} preload="none" />
6618 stevensc 282
      )}
6623 stevensc 283
      {document && (
7089 stevensc 284
        <a href={document} download target="_blank" rel="noreferrer">
7090 stevensc 285
          <img
286
            className="pdf"
287
            src="/images/extension/pdf.png"
288
            alt="pdf"
289
            width="40px"
290
          />
6618 stevensc 291
        </a>
292
      )}
293
      {isShare && (
294
        <Feed.Shared
295
          name={sharedItem.name}
7090 stevensc 296
          ownerImage={sharedItem.image}
297
          image={sharedItem.file_image}
6618 stevensc 298
          timeElapse={sharedItem.time_elapse}
299
          description={sharedItem.description}
6623 stevensc 300
          video={sharedItem.file_video}
301
          imagePreview={sharedItem.file_image_preview}
302
          document={sharedItem.file_document}
6618 stevensc 303
        />
304
      )}
305
    </div>
306
  )
307
}
6623 stevensc 308
export const FeedDescription = ({ description }) => {
6618 stevensc 309
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
6832 stevensc 310
  const labels = useSelector(({ intl }) => intl.labels)
6618 stevensc 311
 
312
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
313
 
314
  const htmlParsedText = (fullStringText) => {
315
    const fullText = parse(fullStringText)
316
    if (fullStringText.length > 500) {
317
      const shortenedString = fullStringText.substr(0, 500)
318
      const shortenedText = parse(`${shortenedString}... `)
319
      return (
320
        <p>
321
          {isReadMoreActive ? fullText : shortenedText}
322
          <span className="cursor-pointer" onClick={readMoreHandler}>
6832 stevensc 323
            {isReadMoreActive ? labels.read_less : labels.read_more}
6618 stevensc 324
          </span>
325
        </p>
326
      )
327
    }
328
    return <p>{fullText}</p>
329
  }
330
 
6623 stevensc 331
  return <div className="show-read-more">{htmlParsedText(description)}</div>
6618 stevensc 332
}
333
 
334
export const FeedShared = ({
335
  name,
7090 stevensc 336
  ownerImage,
6618 stevensc 337
  image,
338
  timeElapse,
339
  description,
6623 stevensc 340
  video,
341
  imagePreview,
342
  document,
6618 stevensc 343
}) => {
344
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
6832 stevensc 345
  const labels = useSelector(({ intl }) => intl.labels)
6618 stevensc 346
 
347
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
348
 
6831 stevensc 349
  const htmlParsedText = (fullStringText = '') => {
6618 stevensc 350
    const fullText = parse(fullStringText)
351
    if (fullStringText.length > 500) {
352
      const shortenedString = fullStringText.substr(0, 500)
353
      const shortenedText = parse(`${shortenedString}... `)
354
      return (
355
        <p>
356
          {isReadMoreActive ? fullText : shortenedText}
357
          <span className="cursor-pointer" onClick={readMoreHandler}>
6832 stevensc 358
            {isReadMoreActive ? labels.read_less : labels.read_more}
6618 stevensc 359
          </span>
360
        </p>
361
      )
362
    }
363
    return <p>{fullText}</p>
364
  }
365
 
366
  return (
367
    <div className="shared-post-bar">
368
      <div className="post-bar">
369
        <div className="post_topbar">
370
          <div className="usy-dt">
7090 stevensc 371
            <img
372
              src={ownerImage}
373
              alt=""
374
              style={{ width: '50px', height: 'auto' }}
375
            />
6618 stevensc 376
            <div className="usy-name">
377
              <h3>{name}</h3>
378
              <span>{timeElapse}</span>
379
            </div>
380
          </div>
381
        </div>
382
        <div className="job_descp">
383
          <div className="show-read-more">{htmlParsedText(description)}</div>
6623 stevensc 384
          {image && <img src={image} className="Entradas" loading="lazy" />}
385
          {video && (
386
            <video src={video} controls poster={imagePreview} preload="none" />
6618 stevensc 387
          )}
6623 stevensc 388
          {document && (
389
            <a href={document} target="_blank" rel="noreferrer">
7090 stevensc 390
              <img
391
                className="pdf"
392
                src="/images/extension/pdf.png"
393
                alt="pdf"
394
                width="40px"
395
              />
6618 stevensc 396
            </a>
397
          )}
398
        </div>
399
      </div>
400
    </div>
401
  )
402
}
403
 
404
export const FeedHeader = ({
405
  ownerName,
406
  ownerImage,
407
  ownerTimeElapse,
408
  ownerUrl,
409
  feedDeleteUrl,
410
  feedUnique,
411
  feedType,
412
}) => {
413
  const [showConfirmModal, setShowConfirmModal] = useState(false)
414
  const [displayOption, setDisplayOption] = useState(false)
415
  const deleteButton = useRef(null)
416
  const labels = useSelector(({ intl }) => intl.labels)
417
  const dispatch = useDispatch()
418
  useOutsideClick(deleteButton, () => setDisplayOption(false))
419
 
420
  const handleShowConfirmModal = () => {
421
    setShowConfirmModal(!showConfirmModal)
422
  }
423
 
424
  const deleteFeedHandler = () => {
425
    axios.post(feedDeleteUrl).then((res) => {
426
      const { data } = res
427
      if (!data.success) {
428
        dispatch(addNotification({ style: 'danger', msg: data.data }))
429
        return
430
      }
431
      dispatch(addNotification({ style: 'success', msg: data.data }))
432
      handleShowConfirmModal()
433
      dispatch(deleteFeed(feedUnique))
434
    })
435
  }
436
 
437
  return (
438
    <>
439
      <div className="post_topbar">
440
        <div className="usy-dt">
441
          <a href={ownerUrl}>
442
            <img
443
              src={ownerImage}
444
              alt=""
445
              style={{ width: '50px', height: 'auto' }}
446
            />
447
          </a>
448
          <div className="usy-name">
449
            <a href={ownerUrl}>
450
              <h3>{ownerName}</h3>
451
            </a>
452
            <span>
453
              {feedType === 'g' && <GroupsRoundedIcon />}
454
              {ownerTimeElapse}
455
            </span>
456
          </div>
457
        </div>
458
        {feedDeleteUrl && (
459
          <div className="cursor-pointer d-flex align-items-center">
460
            <img
461
              src="/images/icons/options.png"
462
              className="cursor-pointer img-icon options"
463
              onClick={() => setDisplayOption(!displayOption)}
464
            />
465
            <div className={`feed-options ${displayOption ? 'active' : ''}`}>
466
              <ul>
467
                <li>
468
                  <button
469
                    className="option-btn"
470
                    onClick={handleShowConfirmModal}
471
                    ref={deleteButton}
472
                  >
473
                    <i className="fa fa-trash-o mr-1" />
474
                    {labels.delete}
475
                  </button>
476
                </li>
477
              </ul>
478
            </div>
479
            <ConfirmModal
480
              show={showConfirmModal}
481
              onClose={() => handleShowConfirmModal(false)}
482
              onAccept={deleteFeedHandler}
483
              acceptLabel="Aceptar"
484
            />
485
          </div>
486
        )}
487
      </div>
488
    </>
489
  )
490
}
491
 
492
Feed.Shared = FeedShared
493
Feed.Description = FeedDescription
494
Feed.Content = FeedContent
495
Feed.Header = FeedHeader
496
 
497
export default React.memo(Feed)