Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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