Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

Rev Autor Línea Nro. Línea
1025 stevensc 1
import React, { useEffect, useState } from "react";
1 www 2
import { connect } from "react-redux";
3
import { useForm } from "react-hook-form";
4
import FormErrorFeedback from "../../../shared/form-error-feedback/FormErrorFeedback";
5
import FeedCommentTemplate from "./feed-comment/FeedCommentTemplate";
6
import { openShareModal as OpenShareModalAction } from "../../../redux/share-modal/shareModal.actions";
7
import { addNotification } from "../../../redux/notification/notification.actions";
8
import { deleteFeed } from "../../../redux/feed/feed.actions";
9
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
10
import parse from "html-react-parser";
1021 stevensc 11
import { axios } from "../../../utils";
1 www 12
import ConfirmModal from "../../../shared/confirm-modal/ConfirmModal";
57 steven 13
import { Modal } from "react-bootstrap";
1 www 14
import styles from "./feedTemplate.module.scss";
15
import { feedTypes } from "../../../redux/feed/feed.types";
16
 
17
const FeedTemplate = (props) => {
18
  // Destructuring feed data
19
  const {
20
    feed_unique,
21
    feed_id_encrypted,
22
    owner_name,
23
    owner_url,
24
    owner_image,
25
    owner_comments,
26
    owner_shared,
27
    owner_time_elapse,
28
    owner_description,
29
    owner_file_image,
30
    owner_file_video,
31
    owner_file_document,
32
    owner_file_image_preview,
33
    shared_name,
34
    shared_image,
35
    shared_time_elapse,
36
    shared_description,
37
    shared_file_video,
38
    shared_file_image_preview,
39
    shared_file_image,
40
    shared_file_document,
41
    feed_like_url,
42
    feed_unlike_url,
43
    feed_is_liked,
44
    feed_share_url,
45
    feed_delete_url,
46
    comments,
47
    comment_add_url,
48
  } = props.feed;
49
 
722 steven 50
  const [totalComments, setTotalComments] = useState(owner_comments || 0);
51
 
1 www 52
  // Destructuring redux
53
  const { feedType } = props;
54
  const { deleteFeed, addNotification, openShareModal } = props;
55
 
56
  const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
57
 
58
  // react hook form
59
  const { register, handleSubmit, errors } = useForm();
60
 
61
  const [commentsState, setCommentsState] = useState(comments);
1023 stevensc 62
  const [ownerShared, setOwnerShared] = useState(owner_shared);
1 www 63
 
64
  const [isReadMoreActive, setIsReadMoreActive] = useState(false);
65
  const [showConfirmModal, setShowConfirmModal] = useState(false);
56 steven 66
  const [show, setShow] = useState(false);
1 www 67
 
1024 stevensc 68
  useEffect(() => { setOwnerShared(owner_shared) }, [owner_shared]);
1026 stevensc 69
  useEffect(() => { console.log('Funciona') }, [owner_shared]);
56 steven 70
  const handleClose = () => setShow(false);
71
  const handleShow = () => setShow(true);
1 www 72
  const deleteFeedHandler = () => {
73
    axios.post(feed_delete_url).then((res) => {
74
      const data = res.data;
75
      if (data.success) {
76
        deleteFeed(feed_unique);
77
        addNotification({
78
          style: "success",
79
          msg: data.data,
80
        });
81
      } else {
82
        addNotification({
83
          style: "danger",
84
          msg: data.data,
85
        });
86
      }
87
    });
88
  };
89
 
90
  const handleShowConfirmModal = () => {
91
    setShowConfirmModal(!showConfirmModal);
92
  };
93
 
94
  const handleModalAccept = () => {
95
    deleteFeedHandler();
96
  };
97
 
98
  const likeHandler = (event, likeUrl) => {
99
    event.preventDefault();
100
    setFeedIsLiked(!feedIsLiked);
101
    axios.post(likeUrl).then((res) => {
102
      const resData = res.data;
103
      const { success, data } = resData;
104
      if (!success) {
105
        setFeedIsLiked((previousState) => !previousState);
106
        addNotification({
107
          style: "danger",
108
          msg: data,
109
        });
110
      }
111
    });
112
  };
113
 
114
  const submitCommentHandler = (data, e) => {
115
    const currentFormData = new FormData();
116
    for (let input in data) {
117
      currentFormData.append(input, data[input]);
118
    }
119
    axios.post(comment_add_url, currentFormData).then((res) => {
120
      const resData = res.data;
121
      const { data, success, total_comments } = resData;
122
      if (success) {
123
        const newComment = data;
722 steven 124
        setTotalComments(total_comments);
1 www 125
        setCommentsState([...commentsState, newComment]);
126
        e.target.reset();
127
      } else {
128
        addNotification({
129
          style: "danger",
130
          msg: data,
131
        });
132
      }
133
    });
134
  };
135
 
136
  const deleteCommentHandler = (commentUnique, deleteCommentUrl) => {
137
    axios
138
      .post(deleteCommentUrl)
139
      .then((res) => {
975 steven 140
        const { success, data, total_comments } = res.data;
1 www 141
        if (success) {
142
          const newCommentsState = commentsState.filter(
143
            (comment) => comment.unique !== commentUnique
144
          );
145
          setCommentsState(newCommentsState);
975 steven 146
          setTotalComments(total_comments);
1 www 147
        } else {
148
          addNotification({
149
            style: "danger",
150
            msg: data,
151
          });
152
        }
153
      })
154
      .catch((error) => {
155
        addNotification({
156
          style: "danger",
157
          msg: error.message,
158
        });
159
      });
160
  };
161
 
162
  const btnShareHandler = (event) => {
163
    event.preventDefault();
1018 stevensc 164
    openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique);
1 www 165
  };
