Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 6451 | Rev 6453 | 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
 
6450 stevensc 143
    if (!time) return
144
 
6433 stevensc 145
    const interval = setInterval(() => {
6436 stevensc 146
      timeRef.current = timeRef.current - 60
147
      setRemainingTime(() => getTimeDiff(timeRef.current))
6437 stevensc 148
    }, 60000)
6417 stevensc 149
 
6433 stevensc 150
    return () => {
151
      clearInterval(interval)
152
    }
153
  }, [])
154
 
6449 stevensc 155
  useEffect(() => {
6452 stevensc 156
    if (!votes) return
157
    votes.forEach((vote) => (voteRef.current += Number(vote)))
158
    console.log(voteRef.current)
6449 stevensc 159
  }, [])
160
 
6390 stevensc 161
  return (
6392 stevensc 162
    <form onChange={sendVote} className={styles.survey_form}>
6390 stevensc 163
      <h3>{question}</h3>
6410 stevensc 164
      {resultType === 'pu' && (
6450 stevensc 165
        <span
166
          title="Los resultados estaran disponibles al finalizar la
167
          encuesta."
168
        >
169
          <PublicIcon /> Público
6410 stevensc 170
        </span>
171
      )}
172
      {resultType === 'pr' && (
6450 stevensc 173
        <span title="Los resultados de la votación son privados.">
174
          <LockClockIcon /> Privado.
6410 stevensc 175
        </span>
176
      )}
6390 stevensc 177
      {answers.map(
178
        (option, index) =>
179
          option && (
6449 stevensc 180
            <RadioButton
181
              disabled={!isActive}
182
              porcentage={
183
                !time && votes && getPorcentage(votes[index], voteRef.current)
184
              }
185
              key={index}
186
            >
6390 stevensc 187
              <input
188
                type="radio"
6392 stevensc 189
                name="vote"
190
                id={`vote-${index + 1}`}
6390 stevensc 191
                disabled={!isActive}
6392 stevensc 192
                ref={register({ required: true })}
193
                value={index + 1}
6390 stevensc 194
              />
6392 stevensc 195
              <label htmlFor={`vote-${index + 1}`}>{option}</label>
6450 stevensc 196
              {!time && votes && (
197
                <span className="mb-0">
198
                  {getPorcentage(votes[index], voteRef.current)}%
199
                </span>
200
              )}
6440 stevensc 201
            </RadioButton>
6390 stevensc 202
          )
203
      )}
6438 stevensc 204
      <span>Tiempo restante: {remainingTime}</span>
6390 stevensc 205
    </form>
206
  )
207
}
208
 
6393 stevensc 209
const mapDispatchToProps = {
210
  addNotification: (notification) => addNotification(notification),
6401 stevensc 211
  updateFeed: (payload) => updateFeed(payload),
6393 stevensc 212
}
213
 
214
export default connect(null, mapDispatchToProps)(SurveyForm)