Rev 3596 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useCallback, useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
import { styled, Typography } from '@mui/material';
import { axios } from '@app/utils';
import { REACTIONS } from '@app/constants/feed';
import { addNotification } from '@app/redux/notification/notification.actions';
import colors from '@styles/config/colors';
const ReactionsBox = styled('div')(({ theme }) => ({
position: 'absolute',
bottom: '100%',
backgroundColor: colors.main,
border: `1px solid ${colors.border.primary}`,
gap: theme.spacing(0.5),
left: 0,
display: 'flex',
padding: theme.spacing(0.5),
width: 'fit-content',
borderRadius: theme.shape.borderRadius,
transform: 'scale(0)',
transformOrigin: 'center',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.short,
easing: theme.transitions.easing.easeInOut,
delay: theme.transitions.duration.short
}),
'& > button': {
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.short,
easing: theme.transitions.easing.easeInOut
}),
'&:hover': {
transform: 'scale(1.1) translateY(-4px)'
},
svg: {
fontSize: '32px'
}
}
}));
export function withReactions(Component) {
const ReactionsButton = ({
saveUrl = '',
deleteUrl = '',
currentReactionType = null,
onReaction = () => null
}) => {
const [isHover, setIsHover] = useState(false);
const dispatch = useDispatch();
const currentReaction = useMemo(
() => REACTIONS.find((r) => r.type === currentReactionType),
[currentReactionType]
);
const Icon = currentReaction ? currentReaction.icon : REACTIONS[0].icon;
const handleHover = () => setIsHover(!isHover);
const saveReaction = useCallback(
(type = 'r') => {
const formData = new FormData();
formData.append('reaction', type);
axios.post(saveUrl, formData).then((res) => {
const { success, data } = res.data;
if (!success) {
dispatch(addNotification({ style: 'danger', msg: data }));
}
onReaction(data, type);
});
},
[saveUrl, dispatch]
);
const deleteReaction = useCallback(() => {
axios.post(deleteUrl).then((res) => {
const { success, data } = res.data;
if (!success) {
dispatch(addNotification({ style: 'danger', msg: data }));
return;
}
onReaction({
reactions: data.reactions,
currentReactionType: ''
});
});
}, []);
return (
<Component onClick={currentReaction ? deleteReaction : handleHover}>
{currentReaction ? <Icon style={{ color: currentReaction.color }} /> : <Icon />}
<Typography sx={{ display: { xs: 'none', md: 'inline-flex' } }} variant='overline'>
{currentReaction ? currentReaction.label : 'Reaccionar'}
</Typography>
<ReactionsBox
sx={{
transform: isHover ? 'scale(1)' : 'scale(0)',
transformOrigin: 'center'
}}
>
{REACTIONS.map(({ type, label, icon: Icon, color }) => (
<button
key={type}
title={label}
onClickCapture={(e) => {
e.stopPropagation();
saveReaction(type);
}}
>
<Icon style={{ color }} />
</button>
))}
</ReactionsBox>
</Component>
);
};
return ReactionsButton;
}