Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
6436 stevensc 1
import React, { useEffect, useRef, useState } from 'react'
6393 stevensc 2
import { axios } from '../../../utils'
6392 stevensc 3
import { useForm } from 'react-hook-form'
6393 stevensc 4
import { connect } from 'react-redux'
5
 
6410 stevensc 6
import { updateFeed } from '../../../redux/feed/feed.actions'
6392 stevensc 7
import { addNotification } from '../../../redux/notification/notification.actions'
6390 stevensc 8
 
6410 stevensc 9
import LockClockIcon from '@mui/icons-material/LockClock'
10
import PublicIcon from '@mui/icons-material/Public'
11
 
6393 stevensc 12
import styles from './survey.module.scss'
6440 stevensc 13
import styled, { css } from 'styled-components'
6393 stevensc 14
 
6440 stevensc 15
const RadioButton = styled.div`
16
  display: flex;
17
  align-items: center;
18
  gap: 0.5rem;
19
  padding: 0.5rem 1rem;
6441 stevensc 20
  border: 2px solid var(--border-primary);
6440 stevensc 21
  border-radius: 50px;
22
  cursor: pointer;
23
  transition: all 200ms ease;
24
  position: relative;
6442 stevensc 25
  overflow: hidden;
6461 stevensc 26
  margin-bottom: 0.5rem;
6440 stevensc 27
 
28
  input {
29
    margin: 0 !important;
30
  }
31
 
32
  label {
6441 stevensc 33
    color: var(--font-color);
6440 stevensc 34
    font-weight: 500;
35
  }
36
 
37
  &::before {
6447 stevensc 38
    content: '';
6440 stevensc 39
    position: absolute;
40
    left: 0;
41
    top: 0;
42
    height: 100%;
6447 stevensc 43
    width: ${(props) => (props.porcentage ? `${props.porcentage}%` : '0%')};
6449 stevensc 44
    background-color: #0002;
6440 stevensc 45
    z-index: 4;
46
  }
47
 
48
  &:hover {
6441 stevensc 49
    border-color: var(--font-color);
50
    text-shadow: 0 0 1px var(--font-color);
6440 stevensc 51
  }
52
 
53
  ${(props) =>
6446 stevensc 54
    props.disabled &&
6440 stevensc 55
    css`
6446 stevensc 56
      background-color: #9992;
6440 stevensc 57
      cursor: auto;
58
 
59
      label {
60
        color: gray;
61
      }
62
 
63
      &:hover {
6441 stevensc 64
        border-color: var(--border-primary);
6440 stevensc 65
        text-shadow: none;
66
      }
67
    `}
68
`
69
 
6460 stevensc 70
const VoteTag = styled.span`
71
  position: absolute;
72
  bottom: 1rem;
73
  right: 1rem;
6461 stevensc 74
  color: var(--font-color) !important;
6460 stevensc 75
`
76
 
