Proyectos de Subversion LeadersLinked - Backend

Rev

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

Rev Autor Línea Nro. Línea
11166 stevensc 1
import React, { useState, useEffect } from 'react'
2
import axios from 'axios'
16685 stevensc 3
import { config } from './helpers/ckeditor_config'
4
import { useForm } from 'react-hook-form'
16686 stevensc 5
import { connect } from 'react-redux'
16682 stevensc 6
import { Button, Modal } from 'react-bootstrap'
16685 stevensc 7
import { CKEditor } from 'ckeditor4-react'
16696 stevensc 8
import Datetime from 'react-datetime'
16697 stevensc 9
import 'react-datetime/css/react-datetime.css'
16685 stevensc 10
 
16671 stevensc 11
import {
12
  closeShareModal,
13
  setModalType
14
} from '../redux/share-modal/shareModal.actions'
11166 stevensc 15
import { addFeed, fetchFeeds } from '../redux/feed/feed.actions'
16
import { addNotification } from '../redux/notification/notification.actions'
16685 stevensc 17
 
18
import { shareModalTypes } from '../redux/share-modal/shareModal.types'
19
 
11166 stevensc 20
import Spinner from './Spinner'
16685 stevensc 21
import DropzoneComponent from './Dropzone/DropzoneComponent'
7386 stevensc 22
 
