Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
5109 stevensc 1
/* eslint-disable camelcase */
4265 stevensc 2
/* eslint-disable react/prop-types */
4621 stevensc 3
import React, { useEffect, useRef, useState } from 'react'
4265 stevensc 4
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
5
import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'
6
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
7
import InputOption from './InputOption'
4270 stevensc 8
import parse from 'html-react-parser'
4265 stevensc 9
import Avatar from '../../../../shared/Avatar/Avatar'
5107 stevensc 10
import AccessTimeIcon from '@mui/icons-material/AccessTime'
4280 stevensc 11
import { axios } from '../../../../utils'
12
import { addNotification } from '../../../../redux/notification/notification.actions'
13
import { openShareModal } from '../../../../redux/share-modal/shareModal.actions'
14
import { shareModalTypes } from '../../../../redux/share-modal/shareModal.types'
15
import { feedTypes } from '../../../../redux/feed/feed.types'
16
import FeedCommentSection from '../../../components/feed/feed-comment/FeedCommentSection'
6390 stevensc 17
import { connect, useDispatch, useSelector } from 'react-redux'
4309 stevensc 18
import withExternalShare from './withExternalShare'
4621 stevensc 19
import ConfirmModal from '../../../../shared/confirm-modal/ConfirmModal'
20
import { deleteFeed } from '../../../../redux/feed/feed.actions'
5007 stevensc 21
import FeedModal from '../../../components/feed/FeedModal'
5946 stevensc 22
import withReactions from '../../../components/feed/withReaction'
23
import RecommendIcon from '@mui/icons-material/Recommend'
24
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
25
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
26
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
27
import TungstenIcon from '@mui/icons-material/Tungsten'
6390 stevensc 28
import SurveyForm from '../../../components/survey-form/SurveyForm'
4265 stevensc 29
 
