Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 1366 | Rev 2043 | 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";
19
import { axios } 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
              }}
271
              config={{
272
                startupFocus: "end",
766 steven 273
                allowedContent: false,
1169 steven 274
                image_previewText: ' ',
771 steven 275
                toolbarGroups: [
774 steven 276
                  // { name: 'document',	   groups: [ 'mode', 'document', 'doctools' ] },
775 steven 277
                  // { name: 'clipboard',   groups: [ 'undo' ] },
1018 stevensc 278
                  { name: 'editing', groups: ['find', 'selection', 'spellchecker'] },
773 steven 279
                  { name: 'forms' },
1018 stevensc 280
                  { name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
281
                  { name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] },
773 steven 282
                  { name: 'links' },
283
                  { name: 'insert' },
771 steven 284
                  { name: 'styles' },
285
                  { name: 'colors' },
286
                  { name: 'tools' },
287
                  { name: 'others' },
1119 steven 288
                ],
2042 steven 289
                removeButtons: 'Anchor,Scayt',
290
                removePlugins: 'elementspath,Anchor,wsc,scayt'
1 www 291
              }}
292
              name="description"
293
              onBeforeLoad={() => {
294
                setIsCKEditorLoading(false);
1018 stevensc 295
                ("Ready");
296
                ("Ready");
1 www 297
              }}
298
            />
299
            {isCKEditorLoading && (
300
              <StyledSpinnerContainer>
301
                <Spinner />
302
              </StyledSpinnerContainer>
303
            )}
304
            {errors.description && (
305
              <FormErrorFeedback>
306
                {errors.description.message}
307
              </FormErrorFeedback>
308
            )}
309
 
310
            {dropZoneRender()}
311
            {errors.file && (
312
              <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
313
            )}
314
          </Modal.Body>
315
          <Modal.Footer>
316
            <Button size="sm" type="submit">Enviar</Button>
317
            <Button color="danger" size="sm" variant="danger" onClick={closeShareModal}>
318
              Cancelar
319
            </Button>
320
          </Modal.Footer>
321
        </form>
322
        {loading ? (
323
          <StyledSpinnerContainer>
324
            <Spinner />
325
          </StyledSpinnerContainer>
326
        ) : (
327
          ""
328
        )}
329
      </Modal>
330
      <ConfirmModal
331
        show={showConfirmModal}
332
        onClose={handleModalCancel}
333
        onAccept={handleModalAccept}
334
        acceptLabel="Aceptar"
335
        message="No se ha compartido tu publicación , desea descartarlo?"
336
      />
337
    </React.Fragment>
338
  );
339
};
340
 
341
const mapStateToProps = (state) => ({
342
  isOpen: state.shareModal.isOpen,
343
  postUrl: state.shareModal.postUrl,
344
  modalType: state.shareModal.modalType,
345
  lastModalType: state.shareModal.lastModalType,
346
  feedType: state.shareModal.feedType,
1020 stevensc 347
  feedSharedId: state.shareModal.feedSharedId,
1 www 348
});
349
 
350
const mapDispatchToProps = {
351
  addNotification: (notification) => addNotification(notification),
352
  closeShareModal: () => closeShareModal(),
1021 stevensc 353
  openShareModal: (postUrl, modalType, feedType) => openShareModal(postUrl, modalType, feedType),
1 www 354
  setModalType: (modalType) => setModalType(modalType),
1022 stevensc 355
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
1005 steven 356
  fetchFeeds: (url, page) => fetchFeeds(url, page),
1 www 357
};
358
 
359
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal);