Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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