166
 
167
  let commentsRender = null;
168
  if (commentsState.length) {
169
    commentsRender = (
170
      <div className={styles.commentSection}>
171
        <div className={`comment-sec comment-sec-${feed_unique}`}>
172
          <ul>
173
            {[...commentsState].reverse().map((commentData) => {
174
              const { unique } = commentData;
175
              return (
176
                <FeedCommentTemplate
177
                  commentData={commentData}
178
                  onDeleteHandler={deleteCommentHandler}
179
                  key={unique}
180
                />
181
              );
182
            })}
183
          </ul>
184
        </div>
185
      </div>
186
    );
187
  }
188
 
189
  let likeButton = feedIsLiked ? (
190
    <a
191
      href={feed_unlike_url}
192
      id={`btn-unlike-${feed_unique}`}
193
      data-feed-unique={feed_unique}
194
      className="btn-unlike"
195
      onClick={(event) => {
196
        likeHandler(event, feed_unlike_url);
197
      }}
198
    >
199
      <i className="fas fa-heart"></i>
200
      Ya no me gusta
201
    </a>
202
  ) : (
203
    <a
204
      href={feed_like_url}
205
      id={`btn-like-${feed_unique}`}
206
      data-feed-unique={feed_unique}
207
      className="btn-like"
208
      onClick={(event) => {
209
        likeHandler(event, feed_like_url);
210
      }}
211
    >
212
      <i className="far fa-heart"></i>
213
      Me gusta
214
    </a>
215
  );
216
 
217
  const readMoreHandler = (event) => {
218
    event.preventDefault();
219
    setIsReadMoreActive(!isReadMoreActive);
220
  };
221
 
222
  const htmlParsedText = (fullStringText) => {
223
    const fullText = parse(fullStringText);
224
    if (fullStringText.length > 500) {
225
      const shortenedString = fullStringText.substr(0, 500);
226
      const shortenedText = parse(`${shortenedString}... `);
227
      return (
228
        <React.Fragment>
229
          {isReadMoreActive ? fullText : shortenedText}
230
          <a
231
            href="#"
232
            onClick={(e) => {
233
              readMoreHandler(e);
234
            }}
235
          >
236
            {isReadMoreActive ? " Leer menos" : " Leer más"}
237
          </a>
238
        </React.Fragment>
239
      );
240
    } else {
241
      return fullText;
242
    }
243
  };
