Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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