Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
639 stevensc 1
import React, { useEffect, useState } from "react";
2
import { axios } from "../../utils";
3
import { useLocation } from "react-router-dom";
4
import { getBackendVars } from "../../services/backendVars";
5
import { addNotification } from "../../redux/notification/notification.actions";
6
import { Col, Container, Row } from "react-bootstrap";
7
import { useDispatch, useSelector } from "react-redux";
8
import parse from "html-react-parser";
5 stevensc 9
 
639 stevensc 10
import TungstenIcon from "@mui/icons-material/Tungsten";
11
import RecommendIcon from "@mui/icons-material/Recommend";
12
import FavoriteIcon from "@mui/icons-material/FavoriteTwoTone";
13
import SendOutlinedIcon from "@mui/icons-material/SendOutlined";
14
import ChatOutlinedIcon from "@mui/icons-material/ChatOutlined";
15
import EmojiEmotionsIcon from "@mui/icons-material/EmojiEmotions";
16
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
5 stevensc 17
 
639 stevensc 18
import {
19
  CommentForm,
20
  CommentsList,
21
} from "../../components/feed/CommentSection";
22
import HomeNews from "../../components/widgets/default/HomeNews";
23
import InputOption from "../../components/dashboard/linkedin/action-button/InputOption";
24
import withExternalShare from "../../components/dashboard/linkedin/withExternalShare";
25
import Paraphrase from "../../components/UI/Paraphrase";
26
import StyledContainer from "../../components/widgets/WidgetLayout";
27
import withReactions from "../../hocs/withReaction";
28
import MobileShare from "../../components/dashboard/linkedin/mobile-share/MobileShare";
520 stevensc 29
 
