Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
735 stevensc 1
import React, { useEffect, useState } from 'react'
2
import { axios } from '../../utils'
3
import { useLocation } from 'react-router-dom'
4
import { getBackendVars } from '../../services/backendVars'
5
import { addNotification } from '../../redux/notification/notification.actions'
6
import { useDispatch, useSelector } from 'react-redux'
740 stevensc 7
import { Container, Grid } from '@mui/material'
735 stevensc 8
import parse from 'html-react-parser'
5 stevensc 9
 
735 stevensc 10
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
11
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
5 stevensc 12
 
735 stevensc 13
import HomeNews from '../../components/widgets/default/HomeNews'
14
import withExternalShare from '../../components/dashboard/linkedin/withExternalShare'
15
import Paraphrase from '../../components/UI/Paraphrase'
1507 stevensc 16
import WidgetWrapper from '../../components/widgets/WidgetLayout'
735 stevensc 17
import withReactions from '../../hocs/withReaction'
18
import MobileShare from '../../components/dashboard/linkedin/mobile-share/MobileShare'
1650 stevensc 19
import CommentForm from '@app/components/dashboard/linkedin/comments/comment-form'
20
import CommentsList from '@app/components/dashboard/linkedin/comments/comment-list'
2162 stevensc 21
import Button from '@app/components/UI/buttons/Buttons'
22
import FeedReactions from '@app/components/dashboard/linkedin/feed/FeedReactions'
2169 stevensc 23
import PostFile from '@app/components/post/PostFile'
520 stevensc 24
 