244
 
245
  let sharedName = null;
246
  if (shared_name) {
247
    sharedName = (
248
      <div className="shared-post-bar">
249
        <div className="post-bar">
250
          <div className="post_topbar">
251
            <div className="usy-dt">
252
              <img
253
                src={shared_image}
254
                alt=""
255
                style={{
256
                  width: "50px",
257
                  height: "auto",
258
                }}
259
              />
260
              <div className="usy-name">
261
                <h3>{shared_name}</h3>
262
                <span>
263
                  <img
264
                    style={{
265
                      width: "12px",
266
                      height: "auto",
267
                    }}
268
                    src="/images/clock.png"
269
                    alt=""
270
                  />
271
                  {shared_time_elapse}
272
                </span>
273
              </div>
274
            </div>
275
          </div>
276
          <div className="job_descp">
277
            <div className="show-read-more">
278
              {htmlParsedText(shared_description)}
279
            </div>
280
            {shared_file_image ? (
281
              <img src={shared_file_image} className="Entradas" />
282
            ) : null}
283
            {shared_file_video ? (
284
              <video
285
                src={shared_file_video}
286
                controls
287
                poster={shared_file_image_preview}
288
                preload="none"
289
              />
290
            ) : null}
291
            {shared_file_document ? (
292
              <a href={shared_file_document} target="_blank">
293
                Descargar
294
              </a>
295
            ) : null}
296
          </div>
297
        </div>
298
      </div>
299
    );
300
  }
59 steven 301
  const OwnerDescription = () => <div className="show-read-more">
302
    {htmlParsedText(owner_description)}
303
  </div>
55 steven 304
  const TopBar = () => <div className="post_topbar">
305
    <div className="usy-dt">
306
      <a href={owner_url}>
307
        <img
308
          src={owner_image}
309
          alt=""
310
          style={{
311
            width: "50px",
312
            height: "auto",
313
          }}
314
        />
315
      </a>
316
      <div className="usy-name">
317
        <a href={owner_url}>
318
          <h3>{owner_name}</h3>
319
        </a>
320
        <span>
321
          <img src="/images/clock.png" alt="" />
322
          {owner_time_elapse}
323
          {feed_delete_url ? (
324
            <a
325
              href="#"
326
              className="btn-feed-trash"
327
              data-link={feed_delete_url}
328
              data-feed-unique={feed_unique}
329
              onClick={(e) => {
330
                e.preventDefault();
331
                handleShowConfirmModal();
332
              }}
333
            >
334
              <i className="fa fa-trash"></i>
335
            </a>
336
          ) : null}
337
        </span>
338
      </div>
339
    </div>
340
  </div>
1 www 341
 
1021 stevensc 342
  const Content = ({ showDescription }) => <div className="job_descp">
58 steven 343
    {
344
      !!showDescription && (
59 steven 345
        <OwnerDescription />
58 steven 346
      )
347
    }
348
    {owner_file_image ? (
349
      <img src={owner_file_image} className="Entradas" />
350
    ) : null}
351
    {owner_file_video ? (
352
      <video
353
        src={owner_file_video}
354
        controls
355
        poster={owner_file_image_preview}
356
        preload="none"
357
      />
358
    ) : null}
359
    {owner_file_document ? (
360
      <a href={owner_file_document} target="_blank">
361
        Descargar
362
      </a>
363
    ) : null}
364
    {sharedName}
55 steven 365
  </div>
