Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 753 | Rev 755 | 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 = React.memo(
    ({
      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 HOC
}