Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

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