Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
6830 stevensc 1
import React, { useEffect, useRef, useState } from 'react'
2
import { axios } from '../../../utils'
3
import { feedTypes } from '../../../redux/feed/feed.types'
4
import { deleteFeed } from '../../../redux/feed/feed.actions'
5
import { openShareModal } from '../../../redux/share-modal/shareModal.actions'
6
import { shareModalTypes } from '../../../redux/share-modal/shareModal.types'
7
import { addNotification } from '../../../redux/notification/notification.actions'
8
import { connect, useDispatch, useSelector } from 'react-redux'
9
import parse from 'html-react-parser'
10
import TungstenIcon from '@mui/icons-material/Tungsten'
11
import FavoriteIcon from '@mui/icons-material/FavoriteTwoTone'
12
import RecommendIcon from '@mui/icons-material/Recommend'
13
import AccessTimeIcon from '@mui/icons-material/AccessTime'
14
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
15
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
16
import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'
17
import EmojiEmotionsIcon from '@mui/icons-material/EmojiEmotions'
18
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism'
19
 
20
import InputOption from './InputOption'
21
import ConfirmModal from '../../modals/ConfirmModal'
22
import FeedCommentSection from '../CommentSection'
23
import withExternalShare from './withExternalShare'
24
import FeedModal from '../FeedModal'
25
import SurveyForm from '../../survey-form/SurveyForm'
26
 
6835 stevensc 27
import './Feed.scss'
7142 stevensc 28
import ReactionsButton from '../../UI/buttons/ReactionsButton'
7145 stevensc 29
import Options from '../../UI/Option'
30
import { Avatar } from '@mui/material'
6835 stevensc 31
 
6830 stevensc 32
const Feed = (props) => {
33
  const {
34
    isShare = false,
35
    feed_unique,
36
    feed_share_url,
37
    feed_share_external_url,
38
    feed_delete_url,
39
    feed_my_reaction,
40
    feed_reactions,
41
    owner_url,
7136 stevensc 42
    image,
6830 stevensc 43
    owner_image,
44
    owner_name,
45
    owner_description,
46
    owner_shared,
47
    owner_comments,
48
    owner_time_elapse,
49
    owner_file_image_preview,
50
    owner_file_video,
51
    owner_file_image,
52
    owner_file_document,
53
    comment_add_url,
54
    comments,
55
    shared_name,
56
    shared_image,
57
    shared_time_elapse,
58
    shared_description,
59
    shared_file_video,
60
    shared_file_image_preview,
61
    shared_file_image,
62
    owner_external_shared,
63
    shared_file_document,
64
    shared_url,
65
    feed_increment_external_counter_url,
66
    feed_content_type,
67
    feed_vote_url,
7144 stevensc 68
    feed_save_reaction_url,
69
    feed_delete_reaction_url,
6830 stevensc 70
    openShareModal, // REDUX ACTION
71
  } = props
72
  const [ownerReactions, setOwnerReaction] = useState(feed_reactions)
73
  const [totalReactions, setTotalReactions] = useState(0)
74
  const [totalComments, setTotalComments] = useState(owner_comments)
75
  const [externalShare, setExternalShare] = useState(owner_external_shared)
76
  const [sharedState, setSharedState] = useState(owner_shared)
77
  const [showComments, setShowComments] = useState(false)
78
  const [showModal, setShowModal] = useState(false)
6832 stevensc 79
  const labels = useSelector(({ intl }) => intl.labels)
6830 stevensc 80
 
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
  ]
107
 
108
  const handleShare = () =>
109
    openShareModal(
110
      feed_share_url,
111
      shareModalTypes.SHARE,
112
      feedTypes.DASHBOARD,
113
      feed_unique
114
    )
115
  const handleExternalShare = (value) => setExternalShare(value)
116
 
117
  const displayCommentSection = () => setShowComments(!showComments)
118
 
119
  const ExternalShareButton = withExternalShare(
120
    InputOption,
121
    feed_share_external_url,
122
    {
123
      Icon: SendOutlinedIcon,
124
      color: 'gray',
125
      title: 'Send',
126
      shareUrl: feed_increment_external_counter_url,
127
      setValue: handleExternalShare,
128
      withTitle: true,
129
    }
130
  )
131
 
132
  useEffect(() => setSharedState(owner_shared), [owner_shared])
133
 
134
  useEffect(() => {
135
    const feedReactions = ownerReactions?.reduce(
136
      (acc, reaction) => acc + Number(reaction.total),
137
 
138
    )
139
    setTotalReactions(feedReactions)
140
  }, [ownerReactions])
141
 
