Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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