16685 stevensc 23
const ShareModal = (props) => {
24
  const { addNotification, closeShareModal, setModalType, addFeed } = props // Redux actions
25
  const { postUrl, isOpen, modalType, currentPage, timelineUrl, feedSharedId } =
26
    props // Redux states
27
  const [loading, setLoading] = useState(false)
28
 
16671 stevensc 29
  const {
30
    register,
31
    errors,
32
    handleSubmit,
33
    setValue,
34
    getValues,
35
    clearErrors,
16699 stevensc 36
    unregister,
16671 stevensc 37
    reset
16681 stevensc 38
  } = useForm()
7388 stevensc 39
 
16671 stevensc 40
  const recomendationText = {
41
    IMAGE: 'Tamaño recomendado: 720x720',
42
    FILE: 'solo documentos PDF',
43
    VIDEO: 'Video de extensión mp4, mpeg, webm'
44
  }
15353 stevensc 45
 
16681 stevensc 46
  const closeModal = () => {
16685 stevensc 47
    closeShareModal()
16681 stevensc 48
  }
7386 stevensc 49
 
16681 stevensc 50
  const onUploadedHandler = (files) => {
51
    setValue('file', files)
52
    clearErrors('file')
53
  }
7386 stevensc 54
 
16683 stevensc 55
  const onSubmit = handleSubmit((data) => {
16671 stevensc 56
    setLoading(true)
16683 stevensc 57
    const formData = new FormData()
7390 stevensc 58
 
16683 stevensc 59
    Object.entries(data).map(([entry, value]) => formData.append(entry, value))
16696 stevensc 60
    console.log(data)
7386 stevensc 61
 
16696 stevensc 62
    /* axios
16685 stevensc 63
      .post(postUrl, formData)
64
      .then(({ data: response }) => {
65
        const { success, data } = response
66
        if (!success) {
67
          typeof data !== 'string'
68
            ? Object.entries(data).map(([key, value]) =>
69
                addNotification({ style: 'danger', msg: `${key}: ${value[0]}` })
16671 stevensc 70
              )
16685 stevensc 71
            : addNotification({ style: 'danger', msg: data })
16671 stevensc 72
          return
73
        }
7386 stevensc 74
 
16685 stevensc 75
        if (currentPage && timelineUrl) {
76
          fetchFeeds(timelineUrl, currentPage)
77
        }
15215 stevensc 78
 
16685 stevensc 79
        if (feedSharedId) {
80
          addFeed(data, feedSharedId)
81
          return
82
        }
7806 stevensc 83
 
16685 stevensc 84
        addFeed(data)
85
        addNotification({
86
          style: 'success',
87
          msg: 'La publicación ha sido compartida'
88
        })
89
        reset()
90
        clearErrors()
16671 stevensc 91
        closeModal()
92
      })
16685 stevensc 93
      .catch((err) => {
94
        addNotification({ style: 'danger', msg: `Error: ${err}` })
95
        throw new Error(err)
96
      })
16696 stevensc 97
      .finally(() => setLoading(false)) */
16683 stevensc 98
  })
7806 stevensc 99
 
16681 stevensc 100
  useEffect(() => {
101
    clearErrors()
102
  }, [isOpen])
7806 stevensc 103
 
16681 stevensc 104
  useEffect(() => {
105
    register('posted_or_shared')
106
    setValue('posted_or_shared', shareModalTypes.POST)
107
 
108
    if (
109
      [
110
        shareModalTypes.IMAGE,
111
        shareModalTypes.VIDEO,
112
        shareModalTypes.FILE,
113
        shareModalTypes.SHARE,
114
        shareModalTypes.CHAT
16684 stevensc 115
      ].includes(modalType)
16681 stevensc 116
    ) {
117
      register('file', { required: 'El campo es requerido' })
118
    }
119
 
120
    if (modalType === shareModalTypes.POST) {
121
      register('description', { required: 'El campo es requerido' })
122
    }
16696 stevensc 123
 
124
    if (modalType === shareModalTypes.SURVEY) {
16699 stevensc 125
      unregister('description')
16697 stevensc 126
      register('date')
16696 stevensc 127
    }
16681 stevensc 128
  }, [modalType])
129
 
16698 stevensc 130
  useEffect(() => {
131
    console.log(errors)
132
  }, [errors])
133
 
16671 stevensc 134
  return (
16681 stevensc 135
    <Modal show={isOpen} onHide={closeModal}>
16687 stevensc 136
      <form onSubmit={onSubmit} method="post">
137
        <Modal.Header closeButton>
138
          <Modal.Title>Compartir una publicación</Modal.Title>
139
        </Modal.Header>
140
        <Modal.Body>
16675 stevensc 141
          {!loading ? (
16671 stevensc 142
            <>
16676 stevensc 143
              {modalType === shareModalTypes.SURVEY && (
16696 stevensc 144
                <SurveyForm register={register} setValue={setValue} />
16676 stevensc 145
              )}
16675 stevensc 146
              {modalType !== shareModalTypes.SURVEY && (
147
                <>
148
                  <CKEditor
149
                    onChange={(e) =>
150
                      setValue('description', e.editor.getData())
151
                    }
152
                    config={config}
153
                  />
154
                  {errors.description && <p>{errors.description.message}</p>}
155
                </>
156
              )}
16671 stevensc 157
              {![shareModalTypes.POST, shareModalTypes.SURVEY].includes(
158
                modalType
159
              ) && (
16677 stevensc 160
                <>
161
                  <DropzoneComponent
162
                    modalType={modalType}
163
                    onUploaded={onUploadedHandler}
164
                    settedFile={getValues('file')}
165
                    recomendationText={recomendationText[modalType]}
166
                  />
167
                  {errors.file && <p>{errors.file.message}</p>}
168
                </>
16671 stevensc 169
              )}
170
            </>
16675 stevensc 171
          ) : (
172
            <Spinner />
16671 stevensc 173
          )}
16687 stevensc 174
        </Modal.Body>
175
        <Modal.Footer>
176
          <Button size="sm" type="submit" disabled={loading}>
177
            Enviar
178
          </Button>
179
          <Button
16690 stevensc 180
            variant="light"
16687 stevensc 181
            size="sm"
182
            disabled={loading}
183
            onClick={closeShareModal}
184
          >
185
            Cancelar
186
          </Button>
187
          <Button
16690 stevensc 188
            variant="outline-info"
16687 stevensc 189
            size="sm"
190
            disabled={loading}
191
            onClick={() => setModalType(shareModalTypes.SURVEY)}
192
          >
193
            Añadir encuesta
194
          </Button>
195
        </Modal.Footer>
196
      </form>
16671 stevensc 197
    </Modal>
198
  )
199
}
7386 stevensc 200
 
