Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

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