Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

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