Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
6616 stevensc 1
import React, { useState, useEffect } from 'react'
2
import { useForm } from 'react-hook-form'
3
import { connect } from 'react-redux'
4
import { CKEditor } from 'ckeditor4-react'
5
import { axios, CKEDITOR_OPTIONS } from '../../utils'
6
import Modal from 'react-bootstrap/Modal'
7
import Button from 'react-bootstrap/Button'
8
 
9
import {
10
  closeShareModal,
11
  openShareModal,
12
  setModalType,
13
} from '../../redux/share-modal/shareModal.actions'
14
import { addNotification } from '../../redux/notification/notification.actions'
15
import { addFeed, fetchFeeds } from '../../redux/feed/feed.actions'
16
 
6618 stevensc 17
import { shareModalTypes } from '../../redux/'
6616 stevensc 18
import { feedTypes } from '../../redux/feed/feed.types'
19
 
20
import FormErrorFeedback from '../../../shared/form-error-feedback/FormErrorFeedback'
21
import Spinner from '../../../shared/loading-spinner/Spinner'
22
import DropzoneComponent from '../../../shared/dropzone/DropzoneComponent'
23
import ConfirmModal from '../../../shared/confirm-modal/ConfirmModal'
24
 
25
const ShareModal = ({
26
  postUrl,
27
  isOpen,
28
  modalType,
29
  lastModalType,
30
  setModalType,
31
  feedType,
32
  fetchFeeds,
33
  currentPage,
34
  timelineUrl,
35
  feedSharedId,
36
  closeShareModal, // Redux action
37
  addNotification, // Redux action
38
  addFeed, // Redux action
39
  openShareModal, // Redux action
40
}) => {
41
  const [loading, setLoading] = useState(false)
42
  const [isCKEditorLoading, setIsCKEditorLoading] = useState(true)
43
  const [showConfirmModal, setShowConfirmModal] = useState(false)
44
 
45
  const {
46
    register,
47
    unregister,
48
    errors,
49
    handleSubmit,
50
    setValue,
51
    watch,
52
    getValues,
53
    clearErrors,
54
    setError,
55
  } = useForm({
56
    defaultValues: {
57
      description: '',
58
      share_width: '',
59
    },
60
  })
61
 
62
  useEffect(() => {
63
    register('description', {
64
      required: { value: 'true', message: 'El campo es requerido' },
65
    })
66
    register('posted_or_shared')
67
    if (
68
      modalType !== shareModalTypes.POST &&
69
      modalType !== shareModalTypes.SHARE
70
    ) {
71
      register('file', {
72
        required: { value: 'true', message: 'El campo es requerido' },
73
      })
74
    } else {
75
      if (!getValues('file')) unregister('file')
76
    }
77
  }, [modalType])
78
 
79
  const recomendationText = () => {
80
    switch (modalType) {
81
      case shareModalTypes.IMAGE:
82
        return 'Tamaño recomendado: 720x720'
83
      case shareModalTypes.FILE:
84
        return 'solo documentos PDF'
85
      case shareModalTypes.VIDEO:
86
        return 'Video de extensión mp4, mpeg, webm'
87
      default:
88
        return ''
89
    }
90
  }
91
  useEffect(() => {
92
    const postedOrShared = modalType === shareModalTypes.SHARE ? 's' : 'p'
93
    setValue('posted_or_shared', postedOrShared)
94
    if (getValues('file') || getValues('description')) {
95
      if (modalType !== lastModalType) {
96
        closeShareModal()
97
        handleShowConfirmModal()
98
      }
99
    }
100
  }, [modalType])
101
 
102
  const hideDuplicatedModal = () => {
103
    setTimeout(() => {
104
      const modals = document.getElementsByClassName('modal')
105
      if (modals.length > 1 && modals[0].style.display !== 'none') {
106
        const currentModal = modals[0]
107
        currentModal.style.display = 'none'
108
        for (let index = 0; index < modals.length; index++) {
109
          const element = modals[index]
110
          element.removeAttribute('tabindex')
111
        }
112
      }
113
    }, 3000)
114
  }
115
 
116
  useEffect(() => {
117
    clearErrors()
118
    hideDuplicatedModal()
119
  }, [isOpen])
120
 
121
  const handleShowConfirmModal = () => {
122
    setShowConfirmModal(!showConfirmModal)
123
  }
124
 
125
  const handleModalAccept = () => {
126
    setShowConfirmModal(false)
127
    setValue('description', '')
128
    setValue('file', '')
129
    openShareModal(postUrl, modalType, feedType)
130
    clearErrors()
131
  }
132
 
133
  const handleModalCancel = () => {
134
    setShowConfirmModal(false)
135
    closeShareModal()
136
    setModalType(lastModalType)
137
    openShareModal(postUrl, lastModalType, feedType)
138
  }
139
 
140
  const onSubmit = async (data, e) => {
141
    setLoading(true)
142
    const currentFormData = new FormData()
143
    for (const input in data) {
144
      currentFormData.append(input, data[input])
145
    }
146
    await axios.post(postUrl, currentFormData).then((response) => {
147
      const data = response.data
148
      const newFeed = data.data
149
      if (data.success) {
150
        closeShareModal()
151
        // reset data
152
        e.target.reset()
153
        setValue('description', '')
154
        setValue('file', '')
155
        clearErrors()
156
        addNotification({
157
          style: 'success',
158
          msg: 'La publicación ha sido compartida',
159
        })
160
        if (feedSharedId) {
161
          addFeed(newFeed, feedSharedId)
162
        } else {
163
          addFeed(newFeed)
164
        }
165
        if (currentPage && timelineUrl) {
166
          fetchFeeds(timelineUrl, currentPage)
167
        }
168
      } else {
169
        if (data.data.description || data.data.file || data.data.share_width) {
170
          Object.entries(data.data).map(([key, value]) =>
171
            setError(key, { type: 'required', message: value })
172
          )
173
        } else {
174
          addNotification({
175
            style: 'danger',
176
            msg: data.data,
177
          })
178
        }
179
      }
180
    })
181
 
182
    setLoading(false)
183
  }
184
 
185
  const onUploadedHandler = (files) => {
186
    setValue('file', files)
187
    clearErrors('file')
188
  }
189
 
190
  const dropZoneRender = () => {
191
    if (
192
      modalType !== shareModalTypes.POST &&
193
      modalType !== shareModalTypes.SHARE
194
    ) {
195
      return (
196
        <DropzoneComponent
197
          modalType={modalType}
198
          onUploaded={onUploadedHandler}
199
          settedFile={getValues('file')}
200
          recomendationText={recomendationText()}
201
        />
202
      )
203
    }
204
  }
205
 
206
  const SharedWithSelectRender = () => {
207
    if (feedType === feedTypes.DASHBOARD) {
208
      return (
209
        <>
210
          <select
211
            name="shared_with"
212
            id="shared_with"
213
            className="form-control"
214
            ref={register({ required: 'El campo es requerido' })}
215
            defaultValue="p"
216
          >
217
            <option disabled="disabled" value="" style={{ display: 'none' }}>
218
              {LABELS.SHARE_WITH}
219
            </option>
220
            <option value="p">{LABELS.PUBLIC}</option>
221
            <option value="c">{LABELS.CONNECTIONS}</option>
222
          </select>
223
          {errors.shared_with && (
224
            <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
225
          )}
226
        </>
227
      )
228
    }
229
  }
230
 
231
  return (
232
    <>
233
      <Modal show={isOpen} onHide={closeShareModal} autoFocus={false}>
234
        <Modal.Header closeButton>
235
          <Modal.Title>{LABELS.SHARE_A_POST}</Modal.Title>
236
        </Modal.Header>
237
        <form encType="multipart/form-data" onSubmit={handleSubmit(onSubmit)}>
238
          <Modal.Body>
239
            {SharedWithSelectRender()}
240
            <CKEditor
241
              data={watch('description')}
242
              onChange={(e) => {
243
                const text = e.editor.getData()
244
                setValue('description', text)
245
                if (errors.description && getValues('description'))
246
                  clearErrors('description')
247
              }}
248
              config={CKEDITOR_OPTIONS}
249
              name="description"
250
              onDialogShow={() => {
251
                const modal = document.querySelector('.fade.modal.show')
252
                modal.removeAttribute('tabindex')
253
              }}
254
              onBeforeLoad={() => {
255
                setIsCKEditorLoading(false)
256
              }}
257
            />
258
            {isCKEditorLoading && <Spinner />}
259
            {errors.description && (
260
              <FormErrorFeedback>
261
                {errors.description.message}
262
              </FormErrorFeedback>
263
            )}
264
 
265
            {dropZoneRender()}
266
            {errors.file && (
267
              <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
268
            )}
269
          </Modal.Body>
270
          <Modal.Footer>
271
            <Button size="sm" type="submit">
272
              {LABELS.SEND}
273
            </Button>
274
            <Button
275
              color="danger"
276
              size="sm"
277
              variant="danger"
278
              onClick={closeShareModal}
279
            >
280
              {LABELS.CANCEL}
281
            </Button>
282
          </Modal.Footer>
283
        </form>
284
        {loading && <Spinner />}
285
      </Modal>
286
      <ConfirmModal
287
        show={showConfirmModal}
288
        onClose={handleModalCancel}
289
        onAccept={handleModalAccept}
290
        message="¿No se ha compartido tu publicación , desea descartarlo?"
291
      />
292
    </>
293
  )
294
}
295
 
296
const mapStateToProps = (state) => ({
297
  isOpen: state.shareModal.isOpen,
298
  postUrl: state.shareModal.postUrl,
299
  modalType: state.shareModal.modalType,
300
  lastModalType: state.shareModal.lastModalType,
301
  feedType: state.shareModal.feedType,
302
  feedSharedId: state.shareModal.feedSharedId,
303
})
304
 
305
const mapDispatchToProps = {
306
  addNotification: (notification) => addNotification(notification),
307
  closeShareModal: () => closeShareModal(),
308
  openShareModal: (postUrl, modalType, feedType) =>
309
    openShareModal(postUrl, modalType, feedType),
310
  setModalType: (modalType) => setModalType(modalType),
311
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
312
  fetchFeeds: (url, page) => fetchFeeds(url, page),
313
}
314
 
315
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal)