Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 16750 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
16741 stevensc 1
import React, { useEffect, useRef, useState } from 'react'
2
 
3
import PrivateIcon from '../icons/Private'
4
import PublicIcon from '../icons/Public'
5
 
6
import styles from './survey.module.scss'
7
import styled, { css } from 'styled-components'
8
 
9
const RadioButton = styled.div`
10
  display: flex;
11
  align-items: center;
12
  gap: 0.5rem;
13
  padding: 0.5rem 1rem;
14
  margin-bottom: 0.5rem;
15
  border: 2px solid var(--border-primary);
16
  border-radius: 50px;
17
  cursor: pointer;
18
  transition: all 200ms ease;
19
  position: relative;
20
  overflow: hidden;
21
 
22
  input {
23
    margin: 0 !important;
24
  }
25
 
26
  label {
27
    color: var(--font-color);
28
    font-weight: 500;
29
  }
30
 
31
  &::before {
32
    content: '';
33
    position: absolute;
34
    left: 0;
35
    top: 0;
36
    height: 100%;
37
    width: ${(props) => (props.porcentage ? `${props.porcentage}%` : '0%')};
38
    background-color: #0002;
39
    z-index: 4;
40
  }
41
 
42
  &:hover {
43
    border-color: var(--font-color);
44
    text-shadow: 0 0 1px var(--font-color);
45
  }
46
 
47
  ${(props) =>
48
    props.disabled &&
49
    css`
50
      background-color: #9992;
51
      cursor: auto;
52
 
53
      label {
54
        color: gray;
55
      }
56
 
57
      &:hover {
58
        border-color: var(--border-primary);
59
        text-shadow: none;
60
      }
61
    `}
62
`
63
 
64
const SurveyForm = ({
65
  question,
66
  answers = [],
67
  votes,
68
  active,
69
  time,
70
  resultType
71
}) => {
72
  const [remainingTime, setRemainingTime] = useState('00:00:00')
73
  const [isActive, setIsActive] = useState(Boolean(active))
16750 stevensc 74
  const [totalVotes, setTotalVotes] = useState(0)
16741 stevensc 75
  const timeRef = useRef(time)
76
 
77
  function getTimeDiff(segundos) {
78
    // Obtener la fecha y hora actual
79
    const currentDate = new Date()
80
 
81
    // Calcular la fecha y hora futura sumando los segundos proporcionados
82
    const futureDate = new Date(currentDate.getTime() + segundos * 1000)
83
 
84
    // Calcular la diferencia entre la fecha futura y la fecha actual
85
    const diff = futureDate - currentDate
86
 
87
    // Calcular los componentes de la diferencia de tiempo
88
    const days = Math.floor(diff / (1000 * 60 * 60 * 24))
89
    const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
90
    const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))
91
 
92
    // Devolver el resultado
16742 stevensc 93
    return `${addZero(days)} d ${addZero(hours)} h ${addZero(minutes)} m`
16741 stevensc 94
  }
95
 
96
  function addZero(unit) {
97
    return String(unit).padStart(2, '0')
98
  }
99
 
100
  function getPorcentage(n, total) {
101
    return (n / total) * 100
102
  }
103
 
104
  useEffect(() => {
105
    setRemainingTime(getTimeDiff(time))
106
 
107
    if (!time) return
108
 
109
    const interval = setInterval(() => {
110
      if (!timeRef.current) {
111
        setRemainingTime(() => getTimeDiff(0))
112
        setIsActive(false)
113
        return
114
      }
115
 
116
      if (!timeRef.current <= 60) {
117
        timeRef.current -= 1
118
        setRemainingTime(() => getTimeDiff(timeRef.current))
119
        return
120
      }
121
 
122
      timeRef.current -= 60
123
      setRemainingTime(() => getTimeDiff(timeRef.current))
124
    }, 60000)
125
 
126
    return () => {
127
      clearInterval(interval)
128
    }
129
  }, [])
130
 
131
  useEffect(() => {
132
    if (!votes) return
16756 stevensc 133
    const total = votes.reduce((total, vote) => total + Number(vote), 0)
16750 stevensc 134
    setTotalVotes(total)
16741 stevensc 135
  }, [])
136
 
137
  return (
138
    <form className={styles.survey_form}>
139
      <h3>{question}</h3>
140
      {resultType === 'pu' && (
16750 stevensc 141
        <span title="El número de votos es visible para todos los usuarios">
16741 stevensc 142
          <PublicIcon /> Público
143
        </span>
144
      )}
145
      {resultType === 'pr' && (
16750 stevensc 146
        <span title="Los resultados de la votación son privados">
16741 stevensc 147
          <PrivateIcon /> Privado
148
        </span>
149
      )}
150
      {answers.map(
151
        (option, index) =>
152
          option && (
153
            <RadioButton
154
              disabled={!isActive}
16750 stevensc 155
              porcentage={votes && getPorcentage(votes[index], totalVotes)}
16741 stevensc 156
              key={index}
157
            >
158
              <input
159
                type="radio"
160
                name="vote"
161
                id={`vote-${index + 1}`}
162
                value={index + 1}
16745 stevensc 163
                disabled
16741 stevensc 164
              />
165
              <label htmlFor={`vote-${index + 1}`}>{option}</label>
16750 stevensc 166
              {votes && (
16741 stevensc 167
                <span className="mb-0">
16750 stevensc 168
                  {getPorcentage(votes[index], totalVotes)}%
16741 stevensc 169
                </span>
170
              )}
171
            </RadioButton>
172
          )
173
      )}
174
      <span>Tiempo restante: {remainingTime}</span>
175
    </form>
176
  )
177
}
178
 
179
export default SurveyForm