Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
764 stevensc 1
import React, { useCallback } from 'react'
751 stevensc 2
import { useDispatch } from 'react-redux'
753 stevensc 3
import { axios } from '../utils'
751 stevensc 4
import { addNotification } from 'store/notification/notification.actions'
766 stevensc 5
import styled from 'styled-components'
633 stevensc 6
 
751 stevensc 7
import FunIcon from '../components/UI/icons/Fun'
8
import LoveItIcon from '../components/UI/icons/LoveIt'
9
import SupportIcon from '../components/UI/icons/Support'
10
import InterestIcon from '../components/UI/icons/Interest'
11
import RecommendIcon from '../components/UI/icons/Recommned'
633 stevensc 12
 
764 stevensc 13
const reactions = {
14
  r: {
753 stevensc 15
    icon: RecommendIcon,
764 stevensc 16
    label: 'Me gusta',
17
    type: 'r'
753 stevensc 18
  },
764 stevensc 19
  s: {
753 stevensc 20
    icon: SupportIcon,
764 stevensc 21
    label: 'Dar apoyo',
22
    type: 's'
753 stevensc 23
  },
764 stevensc 24
  l: {
753 stevensc 25
    icon: LoveItIcon,
764 stevensc 26
    label: 'Me encanta',
27
    type: 'l'
753 stevensc 28
  },
764 stevensc 29
  i: {
753 stevensc 30
    icon: InterestIcon,
764 stevensc 31
    label: 'Me interesa',
32
    type: 'i'
753 stevensc 33
  },
764 stevensc 34
  f: {
753 stevensc 35
    icon: FunIcon,
764 stevensc 36
    label: 'Me divierte',
37
    type: 'f'
753 stevensc 38
  }
764 stevensc 39
}
633 stevensc 40
 
766 stevensc 41
const StyledReactionsContainer = styled.div`
42
  position: absolute;
43
  bottom: 100%;
44
  background-color: var(--bg-color);
45
  box-shadow: 0px 0px 3px #000;
46
  gap: 0.5rem;
47
  left: 0;
48
  display: flex;
49
  padding: 0.2rem;
50
  width: fit-content;
51
  border-radius: var(--border-radius);
52
  transform: scale(0);
53
  transform-origin: left bottom;
54
  transition: all 0.2s ease-out;
55
  button {
56
    transition: all 0.2s ease-in;
57
    svg {
58
      font-size: 32px;
59
    }
60
    &:hover {
61
      transform: scale(1.1) translateY(-4px);
62
    }
63
  }
64
`
65
 
754 stevensc 66
export default function withReactions(Component) {
755 stevensc 67
  const HOC = ({
68
    saveUrl = '',
69
    deleteUrl = '',
70
    currentReaction = null,
764 stevensc 71
    onReaction = () => null
755 stevensc 72
  }) => {
73
    const dispatch = useDispatch()
633 stevensc 74
 
755 stevensc 75
    const saveReaction = useCallback(
76
      (type) => {
77
        const formData = new FormData()
78
        formData.append('reaction', type)
633 stevensc 79
 
755 stevensc 80
        axios.post(saveUrl, formData).then((res) => {
753 stevensc 81
          const { success, data } = res.data
633 stevensc 82
 
753 stevensc 83
          if (!success) {
84
            dispatch(addNotification({ style: 'danger', msg: data }))
85
          }
633 stevensc 86
 
764 stevensc 87
          onReaction({
88
            reactions: data.reactions,
89
            currentReaction: type
755 stevensc 90
          })
753 stevensc 91
        })
755 stevensc 92
      },
764 stevensc 93
      [saveUrl, dispatch, reactions]
755 stevensc 94
    )
646 stevensc 95
 
764 stevensc 96
    const deleteReaction = useCallback(() => {
755 stevensc 97
      axios.post(deleteUrl).then((res) => {
98
        const { success, data } = res.data
99
 
100
        if (!success) {
101
          dispatch(addNotification({ style: 'danger', msg: data }))
102
          return
633 stevensc 103
        }
104
 
764 stevensc 105
        onReaction({
106
          reactions: data.reactions,
107
          currentReaction: ''
108
        })
755 stevensc 109
      })
764 stevensc 110
    }, [])
633 stevensc 111
 
755 stevensc 112
    return (
113
      <Component
764 stevensc 114
        icon={currentReaction ? reactions[currentReaction].icon : RecommendIcon}
755 stevensc 115
        onClick={() =>
764 stevensc 116
          currentReaction ? deleteReaction() : saveReaction(reactions.r.type)
755 stevensc 117
        }
764 stevensc 118
        label={
119
          currentReaction ? reactions[currentReaction].label : 'Reaccionar'
120
        }
755 stevensc 121
      >
766 stevensc 122
        <StyledReactionsContainer>
764 stevensc 123
          {Object.values(reactions).map(({ type, label, icon: Icon }) => (
755 stevensc 124
            <button
125
              key={type}
764 stevensc 126
              title={label}
755 stevensc 127
              onClick={(e) => {
128
                e.stopPropagation()
129
                saveReaction(type)
766 stevensc 130
                e.currentTarget.blur()
755 stevensc 131
              }}
132
            >
133
              <Icon />
134
            </button>
135
          ))}
766 stevensc 136
        </StyledReactionsContainer>
755 stevensc 137
      </Component>
138
    )
139
  }
140
 
764 stevensc 141
  return HOC
633 stevensc 142
}