<template> <div class="movies"> <div class="content-inner"> <SearchBar :placeholder="`Search ${totalCount} movies`" /> <div ref="tiles" class="tiles" > <MovieTile v-for="movie in movies" :key="`movie-${movie.id}`" :movie="movie" /> </div> <Pagination v-if="totalCount > 0" :items-total="totalCount" :items-per-page="limit" class="pagination-bottom" /> </div> <Footer /> </div> </template> <script> import MovieTile from './movie-tile.vue'; import SearchBar from '../search/bar.vue'; import Pagination from '../pagination/pagination.vue'; async function fetchMovies() { if (this.$route.query.query) { await this.searchMovies(); return; } const { movies, totalCount } = await this.$store.dispatch('fetchMovies', { limit: this.limit, range: this.$route.params.range, pageNumber: this.$route.params.pageNumber, }); this.movies = movies; this.totalCount = totalCount; this.$refs.tiles.scrollIntoView(); } async function searchMovies() { const { movies, totalCount } = await this.$store.dispatch('searchMovies', { query: this.$route.query.query, limit: this.limit, pageNumber: this.$route.params.pageNumber, }); this.movies = movies; this.totalCount = totalCount; this.$refs.tiles.scrollIntoView(); } async function mounted() { this.pageTitle = 'Movies'; await this.fetchMovies(); } export default { components: { MovieTile, SearchBar, Pagination, }, data() { return { movies: [], totalCount: 0, limit: 20, }; }, watch: { $route: fetchMovies, }, mounted, methods: { fetchMovies, searchMovies, }, }; </script> <style lang="scss" scoped> @import 'breakpoints'; .movies { display: flex; flex-direction: column; flex-grow: 1; } .content-inner { padding: 0 1rem; } .search { margin: 1rem 0 0 0; } .tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr)); grid-gap: 1rem; padding: 1rem 0; } @media(max-width: $breakpoint-kilo) { .tiles { grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); } } </style>