traxxx/assets/components/actors/actors.vue

194 lines
4.6 KiB
Vue

<template>
<div class="actors">
<nav class="filter">
<ul class="genders nolist">
<li class="gender">
<router-link
:to="{ name: 'actors', params: { gender: 'female', letter } }"
: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 } }"
:class="{ selected: gender === 'male' }"
class="gender-link male"
><Gender gender="male" /></router-link>
</li>
<li class="gender">
<router-link
:to="{ name: 'actors', params: { gender: 'trans', letter } }"
:class="{ selected: gender === 'trans' }"
class="gender-link transsexual"
><Gender gender="transsexual" /></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 } }"
:class="{ selected: letterX === letter }"
class="letter-link"
@click="setLetter(letterX)"
>{{ letterX || 'All' }}</router-link>
</li>
</ul>
</nav>
<div class="tiles">
<Actor
v-for="actor in actors"
:key="`actor-${actor.id}`"
:actor="actor"
/>
</div>
</div>
</template>
<script>
import Actor from '../tile/actor.vue';
import Gender from './gender.vue';
async function fetchActors() {
this.actors = await this.$store.dispatch('fetchActors', {
limit: 1000,
letter: this.letter.replace('all', ''),
genders: [this.gender.replace('trans', 'transsexual').replace('other', null)],
});
}
async function setLetter(letter) {
this.letter = letter;
await this.fetchActors();
}
async function mounted() {
this.pageTitle = 'Actors';
await this.fetchActors();
}
export default {
components: {
Actor,
Gender,
},
data() {
return {
actors: [],
pageTitle: null,
letters: ['all'].concat(Array.from({ length: 26 }, (value, index) => String.fromCharCode(index + 97).toUpperCase())),
letter: this.$route.params.letter || 'all',
gender: this.$route.params.gender || 'female',
};
},
mounted,
methods: {
fetchActors,
setLetter,
},
};
</script>
<style lang="scss">
@import 'theme';
.gender-link.selected .gender .icon {
fill: $text-contrast;
filter: none;
}
</style>
<style lang="scss" scoped>
@import 'theme';
.actors {
display: flex;
flex-direction: column;
}
.tiles {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(10rem, .5fr));
grid-gap: 0 .5rem;
padding: 1rem;
flex-grow: 1;
}
.filter {
display: flex;
justify-content: center;
align-items: center;
padding: 0 1rem;
margin: 1rem 0 0 0;
}
.genders {
padding: 0 .5rem 0 0;
border-right: solid 1px $shadow-hint;
margin: 0 1rem 0 0;
}
.letter,
.gender {
display: inline-block;
}
.letter-link,
.gender-link {
width: 2.5rem;
height: 2.5rem;
display: inline-flex;
align-items: center;
justify-content: center;
margin: .25rem .5rem .25rem 0;
color: $shadow;
background: $background;
font-weight: bold;
text-decoration: none;
box-shadow: 0 0 3px $shadow-weak;
&:hover {
color: $primary;
cursor: pointer;
}
&.selected {
background: $primary;
color: $text-contrast;
.icon {
fill: $text-contrast;
}
&.male {
background: $male;
}
&.female {
background: $female;
}
&.transsexual {
width: 2rem;
height: 2rem;
background: $female;
border: solid .25rem $male;
}
}
}
@media(max-width: $breakpoint) {
.actors {
grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
}
}
</style>