Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6448 | Rev 6450 | 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;
20
  margin-bottom: 0.5rem;
6441 stevensc 21
  border: 2px solid var(--border-primary);
6440 stevensc 22
  border-radius: 50px;
23
  cursor: pointer;
24
  transition: all 200ms ease;
25
  position: relative;
6442 stevensc 26
  overflow: hidden;
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
 
6393 stevensc 70
const SurveyForm = ({
71
  question,
72
  answers = [],
6449 stevensc 73
  votes,
6393 stevensc 74
  active,
75
  time,
6401 stevensc 76
  resultType,
6393 stevensc 77
  voteUrl,
6401 stevensc 78
  addNotification, // Redux action
79
  updateFeed, // Redux action
6393 stevensc 80
}) => {
6438 stevensc 81
  const [remainingTime, setRemainingTime] = useState('00:00:00')
6395 stevensc 82
  const [isActive, setIsActive] = useState(Boolean(active))
6436 stevensc 83
  const timeRef = useRef(time)
6449 stevensc 84
  const voteRef = useRef(0)
6393 stevensc 85
  const { register, handleSubmit } = useForm()
6390 stevensc 86
 
6395 stevensc 87
  const sendVote = handleSubmit(({ vote }) => {
88
    setIsActive(false)
6392 stevensc 89
    const formData = new FormData()
90
 
6395 stevensc 91
    formData.append('vote', vote)
92
 
6392 stevensc 93
    axios
94
      .post(voteUrl, formData)
95
      .then(({ data: response }) => {
96
        const { success, data } = response
97
        if (!success) {
98
          addNotification({ style: 'danger', msg: `Error: ${data}` })
6395 stevensc 99
          setIsActive(true)
6392 stevensc 100
        }
101
 
6407 stevensc 102
        updateFeed({ feed: data, uuid: data.feed_uuid })
6392 stevensc 103
      })
104
      .catch((err) => {
105
        addNotification({ style: 'danger', msg: `Error: ${err}` })
6395 stevensc 106
        setIsActive(true)
6392 stevensc 107
        throw new Error(err)
108
      })
6393 stevensc 109
  })
6392 stevensc 110
 
6415 stevensc 111
  function getTimeDiff(segundos) {
112
    // Obtener la fecha y hora actual
113
    const currentDate = new Date()
114
 
115
    // Calcular la fecha y hora futura sumando los segundos proporcionados
6416 stevensc 116
    const futureDate = new Date(currentDate.getTime() + segundos * 1000)
6415 stevensc 117
 
118
    // Calcular la diferencia entre la fecha futura y la fecha actual
119
    const diff = futureDate - currentDate
120
 
121
    // Calcular los componentes de la diferencia de tiempo
6419 stevensc 122
    const days = Math.floor(diff / (1000 * 60 * 60 * 24))
123
    const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
124
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
6415 stevensc 125
 
126
    // Devolver el resultado
6449 stevensc 127
    return `${addZero(days)}días ${addZero(hours)} horas ${addZero(
128
      minutes
129
    )} minutos`
6415 stevensc 130
  }
131
 
6438 stevensc 132
  function addZero(unit) {
133
    return String(unit).padStart(2, '0')
134
  }
135
 
6439 stevensc 136
  function getPorcentage(n, total) {
137
    return (n * total) / 100
138
  }
139
 
6415 stevensc 140
  useEffect(() => {
6421 stevensc 141
    setRemainingTime(getTimeDiff(time))
142
 
6433 stevensc 143
    const interval = setInterval(() => {
6436 stevensc 144
      timeRef.current = timeRef.current - 60
145
      setRemainingTime(() => getTimeDiff(timeRef.current))
6437 stevensc 146
    }, 60000)
6417 stevensc 147
 
6433 stevensc 148
    return () => {
149
      clearInterval(interval)
150
    }
151
  }, [])
152
 
6449 stevensc 153
  useEffect(() => {
154
    votes && votes.forEach((vote) => (voteRef.current += vote))
155
  }, [])
156
 
6390 stevensc 157
  return (
6392 stevensc 158
    <form onChange={sendVote} className={styles.survey_form}>
6390 stevensc 159
      <h3>{question}</h3>
6410 stevensc 160
      {resultType === 'pu' && (
161
        <span>
6442 stevensc 162
          <PublicIcon /> Los resultados estaran disponibles al finalizar la
163
          encuesta.
6410 stevensc 164
        </span>
165
      )}
166
      {resultType === 'pr' && (
167
        <span>
6442 stevensc 168
          <LockClockIcon /> Los resultados de la votación son privados.
6410 stevensc 169
        </span>
170
      )}
6390 stevensc 171
      {answers.map(
172
        (option, index) =>
173
          option && (
6449 stevensc 174
            <RadioButton
175
              disabled={!isActive}
176
              porcentage={
177
                !time && votes && getPorcentage(votes[index], voteRef.current)
178
              }
179
              key={index}
180
            >
6390 stevensc 181
              <input
182
                type="radio"
6392 stevensc 183
                name="vote"
184
                id={`vote-${index + 1}`}
6390 stevensc 185
                disabled={!isActive}
6392 stevensc 186
                ref={register({ required: true })}
187
                value={index + 1}
6390 stevensc 188
              />
6392 stevensc 189
              <label htmlFor={`vote-${index + 1}`}>{option}</label>
6440 stevensc 190
            </RadioButton>
6390 stevensc 191
          )
192
      )}
6438 stevensc 193
      <span>Tiempo restante: {remainingTime}</span>
6390 stevensc 194
    </form>
195
  )
196
}
197
 
6393 stevensc 198
const mapDispatchToProps = {
199
  addNotification: (notification) => addNotification(notification),
6401 stevensc 200
  updateFeed: (payload) => updateFeed(payload),
6393 stevensc 201
}
202
 
203
export default connect(null, mapDispatchToProps)(SurveyForm)