Proyectos de Subversion LeadersLinked - SPA

Rev

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

import React, { useRef, useState } from 'react'
import { axios } from '../../utils'
import { Avatar } from '@mui/material'
import { useHistory } from 'react-router-dom'
import { addNotification } from 'store/notification/notification.actions'
import { useDispatch, useSelector } from 'react-redux'
import styled from 'styled-components'
import Spinner from '../UI/Spinner'
import StyledContainer from '../widgets/WidgetLayout'
import ConfirmModal from '../modals/ConfirmModal'
import {
  AccountCircleOutlined,
  CancelOutlined,
  ChatOutlined,
  DeleteOutline,
  Done,
  Edit,
  LockOpenOutlined,
  LockOutlined,
  LogoutOutlined,
  OpenInNew,
  PersonAddOutlined,
  PersonRemoveOutlined,
  Remove,
  SupervisorAccountOutlined
} from '@mui/icons-material'
import { device } from '../../styles/MediaQueries'

const StyledSpinnerContainer = styled.div`
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.4);
  place-items: center;
  z-index: 50;
`

const StyledItemContainer = styled(StyledContainer)`
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
  border-radius: 5px;
`

const StyledHeader = styled.div`
  align-items: center;
  display: flex;
  gap: 0.5rem;
  justify-content: flex-start;
  position: relative;
  padding: 15px 5px;
`

const StyledContent = styled.div`
  display: flex;
  flex-direction: column;
  text-align: center;
  ul {
    align-items: center;
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    button {
      align-items: center;
      border-radius: var(--border-radius);
      cursor: pointer;
      display: inline-flex;
      flex-direction: column;
      font-size: 0.9rem;
      padding: 5px;
      position: relative;
      &:hover {
        background-color: whitesmoke;
      }
      @media ${device.tablet} {
        flex-direction: row;
        gap: 0.5rem;
        font-size: 1rem;
      }
    }
  }
`

const Actions = styled.div`
  display: flex;
  justify-content: space-around;
  border-top: 1px solid rgb(211, 211, 211);
  padding: 5px;
  button {
    display: inline-flex;
    gap: 1rem;
    align-items: center;
    svg {
      font-size: 1rem;
    }
  }
`

const StyledAvatar = styled(Avatar)`
  height: 60px !important;
  width: 60px !important;
`

