mirror of
https://github.com/romancm/gamebrary
synced 2024-11-27 21:50:24 +00:00
Misc clean up and tweaks
This commit is contained in:
parent
0bed1ffcb8
commit
eded36efd8
22 changed files with 312 additions and 584 deletions
|
@ -108,7 +108,7 @@ export default {
|
|||
align-items: center;
|
||||
|
||||
strong {
|
||||
color: var(--link-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
section {
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
<template lang="html">
|
||||
<div class="game-header">
|
||||
<img :src="coverUrl" :alt="game.name" class="game-cover" />
|
||||
|
||||
<div class="game-rating" v-if="game.age_ratings">
|
||||
<img
|
||||
v-for="{ rating, synopsis, id } in game.age_ratings"
|
||||
:key="id"
|
||||
:src='`/static/img/age-ratings/${ageRatings[rating]}.png`'
|
||||
:alt="synopsis"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
gameId: [Number, String],
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['game', 'platform']),
|
||||
...mapGetters(['ageRatings']),
|
||||
|
||||
coverUrl() {
|
||||
return this.game && this.game.cover
|
||||
? `https://images.igdb.com/igdb/image/upload/t_cover_small_2x/${this.game.cover.image_id}.jpg`
|
||||
: '/static/no-image.jpg';
|
||||
},
|
||||
|
||||
style() {
|
||||
return this.game && this.game.screenshots
|
||||
? `background: url(${this.getImageUrl(this.game.screenshots[0].cloudinary_id)}) center center no-repeat; background-size: cover;`
|
||||
: '';
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
getImageUrl(cloudinaryId) {
|
||||
return cloudinaryId
|
||||
? `https://images.igdb.com/igdb/image/upload/t_screenshot_huge_2x/${cloudinaryId}.jpg`
|
||||
: null;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles";
|
||||
|
||||
.game-header {
|
||||
display: flex;
|
||||
min-height: 20vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: $gp;
|
||||
}
|
||||
|
||||
.game-cover {
|
||||
border: 5px solid var(--modal-text-color);
|
||||
background-size: contain;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
||||
@media($small) {
|
||||
border: 3px solid var(--modal-text-color);
|
||||
height: auto;
|
||||
width: auto;
|
||||
min-width: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.game-rating {
|
||||
margin-top: $gp;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
|
||||
img {
|
||||
height: 60px;
|
||||
margin-left: $gp;
|
||||
|
||||
@media($small) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -48,7 +48,7 @@
|
|||
/>
|
||||
</draggable>
|
||||
|
||||
<game-search :list-id="listIndex" />
|
||||
<add-game :list-id="listIndex" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -60,7 +60,7 @@ import GameCardDefault from '@/components/GameCards/GameCardDefault';
|
|||
import GameCardGrid from '@/components/GameCards/GameCardGrid';
|
||||
import GameCardWide from '@/components/GameCards/GameCardWide';
|
||||
import GameCardText from '@/components/GameCards/GameCardText';
|
||||
import GameSearch from '@/components/GameSearch';
|
||||
import AddGame from '@/components/AddGame';
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import firebase from 'firebase/app';
|
||||
import 'firebase/firestore';
|
||||
|
@ -75,7 +75,7 @@ export default {
|
|||
GameCardGrid,
|
||||
GameCardWide,
|
||||
GameCardText,
|
||||
GameSearch,
|
||||
AddGame,
|
||||
ListSettings,
|
||||
draggable,
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<modal confirm :title="title" ref="listAddModal" padded @open="open">
|
||||
<modal :title="title" ref="listAddModal" @open="open">
|
||||
<button
|
||||
class="small primary add-list-button"
|
||||
:title="$t('list.add')"
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
:title="$t('list.preferences')"
|
||||
v-if="activeList"
|
||||
ref="listSettingsModal"
|
||||
padded
|
||||
@open="open"
|
||||
@close="close"
|
||||
>
|
||||
|
@ -12,13 +11,13 @@
|
|||
</button>
|
||||
|
||||
<div class="list-settings" slot="content" v-if="localList">
|
||||
<section class="setting-box">
|
||||
<section>
|
||||
<h4>List name</h4>
|
||||
|
||||
<input v-model="localList.name" ref="input" />
|
||||
</section>
|
||||
|
||||
<section class="setting-box">
|
||||
<section>
|
||||
<h4>{{ $t('list.view') }}</h4>
|
||||
|
||||
<div class="checkbox-group">
|
||||
|
@ -32,7 +31,7 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<section class="setting-box" v-if="hasMultipleGames">
|
||||
<section v-if="hasMultipleGames">
|
||||
<h4>{{ $t('list.sortList') }}</h4>
|
||||
|
||||
<div class="checkbox-group">
|
||||
|
@ -54,67 +53,65 @@
|
|||
</span>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<modal
|
||||
v-if="localList && localList.games && localList.games.length"
|
||||
ref="addList"
|
||||
:message="warningMessage"
|
||||
title="Are you sure?"
|
||||
:action-text="$t('list.delete')"
|
||||
action-button-class="danger"
|
||||
padded
|
||||
confirm
|
||||
@action="deleteList"
|
||||
>
|
||||
<footer>
|
||||
<modal
|
||||
v-if="localList && localList.games && localList.games.length"
|
||||
ref="addList"
|
||||
:message="warningMessage"
|
||||
title="Are you sure?"
|
||||
:action-text="$t('list.delete')"
|
||||
action-button-class="danger"
|
||||
@action="deleteList"
|
||||
>
|
||||
<button
|
||||
class="danger"
|
||||
:title="$t('list.delete')"
|
||||
>
|
||||
<i class="far fa-trash-alt" />
|
||||
{{ $t('list.delete') }}
|
||||
</button>
|
||||
</modal>
|
||||
|
||||
<button
|
||||
v-else
|
||||
class="danger"
|
||||
:title="$t('list.delete')"
|
||||
@click="deleteList"
|
||||
>
|
||||
<i class="far fa-trash-alt" />
|
||||
{{ $t('list.delete') }}
|
||||
</button>
|
||||
</modal>
|
||||
|
||||
<button
|
||||
v-else
|
||||
class="danger"
|
||||
:title="$t('list.delete')"
|
||||
@click="deleteList"
|
||||
>
|
||||
<i class="far fa-trash-alt" />
|
||||
{{ $t('list.delete') }}
|
||||
</button>
|
||||
<!-- <button
|
||||
class="primary hollow"
|
||||
:title="$t('list.moveLeft')"
|
||||
:disabled="isFirst"
|
||||
@click="moveList(listIndex, listIndex - 1)"
|
||||
>
|
||||
<i class="fas fa-arrow-left" />
|
||||
|
||||
<!-- <button
|
||||
class="primary hollow"
|
||||
:title="$t('list.moveLeft')"
|
||||
:disabled="isFirst"
|
||||
@click="moveList(listIndex, listIndex - 1)"
|
||||
>
|
||||
<i class="fas fa-arrow-left" />
|
||||
{{ $t('list.moveLeft') }}
|
||||
</button>
|
||||
|
||||
{{ $t('list.moveLeft') }}
|
||||
</button>
|
||||
<button
|
||||
class="primary hollow"
|
||||
:title="$t('list.moveRight')"
|
||||
:disabled="isLast"
|
||||
@click="moveList(listIndex, listIndex + 1)"
|
||||
>
|
||||
{{ $t('list.moveRight') }}
|
||||
<i class="fas fa-arrow-right" />
|
||||
</button> -->
|
||||
|
||||
<button
|
||||
class="primary hollow"
|
||||
:title="$t('list.moveRight')"
|
||||
:disabled="isLast"
|
||||
@click="moveList(listIndex, listIndex + 1)"
|
||||
>
|
||||
{{ $t('list.moveRight') }}
|
||||
<i class="fas fa-arrow-right" />
|
||||
</button> -->
|
||||
|
||||
<button
|
||||
class="primary"
|
||||
:title="$t('global.save')"
|
||||
@click="save"
|
||||
>
|
||||
{{ $t('global.save') }}
|
||||
</button>
|
||||
<button
|
||||
class="primary"
|
||||
:title="$t('global.save')"
|
||||
@click="save"
|
||||
>
|
||||
{{ $t('global.save') }}
|
||||
</button>
|
||||
</footer>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
@ -199,6 +196,7 @@ export default {
|
|||
deleteList() {
|
||||
this.$store.commit('REMOVE_LIST', this.listIndex);
|
||||
|
||||
// TODO: move to action
|
||||
db.collection('lists').doc(this.user.uid).set(this.gameLists, { merge: true })
|
||||
.then(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'List deleted' });
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
<template lang="html">
|
||||
<section class="setting-box">
|
||||
<h5 class="title">
|
||||
Game board
|
||||
<span v-if="showBoardSpecificSettings">({{ platform.name }})</span>
|
||||
</h5>
|
||||
|
||||
<!-- <div class="setting">
|
||||
<section>
|
||||
<div class="setting">
|
||||
<i class="fas fa-users" />
|
||||
<h5>{{ $t('settings.public') }}</h5>
|
||||
|
||||
<toggle-switch
|
||||
id="nightMode"
|
||||
v-model="value.public"
|
||||
id="public"
|
||||
v-model="value[platform.code].public"
|
||||
/>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="setting">
|
||||
<i class="fas fa-star-half-alt" />
|
||||
|
@ -21,65 +16,43 @@
|
|||
|
||||
<toggle-switch
|
||||
id="gameRatings"
|
||||
v-model="value.hideGameRatings"
|
||||
v-model="value[platform.code].hideGameRatings"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<template v-if="showBoardSpecificSettings">
|
||||
<wallpaper-upload />
|
||||
<wallpaper-upload />
|
||||
|
||||
<div class="setting">
|
||||
<i class="fas fa-palette" />
|
||||
<h5>Global theme</h5>
|
||||
<div class="setting">
|
||||
<i class="fas fa-palette" />
|
||||
<h5>Global theme</h5>
|
||||
|
||||
<select v-model="value[platform.code].theme">
|
||||
<option v-for="{ id, name } in themes" :key="id" :value="id">
|
||||
{{ name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<select v-model="value[platform.code].theme">
|
||||
<option v-for="{ id, name } in themes" :key="id" :value="id">
|
||||
{{ name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- TODO: refactor gameBoard to allow public data source -->
|
||||
<!-- <section>
|
||||
<h3>{{ $t('gameBoard.settings.shareLink') }}</h3>
|
||||
<div class="links">
|
||||
<a class="link primary" :href="tweetUrl" target="_blank">
|
||||
<i class="fab fa-twitter" />
|
||||
</a>
|
||||
<div class="setting">
|
||||
<i class="fas fa-exclamation-triangle" />
|
||||
<h5>{{ $t('gameBoard.settings.dangerZone') }}</h5>
|
||||
|
||||
<a class="link primary reddit" :href="redditUrl" target="_blank">
|
||||
<i class="fab fa-reddit" />
|
||||
</a>
|
||||
|
||||
<a class="link info" :href="shareUrl" target="_blank">
|
||||
<i class="fas fa-link" />
|
||||
</a>
|
||||
</div>
|
||||
</section> -->
|
||||
|
||||
<div class="setting">
|
||||
<i class="fas fa-exclamation-triangle" />
|
||||
<h5>{{ $t('gameBoard.settings.dangerZone') }}</h5>
|
||||
|
||||
<modal
|
||||
action-text="Delete forever"
|
||||
action-button-class="danger"
|
||||
confirm
|
||||
:message="`Your ${platform.name} collection will be deleted forever.`"
|
||||
:title="`Delete ${platform.name} collection`"
|
||||
padded
|
||||
@action="deletePlatform"
|
||||
<modal
|
||||
action-text="Delete forever"
|
||||
action-button-class="danger"
|
||||
:message="`Your ${platform.name} collection will be deleted forever.`"
|
||||
:title="`Delete ${platform.name} collection`"
|
||||
@action="deletePlatform"
|
||||
>
|
||||
<button
|
||||
class="small warning"
|
||||
:title="$t('list.delete')"
|
||||
>
|
||||
<button
|
||||
class="small warning"
|
||||
:title="$t('list.delete')"
|
||||
>
|
||||
<i class="far fa-trash-alt" />
|
||||
Delete {{ platform.name }} collection
|
||||
</button>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
<i class="far fa-trash-alt" />
|
||||
Delete {{ platform.name }} collection
|
||||
</button>
|
||||
</modal>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
@ -116,10 +89,6 @@ export default {
|
|||
return `Check out my ${this.platform.name} collection at Gamebrary`;
|
||||
},
|
||||
|
||||
showBoardSpecificSettings() {
|
||||
return this.$route.name === 'game-board' && this.platform;
|
||||
},
|
||||
|
||||
tweetUrl() {
|
||||
return `https://twitter.com/intent/tweet?text=${this.shareText}&url=${encodeURIComponent(this.shareUrl)}`;
|
||||
},
|
||||
|
@ -138,9 +107,8 @@ export default {
|
|||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.value.theme) {
|
||||
this.value.theme = {};
|
||||
this.value.theme[this.platform.code] = 'theme-default';
|
||||
if (!this.value[this.platform.code]) {
|
||||
this.value[this.platform.code] = {};
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -150,7 +118,7 @@ export default {
|
|||
|
||||
const db = firebase.firestore();
|
||||
|
||||
// TOOD: move to actions
|
||||
// TODO: move to actions
|
||||
db.collection('lists').doc(this.user.uid).set(this.gameLists, { merge: false })
|
||||
.then(() => {
|
||||
this.$router.push({ name: 'platforms' });
|
||||
|
@ -163,28 +131,3 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles";
|
||||
|
||||
.list-settings {
|
||||
display: grid;
|
||||
grid-gap: $gp;
|
||||
|
||||
section {
|
||||
margin-bottom: $gp;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: $gp / 2 0;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
a {
|
||||
&.reddit {
|
||||
background-color: #ff4500;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<section class="setting-box">
|
||||
<section>
|
||||
<h3>Platform page</h3>
|
||||
|
||||
<div class="setting" v-if="hasLists">
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
<template lang="html">
|
||||
<div class="settings-actions">
|
||||
<button class="secondary" @click="signOut">
|
||||
<i class="fas fa-sign-out-alt" />
|
||||
{{ $t('settings.signOut') }}
|
||||
</button>
|
||||
|
||||
<modal
|
||||
padded
|
||||
confirm
|
||||
:message="$t('settings.deleteAccount.message')"
|
||||
:title="$t('settings.deleteAccount.title')"
|
||||
:action-text="$t('settings.deleteAccount.button')"
|
||||
@action="deleteAccount"
|
||||
>
|
||||
<button class="danger">
|
||||
<i class="fas fa-exclamation-triangle" />
|
||||
{{ $t('settings.deleteAccount.button') }}
|
||||
</button>
|
||||
</modal>
|
||||
|
||||
<button class="primary" @click="save">
|
||||
{{ $t('global.save') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import firebase from 'firebase/app';
|
||||
import Modal from '@/components/Modal';
|
||||
import Gravatar from 'vue-gravatar';
|
||||
import moment from 'moment';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Modal,
|
||||
Gravatar,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
moment,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
exitUrl() {
|
||||
return process.env.NODE_ENV === 'development'
|
||||
? 'http://localhost:3000'
|
||||
: 'https://gamebrary.com';
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
exit() {
|
||||
this.$store.commit('CLEAR_SESSION');
|
||||
window.location.href = this.exitUrl;
|
||||
},
|
||||
|
||||
deleteAccount() {
|
||||
const db = firebase.firestore();
|
||||
|
||||
|
||||
// TOOD: move to actions
|
||||
db.collection('settings').doc(this.user.uid).delete()
|
||||
.then(() => {
|
||||
// TOOD: move to actions
|
||||
db.collection('lists').doc(this.user.uid).delete()
|
||||
.then(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Account deleted' });
|
||||
this.exit();
|
||||
})
|
||||
.catch(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Authentication error', type: 'error' });
|
||||
this.$router.push({ name: 'sessionExpired' });
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Authentication error', type: 'error' });
|
||||
this.$router.push({ name: 'sessionExpired' });
|
||||
});
|
||||
},
|
||||
|
||||
signOut() {
|
||||
firebase.auth().signOut()
|
||||
.then(() => {
|
||||
this.exit();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$bus.$emit('TOAST', { message: error, type: 'error' });
|
||||
});
|
||||
},
|
||||
|
||||
save() {
|
||||
this.$emit('save');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles";
|
||||
|
||||
.settings-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,5 @@
|
|||
<template lang="html">
|
||||
<section class="setting-box">
|
||||
<section>
|
||||
<h3>General</h3>
|
||||
|
||||
<div class="setting">
|
||||
|
|
|
@ -1,59 +1,81 @@
|
|||
<template lang="html">
|
||||
<section class="tags-settings setting-box">
|
||||
<h3>Tags</h3>
|
||||
<div class="tag-input">
|
||||
<input
|
||||
type="text"
|
||||
v-model="tagName"
|
||||
:placeholder="$t('tags.inputPlaceholder')"
|
||||
/>
|
||||
<div>
|
||||
<modal title="Manage tags">
|
||||
<div class="setting">
|
||||
<i class="fas fa-tags" />
|
||||
<h5>Tags</h5>
|
||||
|
||||
<input
|
||||
type="color"
|
||||
class="color-picker"
|
||||
:value="tagHex"
|
||||
@change="updateColor"
|
||||
/>
|
||||
</div>
|
||||
<button class="primary">
|
||||
Manage tags
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tag-actions">
|
||||
<button
|
||||
class="secondary small"
|
||||
:disabled="!tagName"
|
||||
@click="reset"
|
||||
<div slot="content">
|
||||
<div class="tag-input">
|
||||
<input
|
||||
type="text"
|
||||
v-model="tagName"
|
||||
:placeholder="$t('tags.inputPlaceholder')"
|
||||
/>
|
||||
|
||||
<input
|
||||
type="color"
|
||||
class="color-picker"
|
||||
:value="tagHex"
|
||||
@change="updateColor"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="tag-actions">
|
||||
<button
|
||||
class="secondary"
|
||||
:disabled="!tagName"
|
||||
@click="reset"
|
||||
>
|
||||
{{ $t('global.cancel') }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="primary"
|
||||
:disabled="isDuplicate && !editing"
|
||||
@click="submit"
|
||||
>
|
||||
{{ actionLabel }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tags" v-if="hasTags">
|
||||
<tag
|
||||
v-for="(tag, name) in localTags"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
@close="deleteTag(name)"
|
||||
/>
|
||||
<!-- @click.native="editTag(tag, name)" -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <button
|
||||
class="small warning"
|
||||
:title="$t('list.delete')"
|
||||
>
|
||||
{{ $t('global.cancel') }}
|
||||
</button>
|
||||
<i class="far fa-trash-alt" />
|
||||
Delete {{ platform.name }} collection
|
||||
</button> -->
|
||||
|
||||
<button
|
||||
class="primary small"
|
||||
:disabled="isDuplicate && !editing"
|
||||
@click="submit"
|
||||
>
|
||||
{{ actionLabel }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tags" v-if="hasTags">
|
||||
<tag
|
||||
v-for="(tag, name) in localTags"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="tag.hex"
|
||||
@close="deleteTag(name)"
|
||||
/>
|
||||
<!-- @click.native="editTag(tag, name)" -->
|
||||
</div>
|
||||
</section>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tag from '@/components/Tag';
|
||||
import Modal from '@/components/Modal';
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Tag,
|
||||
Modal,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -173,23 +195,17 @@ export default {
|
|||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles";
|
||||
|
||||
.tags-settings {
|
||||
display: grid;
|
||||
grid-gap: $gp;
|
||||
margin: $gp 0;
|
||||
padding: $gp;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.tag-input {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 32px;
|
||||
grid-gap: $gp / 2;
|
||||
grid-template-columns: 1fr 40px;
|
||||
grid-gap: $gp;
|
||||
margin-bottom: $gp;
|
||||
}
|
||||
|
||||
.tag-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: $gp;
|
||||
}
|
||||
|
||||
input {
|
||||
|
@ -198,8 +214,8 @@ export default {
|
|||
|
||||
.color-picker {
|
||||
-webkit-appearance: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- TODO: refactor to live in platform settings -->
|
||||
<template>
|
||||
<div class="setting wallpaper-upload">
|
||||
<template v-if="wallpaperUrl">
|
||||
|
@ -13,7 +14,6 @@
|
|||
ref="addList"
|
||||
:title="$t('settings.wallpaper.currentWallpaper')"
|
||||
large
|
||||
padded
|
||||
action-text="Remove wallpaper"
|
||||
@action="removeWallpaper"
|
||||
>
|
||||
|
@ -160,7 +160,7 @@ export default {
|
|||
border-radius: $border-radius;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--link-color);
|
||||
border-color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
ref="tag"
|
||||
:title="$t('tags.applyTag')"
|
||||
:message="$t('tags.useTags')"
|
||||
padded
|
||||
confirm
|
||||
>
|
||||
<div slot="content">
|
||||
<div
|
||||
|
|
|
@ -1,32 +1,44 @@
|
|||
<template lang="html">
|
||||
<div class="game-detail-wrapper">
|
||||
<div class="game-detail" v-if="game">
|
||||
<div class="game-hero" :style="style" />
|
||||
<div class="game-detail">
|
||||
<game-detail-placeholder v-if="!game" :id="id" />
|
||||
|
||||
<template v-else>
|
||||
<div class="game-detail-container">
|
||||
<pre>{{ tabs }}</pre>
|
||||
<div class="checkbox-group">
|
||||
<span v-for="{ value } in tabs">
|
||||
<label for="videos" :class="{ active: value === tab }">
|
||||
<i class="fab fa-youtube" />
|
||||
Videos
|
||||
</label>
|
||||
<input type="radio" id="videos" :value="value" v-model="tab" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- <component :is="gameCardComponent" /> -->
|
||||
|
||||
<game-screenshots />
|
||||
<game-videos />
|
||||
<igdb-credit gray />
|
||||
<div class="game-info">
|
||||
<game-header />
|
||||
<div class="game-header">
|
||||
<img :src="coverUrl" :alt="game.name" class="game-cover" />
|
||||
|
||||
<div class="game-rating" v-if="game.age_ratings">
|
||||
<img
|
||||
v-for="{ rating, synopsis, id } in game.age_ratings"
|
||||
:key="id"
|
||||
:src='`/static/img/age-ratings/${ageRatings[rating]}.png`'
|
||||
:alt="synopsis"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="game-details">
|
||||
<h2>{{ game.name }}</h2>
|
||||
{{ platform.name }}
|
||||
<game-rating :rating="game.rating" />
|
||||
|
||||
<p class="game-description" v-html="game.summary" />
|
||||
|
||||
<tag
|
||||
v-if="games.includes(game.id)"
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
readonly
|
||||
@action="openTags"
|
||||
@close="removeTag(name)"
|
||||
/>
|
||||
|
||||
<game-details />
|
||||
|
||||
<div class="actions">
|
||||
<button
|
||||
v-if="list.games.includes(game.id)"
|
||||
|
@ -50,24 +62,32 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<p class="game-description" v-html="game.summary" />
|
||||
|
||||
<tag
|
||||
v-if="games.includes(game.id)"
|
||||
v-for="({ games, hex }, name) in tags"
|
||||
:key="name"
|
||||
:label="name"
|
||||
:hex="hex"
|
||||
readonly
|
||||
@action="openTags"
|
||||
@close="removeTag(name)"
|
||||
/>
|
||||
|
||||
<game-details />
|
||||
<game-notes />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<game-screenshots />
|
||||
<game-videos />
|
||||
<igdb-credit gray />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<game-detail-placeholder v-else :id="id" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import Tag from '@/components/Tag';
|
||||
import GameHeader from '@/components/GameDetail/GameHeader';
|
||||
// import GameHeader from '@/components/GameDetail/GameHeader';
|
||||
import GameScreenshots from '@/components/GameDetail/GameScreenshots';
|
||||
import GameNotes from '@/components/GameNotes';
|
||||
import GameRating from '@/components/GameDetail/GameRating';
|
||||
|
@ -84,7 +104,7 @@ export default {
|
|||
components: {
|
||||
IgdbCredit,
|
||||
Tag,
|
||||
GameHeader,
|
||||
// GameHeader,
|
||||
GameRating,
|
||||
GameScreenshots,
|
||||
GameNotes,
|
||||
|
@ -93,6 +113,20 @@ export default {
|
|||
GameDetailPlaceholder,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
tab: '',
|
||||
tabs: [
|
||||
{
|
||||
value: 'videos',
|
||||
icon: 'fab fa-youtube',
|
||||
text: 'Videos',
|
||||
component: 'GameVideos',
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
|
||||
props: {
|
||||
id: [Number, String],
|
||||
listId: [Number, String],
|
||||
|
@ -100,23 +134,12 @@ export default {
|
|||
|
||||
computed: {
|
||||
...mapState(['game', 'user', 'platform', 'tags', 'gameLists']),
|
||||
...mapGetters(['ageRatings']),
|
||||
|
||||
hasTags() {
|
||||
return Object.keys(this.tags) && Object.keys(this.tags).length > 0;
|
||||
},
|
||||
|
||||
style() {
|
||||
const screenshot = this.game.screenshots && this.game.screenshots.length > 0
|
||||
? this.game.screenshots[0]
|
||||
: null;
|
||||
|
||||
const screenshotUrl = screenshot && screenshot.image_id
|
||||
? `https://images.igdb.com/igdb/image/upload/t_screenshot_big/${screenshot.image_id}.jpg`
|
||||
: '';
|
||||
|
||||
return `background: url('${screenshotUrl}') center center no-repeat; background-size: cover;`;
|
||||
},
|
||||
|
||||
activePlatform() {
|
||||
return this.gameLists[this.platform.code];
|
||||
},
|
||||
|
@ -126,7 +149,7 @@ export default {
|
|||
},
|
||||
|
||||
coverUrl() {
|
||||
return this.game.cover && this.game.cover.image_id
|
||||
return this.game && this.game.cover
|
||||
? `https://images.igdb.com/igdb/image/upload/t_cover_small_2x/${this.game.cover.image_id}.jpg`
|
||||
: '/static/no-image.jpg';
|
||||
},
|
||||
|
@ -195,100 +218,5 @@ export default {
|
|||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles";
|
||||
|
||||
.game-detail {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: calc(100vh - #{$navHeight});
|
||||
|
||||
@media($small) {
|
||||
padding-top: $gp * 2;
|
||||
}
|
||||
}
|
||||
|
||||
.game-hero {
|
||||
background-color: #555555;
|
||||
position: absolute;
|
||||
background-position: bottom;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
border-top-left-radius: $border-radius;
|
||||
border-top-right-radius: $border-radius;
|
||||
height: 400px;
|
||||
z-index: 1;
|
||||
|
||||
@media($small) {
|
||||
top: 0;
|
||||
border-radius: 0;
|
||||
padding-top: $gp;
|
||||
}
|
||||
}
|
||||
|
||||
.game-details {
|
||||
margin-top: $gp;
|
||||
|
||||
@media($small) {
|
||||
margin: -$gp;
|
||||
margin-top: $gp;
|
||||
padding: $gp;
|
||||
background-color: var(--modal-background);
|
||||
}
|
||||
}
|
||||
|
||||
.game-info {
|
||||
display: grid;
|
||||
grid-template-columns: 180px auto;
|
||||
grid-gap: $gp * 2;
|
||||
margin: 0 $gp;
|
||||
|
||||
@media($small) {
|
||||
grid-gap: 0;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
.game-description {
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
|
||||
.game-description {
|
||||
line-height: 1.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.game-detail-container {
|
||||
box-shadow: 0 0 2px 0 #a5a2a2;
|
||||
width: $container-width;
|
||||
background: var(--modal-background);
|
||||
opacity: 0.95;
|
||||
max-width: 100%;
|
||||
z-index: 1;
|
||||
margin: $gp * 3;
|
||||
border-radius: $border-radius;
|
||||
|
||||
@media($small) {
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
margin-top: 0;
|
||||
box-shadow: none;
|
||||
background-color: rgba(255, 255, 255, .5);
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.igdb-credit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
padding: $gp;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: $gp;
|
||||
|
||||
button {
|
||||
margin-right: $gp;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,17 +1,38 @@
|
|||
<template lang="html">
|
||||
<modal title="Settings">
|
||||
<modal title="Settings" action-text="Save" @action="save">
|
||||
<button class="small primary">
|
||||
<i class="fas fa-cog" />
|
||||
</button>
|
||||
|
||||
<div class="settings" slot="content">
|
||||
<!-- <pre>{{ localSettings }}</pre> -->
|
||||
<settings-global v-model="localSettings" />
|
||||
<game-board-settings v-model="localSettings" />
|
||||
<tags-settings v-model="localSettings" />
|
||||
</div>
|
||||
|
||||
<settings-actions slot="footer" @save="save" />
|
||||
<div class="setting">
|
||||
<i class="fas fa-sign-out-alt" />
|
||||
{{ $t('settings.signOut') }}
|
||||
|
||||
<button class="secondary" @click="signOut">
|
||||
{{ $t('settings.signOut') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<modal
|
||||
:message="$t('settings.deleteAccount.message')"
|
||||
:title="$t('settings.deleteAccount.title')"
|
||||
:action-text="$t('settings.deleteAccount.button')"
|
||||
@action="deleteAccount"
|
||||
>
|
||||
<div class="setting">
|
||||
<i class="fas fa-exclamation-triangle" />
|
||||
{{ $t('settings.deleteAccount.button') }}
|
||||
|
||||
<button class="danger">
|
||||
{{ $t('settings.deleteAccount.button') }}
|
||||
</button>
|
||||
</div>
|
||||
</modal>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
|
@ -21,11 +42,11 @@ import 'firebase/firestore';
|
|||
import 'firebase/auth';
|
||||
import GameBoardSettings from '@/components/Settings/GameBoardSettings';
|
||||
import SettingsGlobal from '@/components/Settings/SettingsGlobal';
|
||||
import SettingsActions from '@/components/Settings/SettingsActions';
|
||||
import AboutSettings from '@/components/Settings/AboutSettings';
|
||||
import TagsSettings from '@/components/Settings/TagsSettings';
|
||||
import Modal from '@/components/Modal';
|
||||
import moment from 'moment';
|
||||
import firebase from 'firebase/app';
|
||||
import Releases from '@/components/Releases/Releases';
|
||||
|
||||
export default {
|
||||
|
@ -34,7 +55,6 @@ export default {
|
|||
Releases,
|
||||
GameBoardSettings,
|
||||
SettingsGlobal,
|
||||
SettingsActions,
|
||||
AboutSettings,
|
||||
TagsSettings,
|
||||
},
|
||||
|
@ -76,8 +96,48 @@ export default {
|
|||
|
||||
methods: {
|
||||
save() {
|
||||
// TODO: call action directly
|
||||
this.$bus.$emit('SAVE_SETTINGS', this.localSettings);
|
||||
},
|
||||
|
||||
deleteAccount() {
|
||||
const db = firebase.firestore();
|
||||
|
||||
|
||||
// TOOD: move to actions
|
||||
db.collection('settings').doc(this.user.uid).delete()
|
||||
.then(() => {
|
||||
// TOOD: move to actions
|
||||
db.collection('lists').doc(this.user.uid).delete()
|
||||
.then(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Account deleted' });
|
||||
this.exit();
|
||||
})
|
||||
.catch(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Authentication error', type: 'error' });
|
||||
this.$router.push({ name: 'sessionExpired' });
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
this.$bus.$emit('TOAST', { message: 'Authentication error', type: 'error' });
|
||||
this.$router.push({ name: 'sessionExpired' });
|
||||
});
|
||||
},
|
||||
|
||||
signOut() {
|
||||
firebase.auth().signOut()
|
||||
.then(() => {
|
||||
this.exit();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$bus.$emit('TOAST', { message: error, type: 'error' });
|
||||
});
|
||||
},
|
||||
|
||||
exit() {
|
||||
this.$store.commit('CLEAR_SESSION');
|
||||
window.location.href = this.exitUrl;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -88,8 +148,5 @@ export default {
|
|||
.settings {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: $gp * 2 $gp;
|
||||
margin: 0 auto;
|
||||
min-height: 600px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -31,6 +31,11 @@ export default new Router({
|
|||
name: 'game-board',
|
||||
component: GameBoard,
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
name: 'settings',
|
||||
component: GameBoard,
|
||||
},
|
||||
{
|
||||
path: '/auth/:authProvider',
|
||||
name: 'auth',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
$iconSmallSize: 32px;
|
||||
|
||||
a {
|
||||
color: var(--link-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
a.link {
|
||||
|
|
|
@ -2,16 +2,11 @@ input, select {
|
|||
background: #fff;
|
||||
border: 1px solid #555555;
|
||||
border-radius: $border-radius;
|
||||
height: 32px;
|
||||
height: 40px;
|
||||
padding: 0 $gp / 2;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
font-size: 14px;
|
||||
margin-bottom: $gp;
|
||||
|
||||
&.small {
|
||||
height: 20px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
|
@ -31,7 +26,7 @@ input, select {
|
|||
align-items: center;
|
||||
|
||||
&.active {
|
||||
color: var(--link-color);
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
i {
|
||||
|
|
|
@ -9,10 +9,3 @@ h5.title {
|
|||
align-items: center;
|
||||
padding: $gp 0;
|
||||
}
|
||||
|
||||
.setting-box {
|
||||
border: 1px solid rgba(85, 85, 85, .5);
|
||||
border-radius: $border-radius;
|
||||
margin: 0 0 $gp * 1.5;
|
||||
padding: $gp;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
--game-card-background: #ffffff;
|
||||
--game-card-text-color: #333333;
|
||||
--header-text-color: #fff;
|
||||
--link-color: #0ab9e6;
|
||||
--accent-color: #0ab9e6;
|
||||
--list-background: #e5e5e5;
|
||||
--list-header-background: #003087;
|
||||
--list-header-text-color: #ffffff;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
--game-card-background: #12141C;
|
||||
--game-card-text-color: #fc0;
|
||||
--header-text-color: #fcfcfc;
|
||||
--link-color: #8B76C1;
|
||||
--accent-color: #8B76C1;
|
||||
--list-background: #0b212f;
|
||||
--list-header-background: #003b4a;
|
||||
--list-header-text-color: #fcfcfc;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
--game-card-background: #A6A2A2;
|
||||
--game-card-text-color: #222;
|
||||
--header-text-color: #fff;
|
||||
--link-color: #222;
|
||||
--accent-color: #fc0;
|
||||
--list-background: #555;
|
||||
--list-header-background: #333;
|
||||
--list-header-text-color: #c0c0c0;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
--game-card-background: #ffffff;
|
||||
--game-card-text-color: #333333;
|
||||
--header-text-color: #222222;
|
||||
--link-color: #333333;
|
||||
--accent-color: #0ab9e6;
|
||||
--list-background: #e5e5e5;
|
||||
--list-header-background: #555555;
|
||||
--list-header-text-color: #ffffff;
|
||||
|
|
Loading…
Reference in a new issue