Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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