Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
4265 stevensc 1
/* eslint-disable react/prop-types */
4621 stevensc 2
import React, { useEffect, useRef, useState } from 'react'
4265 stevensc 3
import ThumbUpAltOutlinedIcon from '@mui/icons-material/ThumbUpAltOutlined'
4280 stevensc 4
import ThumbUpAltIcon from '@mui/icons-material/ThumbUpAlt'
4265 stevensc 5
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
6
import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'
7
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
4695 stevensc 8
import RecommendIcon from '@mui/icons-material/Recommend';
4265 stevensc 9
import InputOption from './InputOption'
4270 stevensc 10
import parse from 'html-react-parser'
4265 stevensc 11
import Avatar from '../../../../shared/Avatar/Avatar'
4271 stevensc 12
import AccessTimeIcon from '@mui/icons-material/AccessTime';
4280 stevensc 13
import { axios } from '../../../../utils'
14
import { addNotification } from '../../../../redux/notification/notification.actions'
15
import { openShareModal } from '../../../../redux/share-modal/shareModal.actions'
16
import { shareModalTypes } from '../../../../redux/share-modal/shareModal.types'
17
import { feedTypes } from '../../../../redux/feed/feed.types'
18
import FeedCommentSection from '../../../components/feed/feed-comment/FeedCommentSection'
4621 stevensc 19
import { connect, useDispatch } from 'react-redux'
4309 stevensc 20
import withExternalShare from './withExternalShare'
4621 stevensc 21
import ConfirmModal from '../../../../shared/confirm-modal/ConfirmModal'
22
import { deleteFeed } from '../../../../redux/feed/feed.actions'
4265 stevensc 23
 
4271 stevensc 24
const Feed = ({
4310 stevensc 25
  isShare = false,
4280 stevensc 26
  feed_unique,
4271 stevensc 27
  feed_is_liked,
28
  feed_like_url,
29
  feed_unlike_url,
30
  feed_share_url,
31
  feed_share_external_url,
32
  feed_delete_url,
33
  feed_likes,
34
  owner_url,
35
  owner_image,
36
  owner_name,
37
  owner_description,
38
  owner_shared,
39
  owner_comments,
40
  owner_time_elapse,
41
  owner_file_image_preview,
42
  owner_file_video,
43
  owner_file_image,
44
  owner_file_document,
45
  comment_add_url,
4282 stevensc 46
  comments,
4295 stevensc 47
  shared_name,
48
  shared_image,
49
  shared_time_elapse,
50
  shared_description,
51
  shared_file_video,
52
  shared_file_image_preview,
53
  shared_file_image,
4803 stevensc 54
  owner_external_shared,
4295 stevensc 55
  shared_file_document,
4320 stevensc 56
  shared_url,
4802 stevensc 57
  feed_increment_external_counter_url,
4282 stevensc 58
  addNotification, // REDUX ACTION
59
  openShareModal, // REDUX ACTION
4271 stevensc 60
}) => {
4265 stevensc 61
 
4280 stevensc 62
  const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
63
  const [likesState, setLikesState] = useState(feed_likes);
64
  const [totalComments, setTotalComments] = useState(owner_comments);
4802 stevensc 65
  const [externalShare, setExternalShare] = useState(owner_external_shared);
4280 stevensc 66
  const [sharedState, setSharedState] = useState(owner_shared);
67
  const [showComments, setShowComments] = useState(false);
4271 stevensc 68
 
4280 stevensc 69
  const handleLike = (url) => {
70
    axios.post(url)
71
      .then(({ data: response }) => {
72
        if (!response.success) {
73
          addNotification({ style: "danger", msg: response.data })
74
          return
75
        }
76
        setLikesState(response.data.likes)
77
        setFeedIsLiked(!feedIsLiked);
78
      });
79
  };
4278 stevensc 80
 
4280 stevensc 81
  const handleShare = () => openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique)
4803 stevensc 82
  const handleExternalShare = (value) => setExternalShare(value)
4271 stevensc 83
 
4280 stevensc 84
  const displayCommentSection = () => setShowComments(!showComments)
4265 stevensc 85
 
4807 stevensc 86
  const ExternalShareButton = withExternalShare(InputOption, feed_share_external_url, {
4806 stevensc 87
    Icon: SendOutlinedIcon,
88
     color: 'gray',
89
     title: 'Send',
4807 stevensc 90
     shareUrl: feed_increment_external_counter_url,
4806 stevensc 91
     setValue: handleExternalShare
92
     })
4285 stevensc 93
 
4698 stevensc 94
  useEffect(() => setSharedState(owner_shared), [owner_shared]);
95
 
