Rev 645 | Rev 752 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
import React, { useEffect, useRef, useState } from "react";
import { useDispatch } from "react-redux";
import { axios, debounce } from "../utils";
import { addNotification } from "store/notification/notification.actions";
import useOutsideClick from "hooks/useOutsideClick";
import ReactionIcon from "@mui/icons-material/Recommend";
import FunIcon from "../components/UI/icons/Fun";
import LoveItIcon from "../components/UI/icons/LoveIt";
import SupportIcon from "../components/UI/icons/Support";
import InterestIcon from "../components/UI/icons/Interest";
import RecommendIcon from "../components/UI/icons/Recommned";
const initialReaction = {
label: "Reaccionar",
icon: ReactionIcon,
type: "default",
};
export default function withReactions(
Component = <></>,
{
saveUrl = "",
deleteUrl = "",
currentReaction = "default",
onSelect = () => null,
} = {}
) {
return function (props) {
const [reaction, setReaction] = useState(initialReaction);
const [isHover, setIsHover] = useState(false);
const rectionBtn = useRef(null);
const dispatch = useDispatch();
useOutsideClick(rectionBtn, () => setIsHover(false));
const reactions = [
{
type: "r",
icon: RecommendIcon,
label: "Me gusta",
},
{
type: "s",
icon: SupportIcon,
label: "Dar apoyo",
},
{
type: "l",
icon: LoveItIcon,
label: "Me encanta",
},
{
type: "i",
icon: InterestIcon,
label: "Me interesa",
},
{
type: "f",
icon: FunIcon,
label: "Me divierte",
},
];
const saveReaction = (type) => {
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 }));
return;
}
const newReaction = reactions.find((r) => r.type === type);
setReaction(newReaction);
onSelect(data.reactions);
});
};
const deleteReaction = () => {
axios.post(deleteUrl).then((res) => {
const { success, data } = res.data;
if (!success) {
dispatch(addNotification({ style: "danger", msg: data }));
return;
}
setReaction(initialReaction);
onSelect(data.reactions);
});
};
const onHover = debounce(() => setIsHover(true), 500);
const onUnhover = debounce(() => setIsHover(false), 500);
useEffect(() => {
const currentOption = reactions.find(
({ type }) => type === currentReaction
);
if (!currentOption) {
setReaction(initialReaction);
return;
}
setReaction(currentOption);
}, [currentReaction]);
return (
<Component
onMouseOver={onHover}
onMouseOut={onUnhover}
ref={rectionBtn}
icon={reaction.icon}
onClick={() =>
reaction.type !== "default"
? deleteReaction()
: saveReaction(reactions[0].type)
}
label={reaction.label}
{...props}
>
{isHover && (
<div className={`reactions ${isHover ? "active" : ""}`}>
{reactions.map(({ icon: Icon, type, label }) => (
<button
key={type}
onClick={(e) => {
e.stopPropagation();
saveReaction(type);
setIsHover(false);
}}
title={label}
>
<Icon />
</button>
))}
</div>
)}
</Component>
);
};
}