Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 762 | Rev 764 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React, { useCallback, useEffect, useState } from 'react'
import { useDispatch } from 'react-redux'
import { axios } from '../utils'
import { addNotification } from 'store/notification/notification.actions'

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 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'
  }
]

export default function withReactions(Component) {
  const HOC = ({
    saveUrl = '',
    deleteUrl = '',
    currentReaction = null,
    onSelect = () => null
  }) => {
    const [reaction, setReaction] = useState(null)
    const dispatch = useDispatch()

    const saveReaction = useCallback(
      (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((prevReaction) => {
            return {
              ...prevReaction,
              ...newReaction
            }
          })
          onSelect(data.reactions)
        })
      },
      [saveUrl, dispatch, reactions, setReaction, onSelect]
    )

    const deleteReaction = () => {
      axios.post(deleteUrl).then((res) => {
        const { success, data } = res.data

        if (!success) {
          dispatch(addNotification({ style: 'danger', msg: data }))
          return
        }

        setReaction(null)
        onSelect(data.reactions)
      })
    }

    useEffect(() => {
      if (currentReaction) {
        const reaction = reactions.find(({ type }) => type === currentReaction)
        setReaction(reaction)
      }
    }, [currentReaction])

    return (
      <Component
        icon={reaction ? reaction.icon : RecommendIcon}
        onClick={() =>
          reaction ? deleteReaction() : saveReaction(reactions[0].type)
        }
        label={reaction ? reaction.label : 'Reaccionar'}
      >
        <div className='reactions'>
          {reactions.map(({ icon: Icon, type, label }) => (
            <button
              key={type}
              onClick={(e) => {
                e.stopPropagation()
                saveReaction(type)
              }}
              title={label}
            >
              <Icon />
            </button>
          ))}
        </div>
      </Component>
    )
  }

  return React.memo(HOC, (prevProps, nextProps) => {
    return prevProps.currentReaction === nextProps.currentReaction
  })
}