Added footer and basic stats page.

This commit is contained in:
DebaucheryLibrarian 2020-08-15 19:04:33 +02:00
parent d7974f057f
commit b3435c97c3
14 changed files with 194 additions and 8 deletions

View File

@ -307,6 +307,8 @@
class="pagination-top" class="pagination-top"
/> />
</div> </div>
<Footer />
</div> </div>
</div> </div>
</template> </template>

View File

@ -80,6 +80,8 @@
:items-per-page="limit" :items-per-page="limit"
class="pagination-top" class="pagination-top"
/> />
<Footer />
</div> </div>
</template> </template>

View File

@ -106,6 +106,8 @@
class="pagination-top" class="pagination-top"
/> />
</div> </div>
<Footer />
</div> </div>
</div> </div>
</template> </template>

View File

@ -0,0 +1,34 @@
<template>
<footer class="footer">
<span class="segment">© traxxx</span>
<router-link
:to="{ name: 'stats' }"
class="segment footer-link nolink"
>stats</router-link>
</footer>
</template>
<style lang="scss" scoped>
.footer {
margin: 2rem 0 0 0;
background: var(--background);
color: var(--shadow);
box-shadow: inset 0 1px 3px var(--darken-hint);
font-size: .8rem;
font-weight: bold;
text-align: center;
}
.segment {
padding: .5rem;
&:not(:last-child) {
border-right: solid 1px var(--shadow-hint);
}
}
.footer-link {
text-decoration: underline;
}
</style>

View File

@ -20,6 +20,8 @@
:items-per-page="limit" :items-per-page="limit"
class="pagination-bottom" class="pagination-bottom"
/> />
<Footer />
</div> </div>
</div> </div>
</template> </template>

View File

@ -40,6 +40,8 @@
:entity="entity" :entity="entity"
/> />
</div> </div>
<Footer />
</div> </div>
</template> </template>

View File

