Neste último desafio você aplicará todo o conhecimento adquirido durante o curso e terá que desenvolver uma versão pocket do Spotify, integrada a Web API oficial, utilizando fluxo implícito de concessão (Implicit Grant Flow) para realizar a autenticação do usuário, permite que ele acesse rotas privadas dentro da aplicação.
https://viniciusvinna-react-pocket-spotify.netlify.app
Caso precise consultar o código fonte original para tirar dúvidas, você poderá acessar:
Neste desafio você vai praticar os seus conhecimentos em:
- Fetch API
- JS Funcional:
Map,Filter - Modularização:
BEM(Bloco, Elemento e Modificador) - Presentational e Container Components
- Rails-Style Structure
- React Hooks,
useState,useEffect,useRef - React Testing Library
- React
- React Router Dom
- Rotas Privadas
- Redux:
ActionTypes,Action Creators,Reducers,Store - Redux Persist:
LocalStorage
- Ser desenvolvido utilizando abordagem funcional com React Hooks.
- A aplicação deve possuir controle de estado global controlado pelo
Redux. - Consumir os dados do
Spotify Web API, utilizando oFetch APIdo Javascript e apenas o métodoGETnas requisições. - Atenticação deve utilizar o fluxo
Implicit Grant Flowda documentação ofial. - Rotas privadas devem redirecionar o usuário para a tela de login, caso o token de autenticação tenha expirado.
- A rota privada
/dashboarddeverá exibir a lista de categorias daSpotify Web API. - A rota privada
/dashboard/{categoria_id}deverá exibir a lista de playlists da categoria selecionada. - A rota privada
/dashboard/{categoria_id}/{playlist_id}deverá exibir a lista de faixas da playlist selecionada. - O usuário deverá ser capaz de reproduzir as faixas ao clicar em cada uma delas.
- A faixa deve continuar tocando enquanto o usuário navega por outras rotas, clicando no botão
voltar do navegadorou dainterface de usuário. - O player deve possuir os controles de
PlayePause. - Quando a música acabar o player deverá desaparecer da UI.
Antes de começar a desenvolver o projeto, primeiro você precisará criar uma conta de desenvolver no Spotify e registrar seu aplicativo:
Para utilizar a Web API, é necessário que você tenha uma conta de usuário (premium ou gratuita). Crie uma conta gratuita em www.spotify.com. Após criar a conta, acesse a página
Dashboardhttps://developer.spotify.com/dashboard.
Registre seu APP sem fins comerciais:
Após concluir o registro você será redirecionado(a) para página de analytics do
React Pocket Spotifyonde serão revelados os tokensClient IDeClient Secret. Você precisará apenas do ClientID para realizar as requisições do Spotify Web API.
Nesse projeto vamos utilizar o fluxo implícito de concessão é para
clientesimplementados inteiramente usando JavaScript e em execução no navegador do proprietário do recurso.Leia mais na seção
Implicit Grant Flowem https://developer.spotify.com/documentation/general/guides/authorization-guide
- Documentação oficial: https://developer.spotify.com/documentation/web-api/reference
A estrutura de pastas utilizada é conhecida como
Rails-Style Structure (function-first organization)com um arquivo index por pasta de feature levemente inspirada no Destiny: Prettier for File Structures:
.
├── actions
│ ├── auth.js
│ ├── content.js
│ ├── index.js
│ └── user.js
├── assets
│ ├── icons
│ │ ├── spotify-icon-green.svg
│ │ └── spotify-icon-white.svg
│ ├── images
│ │ ├── app-intro-1.jpg
│ │ └── app-intro-2.jpg
│ └── logos
│ ├── spotify-logo-green.svg
│ └── spotify-logo-white.svg
├── components
│ ├── Loading
│ │ ├── Loading.jsx
│ │ └── Loading.scss
│ ├── Logo
│ │ └── Logo.jsx
│ ├── RouteHeader
│ │ ├── RouteHeader.jsx
│ │ └── RouteHeader.scss
│ ├── WelcomeBox
│ │ ├── WelcomeBox.jsx
│ │ └── WelcomeBox.scss
│ └── index.jsx
├── config
│ └── index.js
├── constants
│ ├── auth.js
│ ├── content.js
│ └── user.js
├── containers
│ ├── App
│ │ ├── App.jsx
│ │ └── App.scss
│ ├── Authorize
│ │ ├── Authorize.jsx
│ │ └── Authorize.scss
│ ├── Categories
│ │ ├── Categories.jsx
│ │ ├── Categories.scss
│ │ └── CategoryItem.jsx
│ ├── Dashboard
│ │ ├── Dashboard.jsx
│ │ └── Dashboard.scss
│ ├── Login
│ │ ├── Login.jsx
│ │ └── Login.scss
│ ├── Player
│ │ ├── Player.jsx
│ │ └── Player.scss
│ ├── Playlists
│ │ ├── PlaylistItem.jsx
│ │ ├── Playlists.jsx
│ │ └── Playlists.scss
│ ├── PrivateRoute
│ │ └── PrivateRoute.jsx
│ ├── Topbar
│ │ ├── Topbar.jsx
│ │ └── Topbar.scss
│ ├── Tracks
│ │ ├── Track.jsx
│ │ ├── Track.scss
│ │ ├── Tracks.jsx
│ │ └── Tracks.scss
│ └── index.jsx
├── index.js
├── modules
│ ├── custom-hooks.js
│ ├── endpoints.js
│ ├── helpers.js
│ ├── request.js
│ └── url.js
├── reducers
│ ├── app.js
│ ├── auth.js
│ ├── content.js
│ ├── index.js
│ └── user.js
├── routes
│ ├── AuthorizeRoute.jsx
│ ├── DashboardRoute.jsx
│ ├── LoginRoute.jsx
│ ├── PlaylistsRoute.jsx
│ ├── TracksRoute.jsx
│ └── index.jsx
├── serviceWorker.js
├── setupTests.js
├── store
│ └── index.js
└── styles
├── globalStyles.scss
├── normalize.scss
└── reset.scssPara que seu teste seja avaliado corretamente na plataforma é necessário que os Componentes e Contêineres tenham tenham os atributos data-testid atribuídos aos seguintes componentes
.
├── components
│ ├── Loading
│ │ └── Loading.jsx ➡️ data-testid="loading"
│ ├── Logo
│ │ └── Logo.jsx ➡️ data-testid="logo"
│ ├── RouteHeader
│ │ └── RouteHeader.jsx ➡️ data-testid="route-header"
│ └── WelcomeBox
│ └── WelcomeBox.jsx ➡️ data-testid="welcome-box"
└── containers
├── App
│ └── App.jsx ➡️ data-testid="app"
├── Authorize
│ └── Authorize.jsx ➡️ data-testid="callback"
├── Categories
│ ├── Categories.jsx ➡️ data-testid="categories"
│ └── CategoryItem.jsx ➡️ data-testid="category"
├── Dashboard
│ └── Dashboard.jsx ➡️ data-testid="dashboard"
├── Login
│ └── Login.jsx ➡️ data-testid="login"
├── Player
│ └── Player.jsx ➡️ data-testid="player"
├── Playlists
│ ├── PlaylistItem.jsx ➡️ data-testid="playlist"
│ └── Playlists.jsx ➡️ data-testid="playlists"
├── Topbar
│ └── Topbar.jsx ➡️ data-testid="topbar"
└── Tracks
├── Track.jsx ➡️ data-testid="track"
└── Tracks.jsx ➡️ data-testid="tracks"{
"lodash": "^4.17.15",
"node-sass": "^4.14.0",
"prop-types": "^15.7.2",
"react-icons": "^3.10.0",
"react-ink": "^6.4.0",
"react-redux": "^7.2.0",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5",
"redux-persist": "^6.0.0"
}Você pode instalar todas as dependências necessárias através utilizando o Yarn ou NPM:
- Yarn
▶️ yarn add lodash node-sass prop-types react-icons react-ink react-redux react-router-dom redux redux-persist - NPM
▶️ npm install --save lodash node-sass prop-types react-icons react-ink react-redux react-router-dom redux redux-persist
- Node v13.8.0 - ou superior, instalado em seu computador.
- Create React App





