Proyectos de Subversion LeadersLinked - SPA

Rev

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>
    </>
  );
}