Added actors pagination.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<form
|
||||
v-show="showFilters"
|
||||
class="filters"
|
||||
@submit.prevent
|
||||
>
|
||||
@@ -192,7 +193,7 @@
|
||||
v-if="!filters.country"
|
||||
v-model="countryQuery"
|
||||
type="search"
|
||||
placeholder="Search country"
|
||||
placeholder="Filter country"
|
||||
class="input input-inline countries-search"
|
||||
>
|
||||
|
||||
@@ -221,16 +222,45 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ul class="actors nolist">
|
||||
<li
|
||||
v-for="actor in actors"
|
||||
:key="`actor-${actor.id}`"
|
||||
<div class="actors-anchor">
|
||||
<div
|
||||
class="sidebar-toggle"
|
||||
@click="toggleFilters"
|
||||
>
|
||||
<ActorTile
|
||||
:actor="actor"
|
||||
<Icon
|
||||
v-show="showFilters"
|
||||
icon="arrow-left3"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Icon
|
||||
v-show="!showFilters"
|
||||
icon="arrow-right3"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref="container"
|
||||
class="actors-container"
|
||||
>
|
||||
<ul class="actors nolist">
|
||||
<li
|
||||
v-for="actor in actors"
|
||||
:key="`actor-${actor.id}`"
|
||||
>
|
||||
<ActorTile
|
||||
:actor="actor"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Pagination
|
||||
:page="currentPage"
|
||||
:total="total"
|
||||
:redirect="false"
|
||||
@navigation="paginate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -242,16 +272,21 @@ import navigate from '#/src/navigate.js';
|
||||
import { get } from '#/src/api.js';
|
||||
|
||||
import ActorTile from '#/components/actors/tile.vue';
|
||||
import Pagination from '#/components/pagination/pagination.vue';
|
||||
import Gender from '#/components/actors/gender.vue';
|
||||
import Checkbox from '#/components/form/checkbox.vue';
|
||||
import RangeFilter from '#/components/filters/range.vue';
|
||||
import Countries from '#/components/filters/countries.vue';
|
||||
|
||||
const { pageProps, urlParsed } = inject('pageContext');
|
||||
const pageContext = inject('pageContext');
|
||||
const { pageProps, urlParsed, routeParams } = pageContext;
|
||||
|
||||
const q = ref(urlParsed.search.q);
|
||||
const actors = ref([]);
|
||||
|
||||
const container = ref(null);
|
||||
const showFilters = ref(true);
|
||||
|
||||
const countries = ref(pageProps.countries);
|
||||
const countryQuery = ref('');
|
||||
|
||||
@@ -266,6 +301,9 @@ actors.value = pageProps.actors;
|
||||
const braSizes = 'ABCDEFGHIJKZ'.split('');
|
||||
const naturalBoobsValues = [true, undefined, false];
|
||||
|
||||
const currentPage = ref(Number(routeParams.page));
|
||||
const total = ref(Number(pageProps.total));
|
||||
|
||||
const filters = ref({
|
||||
gender: urlParsed.search.gender,
|
||||
ageRequired: !!urlParsed.search.age,
|
||||
@@ -284,9 +322,11 @@ const filters = ref({
|
||||
avatarRequired: !!urlParsed.search.avatar,
|
||||
});
|
||||
|
||||
console.log(filters.value.dobType);
|
||||
async function search(resetPage = true) {
|
||||
if (resetPage) {
|
||||
currentPage.value = 1;
|
||||
}
|
||||
|
||||
async function search() {
|
||||
const query = {
|
||||
q: q.value || undefined,
|
||||
gender: filters.value.gender || undefined,
|
||||
@@ -301,12 +341,21 @@ async function search() {
|
||||
avatar: filters.value.avatarRequired || undefined,
|
||||
};
|
||||
|
||||
navigate('/actors', query, { redirect: false });
|
||||
|
||||
const res = await get('/actors', query);
|
||||
const res = await get('/actors', { ...query, page: currentPage.value }); // client uses param rather than query pagination
|
||||
|
||||
actors.value = res.actors;
|
||||
total.value = res.total;
|
||||
|
||||
countries.value = res.countries;
|
||||
|
||||
container.value.scrollTop = 0;
|
||||
|
||||
navigate(`/actors/${currentPage.value}`, query, { redirect: false });
|
||||
}
|
||||
|
||||
function paginate({ page }) {
|
||||
currentPage.value = page;
|
||||
search(false);
|
||||
}
|
||||
|
||||
function updateFilter(prop, value, reload = true) {
|
||||
@@ -316,6 +365,10 @@ function updateFilter(prop, value, reload = true) {
|
||||
search();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFilters() {
|
||||
showFilters.value = !showFilters.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -355,6 +408,7 @@ function updateFilter(prop, value, reload = true) {
|
||||
|
||||
.filters {
|
||||
width: 17rem;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
border-right: solid 1px var(--shadow-weak-30);
|
||||
overflow-y: auto;
|
||||
@@ -365,17 +419,57 @@ function updateFilter(prop, value, reload = true) {
|
||||
}
|
||||
|
||||
.filter {
|
||||
padding: .5rem .25rem;
|
||||
border-bottom: solid 1px var(--shadow-weak-30);
|
||||
padding: .5rem;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: solid 1px var(--shadow-weak-30);
|
||||
}
|
||||
}
|
||||
|
||||
.actors-anchor {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
width: 1.5rem;
|
||||
height: 2rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
bottom: .5rem;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
border-radius: 0 .25rem .25rem 0;
|
||||
background: var(--background);
|
||||
box-shadow: 0 0 3px var(--shadow-weak-30);
|
||||
|
||||
.icon {
|
||||
fill: var(--shadow);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
fill: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actors-container {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.actors {
|
||||
display: grid;
|
||||
flex-grow: 1;
|
||||
grid-template-columns: repeat(auto-fill, 10rem);
|
||||
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||
gap: .25rem;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.genders {
|
||||
@@ -430,10 +524,17 @@ function updateFilter(prop, value, reload = true) {
|
||||
|
||||
.select {
|
||||
flex-grow: 1;
|
||||
color: var(--shadow-strong-10);
|
||||
|
||||
option {
|
||||
color: var(--text);
|
||||
}
|
||||
}
|
||||
|
||||
.countries-container {
|
||||
border-bottom: solid 1px var(--shadow-weak-30);
|
||||
padding: .25rem 0;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.countries-search {
|
||||
|
||||
@@ -9,7 +9,7 @@ export async function onBeforeRender(pageContext) {
|
||||
total,
|
||||
} = await fetchActors(curateActorsQuery(pageContext.urlQuery), {
|
||||
page: Number(pageContext.routeParams.page) || 1,
|
||||
limit: Number(pageContext.urlParsed.search.limit) || 50,
|
||||
limit: Number(pageContext.urlParsed.search.limit) || 120,
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
20
pages/actors/+route.js
Normal file
20
pages/actors/+route.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { match } from 'path-to-regexp';
|
||||
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
||||
|
||||
const path = '/actors/:page?';
|
||||
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||
|
||||
export default (pageContext) => {
|
||||
const matched = urlMatch(pageContext.urlPathname);
|
||||
|
||||
if (matched) {
|
||||
return {
|
||||
routeParams: {
|
||||
page: matched.params.page || '1',
|
||||
path,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -1 +1 @@
|
||||
export default '/actors/@actorId/*';
|
||||
export default '/actor/@actorId/*';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fetchLatest, fetchUpcoming, fetchNew } from '../../src/scenes';
|
||||
import { fetchLatest, fetchUpcoming, fetchNew } from '#/src/scenes.js';
|
||||
|
||||
async function fetchScenes(scope, page, limit) {
|
||||
if (scope === 'new') {
|
||||
|
||||
@@ -1,33 +1,20 @@
|
||||
import { resolveRoute } from 'vike/routing';
|
||||
import { match } from 'path-to-regexp';
|
||||
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
||||
|
||||
const path = '/updates/:scope?/:page?';
|
||||
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||
|
||||
export default (pageContext) => {
|
||||
{
|
||||
const result = resolveRoute('/updates/@scope/@page', pageContext.urlPathname);
|
||||
const matched = urlMatch(pageContext.urlPathname);
|
||||
|
||||
if (result.match) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const result = resolveRoute('/updates/@scope', pageContext.urlPathname);
|
||||
|
||||
if (result.match) {
|
||||
result.routeParams.page = '1';
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const result = resolveRoute('/updates', pageContext.urlPathname);
|
||||
|
||||
if (result.match) {
|
||||
result.routeParams.scope = 'latest';
|
||||
result.routeParams.page = '1';
|
||||
|
||||
return result;
|
||||
}
|
||||
if (matched) {
|
||||
return {
|
||||
routeParams: {
|
||||
scope: matched.params.scope || 'latest',
|
||||
page: matched.params.page || '1',
|
||||
path,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user