-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d6de24a
commit 150ad4e
Showing
15 changed files
with
1,561 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/// <reference types="next" /> | ||
/// <reference types="next/types/global" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import format from 'date-fns/format'; | ||
import ptBR from 'date-fns/locale/pt-BR'; | ||
|
||
import styles from './styles.module.scss' | ||
|
||
export function Header() { | ||
const currentDate = format(new Date(), 'EEEEEE, d MMMM', { | ||
locale: ptBR, | ||
}); | ||
|
||
return ( | ||
<header className={styles.headerContainer}> | ||
<img src="logo.svg" alt="Podcastr" /> | ||
|
||
<p>O melhor para você ouvir, sempre</p> | ||
|
||
<span>{currentDate}</span> | ||
</header> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.headerContainer { | ||
background: var(--white); | ||
height: 6.5rem; | ||
|
||
display: flex; | ||
align-items: center; | ||
|
||
padding: 2rem 4rem; | ||
|
||
border-bottom: 1px solid var(--gray-100); | ||
|
||
p { | ||
margin-left: 2rem; | ||
padding: 0.25rem 0 0.25rem 2rem; | ||
border-left: 1px solid var(--gray-100); | ||
} | ||
|
||
span { | ||
margin-left: auto; | ||
text-transform: capitalize; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import styles from "./styles.module.scss"; | ||
|
||
export function Player() { | ||
return ( | ||
<div className={styles.playerContainer}> | ||
<header> | ||
<img src="/playing.svg" alt="Tocando agora" /> | ||
<strong>Tocando agora</strong> | ||
</header> | ||
|
||
<div className={styles.emptyPlayer}> | ||
<strong>Selecione um podcast para ouvir</strong> | ||
</div> | ||
|
||
<footer className={styles.empty}> | ||
<div className={styles.progress}> | ||
<span>00:00</span> | ||
<div className={styles.slider}> | ||
<div className={styles.emptySlider} /> | ||
</div> | ||
<span>00:00</span> | ||
</div> | ||
|
||
<div className={styles.buttons}> | ||
<button type="button"> | ||
<img src="/shuffle.svg" alt="Modo aleatório" /> | ||
</button> | ||
<button type="button"> | ||
<img src="/play-previous.svg" alt="Anterior" /> | ||
</button> | ||
<button type="button" className={styles.playButton}> | ||
<img src="/play.svg" alt="Tocar" /> | ||
</button> | ||
<button type="button"> | ||
<img src="/play-next.svg" alt="Próxima" /> | ||
</button> | ||
<button type="button"> | ||
<img src="/repeat.svg" alt="Repetir" /> | ||
</button> | ||
</div> | ||
</footer> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
.playerContainer { | ||
padding: 3rem 4rem; | ||
width: 26.5rem; | ||
height: 100vh; | ||
|
||
background: var(--purple-500); | ||
color: var(--white); | ||
|
||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: space-between; | ||
|
||
header { | ||
display: flex; | ||
align-items: center; | ||
gap: 1rem; | ||
} | ||
|
||
strong { | ||
font-family: Lexend, sans-serif; | ||
font-weight: 600; | ||
} | ||
|
||
footer { | ||
align-self: stretch; | ||
&.empty { | ||
opacity: 0.5; | ||
} | ||
} | ||
} | ||
|
||
.emptyPlayer { | ||
width: 100%; | ||
height: 20rem; | ||
border: 1.5px dashed var(--purple-300); | ||
border-radius: 1.5rem; | ||
background: linear-gradient( | ||
143.8deg, | ||
rgba(145, 100, 250, 0.8) 0%, | ||
rgba(0, 0, 0, 0) 100% | ||
); | ||
|
||
padding: 4rem; | ||
text-align: center; | ||
|
||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.progress { | ||
display: flex; | ||
align-items: center; | ||
gap: 0.5rem; | ||
font-size: 0.875rem; | ||
|
||
span { | ||
display: inline-block; | ||
width: 4rem; | ||
text-align: center; | ||
} | ||
|
||
.slider { | ||
flex: 1; | ||
|
||
.emptySlider { | ||
width: 100%; | ||
height: 4px; | ||
background: var(--purple-300); | ||
border-radius: 2px; | ||
} | ||
} | ||
} | ||
|
||
.buttons { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
margin-top: 2.5rem; | ||
gap: 1.5rem; | ||
|
||
button { | ||
background: transparent; | ||
border: 0; | ||
font-size: 0; | ||
|
||
&.playButton { | ||
width: 4rem; | ||
height: 4rem; | ||
border-radius: 1rem; | ||
background: var(--purple-400); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import "../styles/global.scss"; | ||
|
||
import { Header } from "../components/Header"; | ||
import { Player } from "../components/Player"; | ||
|
||
import styles from "../styles/app.module.scss"; | ||
|
||
function MyApp({ Component, pageProps }) { | ||
return ( | ||
<div className={styles.wrapper}> | ||
<main> | ||
<Header /> | ||
<Component {...pageProps} /> | ||
</main> | ||
<Player /> | ||
</div> | ||
); | ||
} | ||
|
||
export default MyApp; | ||
|
||
/* Toda página da aplicação é exibida dentro do App. Todo componente dentro do | ||
* App estará presente em todas as páginas da aplicação | ||
* | ||
* No React, um componente é formado por uma tag e sua respectiva função que | ||
* retorna código HTML. | ||
* | ||
* Como o return permite apenas o retorno de um componente, é necessário | ||
* envolver tudo com uma tag. Porém, essa tag "pai" ficará sozinha dentro de | ||
* "root" no HTML, sendo praticamente inútil. Por isso o React possui a tag em | ||
* branco (<></>). Dessa maneira, o browser monta todo o conteúdo retornado | ||
* pela função diretamente na tag root do HTML. Não utilizamos nesse trecho pois | ||
* foi necessário incluir uma classe para essa tag externa. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* Sempre que trocamos de rota, o _app é recarregado. Então usamos o arquivo | ||
* _document para definir o formato do HTML que ficará "por fora" da aplicação. | ||
* Ele é carregado uma única vez. | ||
*/ | ||
|
||
import Document, { Html, Head, Main, NextScript } from 'next/document'; | ||
|
||
export default class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<Head> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" /> | ||
<link href="https://fonts.googleapis.com/css2?family=Inter&family=Lexend:wght@500;600&display=swap" rel="stylesheet" /> | ||
</Head> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Utilizamos nesse projeto um simulador de servidor que devolve JSON. | ||
|
||
/* SPA (single page application): a aplicação executa sempre na mesma página, | ||
* alterando apenas os elementos necessários. Para isso usamos useEffect. Essa | ||
* função dispara alguma coisa quando algo mudar. A arrow function será | ||
* executada quando alguem valor dentro das chaves mudar. Para que uma função | ||
* seja executada assim que o componente for exibido em tela (uma única vez), | ||
* basta deixar as chaves sem valores dentro. Essa estratégia não é interessante | ||
* quando se quer fazer a indexação de conteúdos da página. Os crawlers (robôs | ||
* que procuram conteúdo para indexar nas páginas de empresas, exemplo: crawler | ||
* do google, bing etc) não esperam a resposta do servidor com o conteúdo, assim | ||
* entendendem como se a página estivesse vazia. | ||
* | ||
* import { useEffect } from "react"; | ||
* | ||
* export default function Home() { | ||
* useEffect(() => { | ||
* fetch("http://localhost:3333/episodes") | ||
* .then((response) => response.json()) | ||
* .then((data) => console.log(data)); | ||
* }, []); | ||
* | ||
* return <h1>Index</h1>; | ||
* } | ||
*/ | ||
|
||
/* SSR (server side rendering): uma página é renderizada estaticamente com todos | ||
* os seus js e css. Para isso basta, dentro de qualquer página (pasta pages) | ||
* exportarmos a função getServerSideProps. Porém esssa função é executada TODA | ||
* vez que a home da aplicação é acessada. Se for uma página que sobre pouca | ||
* alteração (exemplo: a cada dua apenas um podcast é liberado), não tem o | ||
* porquê da home ter seus dados acessados na API toda vez (se o site tiver | ||
* um milhão de acessos simultâneos, para cada acesso haverá uma requisição à | ||
* API para o mesmo conteúdo). Isso será resolvido com a próxima abordagem. | ||
* | ||
* export default function Home(props) { | ||
* console.log(props.episodes); | ||
* return <h1>Index</h1>; | ||
* } | ||
* | ||
* export async function getServerSideProps() { | ||
* const response = await fetch("http://localhost:3333/episodes"); | ||
* const data = await response.json(); | ||
* | ||
* return { | ||
* props: { | ||
* episodes: data, | ||
* }, | ||
* }; | ||
* } | ||
*/ | ||
|
||
/* SSG (static site generation): quando uma página é acessada, é gerada uma | ||
* versão estática dela (HTML público). Todos os próximos acessos serão servidos | ||
* com essa mesma página estática até que uma nova página seja gerada | ||
* (definindo um intervalo de tempo em segundos para tal ação atrvés do | ||
* revalidate). No exemplo foi utilizado 60 * 60 * 8 = 8 horas. | ||
*/ | ||
|
||
export default function Home(props) { | ||
return ( | ||
<div> | ||
<h1>Index</h1> | ||
<p>{JSON.stringify(props.episodes)}</p> | ||
</div> | ||
); | ||
} | ||
export async function getStaticProps() { | ||
const response = await fetch("http://localhost:3333/episodes"); | ||
const data = await response.json(); | ||
return { | ||
props: { | ||
episodes: data, | ||
}, | ||
revalidate: 60 * 60 * 8, | ||
}; | ||
} | ||
|
||
/* O recurso SSG só funciona em produção, então para simulação, precisaremos | ||
* fazer uma build. Para isso, paramos a aplicação e deixamos somente o servidor | ||
* rodando. Comando: yarn build | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.wrapper { | ||
display: flex; | ||
|
||
main { | ||
flex: 1; | ||
} | ||
} |
Oops, something went wrong.