const ProfileItem = ({
  image,
  name,
  email,
  network,
  status,
  fetchCallback,
  link_remove,
  link_view,
  link_edit,
  link_delete,
  link_cancel,
  link_block,
  link_reject,
  link_accept,
  link_inmail,
  link_request,
  link_unblock,
  link_unfollow,
  link_approve,
  link_leave,
  link_admin,
  link_impersonate,
  btnAcceptTitle = 'Ver',
  btnCancelTitle = 'Borrar',
  btnEditTitle = 'Editar',
  btnLeaveTitle = 'Dejar',
  isTopData
}) => {
  const [isShowConfirmation, setIsShowConfirmation] = useState(false)
  const [loading, setLoading] = useState(false)
  const confirmUrl = useRef('')
  const labels = useSelector(({ intl }) => intl.labels)
  const dispatch = useDispatch()
  const history = useHistory()

  const showConfirm = (url = '') => {
    setIsShowConfirmation(true)
    confirmUrl.current = url
  }

  const closeConfirm = () => {
    setIsShowConfirmation(false)
    confirmUrl.current = ''
  }

  const getImpersonateUrl = async (url = '') => {
    try {
      const { data } = await axios.get(url)
      if (data.success) window.location.href = data.data
    } catch (error) {
      console.log('>>: error > ', error)
    }
  }

  const onConfirm = (url) => {
    setLoading(true)
    axios
      .post(url)
      .then((response) => {
        const { success, data } = response.data

        if (!success) {
          const errorMessage =
            typeof data === 'string'
              ? data
              : 'Error interno. Por favor, inténtelo de nuevo más tarde.'

          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
          return
        }

        if (fetchCallback) fetchCallback()
        dispatch(addNotification({ style: 'success', msg: data }))
      })
      .catch(() => {
        dispatch(
          addNotification({
            style: 'error',
            msg: 'Error interno. Por favor, inténtelo de nuevo más tarde.'
          })
        )
      })
      .finally(() => {
        confirmUrl.current = ''
        setLoading(false)
      })
  }

  const handleUnfollow = (link_unfollow) => {
    setLoading(true)
    axios
      .post(link_unfollow)
      .then((response) => {
        const { data, success } = response.data

        if (!success) {
          const errorMessage =
            typeof data === 'string'
              ? data
              : 'Error interno. Por favor, inténtelo de nuevo más tarde.'

          dispatch(addNotification({ style: 'danger', msg: errorMessage }))
          return
        }

        if (fetchCallback) fetchCallback()
        dispatch(addNotification({ style: 'success', msg: data }))
      })
      .finally(() => setLoading(false))
  }

  const getManageUrl = async () => {
    try {
      const { data } = await axios.get(link_admin)
      if (data.success) window.open(data.data, '_backend')
    } catch (error) {
      console.log('>>: error > ', error)
    }
  }

  const navigateTo = (url) => {
    history.push(url)
  }

  const linksOptions = [
    {
      label: btnAcceptTitle || labels.accept,
      url: link_view,
      color: 'primary',
      icon: OpenInNew
    },
    {
      label: btnEditTitle || labels.edit,
      url: link_edit,
      color: 'secondary',
      icon: Edit
    },
    { label: labels.approve, url: link_approve, color: 'tertiary', icon: Done },
    { label: btnLeaveTitle, url: link_remove, color: 'tertiary', icon: Remove },
    { label: labels.accept, url: link_accept, color: 'secondary', icon: Done },
    {
      label: labels.reject,
      url: link_reject,
      color: 'tertiary',
      icon: CancelOutlined
    },
    {
      label: btnCancelTitle || labels.cancel,
      url: link_delete,
      color: 'tertiary',
      icon: DeleteOutline
    },
    {
      label: labels.message || 'Mensaje',
      url: link_inmail,
      color: 'secondary',
      icon: ChatOutlined
    },
    {
      label: labels.administrate,
      url: link_admin,
      color: 'secondary',
      icon: SupervisorAccountOutlined
    },
    {
      label: labels.unfollow,
      url: link_unfollow,
      color: 'tertiary',
      icon: PersonRemoveOutlined
    },
    {
      label: labels.block,
      url: link_block,
      color: 'tertiary',
      icon: LockOutlined
    },
    {
      label: labels.unblock,
      url: link_unblock,
      color: 'tertiary',
      icon: LockOpenOutlined
    },
    {
      label: labels.connect,
      url: link_request,
      color: 'tertiary',
      icon: PersonAddOutlined
    },
    {
      label: labels.cancel,
      url: link_cancel,
      color: 'tertiary',
      icon: CancelOutlined
    },
    {
      label: btnLeaveTitle,
      url: link_leave,
      color: 'tertiary',
      icon: LogoutOutlined
    },
    {
      label: 'Personificar',
      url: link_impersonate,
      color: 'tertiary',
      icon: AccountCircleOutlined
    }
  ]

  return (
    <>
      <StyledItemContainer>
        <StyledHeader>
          {image && <StyledAvatar src={image} alt={`${name} image`} />}
          <StyledContent>
            <h2>{name}</h2>
            {isTopData && email && <h4>{email}</h4>}
            {network && <span>{network}</span>}
            {status && <span>{status}</span>}
            {isTopData && (
              <ul>
                {link_view && (
                  <li>
                    <button onClick={() => navigateTo(link_view)}>
                      <OpenInNew />
                      {btnAcceptTitle}
                    </button>
                  </li>
                )}
                {link_inmail && (
                  <li>
                    <button onClick={() => navigateTo(link_inmail)}>
                      <ChatOutlined />
                      {labels.message}
                    </button>
                  </li>
                )}
              </ul>
            )}
          </StyledContent>
        </StyledHeader>
        <Actions>
          {linksOptions.map(({ label, url, icon: Icon, color }) => {
            const breakOptions = [link_view, link_edit, link_inmail]

            if (!url) {
              return null
            }

            if (url === link_view && isTopData) {
              return null
            }

            if (url === link_inmail && isTopData) {
              return null
            }

            return (
              <button
                key={url}
                className={`btn btn-${color}`}
                onClick={() => {
                  if (url === link_unfollow) {
                    return handleUnfollow(url)
                  }

                  if (url === link_admin) {
                    return getManageUrl()
                  }

                  if (url === link_impersonate) {
                    return getImpersonateUrl(url)
                  }

                  if (!breakOptions.includes(url)) {
                    return showConfirm(url)
                  } else {
                    history.push(url)
                  }
                }}
              >
                <Icon />
                {label}
              </button>
            )
          })}
        </Actions>
        {loading && (
          <StyledSpinnerContainer>
            <Spinner />
          </StyledSpinnerContainer>
        )}
      </StyledItemContainer>
      <ConfirmModal
        show={isShowConfirmation}
        onClose={() => closeConfirm()}
        onAccept={() => onConfirm(confirmUrl.current)}
      />
    </>
  )
}

export default ProfileItem