Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
5115 stevensc 1
/* eslint-disable camelcase */
3207 stevensc 2
/* eslint-disable react/prop-types */
5115 stevensc 3
import React, { useEffect, useState, useRef } from 'react'
4
import parse from 'html-react-parser'
5414 stevensc 5
import { useDispatch, useSelector } from 'react-redux'
5115 stevensc 6
import { axios } from '../../../utils'
5579 stevensc 7
import {
8
  EmailIcon,
9
  EmailShareButton,
10
  FacebookIcon,
11
  FacebookShareButton,
12
  RedditIcon,
13
  RedditShareButton,
14
  TelegramIcon,
15
  TelegramShareButton,
16
  TwitterIcon,
17
  TwitterShareButton,
18
  WhatsappIcon,
19
  WhatsappShareButton,
20
} from 'react-share'
5782 stevensc 21
import { feedTypes } from '../../../redux/feed/feed.types'
5115 stevensc 22
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'
23
import { openShareModal } from '../../../redux/share-modal/shareModal.actions'
24
import { addNotification } from '../../../redux/notification/notification.actions'
5782 stevensc 25
import useOutsideClick from '../../../hooks/useOutsideClick'
1034 stevensc 26
 
5115 stevensc 27
// Components
28
import FeedModal from './FeedModal'
29
import FeedHeader from './FeedHeader'
30
import FeedCommentSection from './feed-comment/FeedCommentSection'
5782 stevensc 31
import RecommendIcon from '@mui/icons-material/Recommend'
32
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
33
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
34
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
35
import TungstenIcon from '@mui/icons-material/Tungsten'
5667 stevensc 36
import { ReactionButton } from './withReaction'
5115 stevensc 37
 