@ -1,5 +1,6 @@
<template> <template>
<div class="movies"> <div class="movies">
<div class="content-inner">
<div class="tiles"> <div class="tiles">
<MovieTile <MovieTile
v-for="movie in movies" v-for="movie in movies"
@ -8,6 +9,9 @@
/> />
</div> </div>
</div> </div>
<Footer />
</div>
</template> </template>
<script> <script>
@ -40,7 +44,9 @@ export default {
@import 'breakpoints'; @import 'breakpoints';
.movies { .movies {
padding: 1rem; display: flex;
flex-direction: column;
flex-grow: 1;
} }
.tiles { .tiles {

View File

@ -0,0 +1,95 @@
<template>
<div class="stats">
<div class="content-inner">
<h1 class="heading">Stats</h1>
<dl class="stat-table">
<div class="stat-row">
<dt class="stat-label">Networks</dt>
<dd class="stat-value">{{ totalNetworks }}</dd>
</div>
<div class="stat-row">
<dt class="stat-label">Channels</dt>
<dd class="stat-value">{{ totalChannels }}</dd>
</div>
<div class="stat-row">
<dt class="stat-label">Scenes</dt>
<dd class="stat-value">{{ totalScenes }}</dd>
</div>
<div class="stat-row">
<dt class="stat-label">Movies</dt>
<dd class="stat-value">{{ totalMovies }}</dd>
</div>
<div class="stat-row">
<dt class="stat-label">Actors</dt>
<dd class="stat-value">{{ totalActors }}</dd>
</div>
</dl>
</div>
<Footer />
</div>
</template>
<script>
async function mounted() {
const stats = await this.$store.dispatch('fetchStats');
this.totalScenes = stats.totalScenes;
this.totalMovies = stats.totalMovies;
this.totalActors = stats.totalActors;
this.totalNetworks = stats.totalNetworks;
this.totalChannels = stats.totalChannels;
}
export default {
data() {
return {
totalScenes: 0,
totalMovies: 0,
totalActors: 0,
totalNetworks: 0,
totalChannels: 0,
};
},
mounted,
};
</script>
<style lang="scss" scoped>
.stats {
display: flex;
flex-direction: column;
flex-grow: 1;
}
.content-inner {
padding: 1rem;
}
.stat-row {
width: 20rem;
max-width: 100%;
display: flex;
padding: .5rem 0;
justify-content: space-between;
&:not(:last-child) {
border-bottom: solid 1px var(--shadow-hint);
}
}
.stat-label {
display: inline-block;
font-weight: bold;
color: var(--shadow-strong);
}
.stat-value {
display: inline-block;
}
</style>

View File

@ -31,6 +31,8 @@
<FilterBar :fetch-releases="fetchReleases" /> <FilterBar :fetch-releases="fetchReleases" />
<Releases :releases="tag.releases" /> <Releases :releases="tag.releases" />
<Footer />
</div> </div>
</div> </div>
</template> </template>

View File

@ -20,6 +20,8 @@
/> />
</div> </div>
</div> </div>
<Footer />
</div> </div>
</template> </template>
@ -146,7 +148,7 @@ export default {
@import 'theme'; @import 'theme';
.tags { .tags {
padding: 1rem; padding: 1rem 1rem 0 1rem;
} }
.tiles { .tiles {

View File

@ -12,6 +12,7 @@ import '../css/style.scss';
import Container from '../components/container/container.vue'; import Container from '../components/container/container.vue';
import Icon from '../components/icon/icon.vue'; import Icon from '../components/icon/icon.vue';
import Footer from '../components/footer/footer.vue';
function formatDate(date, format = 'MMMM D, YYYY', precision = 'day') { function formatDate(date, format = 'MMMM D, YYYY', precision = 'day') {
if (precision === 'year') { if (precision === 'year') {
@ -39,6 +40,7 @@ function init() {
Vue.mixin({ Vue.mixin({
components: { components: {
Icon, Icon,
Footer,
}, },
watch: { watch: {
pageTitle(title) { pageTitle(title) {

View File

@ -12,6 +12,7 @@ import Movies from '../components/releases/movies.vue';
import Tag from '../components/tags/tag.vue'; import Tag from '../components/tags/tag.vue';
import Tags from '../components/tags/tags.vue'; import Tags from '../components/tags/tags.vue';
import Search from '../components/search/search.vue'; import Search from '../components/search/search.vue';
import Stats from '../components/stats/stats.vue';
import NotFound from '../components/errors/404.vue'; import NotFound from '../components/errors/404.vue';
Vue.use(VueRouter); Vue.use(VueRouter);
@ -172,6 +173,11 @@ const routes = [
component: Search, component: Search,
name: 'search', name: 'search',
}, },
{
path: '/stats',
component: Stats,
name: 'stats',
},
{ {
path: '*', path: '*',
component: NotFound, component: NotFound,

View File

@ -154,6 +154,32 @@ function initUiActions(_store, _router) {
}; };
} }
async function fetchStats() {
const {
scenes,
movies,
actors,
networks,
channels,
} = await graphql(`
query Stats {
scenes: releasesConnection { totalCount }
movies: moviesConnection { totalCount }
actors: actorsConnection { totalCount }
networks: entitiesConnection(filter: { type: { equalTo: "network" } }) { totalCount }
channels: entitiesConnection(filter: { type: { equalTo: "channel" } }) { totalCount }
}
`);
return {
totalScenes: scenes.totalCount,
totalMovies: movies.totalCount,
totalActors: actors.totalCount,
totalNetworks: networks.totalCount,
totalChannels: channels.totalCount,
};
}
return { return {
search, search,
setFilter, setFilter,
@ -161,6 +187,7 @@ function initUiActions(_store, _router) {
setBatch, setBatch,
setSfw, setSfw,
setTheme, setTheme,
fetchStats,
}; };
} }

View File

@ -174,6 +174,8 @@ async function scrapeChannelReleases(scraper, channelEntity, preData) {
: [], : [],
]); ]);
console.log(movies);
logger.info(`Fetching ${latestReleases.length} latest and ${upcomingReleases.length} upcoming updates for '${channelEntity.name}' (${channelEntity.parent?.name})`); logger.info(`Fetching ${latestReleases.length} latest and ${upcomingReleases.length} upcoming updates for '${channelEntity.name}' (${channelEntity.parent?.name})`);
return [...latestReleases, ...upcomingReleases]; return [...latestReleases, ...upcomingReleases];