Proyectos de Subversion LeadersLinked - SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3481 stevensc 1
import React, { useState } from "react";
2
import { useNavigate, useParams } from "react-router-dom";
3
import { connect } from "react-redux";
4
import { styled } from "@mui/material";
5
import { CheckCircle } from "@mui/icons-material";
6
import parse from "html-react-parser";
7
 
8
import { axios } from "@app/utils";
9
import { addNotification } from "@app/redux/notification/notification.actions";
10
import { useFetch } from "@hooks";
11
 
12
import { FILE_TYPE_LABELS } from "@app/constants/files";
13
 
14
import Button from "@app/components/UI/buttons/Buttons";
15
import Spinner from "@app/components/UI/Spinner";
16
import WidgetWrapper from "@app/components/widgets/WidgetLayout";
17
import MicrolearningLayout from "@app/layouts/micro-learning/GoBack";
18
 
19
const Slide = styled(WidgetWrapper)`
20
  margin: auto;
21
  width: fit-content;
22
  svg {
23
    position: absolute;
24
    top: 1rem;
25
    right: 1rem;
26
  }
27
  img,
28
  video {
29
    max-width: 400px;
30
    max-height: 400px;
31
    object-fit: contain;
32
  }
33
  button {
34
    position: absolute;
35
    bottom: 1rem;
36
    right: 1rem;
37
  }
38
`;
39
 
40
const SlideViewPage = ({ addNotification }) => {
41
  const { uuid } = useParams();
42
  const {
43
    data: slide,
44
    isLoading,
45
    mutate,
46
  } = useFetch(`/microlearning/get-slide/${uuid}`, {});
47
  const [displayFile, setDisplayFile] = useState(false);
48
  const navigate = useNavigate();
49
 
50
  const closeParent = async (url = "") => {
51
    const response = await axios.post(url);
52
    const { data, success } = response.data;
53
 
54
    if (!success) {
55
      const errorMessage =
56
        typeof data === "string"
57
          ? data
58
          : Object.entries(data)
59
              .map(([key, value]) => `${key}: ${value}`)
60
              .join(", ");
61
      throw new Error(errorMessage);
62
    }
63
 
64
    const resMsg = data.message ?? data;
65
    addNotification({ style: "success", msg: resMsg });
66
  };
67
 
68
  const markCompleted = async () => {
69
    try {
70
      const response = await axios.post(slide?.link_sync);
71
      const { data, success } = response.data;
72
 
73
      if (!success) {
74
        const errorMessage =
75
          typeof data === "string"
76
            ? data
77
            : Object.entries(data)
78
                .map(([key, value]) => `${key}: ${value}`)
79
                .join(", ");
80
        throw new Error(errorMessage);
81
      }
82
 
83
      if (data.link_close_capsule) {
84
        await closeParent(data?.link_close_capsule);
85
        navigate("/microlearning");
86
      }
87
 
88
      if (data.link_close_topic) {
89
        await closeParent(data?.link_close_topic);
90
      }
91
 
92
      const resMsg = data.message ?? data;
93
      addNotification({ style: "success", msg: resMsg });
94
      mutate({ ...slide, completed: 1 });
95
    } catch (error) {
96
      addNotification({ style: "danger", msg: error.message });
97
    } finally {
98
      setDisplayFile(false);
99
    }
100
  };
101
 
102
  const renderFile = (type = "video") => {
103
    switch (type) {
104
      case "video": {
105
        return (
106
          <>
107
            {displayFile ? (
108
              <video controls controlsList="nodownload" onEnded={markCompleted}>
109
                <source src={slide?.file} />
110
              </video>
111
            ) : (
112
              <>
113
                <img src={slide?.background} alt={slide?.name} />
114
                <Button
115
                  color="primary"
116
                  onClick={() => setDisplayFile(!displayFile)}
117
                >
118
                  {FILE_TYPE_LABELS[slide?.type]}
119
                </Button>
120
              </>
121
            )}
122
          </>
123
        );
124
      }
125
 
126
      case "image": {
127
        return <img src={slide?.file} alt={slide?.name} />;
128
      }
129
 
130
      case "audio": {
131
        return (
132
          <>
133
            {displayFile ? (
134
              <audio
135
                controls
136
                src={slide?.file}
137
                alt={slide?.name}
138
                onEnded={markCompleted}
139
              />
140
            ) : (
141
              <>
142
                <img src={slide?.background} alt={slide?.name} />
143
                <Button
144
                  color="primary"
145
                  onClick={() => setDisplayFile(!displayFile)}
146
                >
147
                  {FILE_TYPE_LABELS[slide?.type]}
148
                </Button>
149
              </>
150
            )}
151
          </>
152
        );
153
      }
154
 
155
      case "text": {
156
        return parse(slide?.description);
157
      }
158
 
159
      case "document": {
160
        return (
161
          <a href={slide?.file} target="_blank" rel="noreferrer">
162
            <img className="pdf" src="/images/extension/pdf.png" alt="pdf" />
163
          </a>
164
        );
165
      }
166
 
167
      default:
168
        return (
169
          <>
170
            {displayFile ? (
171
              <video controls controlsList="nodownload" onEnded={markCompleted}>
172
                <source src={slide?.file} />
173
              </video>
174
            ) : (
175
              <>
176
                <img src={slide?.background} alt={slide?.name} />
177
                <Button
178
                  color="primary"
179
                  onClick={() => setDisplayFile(!displayFile)}
180
                >
181
                  {FILE_TYPE_LABELS[slide?.type]}
182
                </Button>
183
              </>
184
            )}
185
          </>
186
        );
187
    }
188
  };
189
 
190
  if (isLoading) {
191
    return <Spinner />;
192
  }
193
 
194
  return (
195
    <MicrolearningLayout title={slide?.name}>
196
      <Slide>
197
        {slide?.completed && !displayFile ? (
198
          <CheckCircle color="success" />
199
        ) : null}
200
        {renderFile(slide?.type)}
201
      </Slide>
202
 
203
      <Button
204
        color="primary"
205
        disabled={slide?.completed}
206
        onClick={() => markCompleted()}
207
        sx={{ width: "100%", mt: 2 }}
208
      >
209
        Marcar como completado
210
      </Button>
211
    </MicrolearningLayout>
212
  );
213
};
214
 
215
const mapDispatchToProps = {
216
  addNotification: (notification) => addNotification(notification),
217
};
218
 
219
export default connect(null, mapDispatchToProps)(SlideViewPage);