272 lines
5.7 KiB
Vue
272 lines
5.7 KiB
Vue
<template>
|
|
<div class="actors">
|
|
<nav class="filter">
|
|
<ul class="genders nolist">
|
|
<li class="gender">
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender: 'all', letter, pageNumber: 1 } }"
|
|
:class="{ selected: gender === 'all' }"
|
|
class="gender-link all"
|
|
>all</router-link>
|
|
</li>
|
|
<li class="gender">
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender: 'female', letter, pageNumber: 1 } }"
|
|
:class="{ selected: gender === 'female' }"
|
|
class="gender-link female"
|
|
><Gender gender="female" /></router-link>
|
|
</li>
|
|
<li class="gender">
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender: 'male', letter, pageNumber: 1 } }"
|
|
:class="{ selected: gender === 'male' }"
|
|
class="gender-link male"
|
|
replace
|
|
><Gender gender="male" /></router-link>
|
|
</li>
|
|
<li class="gender">
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender: 'trans', letter, pageNumber: 1 } }"
|
|
:class="{ selected: gender === 'trans' }"
|
|
class="gender-link transsexual"
|
|
replace
|
|
><Gender gender="transsexual" /></router-link>
|
|
</li>
|
|
<li class="gender">
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender: 'other', letter, pageNumber: 1 } }"
|
|
:class="{ selected: gender === 'other' }"
|
|
class="gender-link other"
|
|
replace
|
|
><Icon icon="question5" /></router-link>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="letters nolist">
|
|
<li
|
|
v-for="letterX in letters"
|
|
:key="letterX"
|
|
class="letter"
|
|
>
|
|
<router-link
|
|
:to="{ name: 'actors', params: { gender, letter: letterX, pageNumber: 1 } }"
|
|
:class="{ selected: letterX === letter }"
|
|
class="letter-link"
|
|
replace
|
|
>{{ letterX || 'All' }}</router-link>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<Pagination
|
|
:items-total="totalCount"
|
|
:items-per-page="limit"
|
|
/>
|
|
|
|
<div class="tiles">
|
|
<Actor
|
|
v-for="actor in actors"
|
|
:key="`actor-${actor.id}`"
|
|
:actor="actor"
|
|
/>
|
|
</div>
|
|
|
|
<Pagination
|
|
v-if="totalCount > 0"
|
|
:items-total="totalCount"
|
|
:items-per-page="limit"
|
|
class="pagination-top"
|
|
/>
|
|
|
|
<Footer />
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Actor from './tile.vue';
|
|
import Gender from './gender.vue';
|
|
import Pagination from '../pagination/pagination.vue';
|
|
|
|
async function fetchActors() {
|
|
const curatedGender = this.gender.replace('trans', 'transsexual');
|
|
|
|
const { actors, totalCount } = await this.$store.dispatch('fetchActors', {
|
|
limit: this.limit,
|
|
pageNumber: Number(this.$route.params.pageNumber) || 1,
|
|
letter: this.letter.replace('all', ''),
|
|
gender: curatedGender === 'other' ? null : curatedGender,
|
|
});
|
|
|
|
this.actors = actors;
|
|
this.totalCount = totalCount;
|
|
}
|
|
|
|
function letter() {
|
|
return this.$route.params.letter || 'all';
|
|
}
|
|
|
|
function gender() {
|
|
return this.$route.params.gender || 'all';
|
|
}
|
|
|
|
async function route() {
|
|
await this.fetchActors();
|
|
}
|
|
|
|
async function mounted() {
|
|
this.pageTitle = 'Actors';
|
|
|
|
await this.fetchActors();
|
|
}
|
|
|
|
export default {
|
|
components: {
|
|
Actor,
|
|
Gender,
|
|
Pagination,
|
|
},
|
|
data() {
|
|
return {
|
|
actors: [],
|
|
pageTitle: null,
|
|
totalCount: 0,
|
|
limit: 30,
|
|
letters: ['all'].concat(Array.from({ length: 26 }, (value, index) => String.fromCharCode(index + 97).toUpperCase())),
|
|
};
|
|
},
|
|
computed: {
|
|
letter,
|
|
gender,
|
|
},
|
|
watch: {
|
|
$route: route,
|
|
},
|
|
mounted,
|
|
methods: {
|
|
fetchActors,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.gender-link {
|
|
&.selected .gender .icon {
|
|
fill: var(--text-light);
|
|
filter: none;
|
|
}
|
|
|
|
&:hover:not(.selected) {
|
|
.gender .icon {
|
|
fill: var(--text-light);
|
|
}
|
|
|
|
.male .icon {
|
|
filter: drop-shadow(0 0 1px var(--male));
|
|
}
|
|
|
|
.female .icon {
|
|
filter: drop-shadow(0 0 1px var(--female));
|
|
}
|
|
}
|
|
|
|
&:hover:not(.selected) .transsexual .icon {
|
|
fill: var(--female);
|
|
filter: drop-shadow(1px 0 0 var(--text-light)) drop-shadow(-1px 0 0 var(--text-light)) drop-shadow(0 1px 0 var(--text-light)) drop-shadow(0 -1px 0 var(--text-light)) drop-shadow(1px 0 0 var(--male)) drop-shadow(-1px 0 0 var(--male)) drop-shadow(0 1px 0 var(--male)) drop-shadow(0 -1px 0 var(--male)) drop-shadow(0 0 1px rgba(0, 0, 0, 0.5));
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<style lang="scss" scoped>
|
|
@import 'breakpoints';
|
|
|
|
.actors {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.tiles {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
|
|
grid-gap: .5rem;
|
|
padding: 1rem;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.filter {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 0 1rem;
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
.genders {
|
|
display: flex;
|
|
flex-shrink: 0;
|
|
padding: 0 .5rem 0 0;
|
|
border-right: solid 1px var(--shadow-hint);
|
|
margin: 0 1rem 0 0;
|
|
}
|
|
|
|
.letter,
|
|
.gender {
|
|
display: inline-block;
|
|
}
|
|
|
|
.letter-link,
|
|
.gender-link {
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
box-sizing: border-box;
|
|
margin: .25rem .5rem .25rem 0;
|
|
color: var(--shadow);
|
|
background: var(--background);
|
|
font-weight: bold;
|
|
text-decoration: none;
|
|
box-shadow: 0 0 3px var(--darken-weak);
|
|
|
|
.male,
|
|
.female,
|
|
.transsexual {
|
|
padding: .2rem 0 0 0;
|
|
}
|
|
|
|
.icon {
|
|
fill: var(--shadow);
|
|
}
|
|
|
|
&:hover {
|
|
color: var(--text);
|
|
cursor: pointer;
|
|
|
|
.icon {
|
|
fill: var(--text);
|
|
}
|
|
}
|
|
|
|
&.selected {
|
|
background: var(--primary);
|
|
color: var(--text-light);
|
|
|
|
&.other .icon {
|
|
fill: var(--text-light);
|
|
}
|
|
}
|
|
}
|
|
|
|
@media(max-width: $breakpoint) {
|
|
.genders {
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
|
|
@media(max-width: $breakpoint-micro) {
|
|
.tiles {
|
|
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
|
|
}
|
|
}
|
|
</style>
|