Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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