Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
2970 stevensc 1
import React, { useEffect, useMemo, useRef, useState } from 'react'
813 stevensc 2
import { useForm } from 'react-hook-form'
2970 stevensc 3
import { styled } from '@mui/material'
4
import { Public, LockClock } from '@mui/icons-material'
5 stevensc 5
 
2969 stevensc 6
import { axios } from '@utils'
2970 stevensc 7
import { updateFeed } from '@store/feed/feed.actions'
2969 stevensc 8
import { addNotification } from '@store/notification/notification.actions'
5 stevensc 9
 
2970 stevensc 10
import styles from './survey.module.scss'
11
 
2969 stevensc 12
const RadioButton = styled('div')`
5 stevensc 13
  display: flex;
14
  align-items: center;
15
  gap: 0.5rem;
16
  padding: 0.5rem 1rem;
17
  border: 2px solid var(--border-primary);
18
  border-radius: 50px;
19
  cursor: pointer;
20
  transition: all 200ms ease;
21
  position: relative;
22
  overflow: hidden;
23
  margin-bottom: 0.5rem;
24
  input {
25
    margin: 0 !important;
26
  }
27
  label {
28
    color: var(--font-color);
29
    font-weight: 500;
30
  }
31
  &::before {
813 stevensc 32
    content: '';
5 stevensc 33
    position: absolute;
34
    left: 0;
35
    top: 0;
36
    height: 100%;
813 stevensc 37
    width: ${(props) => (props.porcentage ? `${props.porcentage}%` : '0%')};
5 stevensc 38
    background-color: #0002;
39
    z-index: 4;
40
  }
41
  &:hover {
42
    border-color: var(--font-color);
43
    text-shadow: 0 0 1px var(--font-color);
44
  }
813 stevensc 45
`
5 stevensc 46
 
2969 stevensc 47
const VoteTag = styled('span')`
5 stevensc 48
  position: absolute;
49
  bottom: 1rem;
50
  right: 1rem;
51
  color: var(--font-color) !important;
52
  font-weight: 600;
813 stevensc 53
`
5 stevensc 54
 
2970 stevensc 55
const SurveyForm = ({
56
  active = 0,
57
  question = '¿Cómo consideras el ambiente laboral?',
58
  answers = ['Excelente', 'Regular', null, null, null],
59
  votes = [null, null, null, null, null],
60
  time = 0,
61
  voteUrl = '/feed/vote/d454717c-ba6f-485c-b94c-4fbb5f5bed94',
62
  resultType
63
}) => {
813 stevensc 64
  const [remainingTime, setRemainingTime] = useState('00:00:00')
65
  const [isActive, setIsActive] = useState(true)
66
  const timeRef = useRef(time)
2970 stevensc 67
 
813 stevensc 68
  const { register, handleSubmit } = useForm()
5 stevensc 69
 
2970 stevensc 70
  const totalVotes = useMemo(
71
    () =>
72
      votes.reduce((curr, next) => {
73
        if (next === null) return curr
74
        return curr + next
75
      }, 0),
76
    [votes]
77
  )
78
 
3014 stevensc 79
  const sendVote = handleSubmit(({ vote }) => {
80
    setIsActive(false)
81
 
82
    const formData = new FormData()
83
    formData.append('vote', vote)
84
 
85
    axios
86
      .post(voteUrl, formData)
87
      .then(({ data: response }) => {
88
        const { success, data } = response
89
 
90
        if (!success) {
91
          const errorMessage =
92
            typeof data === 'string'
93
              ? data
94
              : 'Error interno, por favor intente mas tarde.'
95
          throw new Error(errorMessage)
96
        }
97
 
98
        updateFeed({ feed: data, uuid: data.feed_uuid })
99
        addNotification({ style: 'success', msg: 'Voto emitido con exito' })
100
      })
101
      .catch((err) => {
102
        setIsActive(true)
103
        addNotification({ style: 'danger', msg: err.message })
104
      })
105
  })
106
 
107
  function getTimeDiff(segundos) {
108
    const currentDate = new Date()
109
    const futureDate = new Date(currentDate.getTime() + segundos * 1000)
110
    const diff = futureDate - currentDate
111
 
112
    const days = Math.floor(diff / (1000 * 60 * 60 * 24))
113
    const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
114
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
115
 
116
    return `${addZero(days)}d ${addZero(hours)}h ${addZero(minutes)}m`
117
  }
118
 
119
  function addZero(unit) {
120
    return String(unit).padStart(2, '0')
121
  }
122
 
123
  function getPorcentage(n, total) {
124
    return (n / total) * 100
125
  }
126
 
127
  useEffect(() => {
128
    setIsActive(!!active)
129
  }, [active])
130
 
5 stevensc 131
  return (
3014 stevensc 132
    <form onChange={sendVote} className={styles.survey_form}>
5 stevensc 133
      <h3>{question}</h3>
813 stevensc 134
      {resultType === 'pu' && (
5 stevensc 135
        <span
813 stevensc 136
          className='mb-2'
137
          title='El número de votos es visible para todos los usuarios'
5 stevensc 138
        >
2969 stevensc 139
          <Public /> Público
5 stevensc 140
        </span>
141
      )}
813 stevensc 142
      {resultType === 'pr' && (
5 stevensc 143
        <span
813 stevensc 144
          className='mb-2'
145
          title='Los resultados de la votación son privados'
5 stevensc 146
        >
2969 stevensc 147
          <LockClock /> Privado
5 stevensc 148
        </span>
149
      )}
150
      {answers.map(
151
        (option, index) =>
152
          option && (
2970 stevensc 153
            <RadioButton disabled={!isActive} key={index}>
5 stevensc 154
              <input
813 stevensc 155
                type='radio'
156
                name='vote'
5 stevensc 157
                id={`vote-${index + 1}`}
158
                disabled={!isActive}
159
                ref={register({ required: true })}
160
                value={index + 1}
161
              />
162
              <label htmlFor={`vote-${index + 1}`}>{option}</label>
3014 stevensc 163
              {!!totalVotes && (
164
                <span className='mb-0'>
165
                  {getPorcentage(votes[index], totalVotes)}%
166
                </span>
167
              )}
5 stevensc 168
            </RadioButton>
169
          )
170
      )}
171
      <span>Tiempo restante: {remainingTime}</span>
172
      {!isActive && <VoteTag>Tu voto ya fue emitido</VoteTag>}
173
    </form>
813 stevensc 174
  )
175
}
5 stevensc 176
 
2969 stevensc 177
export default SurveyForm