Proyecto cliente SPA para la API de películas con Nuxt.js

Página de películas favoritas

Antes de nada, la sección de películas favoritas debería aparecer únicamente si el usuario está autenticado, así que en lugar de generar el menú dinámicamente vamos a hacerlo a mano comprobando esa posibilidad:

pages/favoritas.vue

<ul class="menu-list">
  <li>
    <nuxt-link to="/pelis" exact-active-class="is-active">
      <b-icon icon="video"/>
      Películas
    </nuxt-link>
  </li>
  <li v-if="user">
    <nuxt-link to="/favoritas" exact-active-class="is-active">
      <b-icon icon="star"/>
      Favoritas
    </nuxt-link>
  </li>
</ul>

Otra opción importante es que no se pueda visitar esta página si no estamos autenticados.

Para manejar la situación usaremos el fetch, un método que se ejecuta antes de montar la página y que está indicado para gestionar el store. En él podemos comprobar si hay un usuario y si no redireccionar a otra página:

fetch ({ store, redirect }) {
  if (!store.state.user) {
    return redirect('/')
  }
},

Si intentamos visitar /favoritas sin iniciar sesión seremos redirigidos automáticamente a la portada.

Por supuesto también tenemos que tener en cuenta que al cerrar la sesión se redireccione a la portada, así que modificaremos el logout() para hacerlo, esta vez usando el módulo $router de Nuxt.js:

layouts/default.vue

logout() {
  ...
  // Redireccionamos a la portada al salir
  this.$router.replace({ path: '/' })
}

El siguiente paso será recuperar las pelis favoritas del usuario al cargar la página, para ello necesitaremos consultar la API pasando el token de autenticación:

pages/favoritas.vue

asyncData ({ store, $axios }) {
  if (store.state.token) {
    return $axios.get('/favoritas/', {
      headers: {
        'Authorization': `Token ${store.state.token}`
      }
    })
    .then((res) => {
      return {
        'favoritas': res.data
      }
    })
  }
},

Si inspeccionamos las peticiones veremos si se está llamando correctamente a la API.

Sólo tenemos que copiar literalmente la visualización de películas de la portada a esta página y debería funcionar:

<template>
 <section class="section">
   <h2 class="title">Favoritas</h2>
   <div class="columns is-multiline">
     <Peli
       v-for="favorita in favoritas"
       :key="favorita.pelicula.id"
       :peli="favorita.pelicula"
     />
   </div>
 </section>
</template>

Lo mejor de todo es que podemos editar el componente Card para modificar la estructura de todas las películas de la web, tanto de la portada como las de nuestro perfil.

Por cierto, un detalle muy útil sería redireccionar al usuario a sus pelis favoritas cuando se identifique, es fácil usando el módulo $router de Nuxt.js:

layouts/default.vue

.then((res) => {
  if (res.data.key){
    ...
    // Redireccionamos a las pelis favoritas
    this.$router.replace({ path: '/favoritas' })
  }
})