Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 751 | Rev 753 | 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)

        console.log(newReaction)

        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(() => {
      if (currentReaction) {
        const reaction = reactions.find(({ type }) => type === currentReaction)
        setReaction(reaction)
      }
    }, [currentReaction])

    return (
      <Component
        onMouseOver={onHover}
        onMouseLeave={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>
    )
  }
}