4017 stevensc 38
const Feed = ({ feed, owner_shared, image }) => {
1 www 39
  const {
40
    feed_unique,
41
    owner_name,
42
    owner_url,
43
    owner_image,
44
    owner_time_elapse,
45
    owner_file_image,
46
    owner_file_video,
47
    owner_file_document,
5706 stevensc 48
    owner_feed_type,
3207 stevensc 49
    feed_highlighted,
1 www 50
    feed_share_url,
51
    feed_delete_url,
52
    comments,
53
    comment_add_url,
5579 stevensc 54
    feed_share_external_url,
5115 stevensc 55
  } = feed
5781 stevensc 56
  const [totalComments, setTotalComments] = useState(comments.length)
57
  const [totalReactions, setTotalReactions] = useState(0)
5115 stevensc 58
  const [sharedState, setSharedState] = useState(owner_shared)
59
  const [shareUrl, setShareUrl] = useState('')
5781 stevensc 60
 
5115 stevensc 61
  const [showComments, setShowComments] = useState(false)
3308 stevensc 62
  const [shareOptions, setShareOptions] = useState(false)
5115 stevensc 63
  const [show, setShow] = useState(false)
1 www 64
 
5115 stevensc 65
  const shareContainer = useRef(null)
5781 stevensc 66
  const dispatch = useDispatch()
67
  const outsideClick = useOutsideClick(shareContainer)
1034 stevensc 68
 
5781 stevensc 69
  const reactionsOptions = [
70
    {
71
      type: 'r',
72
      icon: <RecommendIcon style={{ color: '#7405f9' }} />,
73
    },
74
    {
75
      type: 's',
76
      icon: <VolunteerActivismIcon style={{ color: '#6495ED' }} />,
77
    },
78
    {
79
      type: 'l',
80
      icon: <FavoriteIcon style={{ color: '#DF704D' }} />,
81
    },
82
    {
83
      type: 'i',
84
      icon: (
85
        <TungstenIcon
86
          style={{ color: '#F5BB5C', transform: 'rotate(180deg)' }}
87
        />
88
      ),
89
    },
90
    {
91
      type: 'f',
92
      icon: <EmojiEmotionsIcon style={{ color: '#FF7F50' }} />,
93
    },
94
  ]
1030 stevensc 95
 
4016 stevensc 96
  const getShareUrl = new Promise((resolve, reject) => {
97
    if (shareOptions) {
5579 stevensc 98
      axios
99
        .get(feed_share_external_url)
4016 stevensc 100
        .then(({ data }) => {
101
          if (!data.success) {
102
            dispatch(addNotification({ style: 'danger', msg: data.data }))
103
            setShareOptions(false)
104
            return reject(data.data)
105
          }
106
          setShareUrl(data.data)
107
          return resolve(data.data)
108
        })
109
        .catch((err) => reject(err))
4015 stevensc 110
    }
5115 stevensc 111
  })
4015 stevensc 112
 
5781 stevensc 113
  const saveReaction = (type) => {
114
    const reactionTypesUrl = {
115
      r: feed.feed_save_reaction_recommended_url,
116
      s: feed.feed_save_reaction_support_url,
117
      l: feed.feed_save_reaction_love_url,
118
      i: feed.feed_save_reaction_interest_url,
119
      f: feed.feed_save_reaction_fun_url,
120
    }
121
 
122
    axios.post(reactionTypesUrl[type]).then((res) => {
5579 stevensc 123
      const { success, data } = res.data
5781 stevensc 124
 
5579 stevensc 125
      if (!success) {
5781 stevensc 126
        dispatch(addNotification({ style: 'danger', msg: data }))
5579 stevensc 127
      }
5781 stevensc 128
 
129
      return data
5579 stevensc 130
    })
5781 stevensc 131
  }
1 www 132
 
5781 stevensc 133
  const deleteReaction = () => {
134
    axios.post(feed.fefeed_delete_reaction_url).then((res) => {
135
      const { success, data } = res.data
136
 
137
      if (!success) {
138
        dispatch(addNotification({ style: 'danger', msg: data }))
139
        return
140
      }
141
 
142
      return data
143
    })
144
  }
145
 
3962 stevensc 146
  const displayComments = () => setShowComments(!showComments)
147
 
5781 stevensc 148
  const btnShareHandler = () => {
5579 stevensc 149
    dispatch(
150
      openShareModal(
151
        feed_share_url,
152
        shareModalTypes.SHARE,
153
        feedTypes.DASHBOARD,
154
        feed_unique
155
      )
156
    )
5781 stevensc 157
  }
1 www 158
 
5781 stevensc 159
  useEffect(() => setSharedState(owner_shared), [owner_shared])
160
 
161
  useEffect(() => outsideClick && setShareOptions(false), [outsideClick])
162
 
163
  useEffect(() => {
164
    const feedReactions = feed.feed_reactions.reduce(
165
      (acc, reaction) => acc + Number(reaction.total),
166
 
167
    )
168
    setTotalReactions(feedReactions)
169
  }, [feed.feed_reactions])
170
 
1 www 171
  return (
4017 stevensc 172
    <>
5579 stevensc 173
      <FeedModal isShow={show} handleClose={() => setShow(false)} feed={feed} />
5449 stevensc 174
      <div className={`feed ${feed_highlighted ? 'highlighted' : ''}`}>
3630 stevensc 175
        <FeedHeader
176
          ownerName={owner_name}
177
          ownerImage={owner_image}
178
          ownerTimeElapse={owner_time_elapse}
179
          ownerUrl={owner_url}
180
          feedDeleteUrl={feed_delete_url}
181
          feedUnique={feed_unique}
5706 stevensc 182
          feedType={owner_feed_type}
3630 stevensc 183
        />
5579 stevensc 184
        <div
185
          onClick={() =>
186
            (owner_file_image || owner_file_video || owner_file_document) &&
187
            setShow(true)
188
          }
718 steven 189
        >
4017 stevensc 190
          <Feed.Content
5115 stevensc 191
            isShare={!!feed.shared_name}
4017 stevensc 192
            ownerFileImage={feed.owner_file_image}
193
            ownerFileVideo={feed.owner_file_video}
194
            ownerFileImagePreview={feed.owner_file_image_preview}
195
            ownerFileDocument={feed.owner_file_document}
196
            ownerDescription={feed.owner_description}
197
            sharedItem={{
198
              name: feed.shared_name,
199
              image: feed.shared_image,
200
              time_elapse: feed.shared_time_elapse,
201
              description: feed.shared_description,
202
              file_video: feed.shared_file_video,
203
              file_image_preview: feed.shared_file_image_preview,
204
              file_image: feed.shared_file_image,
5579 stevensc 205
              file_document: feed.shared_file_document,
4017 stevensc 206
            }}
207
          />
718 steven 208
        </div>
5781 stevensc 209
        <div className="d-inline-flex align-items-center">
210
          {reactionsOptions
211
            .filter((option) =>
212
              feed.feed_reactions.find(
213
                (reaction) => reaction.reaction === option.type
214
              )
215
            )
216
            .map((reaction) => reaction.icon)}
217
        </div>
5706 stevensc 218
        <ul className="reactions-list">
219
          <li>
5771 stevensc 220
            <ReactionButton
5781 stevensc 221
              onSelect={saveReaction}
222
              onDelete={deleteReaction}
5772 stevensc 223
              myReaction={feed.feed_my_reaction}
5771 stevensc 224
            />
5706 stevensc 225
          </li>
226
          <li>
227
            <button
228
              type="button"
229
              id={`btn-comments-${feed_unique}`}
230
              className="btn-indicator"
231
              onClick={displayComments}
232
            >
233
              <img src="/images/icons/message.png" className="mr-1 img-icon" />
234
              {totalComments}
235
            </button>
236
          </li>
237
          <li>
238
            <button
239
              type="button"
240
              id={`btn-share-${feed_unique}`}
241
              className="btn-indicator"
242
              onClick={btnShareHandler}
243
            >
244
              <img src="/images/icons/share.png" className="mr-1 img-icon" />
245
              {sharedState}
246
            </button>
247
          </li>
248
          <li className="position-relative">
249
            <button
250
              type="button"
251
              className="btn-indicator"
252
              onClick={() => setShareOptions(!shareOptions)}
253
            >
254
              <i className="mr-1 far fa-share-square" />
255
            </button>
256
            {shareOptions && (
257
              <div className="ext_share" ref={shareContainer}>
258
                <FacebookShareButton
259
                  beforeOnClick={() => getShareUrl}
260
                  url={shareUrl}
261
                >
262
                  <FacebookIcon size={32} round />
263
                </FacebookShareButton>
264
                <TwitterShareButton
265
                  beforeOnClick={() => getShareUrl}
266
                  url={shareUrl}
267
                >
268
                  <TwitterIcon size={32} round />
269
                </TwitterShareButton>
270
                <TelegramShareButton
271
                  beforeOnClick={() => getShareUrl}
272
                  url={shareUrl}
273
                >
274
                  <TelegramIcon size={32} round />
275
                </TelegramShareButton>
276
                <WhatsappShareButton
277
                  beforeOnClick={() => getShareUrl}
278
                  url={shareUrl}
279
                >
280
                  <WhatsappIcon size={32} round />
281
                </WhatsappShareButton>
282
                <RedditShareButton
283
                  beforeOnClick={() => getShareUrl}
284
                  url={shareUrl}
285
                >
286
                  <RedditIcon size={32} round />
287
                </RedditShareButton>
288
                <EmailShareButton
289
                  beforeOnClick={() => getShareUrl}
290
                  url={shareUrl}
291
                >
292
                  <EmailIcon size={32} round />
293
                </EmailShareButton>
294
              </div>
295
            )}
296
          </li>
297
        </ul>
298
 
3943 stevensc 299
        <FeedCommentSection
300
          feedId={feed.feed_unique}
301
          image={image}
302
          addUrl={comment_add_url}
5583 stevensc 303
          updateTotalComments={(total) => setTotalComments(total)}
5579 stevensc 304
          currentComments={comments}
3962 stevensc 305
          isShow={showComments}
3943 stevensc 306
        />
5115 stevensc 307
      </div>
4017 stevensc 308
    </>
5115 stevensc 309
  )
310
}
1 www 311
 
