Added pagination and search to movies page.

This commit is contained in:
DebaucheryLibrarian
2021-08-22 00:40:22 +02:00
parent 5e292a0880
commit 4b18867883
55 changed files with 274 additions and 103 deletions

View File

@@ -6,7 +6,7 @@
>
<input
v-model="query"
:placeholder="`Find ${channelCount} channels in ${entities.length} networks`"
:placeholder="`Search ${channelCount} channels in ${entities.length} networks`"
class="query"
@input="searchEntities"
>
@@ -98,45 +98,7 @@ export default {
}
.search {
display: flex;
width: 100%;
max-width: 40rem;
}
.query {
color: var(--text);
background: var(--background);
flex-grow: 1;
box-sizing: border-box;
padding: 1rem;
border: none;
box-sizing: border-box;
box-shadow: 0 0 3px var(--darken-weak);
margin: 1rem 0;
font-size: 1rem;
outline: none;
&:focus {
box-shadow: 0 0 3px var(--primary);
}
}
.search-button {
padding: 1rem;
background: none;
border: none;
.icon {
fill: var(--shadow);
}
&:hover {
cursor: pointer;
.icon {
fill: var(--primary);
}
}
margin: 1rem 0 0 0;
}
.entity-tiles {

View File

@@ -179,7 +179,7 @@ export default {
}
}
@media(max-width: $breakpoint) {
@media(max-width: $breakpoint-kilo) {
.movie {
height: 12rem;
}

View File

@@ -1,6 +1,11 @@
<template>
<div class="movies">
<div class="content-inner">
<Search
:search="searchMovies"
:placeholder="`Search ${totalCount} movies`"
/>
<div class="tiles">
<MovieTile
v-for="movie in movies"
@@ -8,6 +13,13 @@
:movie="movie"
/>
</div>
<Pagination
v-if="totalCount > 0"
:items-total="totalCount"
:items-per-page="limit"
class="pagination-bottom"
/>
</div>
<Footer />
@@ -16,27 +28,62 @@
<script>
import MovieTile from './movie-tile.vue';
import Search from '../search/bar.vue';
import Pagination from '../pagination/pagination.vue';
async function fetchMovies() {
if (this.$route.query.query) {
await this.searchMovies();
return;
}
async function mounted() {
const { movies, totalCount } = await this.$store.dispatch('fetchMovies', {
limit: 30,
limit: this.limit,
range: this.$route.params.range,
pageNumber: this.$route.params.pageNumber,
});
this.movies = movies;
this.totalCount = totalCount;
}
async function searchMovies() {
const movies = await this.$store.dispatch('searchMovies', {
query: this.$route.query.query,
limit: this.limit,
});
this.movies = movies;
this.totalCount = movies.length;
}
async function mounted() {
this.pageTitle = 'Movies';
await this.fetchMovies();
}
export default {
components: {
MovieTile,
Search,
Pagination,
},
data() {
return {
movies: [],
totalCount: 0,
limit: 30,
};
},
watch: {
$route: fetchMovies,
},
mounted,
methods: {
fetchMovies,
searchMovies,
},
};
</script>
@@ -49,14 +96,22 @@ export default {
flex-grow: 1;
}
.content-inner {
padding: 0 1rem;
}
.search {
margin: 1rem 0;
}
.tiles {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(25rem, 1fr));
grid-gap: 1rem;
padding: 1rem;
margin: 0 0 1rem 0;
}
@media(max-width: $breakpoint) {
@media(max-width: $breakpoint-kilo) {
.tiles {
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}

View File

@@ -0,0 +1,84 @@
<template>
<form
class="search"
@submit.prevent="search"
>
<input
v-model="query"
:placeholder="placeholder || 'Search'"
class="query"
@input="search"
>
<button
type="submit"
class="search-button"
><Icon icon="search" /></button>
</form>
</template>
<script>
function search() {
this.$router.replace({ query: { query: this.query || undefined } });
}
export default {
props: {
placeholder: {
type: String,
default: null,
},
},
data() {
return {
query: this.$route.query.query || null,
};
},
methods: {
search,
},
};
</script>
<style lang="scss" scoped>
.search {
display: flex;
width: 100%;
max-width: 40rem;
}
.query {
color: var(--text);
background: var(--background);
flex-grow: 1;
box-sizing: border-box;
padding: 1rem;
border: none;
box-sizing: border-box;
box-shadow: 0 0 3px var(--darken-weak);
font-size: 1rem;
outline: none;
&:focus {
box-shadow: 0 0 3px var(--primary);
}
}
.search-button {
padding: 1rem;
background: none;
border: none;
.icon {
fill: var(--shadow);
}
&:hover {
cursor: pointer;
.icon {
fill: var(--primary);
}
}
}
</style>

View File

@@ -132,6 +132,7 @@ async function mounted() {
'da-tp',
'dv-tp',
'tap',
'tvp',
],
misc: [
'gaping',

View File

@@ -96,6 +96,57 @@ const actorFields = `
${actorStashesFields}
`;
const movieFields = `
id
title
url
slug
date
datePrecision
actors {
id
name
slug
}
tags {
id
name
slug
}
entity {
id
name
slug
type
parent {
id
name
slug
type
}
}
covers: moviesCovers {
media {
id
path
thumbnail
lazy
width
height
thumbnailWidth
thumbnailHeight
isS3
sfw: sfwMedia {
id
path
thumbnail
lazy
comment
}
}
}
`;
const campaignsFragment = `
campaigns(filter: {
or: [
@@ -543,6 +594,7 @@ export {
actorFields,
actorStashesFields,
campaignsFragment,
movieFields,
releaseActorsFragment,
releaseFields,
releaseTagsFragment,

View File

@@ -1,5 +1,5 @@
import { graphql } from '../api';
import { releasesFragment, releaseFragment, releaseFields } from '../fragments';
import { releasesFragment, releaseFragment, releaseFields, movieFields } from '../fragments';
import { curateRelease } from '../curate';
import getDateRange from '../get-date-range';
@@ -79,54 +79,7 @@ function initReleasesActions(store, router) {
}
) {
movies: nodes {
id
title
url
slug
date
datePrecision
actors {
id
name
slug
}
tags {
id
name
slug
}
entity {
id
name
slug
type
parent {
id
name
slug
type
}
}
covers: moviesCovers {
media {
id
path
thumbnail
lazy
width
height
thumbnailWidth
thumbnailHeight
isS3
sfw: sfwMedia {
id
path
thumbnail
lazy
comment
}
}
}
${movieFields}
}
totalCount
}
@@ -142,6 +95,28 @@ function initReleasesActions(store, router) {
};
}
async function searchMovies({ _commit }, { query, limit = 20 }) {
const { movies } = await graphql(`
query SearchMovies(
$query: String!
$limit:Int = 20,
) {
movies: searchMovies(
query: $query
minLength: 1
first: $limit
) {
${movieFields}
}
}
`, {
query,
limit,
});
return movies.map(movie => curateRelease(movie));
}
async function fetchMovieById({ _commit }, movieId) {
// const release = await get(`/releases/${releaseId}`);
@@ -297,6 +272,7 @@ function initReleasesActions(store, router) {
fetchReleaseById,
fetchMovies,
fetchMovieById,
searchMovies,
};
}

View File

@@ -196,6 +196,17 @@ const routes = [
{
path: '/movies',
component: Movies,
redirect: {
name: 'movies',
params: {
range: 'latest',
pageNumber: 1,
},
},
},
{
path: '/movies/:range/:pageNumber',
component: Movies,
name: 'movies',
},
{