142
  return (
143
    <>
144
      {showModal && (
145
        <FeedModal
146
          isShow={true}
147
          feed={props}
148
          handleClose={() => setShowModal(false)}
149
        />
150
      )}
151
      <div className="feed">
152
        <Feed.Header
153
          image={owner_image}
154
          name={owner_name}
155
          timeElapsed={owner_time_elapse}
156
          viewUrl={owner_url}
157
          deleteUrl={feed_delete_url}
158
          feedUnique={feed_unique}
159
        />
160
 
161
        <div
162
          className="feed__body"
163
          onClick={() =>
164
            (owner_file_image || owner_file_video || owner_file_document) &&
165
            setShowModal(true)
166
          }
167
        >
168
          <Feed.Content
169
            description={owner_description}
170
            image={owner_file_image}
171
            imagePreview={owner_file_image_preview}
172
            video={owner_file_video}
173
            document={owner_file_document}
174
            sharedItem={{
175
              name: shared_name,
176
              image: shared_image,
177
              time_elapse: shared_time_elapse,
178
              description: shared_description,
179
              file_video: shared_file_video,
180
              file_image_preview: shared_file_image_preview,
181
              file_image: shared_file_image,
182
              file_document: shared_file_document,
183
              shared_url,
184
            }}
185
            type={feed_content_type}
186
            voteUrl={feed_vote_url}
187
          />
188
        </div>
189
 
190
        {!isShare && feed_content_type !== 'fast-survey' && (
191
          <div className="px-3 d-flex align-items-center justify-content-between">
192
            <div className="reactions-counter">
193
              {reactionsOptions
194
                .filter((option) =>
195
                  ownerReactions.find(
196
                    (reaction) => reaction.reaction === option.type
197
                  )
198
                )
199
                .map((reaction) => reaction.icon)}
200
              <span>{totalReactions} reacciones</span>
201
            </div>
202
            <div
203
              className="d-inline-flex align-items-center"
204
              style={{ gap: '5px' }}
205
            >
206
              {!!totalComments && (
6832 stevensc 207
                <span>{`${totalComments} ${labels.comments?.toLowerCase()}`}</span>
6830 stevensc 208
              )}
209
              {!!sharedState && (
6832 stevensc 210
                <span>{`${sharedState} ${labels.shared?.toLowerCase()}`}</span>
6830 stevensc 211
              )}
212
              {!!externalShare && (
6832 stevensc 213
                <span>{`${externalShare} ${labels.sends?.toLowerCase()}`}</span>
6830 stevensc 214
              )}
215
            </div>
216
          </div>
217
        )}
218
 
219
        {!isShare && feed_content_type !== 'fast-survey' && (
220
          <div className="feed__buttons">
7142 stevensc 221
            <ReactionsButton
7143 stevensc 222
              className="feed__share-option position-relative"
7142 stevensc 223
              currentReaction={feed_my_reaction}
7144 stevensc 224
              saveUrl={feed_save_reaction_url}
225
              deleteUrl={feed_delete_reaction_url}
7142 stevensc 226
              onChange={(reactions) => setOwnerReaction(reactions)}
227
              withLabel
228
            />
6830 stevensc 229
            <InputOption
230
              Icon={ChatOutlinedIcon}
6832 stevensc 231
              title={labels.comment}
6830 stevensc 232
              color="gray"
233
              onClick={displayCommentSection}
234
              withTitle
235
            />
236
            <InputOption
237
              Icon={ShareOutlinedIcon}
6832 stevensc 238
              title={labels.share}
6830 stevensc 239
              color="gray"
240
              onClick={handleShare}
241
              withTitle
242
            />
243
            <ExternalShareButton />
244
          </div>
245
        )}
246
 
247
        <div className="px-2 pb-2">
248
          <FeedCommentSection
249
            feedId={feed_unique}
7136 stevensc 250
            image={image}
6830 stevensc 251
            addUrl={comment_add_url}
252
            updateTotalComments={(total) => setTotalComments(total)}
253
            currentComments={comments}
254
            isShow={showComments}
255
          />
256
        </div>
257
      </div>
258
    </>
259
  )
260
}
261
 
