Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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