4280 stevensc 96
  return (
97
    <div className='feed'>
98
 
99
      <Feed.Header
100
        image={owner_image}
101
        name={owner_name}
102
        timeElapsed={owner_time_elapse}
4320 stevensc 103
        viewUrl={owner_url}
4284 stevensc 104
        deleteUrl={feed_delete_url}
4621 stevensc 105
        feedUnique={feed_unique}
4280 stevensc 106
      />
107
 
4265 stevensc 108
      <div className='feed__body'>
4280 stevensc 109
        <Feed.Content
110
          ownerDescription={owner_description}
111
          ownerFileImage={owner_file_image}
112
          ownerFileImagepreview={owner_file_image_preview}
113
          ownerFileVideo={owner_file_video}
114
          ownerFileDocument={owner_file_document}
4295 stevensc 115
          sharedItem={{
116
            name: shared_name,
117
            image: shared_image,
118
            time_elapse: shared_time_elapse,
119
            description: shared_description,
120
            file_video: shared_file_video,
121
            file_image_preview: shared_file_image_preview,
122
            file_image: shared_file_image,
4320 stevensc 123
            file_document: shared_file_document,
124
            shared_url: shared_url
4295 stevensc 125
          }}
4280 stevensc 126
        />
4265 stevensc 127
      </div>
4698 stevensc 128
 
129
      {!isShare &&
130
        <div className="px-3 d-flex align-items-center justify-content-between">
131
          {!!likesState &&
132
            <div className="d-inline-flex align-items-center" style={{ gap: '.5rem' }}>
133
              <RecommendIcon style={{ color: '#7405f9' }} />
134
              <span>{likesState}</span>
135
            </div>}
136
          <div className="d-inline-flex align-items-center" style={{ gap: '5px' }}>
137
            {!!totalComments && <span>{`${totalComments} comentarios`}</span>}
4802 stevensc 138
            {!!sharedState && <span>{`${sharedState} compartidos`}</span>}
139
            {!!externalShare && <span>{`${externalShare} enviados`}</span>}
4698 stevensc 140
          </div>
4697 stevensc 141
        </div>
4698 stevensc 142
      }
4265 stevensc 143
 
4310 stevensc 144
      {
145
        !isShare &&
146
        <div className='feed__buttons'>
147
          <InputOption
148
            Icon={feedIsLiked ? ThumbUpAltIcon : ThumbUpAltOutlinedIcon}
149
            title='Like'
150
            color={feedIsLiked ? '#7405f9' : 'gray'}
151
            onClick={() => handleLike(feedIsLiked ? feed_unlike_url : feed_like_url)}
152
          />
153
          <InputOption
154
            Icon={ChatOutlinedIcon}
155
            title='Comment'
156
            color='gray'
157
            onClick={displayCommentSection}
158
          />
159
          <InputOption
160
            Icon={ShareOutlinedIcon}
161
            title='Share'
162
            color='gray'
163
            onClick={handleShare}
164
          />
165
          <ExternalShareButton />
166
        </div>
167
      }
4265 stevensc 168
 
4322 stevensc 169
      <div className='px-2 pb-2'>
170
        <FeedCommentSection
171
          feedId={feed_unique}
172
          image={owner_image}
173
          addUrl={comment_add_url}
174
          updateTotalComments={(total) => setTotalComments(total)}
175
          comments={comments}
176
          isShow={showComments}
177
        />
178
      </div>
4280 stevensc 179
 
4265 stevensc 180
    </div>
181
  )
182
}
183
 
4280 stevensc 184
const Content = ({
185
  ownerDescription,
186
  ownerFileImage,
187
  ownerFileImagepreview,
188
  ownerFileVideo,
4295 stevensc 189
  ownerFileDocument,
190
  sharedItem
4280 stevensc 191
}) => {
4636 stevensc 192
  const [isReadMoreActive, setIsReadMoreActive] = useState(false);
193
 
194
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
195
 
196
  const htmlParsedText = (fullStringText) => {
197
    const fullText = parse(fullStringText)
198
    if (fullStringText.length > 500) {
199
      const shortenedString = fullStringText.substr(0, 500);
200
      const shortenedText = parse(`${shortenedString}... `);
201
      return (
4697 stevensc 202
        <>
4636 stevensc 203
          {isReadMoreActive ? fullText : shortenedText}
204
          <span className='cursor-pointer' onClick={readMoreHandler}>
205
            {isReadMoreActive ? " Leer menos" : " Leer más"}
206
          </span>
4697 stevensc 207
        </>
4636 stevensc 208
      );
209
    }
210
    return <p>{fullText}</p>
211
  }
212
 
4280 stevensc 213
  return (
214
    <>
4636 stevensc 215
      {ownerDescription && htmlParsedText(ownerDescription)}
4280 stevensc 216
      {ownerFileImage &&
217
        <img src={ownerFileImage} className="Entradas" loading='lazy' />
218
      }
219
      {ownerFileVideo &&
220
        <video
221
          src={ownerFileVideo}
222
          controls
223
          poster={ownerFileImagepreview}
224
          preload="none"
225
        />
226
      }
227
      {ownerFileDocument &&
228
        <a href={ownerFileDocument} target="_blank" rel="noreferrer">
229
          Descargar
230
        </a>
231
      }
4295 stevensc 232
      {sharedItem.name &&
4309 stevensc 233
        <div className="p-3">
234
          <Feed
4310 stevensc 235
            isShare={true}
4309 stevensc 236
            owner_name={sharedItem.name}
237
            owner_image={sharedItem.image}
238
            owner_time_elapse={sharedItem.time_elapse}
239
            owner_description={sharedItem.description}
240
            owner_file_video={sharedItem.file_video}
241
            owner_file_image_preview={sharedItem.file_image_preview}
242
            owner_file_image={sharedItem.file_image}
243
            owner_file_document={sharedItem.file_document}
4320 stevensc 244
            owner_url={sharedItem.shared_url}
4309 stevensc 245
          />
246
        </div>
4295 stevensc 247
      }
4280 stevensc 248
    </>
249
  )
250
}
251
 