5 stevensc 25
const PostViewPage = () => {
735 stevensc 26
  const [post, setPost] = useState({})
27
  const [totalSends, setTotalSends] = useState(0)
28
  const [reactions, setReactions] = useState([])
29
  const [myReaction, setMyReaction] = useState('')
30
  const [isMobile, setIsMobile] = useState(false)
31
  const [comments, setComments] = useState([])
32
  const [showComments, setShowComments] = useState(false)
740 stevensc 33
  const { pathname } = useLocation()
735 stevensc 34
  const labels = useSelector(({ intl }) => intl.labels)
35
  const dispatch = useDispatch()
5 stevensc 36
 
37
  const displayCommentSection = () => {
735 stevensc 38
    setShowComments(!showComments)
39
  }
5 stevensc 40
 
41
  const getComments = () => {
42
    axios.get(post.comments_url).then((response) => {
735 stevensc 43
      const { data, success } = response.data
5 stevensc 44
 
45
      if (!success) {
46
        const errorMessage =
735 stevensc 47
          typeof data === 'string' ? data : 'Error interno. Intente más tarde.'
5 stevensc 48
 
735 stevensc 49
        dispatch(addNotification({ style: 'danger', msg: errorMessage }))
50
        return
5 stevensc 51
      }
52
 
735 stevensc 53
      setComments(data)
54
    })
55
  }
5 stevensc 56
 
57
  const handleExternalShare = (value) => {
735 stevensc 58
    setTotalSends(value)
59
  }
5 stevensc 60
 
2162 stevensc 61
  const ExternalShareButton = withExternalShare(Button, post.share_external_url)
5 stevensc 62
 
2162 stevensc 63
  const ReactionButton = withReactions(Button)
639 stevensc 64
 
735 stevensc 65
  const addComment = (comment) => {
1979 stevensc 66
    const formData = new FormData()
67
    formData.append('comment', comment)
68
 
69
    axios.post(post.comments_add_url, formData).then((response) => {
735 stevensc 70
      const { success, data } = response.data
5 stevensc 71
 
72
      if (!success) {
73
        const errorMessage =
735 stevensc 74
          typeof data === 'string' ? data : 'Error interno. Intente más tarde.'
5 stevensc 75
 
735 stevensc 76
        dispatch(addNotification({ style: 'danger', msg: errorMessage }))
77
        return
5 stevensc 78
      }
79
 
735 stevensc 80
      setComments((prevMessages) => [...prevMessages, data])
81
    })
82
  }
5 stevensc 83
 
84
  const deleteComment = (commentUnique, deleteCommentUrl) => {
85
    axios
86
      .post(deleteCommentUrl)
87
      .then((response) => {
735 stevensc 88
        const { success, data } = response.data
5 stevensc 89
 
90
        if (!success) {
91
          const errorMessage =
735 stevensc 92
            typeof data === 'string'
5 stevensc 93
              ? data
735 stevensc 94
              : 'Error interno. Intente más tarde.'
5 stevensc 95
 
735 stevensc 96
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
97
          return
5 stevensc 98
        }
99
 
100
        setComments((prevComments) =>
101
          prevComments.filter((comment) => comment.unique !== commentUnique)
735 stevensc 102
        )
103
        dispatch(addNotification({ style: 'success', msg: data }))
5 stevensc 104
      })
105
      .catch((error) => {
735 stevensc 106
        dispatch(addNotification({ style: 'danger', msg: error }))
107
        throw new Error(error)
108
      })
109
  }
5 stevensc 110
 
111
  useEffect(() => {
112
    getBackendVars(pathname)
113
      .then((post) => {
735 stevensc 114
        setMyReaction(post.my_reaction)
115
        setTotalSends(post.total_share_external)
2165 stevensc 116
        setReactions(post.reactions)
735 stevensc 117
        setPost(post)
5 stevensc 118
      })
520 stevensc 119
      .catch(() => {
5 stevensc 120
        dispatch(
121
          addNotification({
735 stevensc 122
            style: 'danger',
123
            message: 'Error interno. Por favor, inténtelo de nuevo más tarde.'
5 stevensc 124
          })
735 stevensc 125
        )
126
      })
127
  }, [pathname])
5 stevensc 128
 
129
  useEffect(() => {
2185 stevensc 130
    if (showComments && !!comments.length) getComments()
131
  }, [showComments, comments])
5 stevensc 132
 
133
  useEffect(() => {
735 stevensc 134
    const ua = navigator.userAgent.toLowerCase()
135
    const isAndroid = ua.includes('android')
639 stevensc 136
 
137
    if (isAndroid) {
735 stevensc 138
      setIsMobile(true)
639 stevensc 139
    }
735 stevensc 140
  }, [])
639 stevensc 141
 
5 stevensc 142
  return (
740 stevensc 143
    <Container as='main' className='px-0'>
144
      <Grid container spacing={2}>
145
        <Grid item xs={12} md={8}>
1507 stevensc 146
          <WidgetWrapper>
769 stevensc 147
            <img
148
              src={post.image}
149
              style={{
150
                width: '100%',
151
                maxHeight: '450px',
152
                objectFit: 'contain'
153
              }}
154
            />
1507 stevensc 155
            <WidgetWrapper.Body>
769 stevensc 156
              <h2>{post.title}</h2>
776 stevensc 157
              <Paraphrase>{post.description}</Paraphrase>
2169 stevensc 158
              <PostFile file={post.file} type={post.type} />
1507 stevensc 159
            </WidgetWrapper.Body>
740 stevensc 160
 
735 stevensc 161
            <div className='d-flex justify-content-between align-items-center px-3'>
2162 stevensc 162
              <FeedReactions
163
                reactions={reactions}
164
                reactionsUrl={post.reactions_url}
165
              />
166
 
5 stevensc 167
              {!!totalSends && (
168
                <span>{`${totalSends} ${labels.sends?.toLowerCase()}`}</span>
169
              )}
170
            </div>
740 stevensc 171
 
1507 stevensc 172
            <WidgetWrapper.Actions>
769 stevensc 173
              <ReactionButton
2164 stevensc 174
                currentReactionType={myReaction}
769 stevensc 175
                saveUrl={post.save_reaction_url}
176
                deleteUrl={post.delete_reaction_url}
2162 stevensc 177
                onReaction={({ reactions }, currentReaction) => {
769 stevensc 178
                  setReactions(reactions)
179
                  setMyReaction(currentReaction)
180
                }}
181
              />
774 stevensc 182
 
2162 stevensc 183
              <Button onClick={displayCommentSection}>
184
                <ChatOutlinedIcon style={{ color: 'gray' }} />
185
                {labels.comment}
186
              </Button>
187
 
777 stevensc 188
              {!isMobile ? (
189
                <ExternalShareButton
190
                  icon={SendOutlinedIcon}
191
                  iconColor='gray'
192
                  label={labels.send}
193
                  shareUrl={post.share_increment_external_counter_url}
194
                  setValue={handleExternalShare}
195
                />
196
              ) : (
197
                <MobileShare
198
                  shareData={{
199
                    title: 'Leaders Linked',
200
                    text: parse(post.description ?? ''),
201
                    url: post.share_external_url
202
                  }}
203
                >
204
                  <SendOutlinedIcon />
205
                  {labels.send}
206
                </MobileShare>
207
              )}
1507 stevensc 208
            </WidgetWrapper.Actions>
740 stevensc 209
 
5 stevensc 210
            {showComments && (
735 stevensc 211
              <div className='px-3 pb-2'>
5 stevensc 212
                <CommentForm onSubmit={addComment} />
213
                <CommentsList comments={comments} onDelete={deleteComment} />
735 stevensc 214
              </div>
5 stevensc 215
            )}
1507 stevensc 216
          </WidgetWrapper>
740 stevensc 217
        </Grid>
218
 
219
        <Grid item xs={12} md={4}>
776 stevensc 220
          <HomeNews currentPost={post.uuid} />
740 stevensc 221
        </Grid>
222
      </Grid>
5 stevensc 223
    </Container>
735 stevensc 224
  )
225
}
5 stevensc 226
 
2162 stevensc 227
export const renderContent = ({ type, file }) => {
228
  switch (type) {
229
    case 'video': {
2165 stevensc 230
      return (
231
        <video src={file} controls preload='none' controlsList='nodownload' />
232
      )
2162 stevensc 233
    }
234
 
235
    case 'image': {
236
      return <img src={file} />
237
    }
238
 
239
    case 'document': {
240
      return (
241
        <a href={file} target='_blank' rel='noreferrer'>
242
          <img className='pdf' src='/images/extension/pdf.png' alt='pdf' />
243
        </a>
244
      )
245
    }
2169 stevensc 246
 
2180 stevensc 247
    case 'audio': {
248
      return (
249
        <audio controls>
250
          <source src={file} />
251
        </audio>
252
      )
253
    }
254
 
2169 stevensc 255
    default: {
256
      return (
257
        <a href={file} target='_blank' rel='noreferrer'>
258
          <img className='pdf' src='/images/extension/pdf.png' alt='pdf' />
259
        </a>
260
      )
261
    }
2162 stevensc 262
  }
263
}
264
 
735 stevensc 265
export default PostViewPage