262
const Content = ({
263
  description,
264
  image,
265
  imagePreview,
266
  video,
267
  document,
268
  sharedItem,
269
  type,
270
  voteUrl,
271
}) => {
7147 stevensc 272
  const [readMore, setReadMore] = useState(false)
6832 stevensc 273
  const labels = useSelector(({ intl }) => intl.labels)
6830 stevensc 274
 
7147 stevensc 275
  const onReadMore = () => {
276
    setReadMore(!readMore)
277
  }
6830 stevensc 278
 
6831 stevensc 279
  const htmlParsedText = (fullStringText = '') => {
6830 stevensc 280
    const fullText = parse(fullStringText)
281
    if (fullStringText.length > 500) {
282
      const shortenedString = fullStringText.substr(0, 500)
283
      const shortenedText = parse(`${shortenedString}... `)
284
      return (
285
        <>
7147 stevensc 286
          {readMore ? fullText : shortenedText}
287
          <span className="cursor-pointer" onClick={onReadMore}>
288
            {readMore ? labels.read_less : labels.read_more}
6830 stevensc 289
          </span>
290
        </>
291
      )
292
    }
293
    return <p>{fullText}</p>
294
  }
295
 
296
  return (
297
    <>
298
      {type !== 'fast-survey' ? (
299
        htmlParsedText(description)
300
      ) : (
301
        <SurveyForm
302
          active={description.active}
303
          question={description.question}
304
          answers={[
305
            description.answer1,
306
            description.answer2,
307
            description.answer3,
308
            description.answer4,
309
            description.answer5,
310
          ]}
311
          votes={
312
            description.votes1 && [
313
              description.votes1,
314
              description.votes2,
315
              description.votes3,
316
              description.votes4,
317
              description.votes5,
318
            ]
319
          }
320
          time={description.time_remaining}
321
          voteUrl={voteUrl}
322
          resultType={description.result_type}
323
        />
324
      )}
325
      {image && <img src={image} className="Entradas" loading="lazy" />}
326
      {video && (
327
        <video src={video} controls poster={imagePreview} preload="none" />
328
      )}
329
      {document && (
7147 stevensc 330
        <a href={document} target="_blank" download rel="noreferrer">
7140 stevensc 331
          <img className="pdf" src="/images/extension/pdf.png" alt="pdf" />
6830 stevensc 332
        </a>
333
      )}
334
      {sharedItem.name && (
335
        <div className="py-3 px-md-3">
336
          <Feed
337
            isShare={true}
338
            owner_name={sharedItem.name}
339
            owner_image={sharedItem.image}
340
            owner_time_elapse={sharedItem.time_elapse}
341
            owner_description={sharedItem.description}
342
            owner_file_video={sharedItem.file_video}
343
            owner_file_image_preview={sharedItem.file_image_preview}
344
            owner_file_image={sharedItem.file_image}
345
            owner_file_document={sharedItem.file_document}
346
            owner_url={sharedItem.shared_url}
347
          />
348
        </div>
349
      )}
350
    </>
351
  )
352
}
353
 
354
const Header = ({
355
  image = '',
356
  name = '',
357
  timeElapsed = '',
358
  deleteUrl = '',
359
  viewUrl = '',
360
  feedUnique = '',
361
}) => {
362
  const [showConfirmModal, setShowConfirmModal] = useState(false)
6832 stevensc 363
  const labels = useSelector(({ intl }) => intl.labels)
7145 stevensc 364
  const options = useRef([])
6830 stevensc 365
  const dispatch = useDispatch()
366
 
7145 stevensc 367
  const toggleConfirm = () => {
368
    setShowConfirmModal(!showConfirmModal)
369
  }
6830 stevensc 370
 
7145 stevensc 371
  const onDelete = () => {
372
    axios.post(deleteUrl).then((response) => {
373
      const { data, success } = response.data
374
 
375
      if (!success) {
376
        dispatch(addNotification({ style: 'danger', msg: data }))
6830 stevensc 377
        return
378
      }
7145 stevensc 379
 
6830 stevensc 380
      dispatch(deleteFeed(feedUnique))
7145 stevensc 381
      toggleConfirm()
382
      dispatch(addNotification({ style: 'success', msg: data }))
6830 stevensc 383
    })
384
  }
385
 
386
  useEffect(() => {
7145 stevensc 387
    if (deleteUrl) {
388
      const deleteOption = { action: toggleConfirm, label: labels.delete }
389
      options.current.concat(deleteOption)
6830 stevensc 390
    }
7145 stevensc 391
  }, [deleteUrl])
6830 stevensc 392
 
393
  return (
394
    <div className="feed__header">
7145 stevensc 395
      <div className="d-inline-flex">
396
        <Avatar src={image} alt={name} sx={{ width: '60px', height: '60px' }} />
6830 stevensc 397
        <div className="feed__info">
398
          <a href={viewUrl}>
399
            <h2>{name}</h2>
400
          </a>
401
          <div className="time__elapse">
402
            <p>{timeElapsed}</p>
403
            <AccessTimeIcon className="time__elapse-icon" />
404
          </div>
405
        </div>
406
      </div>
7146 stevensc 407
      <Options options={options.current} />
7145 stevensc 408
      <ConfirmModal
409
        show={showConfirmModal}
410
        onClose={toggleConfirm}
411
        onAccept={onDelete}
412
      />
6830 stevensc 413
    </div>
414
  )
415
}
416
 
417
Feed.Content = Content
418
Feed.Header = Header
419
 
420
const mapDispatchToProps = {
421
  addNotification: (notification) => addNotification(notification),
422
  openShareModal: (postUrl, modalType, feedType) =>
423
    openShareModal(postUrl, modalType, feedType),
424
}
425
 
426
export default connect(null, mapDispatchToProps)(Feed)