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