16696 stevensc 201
const SurveyForm = ({ register, setValue }) => {
16671 stevensc 202
  const [optionsNumber, setOptionsNumber] = useState(2)
16704 stevensc 203
  const [selectedDate, setSelectedDate] = useState(null)
7386 stevensc 204
 
16671 stevensc 205
  const options = [
206
    { placeholder: 'Por ejemplo: transporte público' },
207
    { placeholder: 'Por ejemplo: coche propio' },
208
    { placeholder: 'Por ejemplo: coche compartido' },
209
    { placeholder: 'Por ejemplo: bicicleta' },
210
    { placeholder: 'Por ejemplo: otro' }
211
  ]
212
 
16704 stevensc 213
  const calculateMaxDate = () => {
214
    const today = new Date()
16705 stevensc 215
    const maxDate = today.setDate(today.getDate() + 29)
16704 stevensc 216
    return new Date(maxDate)
217
  }
218
 
16705 stevensc 219
  const calculateMinDate = () => {
220
    return new Date()
221
  }
222
 
16671 stevensc 223
  const addOption = () => {
16674 stevensc 224
    setOptionsNumber(optionsNumber + 1)
16671 stevensc 225
  }
226
 
227
  const removeOption = () => {
16674 stevensc 228
    setOptionsNumber(optionsNumber - 1)
16671 stevensc 229
  }
230
 
231
  return (
232
    <>
16709 stevensc 233
      <div className="form-row">
234
        <div className="form-group col">
235
          <label htmlFor="privacy">Privacidad</label>
236
          <select
237
            className="form-control"
238
            name="privacy"
239
            id="privacy"
240
            ref={register}
241
          >
242
            <option value="c">Compañía</option>
243
            <option value="p">Público</option>
244
          </select>
245
        </div>
246
        <div className="form-group col">
247
          <label htmlFor="result">Resultado</label>
248
          <select
249
            className="form-control"
250
            name="result"
251
            id="result"
252
            ref={register}
253
          >
254
            <option value="pr">Privado</option>
255
            <option value="pu">Público</option>
256
          </select>
257
        </div>
16694 stevensc 258
      </div>
259
      <div className="form-group">
16671 stevensc 260
        <label htmlFor="question">Tu pregunta*</label>
261
        <input
262
          type="text"
263
          className="form-control"
264
          placeholder="Por ejemplo: ¿cómo te desplazas al trabajo?"
265
          maxLength={140}
266
          id="question"
267
          name="question"
268
          ref={register({ required: true })}
269
        />
270
      </div>
271
      {options.slice(0, optionsNumber).map((option, index) => (
272
        <div className="form-group" key={index}>
273
          <label htmlFor={`option-${index + 1}`}>Opción {index + 1}*</label>
274
          {index > 1 && (
275
            <button className="btn" onClick={removeOption}>
276
              Eliminar
277
            </button>
278
          )}
279
          <input
280
            type="text"
281
            className="form-control"
282
            placeholder={option.placeholder}
283
            maxLength={30}
284
            id={`option-${index + 1}`}
285
            name={`option-${index + 1}`}
286
            ref={register({ required: true })}
287
          />
288
        </div>
289
      ))}
16675 stevensc 290
      {optionsNumber < options.length && (
291
        <button className="btn btn-outline-primary rounded" onClick={addOption}>
292
          Añadir opción
293
        </button>
294
      )}
16696 stevensc 295
      <Datetime
16707 stevensc 296
        dateFormat="DD/MM/YYYY"
297
        timeFormat="HH:mm"
16704 stevensc 298
        value={selectedDate}
299
        onChange={setSelectedDate}
16705 stevensc 300
        isValidDate={(current) =>
301
          current.isBefore(calculateMaxDate()) &&
302
          current.isAfter(calculateMinDate())
303
        } // Se valida que la fecha esté entre la fecha mínima y la fecha máxima
304
        timeConstraints={{
16708 stevensc 305
          hours: { max: 23 },
16705 stevensc 306
          minutes: { max: 59 }
307
        }}
16696 stevensc 308
      />
16671 stevensc 309
    </>
310
  )
11166 stevensc 311
}
7386 stevensc 312
 
16685 stevensc 313
const mapStateToProps = (state) => ({
314
  isOpen: state.shareModal.isOpen,
315
  postUrl: state.shareModal.postUrl,
316
  modalType: state.shareModal.modalType,
317
  feedSharedId: state.shareModal.feedSharedId,
318
  currentPage: state.feed.currentPage,
319
  timelineUrl: state.feed.timelineUrl
320
})
321
 
322
const mapDispatchToProps = {
323
  addNotification: (notification) => addNotification(notification),
324
  closeShareModal: () => closeShareModal(),
325
  setModalType: (modalType) => setModalType(modalType),
326
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId)
327
}
328
 
329
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)