5115 stevensc 30
const Feed = (props) => {
31
  const {
32
    isShare = false,
33
    feed_unique,
34
    feed_share_url,
35
    feed_share_external_url,
36
    feed_delete_url,
5946 stevensc 37
    feed_my_reaction,
38
    feed_save_reaction_recommended_url,
39
    feed_save_reaction_support_url,
40
    feed_save_reaction_love_url,
41
    feed_save_reaction_interest_url,
42
    feed_save_reaction_fun_url,
43
    feed_delete_reaction_url,
44
    feed_reactions,
5115 stevensc 45
    owner_url,
46
    owner_image,
47
    owner_name,
48
    owner_description,
49
    owner_shared,
50
    owner_comments,
51
    owner_time_elapse,
52
    owner_file_image_preview,
53
    owner_file_video,
54
    owner_file_image,
55
    owner_file_document,
56
    comment_add_url,
57
    comments,
58
    shared_name,
59
    shared_image,
60
    shared_time_elapse,
61
    shared_description,
62
    shared_file_video,
63
    shared_file_image_preview,
64
    shared_file_image,
65
    owner_external_shared,
66
    shared_file_document,
67
    shared_url,
68
    feed_increment_external_counter_url,
6391 stevensc 69
    feed_content_type,
6392 stevensc 70
    feed_vote_url,
5115 stevensc 71
    addNotification, // REDUX ACTION
5911 stevensc 72
    openShareModal, // REDUX ACTION
5115 stevensc 73
  } = props
5946 stevensc 74
  const [ownerReactions, setOwnerReaction] = useState(feed_reactions)
75
  const [currentReaction, setCurrentReaction] = useState(feed_my_reaction)
76
  const [totalReactions, setTotalReactions] = useState(0)
5107 stevensc 77
  const [totalComments, setTotalComments] = useState(owner_comments)
78
  const [externalShare, setExternalShare] = useState(owner_external_shared)
79
  const [sharedState, setSharedState] = useState(owner_shared)
80
  const [showComments, setShowComments] = useState(false)
81
  const [showModal, setShowModal] = useState(false)
6390 stevensc 82
  const labels = useSelector(({ labels }) => labels)
4271 stevensc 83
 
5946 stevensc 84
  const reactionsOptions = [
85
    {
86
      type: 'r',
87
      icon: <RecommendIcon style={{ color: '#7405f9' }} />,
88
    },
89
    {
90
      type: 's',
91
      icon: <VolunteerActivismIcon style={{ color: '#6495ED' }} />,
92
    },
93
    {
94
      type: 'l',
95
      icon: <FavoriteIcon style={{ color: '#DF704D' }} />,
96
    },
97
    {
98
      type: 'i',
99
      icon: (
100
        <TungstenIcon
101
          style={{ color: '#F5BB5C', transform: 'rotate(180deg)' }}
102
        />
103
      ),
104
    },
105
    {
106
      type: 'f',
107
      icon: <EmojiEmotionsIcon style={{ color: '#FF7F50' }} />,
108
    },
109
  ]
4278 stevensc 110
 
5911 stevensc 111
  const handleShare = () =>
112
    openShareModal(
113
      feed_share_url,
114
      shareModalTypes.SHARE,
115
      feedTypes.DASHBOARD,
116
      feed_unique
117
    )
4803 stevensc 118
  const handleExternalShare = (value) => setExternalShare(value)
4271 stevensc 119
 
4280 stevensc 120
  const displayCommentSection = () => setShowComments(!showComments)
4265 stevensc 121
 
5946 stevensc 122
  const saveReaction = async (type) => {
123
    const reactionTypesUrl = {
124
      r: feed_save_reaction_recommended_url,
125
      s: feed_save_reaction_support_url,
126
      l: feed_save_reaction_love_url,
127
      i: feed_save_reaction_interest_url,
128
      f: feed_save_reaction_fun_url,
129
    }
130
 
131
    await axios.post(reactionTypesUrl[type]).then((res) => {
132
      const { success, data } = res.data
133
 
134
      if (!success) {
135
        addNotification({ style: 'danger', msg: data })
136
      }
137
 
138
      setOwnerReaction(data.reactions)
139
      setCurrentReaction(type)
140
    })
141
  }
142
 
143
  const deleteReaction = async () => {
144
    await axios.post(feed_delete_reaction_url).then((res) => {
145
      const { success, data } = res.data
146
 
147
      if (!success) {
148
        addNotification({ style: 'danger', msg: data })
149
        return
150
      }
151
 
152
      setOwnerReaction(data.reactions)
153
      setCurrentReaction('')
154
    })
155
  }
156
 
5911 stevensc 157
  const ExternalShareButton = withExternalShare(
158
    InputOption,
159
    feed_share_external_url,
160
    {
161
      Icon: SendOutlinedIcon,
162
      color: 'gray',
163
      title: 'Send',
164
      shareUrl: feed_increment_external_counter_url,
165
      setValue: handleExternalShare,
166
      withTitle: true,
167
    }
168
  )
4285 stevensc 169
 
5946 stevensc 170
  const WithReactionIcon = withReactions(InputOption, {
171
    onSelect: saveReaction,
172
    onDelete: deleteReaction,
173
    myReaction: currentReaction,
174
    withTitle: true,
175
  })
176
 
5107 stevensc 177
  useEffect(() => setSharedState(owner_shared), [owner_shared])
4698 stevensc 178
 
5946 stevensc 179
  useEffect(() => {
5947 stevensc 180
    const feedReactions = ownerReactions?.reduce(
5946 stevensc 181
      (acc, reaction) => acc + Number(reaction.total),
182
 
183
    )
184
    setTotalReactions(feedReactions)
185
  }, [ownerReactions])
186
 
4280 stevensc 187
  return (
5007 stevensc 188
    <>
5911 stevensc 189
      {showModal && (
190
        <FeedModal
191
          isShow={true}
192
          feed={props}
193
          handleClose={() => setShowModal(false)}
194
        />
195
      )}
196
      <div className="feed">
5007 stevensc 197
        <Feed.Header
198
          image={owner_image}
199
          name={owner_name}
200
          timeElapsed={owner_time_elapse}
201
          viewUrl={owner_url}
202
          deleteUrl={feed_delete_url}
203
          feedUnique={feed_unique}
4280 stevensc 204
        />
4698 stevensc 205
 
5911 stevensc 206
        <div
207
          className="feed__body"
208
          onClick={() =>
209
            (owner_file_image || owner_file_video || owner_file_document) &&
210
            setShowModal(true)
211
          }
212
        >
5007 stevensc 213
          <Feed.Content
6390 stevensc 214
            description={owner_description}
215
            image={owner_file_image}
216
            imagePreview={owner_file_image_preview}
217
            video={owner_file_video}
218
            document={owner_file_document}
5007 stevensc 219
            sharedItem={{
220
              name: shared_name,
221
              image: shared_image,
222
              time_elapse: shared_time_elapse,
223
              description: shared_description,
224
              file_video: shared_file_video,
225
              file_image_preview: shared_file_image_preview,
226
              file_image: shared_file_image,
227
              file_document: shared_file_document,
5911 stevensc 228
              shared_url,
5007 stevensc 229
            }}
6391 stevensc 230
            type={feed_content_type}
6392 stevensc 231
            voteUrl={feed_vote_url}
5007 stevensc 232
          />
4697 stevensc 233
        </div>
4265 stevensc 234
 
6400 stevensc 235
        {!isShare && feed_content_type !== 'fast-survey' && (
5007 stevensc 236
          <div className="px-3 d-flex align-items-center justify-content-between">
5946 stevensc 237
            <div className="reactions-counter">
238
              {reactionsOptions
239
                .filter((option) =>
240
                  ownerReactions.find(
241
                    (reaction) => reaction.reaction === option.type
242
                  )
243
                )
244
                .map((reaction) => reaction.icon)}
245
              <span>{totalReactions} reacciones</span>
246
            </div>
5911 stevensc 247
            <div
248
              className="d-inline-flex align-items-center"
249
              style={{ gap: '5px' }}
250
            >
251
              {!!totalComments && (
6457 stevensc 252
                <span>{`${totalComments} ${labels.COMMENTS?.toLowerCase()}`}</span>
5911 stevensc 253
              )}
254
              {!!sharedState && (
6457 stevensc 255
                <span>{`${sharedState} ${labels.SHARED?.toLowerCase()}`}</span>
5911 stevensc 256
              )}
257
              {!!externalShare && (
6457 stevensc 258
                <span>{`${externalShare} ${labels.SENDS?.toLowerCase()}`}</span>
5911 stevensc 259
              )}
5007 stevensc 260
            </div>
261
          </div>
5911 stevensc 262
        )}
5007 stevensc 263
 
6400 stevensc 264
        {!isShare && feed_content_type !== 'fast-survey' && (
5911 stevensc 265
          <div className="feed__buttons">
6400 stevensc 266
            <WithReactionIcon withTitle />
267
            <InputOption
268
              Icon={ChatOutlinedIcon}
269
              title={labels.COMMENT}
270
              color="gray"
271
              onClick={displayCommentSection}
272
              withTitle
273
            />
274
            <InputOption
275
              Icon={ShareOutlinedIcon}
276
              title={labels.SHARE}
277
              color="gray"
278
              onClick={handleShare}
279
              withTitle
280
            />
281
            <ExternalShareButton />
5007 stevensc 282
          </div>
5911 stevensc 283
        )}
5007 stevensc 284
 
5911 stevensc 285
        <div className="px-2 pb-2">
5007 stevensc 286
          <FeedCommentSection
287
            feedId={feed_unique}
288
            image={owner_image}
289
            addUrl={comment_add_url}
290
            updateTotalComments={(total) => setTotalComments(total)}
5948 stevensc 291
            currentComments={comments}
5007 stevensc 292
            isShow={showComments}
4310 stevensc 293
          />
294
        </div>
4322 stevensc 295
      </div>
5007 stevensc 296
    </>
4265 stevensc 297
  )
298
}
299
 
