Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
633 stevensc 1
import React, { useEffect, useRef, useState } from "react";
2
import { useDispatch } from "react-redux";
3
import { axios, debounce } from "../utils";
4
import { addNotification } from "store/notification/notification.actions";
5
import useOutsideClick from "hooks/useOutsideClick";
6
 
7
import ReactionIcon from "@mui/icons-material/Recommend";
8
import FunIcon from "../components/UI/icons/Fun";
9
import LoveItIcon from "../components/UI/icons/LoveIt";
10
import SupportIcon from "../components/UI/icons/Support";
11
import InterestIcon from "../components/UI/icons/Interest";
12
import RecommendIcon from "../components/UI/icons/Recommned";
13
 
14
const initialReaction = {
15
  label: "Reaccionar",
16
  icon: ReactionIcon,
17
  type: "default",
18
};
19
 
20
export default function withReactions(
21
  Component = <></>,
639 stevensc 22
  {
23
    saveUrl = "",
24
    deleteUrl = "",
25
    currentReaction = "default",
26
    onSelect = () => null,
27
  } = {}
633 stevensc 28
) {
29
  return function (props) {
30
    const [reaction, setReaction] = useState(initialReaction);
31
    const [isHover, setIsHover] = useState(false);
32
    const rectionBtn = useRef(null);
33
    const dispatch = useDispatch();
34
    useOutsideClick(rectionBtn, () => setIsHover(false));
35
 
36
    const reactions = [
37
      {
38
        type: "r",
39
        icon: RecommendIcon,
40
        label: "Me gusta",
41
      },
42
      {
43
        type: "s",
44
        icon: SupportIcon,
45
        label: "Dar apoyo",
46
      },
47
      {
48
        type: "l",
49
        icon: LoveItIcon,
50
        label: "Me encanta",
51
      },
52
      {
53
        type: "i",
54
        icon: InterestIcon,
55
        label: "Me interesa",
56
      },
57
      {
58
        type: "f",
59
        icon: FunIcon,
60
        label: "Me divierte",
61
      },
62
    ];
63
 
64
    const saveReaction = (type) => {
65
      const formData = new FormData();
66
      formData.append("reaction", type);
67
 
68
      axios.post(saveUrl, formData).then((res) => {
69
        const { success, data } = res.data;
70
 
71
        if (!success) {
72
          dispatch(addNotification({ style: "danger", msg: data }));
73
          return;
74
        }
75
 
639 stevensc 76
        const newReaction = reactions.find((r) => r.type === type);
646 stevensc 77
 
633 stevensc 78
        setReaction(newReaction);
639 stevensc 79
        onSelect(data.reactions);
633 stevensc 80
      });
81
    };
82
 
83
    const deleteReaction = () => {
84
      axios.post(deleteUrl).then((res) => {
85
        const { success, data } = res.data;
86
 
87
        if (!success) {
88
          dispatch(addNotification({ style: "danger", msg: data }));
89
          return;
90
        }
91
 
92
        setReaction(initialReaction);
639 stevensc 93
        onSelect(data.reactions);
633 stevensc 94
      });
95
    };
96
 
97
    const onHover = debounce(() => setIsHover(true), 500);
98
 
99
    const onUnhover = debounce(() => setIsHover(false), 500);
100
 
101
    useEffect(() => {
102
      const currentOption = reactions.find(
103
        ({ type }) => type === currentReaction
104
      );
105
 
106
      if (!currentOption) {
107
        setReaction(initialReaction);
108
        return;
109
      }
110
 
111
      setReaction(currentOption);
112
    }, [currentReaction]);
113
 
114
    return (
115
      <Component
116
        onMouseOver={onHover}
117
        onMouseOut={onUnhover}
118
        ref={rectionBtn}
119
        icon={reaction.icon}
120
        onClick={() =>
121
          reaction.type !== "default"
122
            ? deleteReaction()
123
            : saveReaction(reactions[0].type)
124
        }
634 stevensc 125
        label={reaction.label}
633 stevensc 126
        {...props}
127
      >
128
        {isHover && (
129
          <div className={`reactions ${isHover ? "active" : ""}`}>
130
            {reactions.map(({ icon: Icon, type, label }) => (
131
              <button
132
                key={type}
133
                onClick={(e) => {
134
                  e.stopPropagation();
135
                  saveReaction(type);
136
                  setIsHover(false);
137
                }}
138
                title={label}
139
              >
140
                <Icon />
141
              </button>
142
            ))}
143
          </div>
144
        )}
145
      </Component>
146
    );
147
  };
148
}