Criação da estrutura

  1. Nós iremos primeiro criar um arquivo dentro de “courses”, chamado “episode” e teremos um arquivo dinâmico nele também, chamado “[id].tsx”

  2. Iremos então criar para esse arquivo de página (head e main) um estilo dentro de “styles” chamado “episodePlayer.module.scss”

    import styles from "../../../styles/episodePlayer.module.scss";
    import Head from "next/head";
    
    const EpisodePlayer = function () {
      return (
        <>
          <Head>
            <title>Onebitflix - {"episodeTitle"}</title>
            <link rel="shortcut icon" href="/favicon.svg" type="image/x-icon" />
          </Head>
          <main></main>
        </>
      );
    };
    
    export default EpisodePlayer;
    
  3. Agora, nós iremos em “episodeList” e iremos criar o router no arquivo.

    const router = useRouter();
    
  4. Nós iremos agora criar um handle chamado “handleEpisodePlayer”, ele vai mandar a pessoa para o episódio clicado na lista.

    1. Nós iremos usar o “episode.order”, pois ele vai indicar qual episódio pegamos do array. Iremos usar também um “-1”, para ele estar de acordo com o array, pois o order começa com 1.

      	const handleEpisodePlayer = () => {
          router.push(
            `/courses/episode/${episode.order - 1}`
          );
        };
      
  5. Agora, iremos em “episodeCard”, criaremos um “onClick” e colocaremos esse handle nele.

    <div className={styles.episodeCard} onClick={handleEpisodePlayer}>
    
  6. Agora, nós podemos clicar em um card e seremos enviados para a página criada, e na url poderemos ver a posição do episódio no array (se for o episódio 1, veremos 0)

  7. Agora, faremos o envio do id do curso

    	const handleEpisodePlayer = () => {
        router.push(`/courses/episode/${episode.order - 1}?courseid=${course.id}`);
      };
    
  8. Com isso, nós iremos receber também o id do curso através da url. Nós então vamos pegar agora o “episodeOrder” e também “courseId”

    1. O “episodeOrder” vai precisar ser um número, então vamos transformar ele na hora de pegar ele com o “parseFloat”

      const episodeOrder = parseFloat(router.query.id?.toString() || "");
      const courseId = router.query.courseid?.toString() || "";
      
  9. Agora nós iremos pegar o header e vamos colocar ele dentro de “main”, usaremos o header gerêrico.

    <HeaderGeneric logoUrl="/home" btnContent={`Voltar para o curso`} btnUrl={`/courses/${courseId}`} />
    
  10. Agora, nós vamos fazer a parte do player em si. Mas antes, nós vamos precisar fazer a função “getCourse” de novo. Vamos então copiar ela do arquivo “[id]”, dentro da página de courses.

    	const [course, setCourse] = useState<CourseType>();
    
      const getCourse = async function () {
        if (typeof courseId !== "string") return;
    
        const res = await courseService.getEpisodes(courseId);
        if (res.status === 200) {
          setCourse(res.data);
        }
      };
    
      useEffect(() => {
        getCourse();
      }, [courseId]);
    
  11. Nós vamos fazer um spinner para retornarmos na verificação que iremos fazer. Essa página de spinner também será retornada quando estivermos fazendo a verificação de autenticação.

    1. Vamos então em “components”, em “common” e iremos criar uma pasta chamada “pageSpinner”, apenas com um “index.tsx”
    const pageSpinner = function () {
      return <div></div>;
    };
    
    export default pageSpinner;
    
  12. Agora, nós iremos configurar esse spinner. Nós iremos colocar uma altura mínima na nossa div, um background e também um alinhamento horizontal e vertical. E dentro da div colocaremos um spinner com a animação de giro, com a cor branca.

    import { Spinner } from "reactstrap";
    
    const PageSpinner = function () {
      return (
        <div className="vh-100 bg-dark d-flex justify-content-center align-items-center">
          <Spinner animation="border" color="light" />
        </div>
      );
    };
    
    export default PageSpinner;
    
  13. Agora vamos fazer uma verificação: Se o curso for undefined, nós iremos retornar essa página

    if (course?.episodes == undefined) return <PageSpinner />;
    
  14. Agora, nós podemos colocar o “courseid” na url como “124” (um id de curso inexistente, pode ser outro) e iremos ver que vai ficar para sempre essa página rodando. Essa página também aparece no episódio de fato enquanto o episódio carrega, pois por um momento, o “course” é undefined.

  15. Agora, nós podemos colocar de fato as informações na página, começando pelo título do head.

    <Head>
    	<title>Onebitflix - {course.episodes[episodeOrder].name}</title>
      <link rel="shortcut icon" href="/favicon.svg" type="image/x-icon" />
    </Head>
    
  16. Agora iremos fazer a criação de um container, esse container vai fazer uma centralização com o flex, também usaremos espaçementos para ele.

    <Container className="d-flex flex-column align-items-center gap-3 pt-3"></Container>
    
  17. Agora, nós iremos fazer a criação de um título, para nós colocarmos o título do episódio

    <p className={styles.episodeTitle}>
    	{course.episodes[episodeOrder].name}
    </p>
    
  18. Agora, nós iremos fazer a instalação de player para colocarmos o vídeo. É o react-player, iremos usar ele pois tem algumas otimizações para o react/next ⇒ https://github.com/CookPete/react-player

    npm install react-player
    
  19. Agora, nós faremos uma renderização condicional com ele. Nós iremos verificar se ele a nossa janela já foi carregada, se não foi carregada, não iremos renderizar ele, se foi, nós vamos renderizar.

    {typeof window == "undefined" ? null : (
    	<ReactPlayer
    	  className={styles.player}
        url={}
        controls
       />
    )}