4017 stevensc 312
const Content = ({
313
  showDescription = true,
314
  ownerFileImage,
315
  ownerFileVideo,
316
  ownerFileImagePreview,
317
  ownerFileDocument,
318
  ownerDescription,
319
  isShare,
5579 stevensc 320
  sharedItem,
4017 stevensc 321
}) => {
5579 stevensc 322
  const labels = useSelector((state) => state.labels)
4017 stevensc 323
  return (
324
    <div className="job_descp">
5579 stevensc 325
      {showDescription && (
4017 stevensc 326
        <Feed.Description ownerDescription={ownerDescription} />
5579 stevensc 327
      )}
328
      {ownerFileImage && (
329
        <img src={ownerFileImage} className="Entradas" loading="lazy" />
330
      )}
331
      {ownerFileVideo && (
4017 stevensc 332
        <video
333
          src={ownerFileVideo}
334
          controls
335
          poster={ownerFileImagePreview}
336
          preload="none"
337
        />
5579 stevensc 338
      )}
339
      {ownerFileDocument && (
4017 stevensc 340
        <a href={ownerFileDocument} target="_blank" rel="noreferrer">
5414 stevensc 341
          {labels.DOWNLOAD}
4017 stevensc 342
        </a>
5579 stevensc 343
      )}
344
      {isShare && (
4017 stevensc 345
        <Feed.SharedContent
346
          name={sharedItem.name}
347
          image={sharedItem.image}
348
          timeElapse={sharedItem.time_elapse}
349
          description={sharedItem.description}
350
          fileVideo={sharedItem.file_video}
351
          fileImagePreview={sharedItem.file_image_preview}
352
          fileImage={sharedItem.file_image}
353
          fileDocument={sharedItem.file_document}
354
        />
5579 stevensc 355
      )}
4017 stevensc 356
    </div>
357
  )
358
}
359
 