6393 stevensc 77
const SurveyForm = ({
78
  question,
79
  answers = [],
6449 stevensc 80
  votes,
6393 stevensc 81
  active,
82
  time,
6401 stevensc 83
  resultType,
6393 stevensc 84
  voteUrl,
6401 stevensc 85
  addNotification, // Redux action
86
  updateFeed, // Redux action
6393 stevensc 87
}) => {
6438 stevensc 88
  const [remainingTime, setRemainingTime] = useState('00:00:00')
6395 stevensc 89
  const [isActive, setIsActive] = useState(Boolean(active))
6436 stevensc 90
  const timeRef = useRef(time)
6449 stevensc 91
  const voteRef = useRef(0)
6393 stevensc 92
  const { register, handleSubmit } = useForm()
6390 stevensc 93
 
6395 stevensc 94
  const sendVote = handleSubmit(({ vote }) => {
95
    setIsActive(false)
6392 stevensc 96
    const formData = new FormData()
97
 
6395 stevensc 98
    formData.append('vote', vote)
99
 
6392 stevensc 100
    axios
101
      .post(voteUrl, formData)
102
      .then(({ data: response }) => {
103
        const { success, data } = response
104
        if (!success) {
105
          addNotification({ style: 'danger', msg: `Error: ${data}` })
6395 stevensc 106
          setIsActive(true)
6392 stevensc 107
        }
108
 
6407 stevensc 109
        updateFeed({ feed: data, uuid: data.feed_uuid })
6460 stevensc 110
        addNotification({ style: 'success', msg: 'Voto emitido con exito' })
6392 stevensc 111
      })
112
      .catch((err) => {
113
        addNotification({ style: 'danger', msg: `Error: ${err}` })
6395 stevensc 114
        setIsActive(true)
6392 stevensc 115
        throw new Error(err)
116
      })
6393 stevensc 117
  })
6392 stevensc 118
 
6415 stevensc 119
  function getTimeDiff(segundos) {
120
    // Obtener la fecha y hora actual
121
    const currentDate = new Date()
122
 
123
    // Calcular la fecha y hora futura sumando los segundos proporcionados
6416 stevensc 124
    const futureDate = new Date(currentDate.getTime() + segundos * 1000)
6415 stevensc 125
 
126
    // Calcular la diferencia entre la fecha futura y la fecha actual
127
    const diff = futureDate - currentDate
128
 
129
    // Calcular los componentes de la diferencia de tiempo
6419 stevensc 130
    const days = Math.floor(diff / (1000 * 60 * 60 * 24))
131
    const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
132
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
6415 stevensc 133
 
134
    // Devolver el resultado
6459 stevensc 135
    return `${addZero(days)}d ${addZero(hours)}h ${addZero(minutes)}m`
6415 stevensc 136
  }
137
 
6438 stevensc 138
  function addZero(unit) {
139
    return String(unit).padStart(2, '0')
140
  }
141
 
6439 stevensc 142
  function getPorcentage(n, total) {
6453 stevensc 143
    return (n / total) * 100
6439 stevensc 144
  }
145
 
6415 stevensc 146
  useEffect(() => {
6421 stevensc 147
    setRemainingTime(getTimeDiff(time))
148
 
6450 stevensc 149
    if (!time) return
150
 
6433 stevensc 151
    const interval = setInterval(() => {
6455 stevensc 152
      if (!timeRef.current) {
153
        setRemainingTime(() => getTimeDiff(0))
6459 stevensc 154
        setIsActive(false)
6455 stevensc 155
        return
156
      }
157
 
158
      if (!timeRef.current <= 60) {
159
        timeRef.current -= 1
160
        setRemainingTime(() => getTimeDiff(timeRef.current))
161
        return
162
      }
163
 
164
      timeRef.current -= 60
6436 stevensc 165
      setRemainingTime(() => getTimeDiff(timeRef.current))
6437 stevensc 166
    }, 60000)
6417 stevensc 167
 
6433 stevensc 168
    return () => {
169
      clearInterval(interval)
170
    }
171
  }, [])
172
 
6449 stevensc 173
  useEffect(() => {
6452 stevensc 174
    if (!votes) return
175
    votes.forEach((vote) => (voteRef.current += Number(vote)))
6449 stevensc 176
  }, [])
177
 
6390 stevensc 178
  return (
6392 stevensc 179
    <form onChange={sendVote} className={styles.survey_form}>
6390 stevensc 180
      <h3>{question}</h3>
6465 stevensc 181
      <span className="mb-2">
182
        {resultType === 'pu' && (
183
          <>
184
            <PublicIcon /> Los resultados estaran disponibles al finalizar la
185
            encuesta
186
          </>
187
        )}
188
        {resultType === 'pr' && (
189
          <>
190
            <LockClockIcon /> Los resultados de la votación son privados
191
          </>
192
        )}
193
      </span>
6390 stevensc 194
      {answers.map(
195
        (option, index) =>
196
          option && (
6449 stevensc 197
            <RadioButton
198
              disabled={!isActive}
199
              porcentage={
200
                !time && votes && getPorcentage(votes[index], voteRef.current)
201
              }
202
              key={index}
203
            >
6390 stevensc 204
              <input
205
                type="radio"
6392 stevensc 206
                name="vote"
207
                id={`vote-${index + 1}`}
6390 stevensc 208
                disabled={!isActive}
6392 stevensc 209
                ref={register({ required: true })}
210
                value={index + 1}
6390 stevensc 211
              />
6392 stevensc 212
              <label htmlFor={`vote-${index + 1}`}>{option}</label>
6450 stevensc 213
              {!time && votes && (
214
                <span className="mb-0">
215
                  {getPorcentage(votes[index], voteRef.current)}%
216
                </span>
217
              )}
6440 stevensc 218
            </RadioButton>
6390 stevensc 219
          )
220
      )}
6438 stevensc 221
      <span>Tiempo restante: {remainingTime}</span>
6460 stevensc 222
      {!isActive && <VoteTag>Tu voto ya fue emitido</VoteTag>}
6390 stevensc 223
    </form>
224
  )
225
}
226
 
6393 stevensc 227
const mapDispatchToProps = {
228
  addNotification: (notification) => addNotification(notification),
6401 stevensc 229
  updateFeed: (payload) => updateFeed(payload),
6393 stevensc 230
}
231
 
232
export default connect(null, mapDispatchToProps)(SurveyForm)