4280 stevensc 300
const Content = ({
6390 stevensc 301
  description,
302
  image,
303
  imagePreview,
304
  video,
305
  document,
5911 stevensc 306
  sharedItem,
6390 stevensc 307
  type,
6392 stevensc 308
  voteUrl,
4280 stevensc 309
}) => {
5107 stevensc 310
  const [isReadMoreActive, setIsReadMoreActive] = useState(false)
6390 stevensc 311
  const labels = useSelector(({ labels }) => labels)
4636 stevensc 312
 
313
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
314
 
315
  const htmlParsedText = (fullStringText) => {
316
    const fullText = parse(fullStringText)
317
    if (fullStringText.length > 500) {
5107 stevensc 318
      const shortenedString = fullStringText.substr(0, 500)
319
      const shortenedText = parse(`${shortenedString}... `)
4636 stevensc 320
      return (
4697 stevensc 321
        <>
4636 stevensc 322
          {isReadMoreActive ? fullText : shortenedText}
5911 stevensc 323
          <span className="cursor-pointer" onClick={readMoreHandler}>
6390 stevensc 324
            {isReadMoreActive ? labels.READ_LESS : labels.READ_MORE}
4636 stevensc 325
          </span>
4697 stevensc 326
        </>
5107 stevensc 327
      )
4636 stevensc 328
    }
329
    return <p>{fullText}</p>
330
  }
331
 
4280 stevensc 332
  return (
333
    <>
6390 stevensc 334
      {type !== 'fast-survey' ? (
335
        htmlParsedText(description)
336
      ) : (
337
        <SurveyForm
338
          active={description.active}
339
          question={description.question}
340
          answers={[
341
            description.answer1,
342
            description.answer2,
343
            description.answer3,
344
            description.answer4,
345
            description.answer5,
346
          ]}
6450 stevensc 347
          votes={
348
            description.votes1 && [
349
              description.votes1,
350
              description.votes2,
351
              description.votes3,
352
              description.votes4,
353
              description.votes5,
354
            ]
355
          }
6390 stevensc 356
          time={description.time_remaining}
6392 stevensc 357
          voteUrl={voteUrl}
6409 stevensc 358
          resultType={description.result_type}
4280 stevensc 359
        />
5911 stevensc 360
      )}
6390 stevensc 361
      {image && <img src={image} className="Entradas" loading="lazy" />}
362
      {video && (
363
        <video src={video} controls poster={imagePreview} preload="none" />
364
      )}
365
      {document && (
366
        <a href={document} target="_blank" rel="noreferrer">
367
          {labels.DOWNLOAD}
4280 stevensc 368
        </a>
5911 stevensc 369
      )}
370
      {sharedItem.name && (
5011 stevensc 371
        <div className="py-3 px-md-3">
4309 stevensc 372
          <Feed
4310 stevensc 373
            isShare={true}
4309 stevensc 374
            owner_name={sharedItem.name}
375
            owner_image={sharedItem.image}
376
            owner_time_elapse={sharedItem.time_elapse}
377
            owner_description={sharedItem.description}
378
            owner_file_video={sharedItem.file_video}
379
            owner_file_image_preview={sharedItem.file_image_preview}
380
            owner_file_image={sharedItem.file_image}
381
            owner_file_document={sharedItem.file_document}
4320 stevensc 382
            owner_url={sharedItem.shared_url}
4309 stevensc 383
          />
384
        </div>
5911 stevensc 385
      )}
4280 stevensc 386
    </>
387
  )
388
}
389
 