5 stevensc 30
const PostViewPage = () => {
639 stevensc 31
  const [post, setPost] = useState({});
32
  const [totalSends, setTotalSends] = useState(0);
33
  const [reactions, setReactions] = useState([]);
34
  const [myReaction, setMyReaction] = useState("");
35
  const [totalReactions, setTotalReactions] = useState(0);
36
  const [isMobile, setIsMobile] = useState(false);
37
  const [comments, setComments] = useState([]);
38
  const [showComments, setShowComments] = useState(false);
39
  const labels = useSelector(({ intl }) => intl.labels);
40
  const dispatch = useDispatch();
41
  const { pathname } = useLocation();
5 stevensc 42
 
43
  const reactionsOptions = [
44
    {
639 stevensc 45
      type: "r",
46
      icon: <RecommendIcon style={{ color: "#7405f9" }} />,
5 stevensc 47
    },
48
    {
639 stevensc 49
      type: "s",
50
      icon: <VolunteerActivismIcon style={{ color: "#6495ED" }} />,
5 stevensc 51
    },
52
    {
639 stevensc 53
      type: "l",
54
      icon: <FavoriteIcon style={{ color: "#DF704D" }} />,
5 stevensc 55
    },
56
    {
639 stevensc 57
      type: "i",
5 stevensc 58
      icon: (
59
        <TungstenIcon
639 stevensc 60
          style={{ color: "#F5BB5C", transform: "rotate(180deg)" }}
5 stevensc 61
        />
62
      ),
63
    },
64
    {
639 stevensc 65
      type: "f",
66
      icon: <EmojiEmotionsIcon style={{ color: "#FF7F50" }} />,
5 stevensc 67
    },
639 stevensc 68
  ];
5 stevensc 69
 
70
  const displayCommentSection = () => {
639 stevensc 71
    setShowComments(!showComments);
72
  };
5 stevensc 73
 
74
  const getComments = () => {
75
    axios.get(post.comments_url).then((response) => {
639 stevensc 76
      const { data, success } = response.data;
5 stevensc 77
 
78
      if (!success) {
79
        const errorMessage =
639 stevensc 80
          typeof data === "string" ? data : "Error interno. Intente más tarde.";
5 stevensc 81
 
639 stevensc 82
        dispatch(addNotification({ style: "danger", msg: errorMessage }));
83
        return;
5 stevensc 84
      }
85
 
639 stevensc 86
      setComments(data);
87
    });
88
  };
5 stevensc 89
 
90
  const handleExternalShare = (value) => {
639 stevensc 91
    setTotalSends(value);
92
  };
5 stevensc 93
 
94
  const ExternalShareButton = withExternalShare(
95
    InputOption,
520 stevensc 96
    post.share_external_url
639 stevensc 97
  );
5 stevensc 98
 
639 stevensc 99
  const ReactionButton = withReactions(InputOption, {
100
    saveUrl: post.save_reaction_url,
101
    deleteUrl: post.delete_reaction_url,
102
    currentReaction: myReaction,
103
    onSelect: (reactions) => setReactions(reactions),
104
  });
105
 
5 stevensc 106
  const addComment = ({ comment }) => {
639 stevensc 107
    const formData = new FormData();
108
    formData.append("comment", comment);
5 stevensc 109
 
110
    axios.post(post.comments_add_url, formData).then((response) => {
639 stevensc 111
      const { success, data } = response.data;
5 stevensc 112
 
113
      if (!success) {
114
        const errorMessage =
639 stevensc 115
          typeof data === "string" ? data : "Error interno. Intente más tarde.";
5 stevensc 116
 
639 stevensc 117
        dispatch(addNotification({ style: "danger", msg: errorMessage }));
118
        return;
5 stevensc 119
      }
120
 
639 stevensc 121
      setComments((prevMessages) => [...prevMessages, data]);
122
    });
123
  };
5 stevensc 124
 
125
  const deleteComment = (commentUnique, deleteCommentUrl) => {
126
    axios
127
      .post(deleteCommentUrl)
128
      .then((response) => {
639 stevensc 129
        const { success, data } = response.data;
5 stevensc 130
 
131
        if (!success) {
132
          const errorMessage =
639 stevensc 133
            typeof data === "string"
5 stevensc 134
              ? data
639 stevensc 135
              : "Error interno. Intente más tarde.";
5 stevensc 136
 
639 stevensc 137
          dispatch(addNotification({ style: "danger", msg: errorMessage }));
138
          return;
5 stevensc 139
        }
140
 
141
        setComments((prevComments) =>
142
          prevComments.filter((comment) => comment.unique !== commentUnique)
639 stevensc 143
        );
144
        dispatch(addNotification({ style: "success", msg: data }));
5 stevensc 145
      })
146
      .catch((error) => {
639 stevensc 147
        dispatch(addNotification({ style: "danger", msg: error }));
148
        throw new Error(error);
149
      });
150
  };
5 stevensc 151
 
152
  useEffect(() => {
153
    getBackendVars(pathname)
154
      .then((post) => {
639 stevensc 155
        setMyReaction(post.my_reaction);
156
        setTotalSends(post.total_share_external);
157
        setPost(post);
5 stevensc 158
      })
520 stevensc 159
      .catch(() => {
5 stevensc 160
        dispatch(
161
          addNotification({
639 stevensc 162
            style: "danger",
163
            message: "Error interno. Por favor, inténtelo de nuevo más tarde.",
5 stevensc 164
          })
639 stevensc 165
        );
166
      });
167
  }, [pathname]);
5 stevensc 168
 
169
  useEffect(() => {
170
    if (showComments && !comments.length) {
639 stevensc 171
      getComments();
5 stevensc 172
    }
639 stevensc 173
  }, [showComments]);
5 stevensc 174
 
175
  useEffect(() => {
176
    const feedReactions = reactions.reduce(
177
      (acc, reaction) => acc + Number(reaction.total),
178
 
639 stevensc 179
    );
5 stevensc 180
 
639 stevensc 181
    setTotalReactions(feedReactions);
182
  }, [reactions]);
5 stevensc 183
 
639 stevensc 184
  useEffect(() => {
185
    const ua = navigator.userAgent.toLowerCase();
186
    const isAndroid = ua.includes("android");
187
 
188
    if (isAndroid) {
189
      setIsMobile(true);
190
    }
191
  }, []);
192
 
5 stevensc 193
  return (
194
    <Container>
195
      <Row>
196
        <Col md="8">
639 stevensc 197
          <StyledContainer>
198
            <img src={post.image} />
199
            <StyledContainer.Header title={post.title} />
200
            <StyledContainer.Body>
520 stevensc 201
              <Paraphrase>{post.description}</Paraphrase>
5 stevensc 202
              {post.file && (
203
                <a href={post.file} download>
639 stevensc 204
                  <img src="/images/extension/pdf.png" alt="pdf" />
5 stevensc 205
                </a>
206
              )}
639 stevensc 207
            </StyledContainer.Body>
5 stevensc 208
            <div className="d-flex justify-content-between align-items-center px-3">
209
              <div className="reactions-counter">
210
                {reactionsOptions
211
                  .filter((option) =>
212
                    reactions.find(({ reaction }) => reaction === option.type)
213
                  )
214
                  .map((reaction) => reaction.icon)}
215
                <span>{totalReactions} reacciones</span>
216
              </div>
217
              {!!totalSends && (
218
                <span>{`${totalSends} ${labels.sends?.toLowerCase()}`}</span>
219
              )}
220
            </div>
639 stevensc 221
            <StyledContainer.Actions>
222
              <ReactionButton />
5 stevensc 223
              <InputOption
520 stevensc 224
                icon={ChatOutlinedIcon}
225
                iconColor="gray"
639 stevensc 226
                label={labels.comment}
5 stevensc 227
                onClick={displayCommentSection}
228
              />
639 stevensc 229
              {!isMobile ? (
230
                <ExternalShareButton
231
                  icon={SendOutlinedIcon}
232
                  iconColor="gray"
233
                  label={labels.send}
234
                  shareUrl={post.increment_external_counter_url}
235
                  setValue={handleExternalShare}
236
                />
237
              ) : (
238
                <MobileShare
239
                  shareData={{
240
                    title: "Leaders Linked",
241
                    text: parse(post.description),
242
                    url: post.share_external_url,
243
                  }}
244
                >
245
                  <SendOutlinedIcon />
246
                  {labels.send}
247
                </MobileShare>
248
              )}
249
            </StyledContainer.Actions>
5 stevensc 250
            {showComments && (
251
              <>
252
                <CommentForm onSubmit={addComment} />
253
                <CommentsList comments={comments} onDelete={deleteComment} />
254
              </>
255
            )}
639 stevensc 256
          </StyledContainer>
5 stevensc 257
        </Col>
258
        <Col md="4">
259
          <HomeNews currentPost={post.uuid} />
260
        </Col>
261
      </Row>
262
    </Container>
639 stevensc 263
  );
264
};
5 stevensc 265
 
639 stevensc 266
export default PostViewPage;