Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
720 stevensc 1
import React, { useRef, useState } from 'react'
2
import { axios } from '../../utils'
3
import { Avatar } from '@mui/material'
723 stevensc 4
import { useHistory } from 'react-router-dom'
720 stevensc 5
import { addNotification } from 'store/notification/notification.actions'
6
import { useDispatch, useSelector } from 'react-redux'
7
import styled from 'styled-components'
8
import Spinner from '../UI/Spinner'
9
import StyledContainer from '../widgets/WidgetLayout'
10
import ConfirmModal from '../modals/ConfirmModal'
11
import {
12
  AccountCircleOutlined,
13
  CancelOutlined,
14
  ChatOutlined,
15
  DeleteOutline,
16
  Done,
17
  Edit,
18
  LockOpenOutlined,
19
  LockOutlined,
20
  LogoutOutlined,
21
  OpenInNew,
22
  PersonAddOutlined,
23
  PersonRemoveOutlined,
24
  Remove,
25
  SupervisorAccountOutlined
26
} from '@mui/icons-material'
721 stevensc 27
import { device } from '../../styles/MediaQueries'
5 stevensc 28
 
29
const StyledSpinnerContainer = styled.div`
30
  position: absolute;
31
  left: 0;
32
  top: 0;
33
  width: 100%;
34
  height: 100%;
35
  background: rgba(255, 255, 255, 0.4);
36
  place-items: center;
496 stevensc 37
  z-index: 50;
720 stevensc 38
`
607 stevensc 39
 
613 stevensc 40
const StyledItemContainer = styled(StyledContainer)`
41
  display: flex;
42
  flex-direction: column;
43
  justify-content: center;
44
  height: 100%;
720 stevensc 45
  border-radius: 5px;
46
`
613 stevensc 47
 
607 stevensc 48
const StyledHeader = styled.div`
49
  align-items: center;
50
  display: flex;
51
  gap: 0.5rem;
663 andreina 52
  justify-content: flex-start;
607 stevensc 53
  position: relative;
663 andreina 54
  padding: 15px 5px;
720 stevensc 55
`
607 stevensc 56
 
611 stevensc 57
const StyledContent = styled.div`
58
  display: flex;
59
  flex-direction: column;
60
  text-align: center;
645 stevensc 61
  ul {
611 stevensc 62
    align-items: center;
63
    display: flex;
64
    justify-content: center;
721 stevensc 65
    gap: 0.5rem;
722 stevensc 66
    button {
721 stevensc 67
      align-items: center;
68
      border-radius: var(--border-radius);
69
      cursor: pointer;
70
      display: inline-flex;
71
      flex-direction: column;
72
      font-size: 0.9rem;
73
      padding: 5px;
74
      position: relative;
75
      &:hover {
76
        background-color: whitesmoke;
77
      }
78
      @media ${device.tablet} {
79
        flex-direction: row;
80
        gap: 0.5rem;
81
        font-size: 1rem;
82
      }
83
    }
611 stevensc 84
  }
720 stevensc 85
`
611 stevensc 86
 
848 stevensc 87
const Actions = styled.div`
88
  display: flex;
89
  justify-content: space-around;
90
  border-top: 1px solid rgb(211, 211, 211);
91
  padding: 5px;
92
  button {
93
    display: inline-flex;
94
    gap: 1rem;
95
    align-items: center;
96
    svg {
97
      font-size: 1rem;
98
    }
99
  }
100
`
101
 
607 stevensc 102
const StyledAvatar = styled(Avatar)`
665 andreina 103
  height: 60px !important;
720 stevensc 104
  width: 60px !important;
105
`
607 stevensc 106
 
