Added country and birthday filters to actors page.

This commit is contained in:
2024-01-03 02:52:41 +01:00
parent b59a6dc066
commit 3c3be10c4e
21 changed files with 1061 additions and 138 deletions

View File

@@ -57,19 +57,56 @@
</ul>
<div class="filter">
<RangeFilter
label="age"
:min="18"
:max="100"
:value="filters.age"
:disabled="!filters.ageRequired"
@enable="(checked) => updateFilter('ageRequired', checked, filters.ageRequired !== checked)"
@input="(range) => updateFilter('age', range, false)"
@change="(range) => updateFilter('age', range, true)"
>
<template #start><Icon icon="leaf" /></template>
<template #end><Icon icon="tree3" /></template>
</RangeFilter>
<div class="filter-section">
<RangeFilter
label="age"
:min="18"
:max="100"
:value="filters.age"
:disabled="!filters.ageRequired"
@enable="(checked) => updateFilter('ageRequired', checked, filters.ageRequired !== checked)"
@input="(range) => updateFilter('age', range, false)"
@change="(range) => updateFilter('age', range, true)"
>
<template #start><Icon icon="leaf" /></template>
<template #end><Icon icon="tree3" /></template>
</RangeFilter>
</div>
<div class="filter-section">
<label class="filter-label">
<span class="label">
<Checkbox
:checked="filters.dobRequired"
class="checkbox"
@change="(checked) => updateFilter('dobRequired', checked, true)"
/>
<select
v-model="filters.dobType"
class="input select"
@change="() => updateFilter('dobRequired', true, true)"
>
<option value="birthday">Birthday</option>
<option value="dob">Date of birth</option>
</select>
</span>
</label>
<div
class="input-container"
@click="() => updateFilter('dobRequired', true, true)"
>
<input
:value="filters.dob"
:disabled="!filters.dobRequired"
:max="maxDob"
type="date"
class="input"
@change="(event) => updateFilter('dob', event.target.value, true)"
>
</div>
</div>
</div>
<div class="filter">
@@ -147,44 +184,33 @@
</RangeFilter>
</div>
<Tooltip class="filter">
<span
:class="{ enabled: filters.country }"
class="filter-trigger"
<div
v-if="filteredCountries.length > 0"
class="countries-container"
>
<input
v-if="!filters.country"
v-model="countryQuery"
type="search"
placeholder="Search country"
class="input input-inline countries-search"
>
<img
v-if="filters.country"
:src="`/img/flags/${filters.country.toLowerCase()}.svg`"
class="flag"
>
<Icon
v-else
icon="earth2"
/>Country
</span>
<template #tooltip>
<input
v-model="countryQuery"
placeholder="Search"
class="input"
>
<div class="countries-list">
<Countries
v-if="!countryQuery"
v-if="!countryQuery && !filters.country && topCountries.length < filteredCountries.length"
:countries="topCountries"
:selected-country="country"
:selected-country="filters.country"
:update-value="updateFilter"
/>
<Countries
:countries="filteredCountries"
:selected-country="country"
:selected-country="filters.country"
:update-value="updateFilter"
/>
</template>
</Tooltip>
</div>
</div>
<div class="filter">
<Checkbox
@@ -210,6 +236,7 @@
<script setup>
import { ref, computed, inject } from 'vue';
import { format, subYears } from 'date-fns';
import navigate from '#/src/navigate.js';
import { get } from '#/src/api.js';
@@ -218,7 +245,6 @@ import ActorTile from '#/components/actors/tile.vue';
import Gender from '#/components/actors/gender.vue';
import Checkbox from '#/components/form/checkbox.vue';
import RangeFilter from '#/components/filters/range.vue';
import Tooltip from '#/components/tooltip/tooltip.vue';
import Countries from '#/components/filters/countries.vue';
const { pageProps, urlParsed } = inject('pageContext');
@@ -230,12 +256,12 @@ const countries = ref(pageProps.countries);
const countryQuery = ref('');
const topCountryAlpha2s = ['AU', 'BR', 'CZ', 'DE', 'JP', 'RU', 'GB', 'US'];
const topCountries = computed(() => countries.value.filter((country) => topCountryAlpha2s.includes(country.alpha2)));
const topCountries = computed(() => topCountryAlpha2s.map((alpha2) => countries.value.find((country) => country.alpha2 === alpha2)).filter(Boolean));
const filteredCountries = computed(() => countries.value.filter((country) => new RegExp(countryQuery.value, 'i').test(country.name)));
actors.value = pageProps.actors;
const maxDob = format(subYears(new Date(), 18), 'yyyy-MM-dd');
console.log(countries.value);
actors.value = pageProps.actors;
const braSizes = 'ABCDEFGHIJKZ'.split('');
const naturalBoobsValues = [true, undefined, false];
@@ -244,6 +270,10 @@ const filters = ref({
gender: urlParsed.search.gender,
ageRequired: !!urlParsed.search.age,
age: urlParsed.search.age?.split(',').map((age) => Number(age)) || [18, 100],
dobRequired: !!urlParsed.search.dob,
dobType: urlParsed.search.dobt ? ({ bd: 'birthday', dob: 'dob' })[urlParsed.search.dobt] : 'birthday',
dob: urlParsed.search.dob || format(subYears(new Date(), 21), 'yyyy-MM-dd'),
country: urlParsed.search.c,
braSizeRequired: !!urlParsed.search.cup,
braSize: urlParsed.search.cup?.split(',') || ['A', 'Z'],
naturalBoobs: urlParsed.search.nb ? urlParsed.search.nb === 'true' : undefined,
@@ -254,12 +284,17 @@ const filters = ref({
avatarRequired: !!urlParsed.search.avatar,
});
console.log(filters.value.dobType);
async function search() {
const query = {
q: q.value || undefined,
gender: filters.value.gender || undefined,
age: filters.value.ageRequired ? filters.value.age.join(',') : undefined,
dob: filters.value.dobRequired ? filters.value.dob : undefined,
dobt: filters.value.dobRequired ? ({ birthday: 'bd', dob: 'dob' })[filters.value.dobType] : undefined,
cup: filters.value.braSizeRequired ? filters.value.braSize.join(',') : undefined,
c: filters.value.country || undefined,
nb: filters.value.naturalBoobs,
height: filters.value.heightRequired ? filters.value.height.join(',') : undefined,
weight: filters.value.weightRequired ? filters.value.weight.join(',') : undefined,
@@ -321,7 +356,6 @@ function updateFilter(prop, value, reload = true) {
.filters {
width: 17rem;
flex-shrink: 0;
padding: .5rem 0;
border-right: solid 1px var(--shadow-weak-30);
overflow-y: auto;
@@ -331,7 +365,7 @@ function updateFilter(prop, value, reload = true) {
}
.filter {
padding: .5rem;
padding: .5rem .25rem;
border-bottom: solid 1px var(--shadow-weak-30);
}
@@ -394,7 +428,59 @@ function updateFilter(prop, value, reload = true) {
}
}
.countries {
overflow: hidden;
.select {
flex-grow: 1;
}
.countries-container {
border-bottom: solid 1px var(--shadow-weak-30);
}
.countries-search {
width: 100%;
margin-bottom: .25rem;
border-bottom: solid 1px var(--shadow-weak-40);
}
.countries-list {
max-height: 13rem;
overflow-y: auto;
}
:deep(.country.selected) .country-name {
padding: .5rem;
}
.filter-trigger {
display: flex;
align-items: center;
color: var(--shadow);
font-size: .9rem;
font-weight: bold;
.icon,
.flag {
fill: var(--shadow);
width: 1rem;
height: 1rem;
margin: -.1rem .75rem 0 0;
}
&:hover {
color: var(--shadow-strong);
cursor: pointer;
.icon {
fill: var(--shadow-strong);
}
}
&.enabled {
color: var(--primary);
.icon {
fill: var(--primary);
}
}
}
</style>

View File

@@ -2,8 +2,6 @@ import { fetchActors } from '#/src/actors.js';
import { curateActorsQuery } from '#/src/web/actors.js';
export async function onBeforeRender(pageContext) {
console.log(pageContext);
const {
actors,
countries,