1 www 366
  return (
367
    <React.Fragment>
56 steven 368
      <Modal
369
        show={show}
370
        onHide={handleClose}
59 steven 371
        dialogClassName="modal-md"
56 steven 372
      >
373
        <div
374
          className="row"
375
        >
376
          <div
377
            className="col-md-8 col-sm-12 col-12"
378
          >
205 steven 379
            <Content
380
              showDescription
381
            />
56 steven 382
          </div>
383
          <div
384
            className="col-md-4 col-sm-12 col-12"
385
          >
386
            <TopBar />
59 steven 387
            <OwnerDescription />
56 steven 388
          </div>
389
        </div>
390
      </Modal>
718 steven 391
      <div className={styles.postContainer} >
58 steven 392
        <TopBar
393
          showDescription
394
        />
718 steven 395
        <div
396
          onClick={() => (owner_file_image || owner_file_video || owner_file_document) ? handleShow() : null}
397
        >
398
          <Content
399
            showDescription
400
          />
401
        </div>
1 www 402
        <div className="job-status-bar">
403
          <ul className="like-com">
404
            <li>{likeButton}</li>
405
            <li>
406
              <a
407
                href="#"
408
                id={`btn-comments-${feed_unique}`}
409
                className="btn-indicator"
410
              >
722 steven 411
                <i className="fas fa-comments"></i> {totalComments}
1 www 412
              </a>
413
            </li>
414
            <li>
415
              <a
416
                href="#"
417
                id={`btn-share-${feed_unique}`}
418
                className="btn-indicator"
419
              >
1023 stevensc 420
                <i className="fas fa-share"></i> {ownerShared}
1 www 421
              </a>
422
            </li>
423
          </ul>
424
          <a
425
            href={feed_share_url}
426
            data-feed-unique={feed_unique}
427
            className="btn-feed-share"
428
            onClick={(e) => {
429
              btnShareHandler(e);
430
            }}
431
          >
432
            <i className="fas fa-share"></i>Compartir
433
          </a>
434
        </div>
435
        {commentsRender}
436
        <div>
437
          <form
438
            className={`form-comment-feed-${feed_unique}`}
439
            data-feed-unique={feed_unique}
440
            onSubmit={handleSubmit(submitCommentHandler)}
441
          >
442
            <div className={styles.feedCommentContainer}>
443
              <input
444
                className={styles.commentInput}
445
                type="text"
446
                name="comment"
447
                id={`comment-${feed_unique}`}
448
                maxLength="256"
449
                placeholder="Escribe un comentario"
450
                ref={register({
451
                  required: {
452
                    value: "true",
453
                    message: "El campo es requerido",
454
                  },
455
                })}
456
              />
457
              <button type="submit" className={styles.submitButton}>
458
                Enviar
459
              </button>{" "}
460
              {/* Falta multilenguaje */}
461
            </div>
462
          </form>
463
          {errors.comment && (
464
            <FormErrorFeedback>{errors.comment.message}</FormErrorFeedback>
465
          )}
466
        </div>
467
      </div>
468
      <ConfirmModal
469
        show={showConfirmModal}
470
        onClose={() => {
471
          setShowConfirmModal(false);
472
        }}
473
        onAccept={handleModalAccept}
474
        acceptLabel="Aceptar"
475
      />
476
    </React.Fragment>
477
  );
478
};
479
 
480
const mapStateToProps = (state) => ({
481
  currentFeed: state.feed.currentFeed,
482
  isShareModalOpen: state.feed.isShareModalOpen,
483
  feedType: state.shareModal.feedType,
484
});
485
 
486
const mapDispatchToProps = {
487
  deleteFeed: (feedId) => deleteFeed(feedId),
1021 stevensc 488
  openShareModal: (postUrl, modalType, feedType, feed_unique) => OpenShareModalAction(postUrl, modalType, feedType, feed_unique),
1 www 489
  addNotification: (notification) => addNotification(notification),
490
};
491
 
492
export default connect(mapStateToProps, mapDispatchToProps)(FeedTemplate);