5 stevensc 107
const ProfileItem = ({
108
  image,
109
  name,
110
  email,
111
  network,
112
  status,
113
  fetchCallback,
114
  link_remove,
115
  link_view,
116
  link_edit,
117
  link_delete,
118
  link_cancel,
119
  link_block,
120
  link_reject,
121
  link_accept,
122
  link_inmail,
123
  link_request,
124
  link_unblock,
125
  link_unfollow,
126
  link_approve,
127
  link_leave,
128
  link_admin,
129
  link_impersonate,
720 stevensc 130
  btnAcceptTitle = 'Ver',
131
  btnCancelTitle = 'Borrar',
132
  btnEditTitle = 'Editar',
133
  btnLeaveTitle = 'Dejar',
134
  isTopData
5 stevensc 135
}) => {
720 stevensc 136
  const [isShowConfirmation, setIsShowConfirmation] = useState(false)
137
  const [loading, setLoading] = useState(false)
138
  const confirmUrl = useRef('')
139
  const labels = useSelector(({ intl }) => intl.labels)
140
  const dispatch = useDispatch()
141
  const history = useHistory()
5 stevensc 142
 
720 stevensc 143
  const showConfirm = (url = '') => {
144
    setIsShowConfirmation(true)
145
    confirmUrl.current = url
146
  }
5 stevensc 147
 
496 stevensc 148
  const closeConfirm = () => {
720 stevensc 149
    setIsShowConfirmation(false)
150
    confirmUrl.current = ''
151
  }
5 stevensc 152
 
720 stevensc 153
  const getImpersonateUrl = async (url = '') => {
5 stevensc 154
    try {
720 stevensc 155
      const { data } = await axios.get(url)
156
      if (data.success) window.location.href = data.data
5 stevensc 157
    } catch (error) {
720 stevensc 158
      console.log('>>: error > ', error)
5 stevensc 159
    }
720 stevensc 160
  }
5 stevensc 161
 
162
  const onConfirm = (url) => {
720 stevensc 163
    setLoading(true)
5 stevensc 164
    axios
165
      .post(url)
166
      .then((response) => {
720 stevensc 167
        const { success, data } = response.data
5 stevensc 168
 
169
        if (!success) {
170
          const errorMessage =
720 stevensc 171
            typeof data === 'string'
5 stevensc 172
              ? data
720 stevensc 173
              : 'Error interno. Por favor, inténtelo de nuevo más tarde.'
5 stevensc 174
 
720 stevensc 175
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
176
          return
5 stevensc 177
        }
178
 
720 stevensc 179
        if (fetchCallback) fetchCallback()
180
        dispatch(addNotification({ style: 'success', msg: data }))
5 stevensc 181
      })
526 stevensc 182
      .catch(() => {
5 stevensc 183
        dispatch(
184
          addNotification({
720 stevensc 185
            style: 'error',
186
            msg: 'Error interno. Por favor, inténtelo de nuevo más tarde.'
5 stevensc 187
          })
720 stevensc 188
        )
5 stevensc 189
      })
190
      .finally(() => {
720 stevensc 191
        confirmUrl.current = ''
192
        setLoading(false)
193
      })
194
  }
5 stevensc 195
 
196
  const handleUnfollow = (link_unfollow) => {
720 stevensc 197
    setLoading(true)
5 stevensc 198
    axios
199
      .post(link_unfollow)
200
      .then((response) => {
720 stevensc 201
        const { data, success } = response.data
5 stevensc 202
 
203
        if (!success) {
204
          const errorMessage =
720 stevensc 205
            typeof data === 'string'
5 stevensc 206
              ? data
720 stevensc 207
              : 'Error interno. Por favor, inténtelo de nuevo más tarde.'
5 stevensc 208
 
720 stevensc 209
          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
210
          return
5 stevensc 211
        }
212
 
720 stevensc 213
        if (fetchCallback) fetchCallback()
214
        dispatch(addNotification({ style: 'success', msg: data }))
5 stevensc 215
      })
720 stevensc 216
      .finally(() => setLoading(false))
217
  }
5 stevensc 218
 
219
  const getManageUrl = async () => {
220
    try {
720 stevensc 221
      const { data } = await axios.get(link_admin)
222
      if (data.success) window.open(data.data, '_backend')
5 stevensc 223
    } catch (error) {
720 stevensc 224
      console.log('>>: error > ', error)
5 stevensc 225
    }
720 stevensc 226
  }
5 stevensc 227
 
723 stevensc 228
  const navigateTo = (url) => {
229
    history.push(url)
230
  }
231
 
5 stevensc 232
  const linksOptions = [
233
    {
234
      label: btnAcceptTitle || labels.accept,
235
      url: link_view,
720 stevensc 236
      color: 'primary',
237
      icon: OpenInNew
5 stevensc 238
    },
239
    {
720 stevensc 240
      label: btnEditTitle || labels.edit,
241
      url: link_edit,
242
      color: 'secondary',
243
      icon: Edit
244
    },
245
    { label: labels.approve, url: link_approve, color: 'tertiary', icon: Done },
246
    { label: btnLeaveTitle, url: link_remove, color: 'tertiary', icon: Remove },
247
    { label: labels.accept, url: link_accept, color: 'secondary', icon: Done },
248
    {
249
      label: labels.reject,
250
      url: link_reject,
251
      color: 'tertiary',
252
      icon: CancelOutlined
253
    },
254
    {
5 stevensc 255
      label: btnCancelTitle || labels.cancel,
256
      url: link_delete,
720 stevensc 257
      color: 'tertiary',
258
      icon: DeleteOutline
5 stevensc 259
    },
260
    {
720 stevensc 261
      label: labels.message || 'Mensaje',
5 stevensc 262
      url: link_inmail,
720 stevensc 263
      color: 'secondary',
264
      icon: ChatOutlined
5 stevensc 265
    },
720 stevensc 266
    {
267
      label: labels.administrate,
268
      url: link_admin,
269
      color: 'secondary',
270
      icon: SupervisorAccountOutlined
271
    },
272
    {
273
      label: labels.unfollow,
274
      url: link_unfollow,
275
      color: 'tertiary',
276
      icon: PersonRemoveOutlined
277
    },
278
    {
279
      label: labels.block,
280
      url: link_block,
281
      color: 'tertiary',
282
      icon: LockOutlined
283
    },
284
    {
285
      label: labels.unblock,
286
      url: link_unblock,
287
      color: 'tertiary',
288
      icon: LockOpenOutlined
289
    },
290
    {
291
      label: labels.connect,
292
      url: link_request,
293
      color: 'tertiary',
294
      icon: PersonAddOutlined
295
    },
296
    {
297
      label: labels.cancel,
298
      url: link_cancel,
299
      color: 'tertiary',
300
      icon: CancelOutlined
301
    },
302
    {
303
      label: btnLeaveTitle,
304
      url: link_leave,
305
      color: 'tertiary',
306
      icon: LogoutOutlined
307
    },
308
    {
309
      label: 'Personificar',
310
      url: link_impersonate,
311
      color: 'tertiary',
312
      icon: AccountCircleOutlined
313
    }
314
  ]
5 stevensc 315
 
316
  return (
597 stevensc 317
    <>
613 stevensc 318
      <StyledItemContainer>
607 stevensc 319
        <StyledHeader>
320
          {image && <StyledAvatar src={image} alt={`${name} image`} />}
611 stevensc 321
          <StyledContent>
322
            <h2>{name}</h2>
597 stevensc 323
            {isTopData && email && <h4>{email}</h4>}
611 stevensc 324
            {network && <span>{network}</span>}
325
            {status && <span>{status}</span>}
597 stevensc 326
            {isTopData && (
327
              <ul>
328
                {link_view && (
329
                  <li>
723 stevensc 330
                    <button onClick={() => navigateTo(link_view)}>
331
                      <OpenInNew />
332
                      {btnAcceptTitle}
333
                    </button>
597 stevensc 334
                  </li>
335
                )}
336
                {link_inmail && (
337
                  <li>
723 stevensc 338
                    <button onClick={() => navigateTo(link_inmail)}>
339
                      <ChatOutlined />
340
                      {labels.message}
341
                    </button>
597 stevensc 342
                  </li>
343
                )}
344
              </ul>
345
            )}
611 stevensc 346
          </StyledContent>
607 stevensc 347
        </StyledHeader>
848 stevensc 348
        <Actions>
846 stevensc 349
          {linksOptions.map(({ label, url, icon: Icon, color }) => {
720 stevensc 350
            const breakOptions = [link_view, link_edit, link_inmail]
5 stevensc 351
 
597 stevensc 352
            if (!url) {
720 stevensc 353
              return null
597 stevensc 354
            }
5 stevensc 355
 
597 stevensc 356
            if (url === link_view && isTopData) {
720 stevensc 357
              return null
597 stevensc 358
            }
5 stevensc 359
 
597 stevensc 360
            if (url === link_inmail && isTopData) {
720 stevensc 361
              return null
597 stevensc 362
            }
5 stevensc 363
 
597 stevensc 364
            return (
598 stevensc 365
              <button
597 stevensc 366
                key={url}
846 stevensc 367
                className={`btn btn-${color}`}
598 stevensc 368
                onClick={() => {
597 stevensc 369
                  if (url === link_unfollow) {
720 stevensc 370
                    return handleUnfollow(url)
5 stevensc 371
                  }
372
 
597 stevensc 373
                  if (url === link_admin) {
720 stevensc 374
                    return getManageUrl()
5 stevensc 375
                  }
376
 
597 stevensc 377
                  if (url === link_impersonate) {
720 stevensc 378
                    return getImpersonateUrl(url)
5 stevensc 379
                  }
380
 
597 stevensc 381
                  if (!breakOptions.includes(url)) {
720 stevensc 382
                    return showConfirm(url)
598 stevensc 383
                  } else {
720 stevensc 384
                    history.push(url)
5 stevensc 385
                  }
386
                }}
387
              >
720 stevensc 388
                <Icon />
598 stevensc 389
                {label}
390
              </button>
720 stevensc 391
            )
597 stevensc 392
          })}
848 stevensc 393
        </Actions>
597 stevensc 394
        {loading && (
395
          <StyledSpinnerContainer>
396
            <Spinner />
397
          </StyledSpinnerContainer>
398
        )}
613 stevensc 399
      </StyledItemContainer>
597 stevensc 400
      <ConfirmModal
401
        show={isShowConfirmation}
402
        onClose={() => closeConfirm()}
403
        onAccept={() => onConfirm(confirmUrl.current)}
404
      />
405
    </>
720 stevensc 406
  )
407
}
5 stevensc 408
 
720 stevensc 409
export default ProfileItem