Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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