Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 1260 | Rev 1366 | 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
        }
1009 steven 178
        if (modalType !== shareModalTypes.SHARE) {
1008 steven 179
          console.log('>>: currentPage', currentPage, timelineUrl)
1009 steven 180
        }
1018 stevensc 181
        if (currentPage && timelineUrl) {
1009 steven 182
          fetchFeeds(timelineUrl, currentPage)
183
        }
1018 stevensc 184
 
1 www 185
      } else {
186
        if (data.data.description || data.data.file || data.data.share_width) {
187
          Object.entries(data.data).map(([key, value]) => {
188
            setError(key, { type: "required", message: value });
189
          });
190
        } else {
191
          addNotification({
192
            style: "danger",
193
            msg: "Ha ocurrido un error",
194
          });
195
        }
196
      }
197
    });
198
 
199
    setLoading(false);
200
  };
201
 
202
  const onUploadedHandler = (files) => {
203
    setValue("file", files);
204
    clearErrors("file");
205
  };
206
 
207
  const dropZoneRender = () => {
208
    if (
209
      modalType !== shareModalTypes.POST &&
210
      modalType !== shareModalTypes.SHARE
211
    ) {
212
      return (
213
        <DropzoneComponent
214
          modalType={modalType}
215
          onUploaded={onUploadedHandler}
216
          settedFile={getValues("file")}
217
          recomendationText={recomendationText()}
218
        />
219
      );
220
    }
221
  };
222
 
223
  const SharedWithSelectRender = () => {
224
    if (feedType === feedTypes.DASHBOARD) {
225
      return (
226
        <React.Fragment>
227
          <select
228
            // value={formData.shared_with}
229
            name="shared_with"
230
            id="shared_with"
231
            className="form-control"
232
            // onChange={(e) => onInputChangeHandler(e)}
233
            ref={register({
234
              required: "El campo es requerido",
235
            })}
236
            defaultValue="p"
237
          >
238
            <option disabled="disabled" value="" style={{ display: "none" }}>
239
              Compartir con
240
            </option>
241
            <option value="p">Público</option>
242
            <option value="c">Conexiones</option>
243
          </select>
244
          {errors.shared_with && (
245
            <FormErrorFeedback>{errors.shared_with.message}</FormErrorFeedback>
246
          )}
247
        </React.Fragment>
248
      );
249
    }
250
  };
251
 
252
  return (
253
    <React.Fragment>
254
      <Modal
255
        show={isOpen}
256
        onHide={closeShareModal}
943 steven 257
        autoFocus={false}
1 www 258
      >
259
        <Modal.Header closeButton>
260
          <Modal.Title>Compartir una publicación</Modal.Title>
261
        </Modal.Header>
262
        <form encType="multipart/form-data" onSubmit={handleSubmit(onSubmit)}>
263
          <Modal.Body>
264
            {SharedWithSelectRender()}
265
            <CKEditor
266
              data={watch("description")}
267
              onChange={(e) => {
268
                const text = e.editor.getData();
269
                setValue("description", text);
270
                if (errors.description && getValues(description)) {
271
                  clearErrors("description");
272
                }
273
              }}
274
              config={{
275
                startupFocus: "end",
766 steven 276
                allowedContent: false,
1169 steven 277
                image_previewText: ' ',
771 steven 278
                toolbarGroups: [
774 steven 279
                  // { name: 'document',	   groups: [ 'mode', 'document', 'doctools' ] },
775 steven 280
                  // { name: 'clipboard',   groups: [ 'undo' ] },
1018 stevensc 281
                  { name: 'editing', groups: ['find', 'selection', 'spellchecker'] },
773 steven 282
                  { name: 'forms' },
1018 stevensc 283
                  { name: 'basicstyles', groups: ['basicstyles', 'cleanup'] },
284
                  { name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align', 'bidi'] },
773 steven 285
                  { name: 'links' },
286
                  { name: 'insert' },
771 steven 287
                  { name: 'styles' },
288
                  { name: 'colors' },
289
                  { name: 'tools' },
290
                  { name: 'others' },
1119 steven 291
                ],
1126 steven 292
                removeButtons: 'Anchor',
1125 steven 293
                removePlugins: 'elementspath,Anchor'
1 www 294
              }}
295
              name="description"
296
              onBeforeLoad={() => {
297
                setIsCKEditorLoading(false);
1018 stevensc 298
                ("Ready");
299
                ("Ready");
1 www 300
              }}
301
            />
302
            {isCKEditorLoading && (
303
              <StyledSpinnerContainer>
304
                <Spinner />
305
              </StyledSpinnerContainer>
306
            )}
307
            {errors.description && (
308
              <FormErrorFeedback>
309
                {errors.description.message}
310
              </FormErrorFeedback>
311
            )}
312
 
313
            {dropZoneRender()}
314
            {errors.file && (
315
              <FormErrorFeedback>{errors.file.message}</FormErrorFeedback>
316
            )}
317
          </Modal.Body>
318
          <Modal.Footer>
319
            <Button size="sm" type="submit">Enviar</Button>
320
            <Button color="danger" size="sm" variant="danger" onClick={closeShareModal}>
321
              Cancelar
322
            </Button>
323
          </Modal.Footer>
324
        </form>
325
        {loading ? (
326
          <StyledSpinnerContainer>
327
            <Spinner />
328
          </StyledSpinnerContainer>
329
        ) : (
330
          ""
331
        )}
332
      </Modal>
333
      <ConfirmModal
334
        show={showConfirmModal}
335
        onClose={handleModalCancel}
336
        onAccept={handleModalAccept}
337
        acceptLabel="Aceptar"
338
        message="No se ha compartido tu publicación , desea descartarlo?"
339
      />
340
    </React.Fragment>
341
  );
342
};
343
 
344
const mapStateToProps = (state) => ({
345
  isOpen: state.shareModal.isOpen,
346
  postUrl: state.shareModal.postUrl,
347
  modalType: state.shareModal.modalType,
348
  lastModalType: state.shareModal.lastModalType,
349
  feedType: state.shareModal.feedType,
1020 stevensc 350
  feedSharedId: state.shareModal.feedSharedId,
1 www 351
});
352
 
353
const mapDispatchToProps = {
354
  addNotification: (notification) => addNotification(notification),
355
  closeShareModal: () => closeShareModal(),
1021 stevensc 356
  openShareModal: (postUrl, modalType, feedType) => openShareModal(postUrl, modalType, feedType),
1 www 357
  setModalType: (modalType) => setModalType(modalType),
1022 stevensc 358
  addFeed: (feed, feedSharedId) => addFeed(feed, feedSharedId),
1005 steven 359
  fetchFeeds: (url, page) => fetchFeeds(url, page),
1 www 360
};
361
 
362
export default connect(mapStateToProps, mapDispatchToProps)(ShareModal);