Proyectos de Subversion LeadersLinked - SPA

Rev

| Ultima modificación | Ver Log |

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