252
const Header = ({
4284 stevensc 253
  image = '',
254
  name = '',
255
  timeElapsed = '',
4320 stevensc 256
  deleteUrl = '',
257
  viewUrl = '',
4621 stevensc 258
  feedUnique = ''
4280 stevensc 259
}) => {
4621 stevensc 260
  const [showConfirmModal, setShowConfirmModal] = useState(false);
261
  const [displayOption, setDisplayOption] = useState(false)
262
  const deleteButton = useRef();
263
  const dispatch = useDispatch()
264
 
265
  const handleShowConfirmModal = () => setShowConfirmModal(!showConfirmModal);
266
 
267
  const deleteFeedHandler = () => {
268
    axios.post(deleteUrl)
269
      .then((res) => {
270
        const { data } = res
271
        if (!data.success) {
272
          dispatch(addNotification({ style: "danger", msg: data.data }))
273
          return
274
        }
275
        dispatch(addNotification({ style: "success", msg: data.data }))
276
        handleShowConfirmModal()
277
        dispatch(deleteFeed(feedUnique));
278
      });
279
  };
280
 
281
  useEffect(() => {
282
    const handleClickOutside = (event) => {
283
      if (deleteButton.current && !deleteButton.current.contains(event.target)) {
284
        setDisplayOption(false)
285
      }
286
    }
287
    document.addEventListener("mousedown", handleClickOutside);
288
 
289
    return () => {
290
      document.removeEventListener("mousedown", handleClickOutside);
291
    };
292
  }, [deleteButton]);
293
 
4280 stevensc 294
  return (
295
    <div className='feed__header'>
4623 stevensc 296
      <div className="d-inline-flex" style={{ gap: '.5rem' }}>
297
        <Avatar
298
          imageUrl={image}
299
          name={name}
300
          size='xl'
301
        />
302
 
303
        <div className='feed__info'>
304
          <a href={viewUrl}>
305
            <h2>{name}</h2>
306
          </a>
307
          <div className='time__elapse'>
308
            <p>
309
              {timeElapsed}
310
            </p>
311
            <AccessTimeIcon className='time__elapse-icon' />
312
          </div>
4280 stevensc 313
        </div>
4623 stevensc 314
 
4280 stevensc 315
      </div>
4623 stevensc 316
 
4621 stevensc 317
      {deleteUrl &&
4623 stevensc 318
        <div className="cursor-pointer d-flex align-items-center position-relative">
4621 stevensc 319
          <img
320
            src='/images/icons/options.png'
321
            className='cursor-pointer img-icon options'
322
            onClick={() => setDisplayOption(!displayOption)}
323
          />
324
          <div className={`feed-options ${displayOption ? 'active' : ''}`}>
325
            <ul>
326
              <li>
327
                <button
328
                  className="option-btn"
329
                  onClick={handleShowConfirmModal}
330
                  ref={deleteButton}
331
                >
332
                  <i className="fa fa-trash-o mr-1" />
333
                  Borrar
334
                </button>
335
              </li>
336
            </ul>
337
          </div>
338
          <ConfirmModal
339
            show={showConfirmModal}
340
            onClose={() => handleShowConfirmModal(false)}
341
            onAccept={deleteFeedHandler}
342
            acceptLabel="Aceptar"
343
          />
344
        </div>}
4280 stevensc 345
    </div>
346
  )
347
}
348
 
349
Feed.Content = Content
350
Feed.Header = Header
351
 
4281 stevensc 352
const mapDispatchToProps = {
353
  addNotification: (notification) => addNotification(notification),
4282 stevensc 354
  openShareModal: (postUrl, modalType, feedType) => openShareModal(postUrl, modalType, feedType),
4281 stevensc 355
};
356
 
357
export default connect(null, mapDispatchToProps)(Feed)