Rev 3481 | AutorÃa | Ultima modificación | Ver Log |
import React, { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { Button, styled } from '@mui/material';
import { CheckCircle } from '@mui/icons-material';
import parse from 'html-react-parser';
import { axios } from '@app/utils';
import { addNotification } from '@app/redux/notification/notification.actions';
import { useFetch } from '@hooks';
import { FILE_TYPE_LABELS } from '@app/constants/files';
import { Card, PageHeader, Spinner } from '@shared/components';
const Slide = styled(Card)`
margin: auto;
width: fit-content;
svg {
position: absolute;
top: 1rem;
right: 1rem;
}
img,
video {
max-width: 400px;
max-height: 400px;
object-fit: contain;
}
button {
position: absolute;
bottom: 1rem;
right: 1rem;
}
`;
export function SlideViewPage() {
const { uuid } = useParams();
const dispatch = useDispatch();
const { data: slide, isLoading, mutate } = useFetch(`/microlearning/get-slide/${uuid}`, {});
const [displayFile, setDisplayFile] = useState(false);
const navigate = useNavigate();
const closeParent = async (url = '') => {
const response = await axios.post(url);
const { data, success } = response.data;
if (!success) {
const errorMessage =
typeof data === 'string'
? data
: Object.entries(data)
.map(([key, value]) => `${key}: ${value}`)
.join(', ');
throw new Error(errorMessage);
}
const resMsg = data.message ?? data;
dispatch(addNotification({ style: 'success', msg: resMsg }));
};
const markCompleted = async () => {
try {
const response = await axios.post(slide?.link_sync);
const { data, success } = response.data;
if (!success) {
const errorMessage =
typeof data === 'string'
? data
: Object.entries(data)
.map(([key, value]) => `${key}: ${value}`)
.join(', ');
throw new Error(errorMessage);
}
if (data.link_close_capsule) {
await closeParent(data?.link_close_capsule);
navigate('/microlearning');
}
if (data.link_close_topic) {
await closeParent(data?.link_close_topic);
}
const resMsg = data.message ?? data;
dispatch(addNotification({ style: 'success', msg: resMsg }));
mutate({ ...slide, completed: 1 });
} catch (error) {
dispatch(addNotification({ style: 'danger', msg: error.message }));
} finally {
setDisplayFile(false);
}
};
const renderFile = (type = 'video') => {
switch (type) {
case 'video': {
return (
<>
{displayFile ? (
<video controls controlsList='nodownload' onEnded={markCompleted}>
<source src={slide?.file} />
</video>
) : (
<>
<img src={slide?.background} alt={slide?.name} />
<Button color='primary' onClick={() => setDisplayFile(!displayFile)}>
{FILE_TYPE_LABELS[slide?.type]}
</Button>
</>
)}
</>
);
}
case 'image': {
return <img src={slide?.file} alt={slide?.name} />;
}
case 'audio': {
return (
<>
{displayFile ? (
<audio controls src={slide?.file} alt={slide?.name} onEnded={markCompleted} />
) : (
<>
<img src={slide?.background} alt={slide?.name} />
<Button color='primary' onClick={() => setDisplayFile(!displayFile)}>
{FILE_TYPE_LABELS[slide?.type]}
</Button>
</>
)}
</>
);
}
case 'text': {
return parse(slide?.description);
}
case 'document': {
return (
<a href={slide?.file} target='_blank' rel='noreferrer'>
<img className='pdf' src='/images/extension/pdf.png' alt='pdf' />
</a>
);
}
default:
return (
<>
{displayFile ? (
<video controls controlsList='nodownload' onEnded={markCompleted}>
<source src={slide?.file} />
</video>
) : (
<>
<img src={slide?.background} alt={slide?.name} />
<Button color='primary' onClick={() => setDisplayFile(!displayFile)}>
{FILE_TYPE_LABELS[slide?.type]}
</Button>
</>
)}
</>
);
}
};
if (isLoading) {
return <Spinner />;
}
return (
<>
<PageHeader title={slide?.name} goBack />
<Slide>
{slide?.completed && !displayFile ? <CheckCircle color='success' /> : null}
{renderFile(slide?.type)}
</Slide>
<Button
color='primary'
disabled={slide?.completed}
onClick={() => markCompleted()}
sx={{ width: '100%', mt: 2 }}
>
Marcar como completado
</Button>
</>
);
}