Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 16752 | Rev 16755 | Ir a la última revisión | | Comparar con el anterior | 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
 
16752 stevensc 9
import { addFeed, fetchFeeds } from '../../../redux/feed/feed.actions'
16750 stevensc 10
import { addNotification } from '../../../redux/notification/notification.actions'
11
import { closeSurveyModal } from '../../../redux/survey-modal/surveyModal.actions'
12
 
13
const SurveyModal = (props) => {
14
  const { addNotification, addFeed } = props // Redux actions
16753 stevensc 15
  const { postUrl, isOpen, currentPage, timelineUrl, state } = props // Redux states
16750 stevensc 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
 
16752 stevensc 67
  const closeModal = () => {
68
    closeSurveyModal()
69
  }
70
 
16750 stevensc 71
  const onSubmit = handleSubmit((data) => {
72
    setLoading(true)
73
    const formData = new FormData()
74
 
75
    Object.entries(data).map(([entry, value]) => formData.append(entry, value))
76
 
77
    for (let i = 1; i <= 5; i++) {
78
      !data[`answer${i}`] && formData.append(`answer${i}`, '')
79
    }
80
 
81
    const numberOfAnswers = Object.entries(data).filter((entry) =>
82
      entry[0].includes('answer')
83
    ).length
84
 
85
    formData.append('feed_content_type', 'fast-survey')
86
    formData.append('number_of_answers', numberOfAnswers)
87
    formData.append('posted_or_shared', 'POST')
88
 
89
    axios
90
      .post(postUrl, formData)
91
      .then(({ data: response }) => {
92
        const { success, data } = response
93
        if (!success) {
94
          typeof data !== 'string'
95
            ? Object.entries(data).map(([key, value]) =>
96
                addNotification({ style: 'danger', msg: `${key}: ${value[0]}` })
97
              )
98
            : addNotification({ style: 'danger', msg: data })
99
          return
100
        }
101
 
102
        if (currentPage && timelineUrl) {
103
          fetchFeeds(timelineUrl, currentPage)
104
        }
105
 
106
        addFeed(data)
107
 
108
        addNotification({
109
          style: 'success',
110
          msg: 'La publicación ha sido compartida'
111
        })
112
        reset()
113
        clearErrors()
16752 stevensc 114
        closeModal()
16750 stevensc 115
      })
116
      .catch((err) => {
117
        addNotification({ style: 'danger', msg: `Error: ${err}` })
118
        throw new Error(err)
119
      })
120
      .finally(() => setLoading(false))
121
  })
122
 
123
  useEffect(() => {
16753 stevensc 124
    console.log(state)
16750 stevensc 125
    clearErrors()
126
  }, [isOpen])
127
 
128
  useEffect(() => {
129
    register('duration_days')
130
    register('duration_hours')
131
    register('duration_minutes')
132
  }, [])
133
 
134
  return (
16752 stevensc 135
    <Modal show={isOpen} onHide={closeModal}>
16750 stevensc 136
      <form onSubmit={onSubmit} method="post">
137
        <Modal.Header closeButton>
138
          <Modal.Title>Encuestas rápidas</Modal.Title>
139
        </Modal.Header>
140
        <Modal.Body>
141
          <div className="form-row">
142
            <div className="form-group col">
143
              <label htmlFor="privacy">Privacidad</label>
144
              <select
145
                className="form-control"
146
                name="privacy"
147
                id="privacy"
148
                ref={register}
149
              >
150
                <option value="c">Compañía</option>
151
                <option value="p">Público</option>
152
              </select>
153
            </div>
154
            <div className="form-group col">
155
              <label htmlFor="result_type">Resultado</label>
156
              <select
157
                className="form-control"
158
                name="result_type"
159
                id="result_type"
160
                ref={register}
161
              >
162
                <option value="pr">Privado</option>
163
                <option value="pu">Público</option>
164
              </select>
165
            </div>
166
          </div>
167
          <div className="form-group">
168
            <label htmlFor="question">Tu pregunta*</label>
169
            <input
170
              type="text"
171
              className="form-control"
172
              placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"
173
              maxLength={1024}
174
              id="question"
175
              name="question"
176
              ref={register({ required: true })}
177
            />
178
          </div>
179
          {options.slice(0, optionsNumber).map((option, index) => (
180
            <div className="form-group" key={index}>
181
              <label htmlFor={`answer${index + 1}`}>Opción {index + 1}*</label>
182
              {index > 1 && (
183
                <button className="btn" onClick={removeOption}>
184
                  Eliminar
185
                </button>
186
              )}
187
              <input
188
                type="text"
189
                className="form-control"
190
                placeholder={option.placeholder}
191
                maxLength={100}
192
                id={`answer${index + 1}`}
193
                name={`answer${index + 1}`}
194
                ref={register({ required: true })}
195
              />
196
            </div>
197
          ))}
198
          {optionsNumber < options.length && (
199
            <button
200
              className="btn btn-outline-primary rounded"
201
              onClick={addOption}
202
            >
203
              Añadir opción
204
            </button>
205
          )}
206
          <div className="form-group">
207
            <label htmlFor="question">Duración</label>
208
            <Datetime
209
              dateFormat="DD/MM/YYYY"
210
              onChange={handleChange}
211
              isValidDate={(current) =>
212
                current.isBefore(calculateMaxDate()) &&
213
                current.isAfter(calculateMinDate())
214
              } // Se valida que la fecha esté entre la fecha mínima y la fecha máxima
215
              value={selectedDate}
216
            />
217
          </div>
218
        </Modal.Body>
219
        <Modal.Footer>
220
          <Button size="sm" type="submit" disabled={loading}>
221
            Enviar
222
          </Button>
223
          <Button
224
            variant="light"
225
            size="sm"
226
            disabled={loading}
227
            onClick={closeSurveyModal}
228
          >
229
            Cancelar
230
          </Button>
231
        </Modal.Footer>
232
      </form>
233
    </Modal>
234
  )
235
}
236
 
237
const mapStateToProps = (state) => ({
238
  isOpen: state.surveyModal.isOpen,
239
  postUrl: state.surveyModal.postUrl,
240
  currentPage: state.feed.currentPage,
16753 stevensc 241
  timelineUrl: state.feed.timelineUrl,
242
  state: state
16750 stevensc 243
})
244
 
245
const mapDispatchToProps = {
246
  addNotification: (notification) => addNotification(notification),
247
  closeSurveyModal: () => closeSurveyModal(),
248
  addFeed: (feed) => addFeed(feed)
249
}
250
 
251
export default connect(mapStateToProps, mapDispatchToProps)(SurveyModal)