Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 16752 | Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
16750 stevensc 1
import React, { useState, useEffect } from 'react'
2
import axios from 'axios'
3
import { useForm } from 'react-hook-form'
4
import { connect } from 'react-redux'
5
import { Button, Modal } from 'react-bootstrap'
6
import Datetime from 'react-datetime'
7
import 'react-datetime/css/react-datetime.css'
8
 
9
import { addNotification } from '../../../redux/notification/notification.actions'
10
import { closeSurveyModal } from '../../../redux/survey-modal/surveyModal.actions'
11
import { addFeed, fetchFeeds } from '../../../redux/feed/feed.actions'
12
 
13
const SurveyModal = (props) => {
14
  const { addNotification, addFeed } = props // Redux actions
15
  const { postUrl, isOpen, currentPage, timelineUrl } = props // Redux states
16
  const [loading, setLoading] = useState(false)
17
  const [selectedDate, setSelectedDate] = useState(null)
18
  const [optionsNumber, setOptionsNumber] = useState(2)
19
 
20
  const { register, handleSubmit, setValue, clearErrors, reset } = useForm()
21
 
22
  const options = [
23
    { placeholder: 'Por ejemplo: transporte público' },
24
    { placeholder: 'Por ejemplo: coche propio' },
25
    { placeholder: 'Por ejemplo: coche compartido' },
26
    { placeholder: 'Por ejemplo: bicicleta' },
27
    { placeholder: 'Por ejemplo: otro' }
28
  ]
29
 
30
  const calculateMaxDate = () => {
31
    const today = new Date()
32
    const maxDate = today.setDate(today.getDate() + 29)
33
    return new Date(maxDate)
34
  }
35
 
36
  const calculateMinDate = () => {
37
    return new Date()
38
  }
39
 
40
  const handleChange = (selected) => {
41
    setSelectedDate(selected)
42
 
43
    if (!selected) {
44
      return null
45
    }
46
 
47
    const currentDate = new Date()
48
    const selectedDt = new Date(selected.format('YYYY-MM-DD HH:mm'))
49
    const timeDiff = selectedDt.getTime() - currentDate.getTime()
50
    const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
51
    const hoursDiff = Math.floor((timeDiff / (1000 * 60 * 60)) % 24)
52
    const minutesDiff = Math.floor((timeDiff / (1000 * 60)) % 60)
53
 
54
    setValue('duration_days', daysDiff)
55
    setValue('duration_hours', hoursDiff)
56
    setValue('duration_minutes', minutesDiff)
57
  }
58
 
59
  const addOption = () => {
60
    setOptionsNumber(optionsNumber + 1)
61
  }
62
 
63
  const removeOption = () => {
64
    setOptionsNumber(optionsNumber - 1)
65
  }
66
 
67
  const onSubmit = handleSubmit((data) => {
68
    setLoading(true)
69
    const formData = new FormData()
70
 
71
    Object.entries(data).map(([entry, value]) => formData.append(entry, value))
72
 
73
    for (let i = 1; i <= 5; i++) {
74
      !data[`answer${i}`] && formData.append(`answer${i}`, '')
75
    }
76
 
77
    const numberOfAnswers = Object.entries(data).filter((entry) =>
78
      entry[0].includes('answer')
79
    ).length
80
 
81
    formData.append('feed_content_type', 'fast-survey')
82
    formData.append('number_of_answers', numberOfAnswers)
83
    formData.append('posted_or_shared', 'POST')
84
 
85
    axios
86
      .post(postUrl, formData)
87
      .then(({ data: response }) => {
88
        const { success, data } = response
89
        if (!success) {
90
          typeof data !== 'string'
91
            ? Object.entries(data).map(([key, value]) =>
92
                addNotification({ style: 'danger', msg: `${key}: ${value[0]}` })
93
              )
94
            : addNotification({ style: 'danger', msg: data })
95
          return
96
        }
97
 
98
        if (currentPage && timelineUrl) {
99
          fetchFeeds(timelineUrl, currentPage)
100
        }
101
 
102
        addFeed(data)
103
 
104
        addNotification({
105
          style: 'success',
106
          msg: 'La publicación ha sido compartida'
107
        })
108
        reset()
109
        clearErrors()
110
        closeSurveyModal()
111
      })
112
      .catch((err) => {
113
        addNotification({ style: 'danger', msg: `Error: ${err}` })
114
        throw new Error(err)
115
      })
116
      .finally(() => setLoading(false))
117
  })
118
 
119
  useEffect(() => {
120
    clearErrors()
121
  }, [isOpen])
122
 
123
  useEffect(() => {
124
    register('duration_days')
125
    register('duration_hours')
126
    register('duration_minutes')
127
  }, [])
128
 
129
  return (
130
    <Modal show={isOpen} onHide={closeSurveyModal}>
131
      <form onSubmit={onSubmit} method="post">
132
        <Modal.Header closeButton>
133
          <Modal.Title>Encuestas rápidas</Modal.Title>
134
        </Modal.Header>
135
        <Modal.Body>
136
          <div className="form-row">
137
            <div className="form-group col">
138
              <label htmlFor="privacy">Privacidad</label>
139
              <select
140
                className="form-control"
141
                name="privacy"
142
                id="privacy"
143
                ref={register}
144
              >
145
                <option value="c">Compañía</option>
146
                <option value="p">Público</option>
147
              </select>
148
            </div>
149
            <div className="form-group col">
150
              <label htmlFor="result_type">Resultado</label>
151
              <select
152
                className="form-control"
153
                name="result_type"
154
                id="result_type"
155
                ref={register}
156
              >
157
                <option value="pr">Privado</option>
158
                <option value="pu">Público</option>
159
              </select>
160
            </div>
161
          </div>
162
          <div className="form-group">
163
            <label htmlFor="question">Tu pregunta*</label>
164
            <input
165
              type="text"
166
              className="form-control"
167
              placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"
168
              maxLength={1024}
169
              id="question"
170
              name="question"
171
              ref={register({ required: true })}
172
            />
173
          </div>
174
          {options.slice(0, optionsNumber).map((option, index) => (
175
            <div className="form-group" key={index}>
176
              <label htmlFor={`answer${index + 1}`}>Opción {index + 1}*</label>
177
              {index > 1 && (
178
                <button className="btn" onClick={removeOption}>
179
                  Eliminar
180
                </button>
181
              )}
182
              <input
183
                type="text"
184
                className="form-control"
185
                placeholder={option.placeholder}
186
                maxLength={100}
187
                id={`answer${index + 1}`}
188
                name={`answer${index + 1}`}
189
                ref={register({ required: true })}
190
              />
191
            </div>
192
          ))}
193
          {optionsNumber < options.length && (
194
            <button
195
              className="btn btn-outline-primary rounded"
196
              onClick={addOption}
197
            >
198
              Añadir opción
199
            </button>
200
          )}
201
          <div className="form-group">
202
            <label htmlFor="question">Duración</label>
203
            <Datetime
204
              dateFormat="DD/MM/YYYY"
205
              onChange={handleChange}
206
              isValidDate={(current) =>
207
                current.isBefore(calculateMaxDate()) &&
208
                current.isAfter(calculateMinDate())
209
              } // Se valida que la fecha esté entre la fecha mínima y la fecha máxima
210
              value={selectedDate}
211
            />
212
          </div>
213
        </Modal.Body>
214
        <Modal.Footer>
215
          <Button size="sm" type="submit" disabled={loading}>
216
            Enviar
217
          </Button>
218
          <Button
219
            variant="light"
220
            size="sm"
221
            disabled={loading}
222
            onClick={closeSurveyModal}
223
          >
224
            Cancelar
225
          </Button>
226
        </Modal.Footer>
227
      </form>
228
    </Modal>
229
  )
230
}
231
 
232
const mapStateToProps = (state) => ({
233
  isOpen: state.surveyModal.isOpen,
234
  postUrl: state.surveyModal.postUrl,
235
  currentPage: state.feed.currentPage,
236
  timelineUrl: state.feed.timelineUrl
237
})
238
 
239
const mapDispatchToProps = {
240
  addNotification: (notification) => addNotification(notification),
241
  closeSurveyModal: () => closeSurveyModal(),
242
  addFeed: (feed) => addFeed(feed)
243
}
244
 
245
export default connect(mapStateToProps, mapDispatchToProps)(SurveyModal)