Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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