Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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