390
const Header = ({
4284 stevensc 391
  image = '',
392
  name = '',
393
  timeElapsed = '',
4320 stevensc 394
  deleteUrl = '',
395
  viewUrl = '',
5911 stevensc 396
  feedUnique = '',
4280 stevensc 397
}) => {
5107 stevensc 398
  const [showConfirmModal, setShowConfirmModal] = useState(false)
4621 stevensc 399
  const [displayOption, setDisplayOption] = useState(false)
5107 stevensc 400
  const deleteButton = useRef()
4621 stevensc 401
  const dispatch = useDispatch()
6390 stevensc 402
  const labels = useSelector(({ labels }) => labels)
4621 stevensc 403
 
5107 stevensc 404
  const handleShowConfirmModal = () => setShowConfirmModal(!showConfirmModal)
4621 stevensc 405
 
406
  const deleteFeedHandler = () => {
5911 stevensc 407
    axios.post(deleteUrl).then((res) => {
408
      const { data } = res
409
      if (!data.success) {
410
        dispatch(addNotification({ style: 'danger', msg: data.data }))
411
        return
412
      }
413
      dispatch(addNotification({ style: 'success', msg: data.data }))
414
      handleShowConfirmModal()
415
      dispatch(deleteFeed(feedUnique))
416
    })
5107 stevensc 417
  }
4621 stevensc 418
 
419
  useEffect(() => {
420
    const handleClickOutside = (event) => {
5911 stevensc 421
      if (
422
        deleteButton.current &&
423
        !deleteButton.current.contains(event.target)
424
      ) {
4621 stevensc 425
        setDisplayOption(false)
426
      }
427
    }
5107 stevensc 428
    document.addEventListener('mousedown', handleClickOutside)
4621 stevensc 429
 
430
    return () => {
5107 stevensc 431
      document.removeEventListener('mousedown', handleClickOutside)
432
    }
433
  }, [deleteButton])
4621 stevensc 434
 
4280 stevensc 435
  return (
5911 stevensc 436
    <div className="feed__header">
4623 stevensc 437
      <div className="d-inline-flex" style={{ gap: '.5rem' }}>
5911 stevensc 438
        <Avatar imageUrl={image} name={name} size="xl" />
4623 stevensc 439
 
5911 stevensc 440
        <div className="feed__info">
4623 stevensc 441
          <a href={viewUrl}>
442
            <h2>{name}</h2>
443
          </a>
5911 stevensc 444
          <div className="time__elapse">
445
            <p>{timeElapsed}</p>
446
            <AccessTimeIcon className="time__elapse-icon" />
4623 stevensc 447
          </div>
4280 stevensc 448
        </div>
449
      </div>
4623 stevensc 450
 
5911 stevensc 451
      {deleteUrl && (
4623 stevensc 452
        <div className="cursor-pointer d-flex align-items-center position-relative">
4621 stevensc 453
          <img
5911 stevensc 454
            src="/images/icons/options.png"
455
            className="cursor-pointer img-icon options"
4621 stevensc 456
            onClick={() => setDisplayOption(!displayOption)}
457
          />
458
          <div className={`feed-options ${displayOption ? 'active' : ''}`}>
459
            <ul>
460
              <li>
461
                <button
462
                  className="option-btn"
463
                  onClick={handleShowConfirmModal}
464
                  ref={deleteButton}
465
                >
466
                  <i className="fa fa-trash-o mr-1" />
6390 stevensc 467
                  {labels.DELETE}
4621 stevensc 468
                </button>
469
              </li>
470
            </ul>
471
          </div>
472
          <ConfirmModal
473
            show={showConfirmModal}
474
            onClose={() => handleShowConfirmModal(false)}
475
            onAccept={deleteFeedHandler}
6390 stevensc 476
            acceptLabel={labels.ACCEPT}
4621 stevensc 477
          />
5911 stevensc 478
        </div>
479
      )}
4280 stevensc 480
    </div>
481
  )
482
}
483
 
484
Feed.Content = Content
485
Feed.Header = Header
486
 
4281 stevensc 487
const mapDispatchToProps = {
488
  addNotification: (notification) => addNotification(notification),
5911 stevensc 489
  openShareModal: (postUrl, modalType, feedType) =>
490
    openShareModal(postUrl, modalType, feedType),
5107 stevensc 491
}
4281 stevensc 492
 
5107 stevensc 493
export default connect(null, mapDispatchToProps)(Feed)