Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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