Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3081 | Rev 3654 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3432 stevensc 1
import React, { useMemo } from "react";
2
import { Controller, useForm } from "react-hook-form";
3076 stevensc 3
import {
4
  FormControlLabel,
5
  Radio,
6
  RadioGroup,
7
  styled,
3432 stevensc 8
  Typography,
9
} from "@mui/material";
10
import { Public, LockClock } from "@mui/icons-material";
5 stevensc 11
 
3432 stevensc 12
import { axios } from "@utils";
13
import { getTimeDiff } from "@utils/dates";
14
import { updateFeed } from "@store/feed/feed.actions";
15
import { addNotification } from "@store/notification/notification.actions";
5 stevensc 16
 
3432 stevensc 17
import Widget from "@components/UI/Widget";
18
import FormErrorFeedback from "@components/UI/form/FormErrorFeedback";
2970 stevensc 19
 
3432 stevensc 20
const AnswerContainer = styled("div")`
5 stevensc 21
  display: flex;
22
  align-items: center;
23
  gap: 0.5rem;
24
  padding: 0.5rem 1rem;
25
  border: 2px solid var(--border-primary);
26
  border-radius: 50px;
27
  cursor: pointer;
28
  transition: all 200ms ease;
29
  position: relative;
30
  overflow: hidden;
31
  margin-bottom: 0.5rem;
32
  &:hover {
33
    border-color: var(--font-color);
34
    text-shadow: 0 0 1px var(--font-color);
35
  }
3432 stevensc 36
`;
5 stevensc 37
 
3017 stevensc 38
const SurveyForm = ({
39
  active = false,
3432 stevensc 40
  question = "¿Cómo consideras el ambiente laboral?",
3017 stevensc 41
  answers = [],
42
  votes = [],
43
  time = 0,
3432 stevensc 44
  voteUrl = "/feed/vote/d454717c-ba6f-485c-b94c-4fbb5f5bed94",
45
  resultType = "pu",
3017 stevensc 46
}) => {
3019 stevensc 47
  const totalVotes = useMemo(
48
    () =>
49
      votes.reduce((acc, cur) => {
3432 stevensc 50
        if (!cur) return acc;
51
        return acc + cur;
3019 stevensc 52
      }, 0),
53
    [votes]
3432 stevensc 54
  );
55
  const timeRemaining = useMemo(() => getTimeDiff(time), [time]);
3019 stevensc 56
 
3432 stevensc 57
  const { control, handleSubmit } = useForm();
5 stevensc 58
 
3014 stevensc 59
  const sendVote = handleSubmit(({ vote }) => {
3432 stevensc 60
    const formData = new FormData();
61
    formData.append("vote", vote);
3014 stevensc 62
 
63
    axios
64
      .post(voteUrl, formData)
3432 stevensc 65
      .then((response) => {
66
        const { success, data } = response.data;
3014 stevensc 67
 
68
        if (!success) {
69
          const errorMessage =
3432 stevensc 70
            typeof data === "string"
3014 stevensc 71
              ? data
3432 stevensc 72
              : "Error interno, por favor intente mas tarde.";
73
          throw new Error(errorMessage);
3014 stevensc 74
        }
75
 
3432 stevensc 76
        updateFeed({ feed: data, uuid: data.feed_uuid });
77
        addNotification({ style: "success", msg: "Voto emitido con exito" });
3014 stevensc 78
      })
79
      .catch((err) => {
3432 stevensc 80
        addNotification({ style: "danger", msg: err.message });
81
      });
82
  });
3014 stevensc 83
 
3019 stevensc 84
  function getPorcentage(n, total) {
3432 stevensc 85
    return (n / total) * 100;
3019 stevensc 86
  }
87
 
3017 stevensc 88
  return (
89
    <Widget>
90
      <Widget.Body>
3432 stevensc 91
        <Typography variant="h3">{question}</Typography>
3014 stevensc 92
 
3432 stevensc 93
        {resultType === "pu" ? (
3017 stevensc 94
          <Typography
3432 stevensc 95
            variant="overline"
96
            title="El número de votos es visible para todos los usuarios"
3019 stevensc 97
            sx={{ paddingBottom: (theme) => theme.spacing(0.5) }}
3017 stevensc 98
          >
3432 stevensc 99
            <Public sx={{ fontSize: "1.3rem" }} /> Público
3017 stevensc 100
          </Typography>
101
        ) : (
102
          <Typography
3432 stevensc 103
            variant="overline"
104
            title="Los resultados de la votación son privados"
3019 stevensc 105
            sx={{ paddingBottom: (theme) => theme.spacing(0.5) }}
3017 stevensc 106
          >
3432 stevensc 107
            <LockClock sx={{ fontSize: "1.3rem" }} /> Privado
3017 stevensc 108
          </Typography>
109
        )}
3014 stevensc 110
 
3020 stevensc 111
        <form onChange={sendVote}>
3081 stevensc 112
          <Controller
3432 stevensc 113
            name="vote"
3081 stevensc 114
            control={control}
3432 stevensc 115
            rules={{ required: "Por favor seleccione una opción" }}
116
            defaultValue=""
3081 stevensc 117
            disabled={!active}
118
            render={({ field, fieldState: { error } }) => (
119
              <>
120
                <RadioGroup {...field}>
121
                  {answers.map((answer, index) => {
3432 stevensc 122
                    if (answer === null) return null;
3014 stevensc 123
 
3081 stevensc 124
                    return (
125
                      <AnswerContainer
126
                        key={answer}
127
                        sx={{
3432 stevensc 128
                          "::before": {
129
                            content: "",
130
                            position: "absolute",
3081 stevensc 131
                            left: 0,
132
                            top: 0,
3432 stevensc 133
                            height: "100%",
134
                            backgroundColor: "#0002",
3081 stevensc 135
                            zIndex: 4,
136
                            width: totalVotes
137
                              ? `${getPorcentage(votes[index], totalVotes)}%`
3432 stevensc 138
                              : 0,
139
                          },
3081 stevensc 140
                        }}
141
                      >
142
                        <FormControlLabel
143
                          value={index + 1}
144
                          control={<Radio sx={{ padding: 0 }} />}
145
                          label={answer}
146
                          sx={{ margin: 0, gap: 1 }}
147
                          disabled={field.disabled}
148
                        />
3018 stevensc 149
 
3081 stevensc 150
                        {totalVotes ? (
3432 stevensc 151
                          <Typography variant="overline">
3081 stevensc 152
                            {getPorcentage(votes[index], totalVotes)}%
153
                          </Typography>
154
                        ) : null}
155
                      </AnswerContainer>
3432 stevensc 156
                    );
3081 stevensc 157
                  })}
158
                </RadioGroup>
159
                {error && (
160
                  <FormErrorFeedback>{error.message}</FormErrorFeedback>
161
                )}
162
              </>
163
            )}
164
          />
3018 stevensc 165
 
3432 stevensc 166
          <Typography variant="overline">
3021 stevensc 167
            Tiempo restante: {timeRemaining}
168
          </Typography>
3018 stevensc 169
 
170
          {!active && (
3432 stevensc 171
            <Typography variant="overline">
3018 stevensc 172
              El formulario ya ha finalizado
173
            </Typography>
174
          )}
3017 stevensc 175
        </form>
176
      </Widget.Body>
177
    </Widget>
3432 stevensc 178
  );
179
};
5 stevensc 180
 
3432 stevensc 181
export default SurveyForm;