360
const Description = ({ ownerDescription }) => {
5115 stevensc 361
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
5579 stevensc 362
  const labels = useSelector((state) => state.labels)
4017 stevensc 363
 
364
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
365
 
366
  const htmlParsedText = (fullStringText) => {
367
    const fullText = parse(fullStringText)
368
    if (fullStringText.length > 500) {
5115 stevensc 369
      const shortenedString = fullStringText.substr(0, 500)
370
      const shortenedText = parse(`${shortenedString}... `)
4017 stevensc 371
      return (
372
        <p>
373
          {isReadMoreActive ? fullText : shortenedText}
5579 stevensc 374
          <span className="cursor-pointer" onClick={readMoreHandler}>
5414 stevensc 375
            {isReadMoreActive ? labels.READ_LESS : labels.READ_MORE}
4017 stevensc 376
          </span>
377
        </p>
5115 stevensc 378
      )
4017 stevensc 379
    }
380
    return <p>{fullText}</p>
5115 stevensc 381
  }
4017 stevensc 382
 
383
  return (
5579 stevensc 384
    <div className="show-read-more">{htmlParsedText(ownerDescription)}</div>
4017 stevensc 385
  )
386
}
387
 
388
const SharedContent = ({
389
  name,
390
  image,
391
  timeElapse,
392
  description,
393
  fileVideo,
394
  fileImagePreview,
395
  fileImage,
5579 stevensc 396
  fileDocument,
4017 stevensc 397
}) => {
5115 stevensc 398
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
5579 stevensc 399
  const labels = useSelector((state) => state.labels)
4017 stevensc 400
 
401
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
402
 
403
  const htmlParsedText = (fullStringText) => {
404
    const fullText = parse(fullStringText)
405
    if (fullStringText.length > 500) {
5115 stevensc 406
      const shortenedString = fullStringText.substr(0, 500)
407
      const shortenedText = parse(`${shortenedString}... `)
4017 stevensc 408
      return (
409
        <p>
410
          {isReadMoreActive ? fullText : shortenedText}
5579 stevensc 411
          <span className="cursor-pointer" onClick={readMoreHandler}>
5414 stevensc 412
            {isReadMoreActive ? labels.READ_LESS : labels.READ_MORE}
4017 stevensc 413
          </span>
414
        </p>
5115 stevensc 415
      )
4017 stevensc 416
    }
417
    return <p>{fullText}</p>
5115 stevensc 418
  }
4017 stevensc 419
 
420
  return (
421
    <div className="shared-post-bar">
422
      <div className="post-bar">
423
        <div className="post_topbar">
424
          <div className="usy-dt">
5579 stevensc 425
            <img src={image} alt="" style={{ width: '50px', height: 'auto' }} />
4017 stevensc 426
            <div className="usy-name">
427
              <h3>{name}</h3>
5579 stevensc 428
              <span>{timeElapse}</span>
4017 stevensc 429
            </div>
430
          </div>
431
        </div>
432
        <div className="job_descp">
5579 stevensc 433
          <div className="show-read-more">{htmlParsedText(description)}</div>
434
          {fileImage && (
435
            <img src={fileImage} className="Entradas" loading="lazy" />
436
          )}
437
          {fileVideo && (
4017 stevensc 438
            <video
439
              src={fileVideo}
440
              controls
441
              poster={fileImagePreview}
442
              preload="none"
443
            />
5579 stevensc 444
          )}
445
          {fileDocument && (
4017 stevensc 446
            <a href={fileDocument} target="_blank" rel="noreferrer">
5414 stevensc 447
              {labels.DOWNLOAD}
4017 stevensc 448
            </a>
5579 stevensc 449
          )}
4017 stevensc 450
        </div>
451
      </div>
452
    </div>
453
  )
454
}
455
 
456
Feed.SharedContent = SharedContent
457
Feed.Description = Description
458
Feed.Content = Content
459
 
5115 stevensc 460
export default React.memo(Feed)