layout fixes

This commit is contained in:
Gamebrary 2022-08-15 21:38:07 -07:00
parent c45607d5c9
commit 583b23bcf6
4 changed files with 107 additions and 133 deletions

View file

@ -1,51 +0,0 @@
<template lang="html">
<b-row>
<b-col
offset="2"
offset-sm="0"
cols="8"
sm="4"
md="4"
xl="3"
>
<router-link :to="{ name: 'game', params: { id: game.id, slug: game.slug }}">
<b-img
:src="gameCoverUrl"
rounded
class="cursor-pointer"
fluid-grow
/>
</router-link>
</b-col>
<b-col
cols="12"
sm="8"
md="8"
lg="8"
xl="9"
class="bg-white rounded p-5"
>
<slot />
</b-col>
</b-row>
</template>
<script>
import { getGameCoverUrl } from '@/utils';
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['game']),
gameCoverUrl() {
return getGameCoverUrl(this.game);
},
},
};
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
</style>

View file

@ -1,51 +1,77 @@
<!-- TODO: finish layout -->
<template lang="html">
<b-container fluid class="p-2">
<portal to="pageTitle">
<div>
<b-button
:to="{ name: 'settings' }"
variant="light"
class="mr-2"
>
<i class="fa-solid fa-chevron-left" />
</b-button>
Notes
</div>
</portal>
<div v-if="loading">
Loading...
</div>
<game-sub-page v-else>
<game-note v-if="note" :note="{ note }" />
<b-row>
<b-col cols="6">
<b-img
v-if="game && game.id"
:src="getCoverUrl(game.id)"
class="cursor-pointer"
thumbnail
@click="selectedNote = filteredNotes[index]"
/>
</b-col>
<b-button
variant="primary"
:disabled="saving || !dirtied"
@click="saveNote"
>
<b-spinner small v-if="saving" />
<span v-else>{{ $t('global.save') }}</span>
</b-button>
<b-col>
<game-note v-if="note" :note="{ note }" />
<b-button
variant="danger"
class="mr-1"
v-if="notes[game.id] && !saving"
:disabled="deleting"
@click="deleteNote"
>
<b-spinner small v-if="deleting" />
<b-button
variant="primary"
:disabled="saving || !dirtied"
@click="saveNote"
>
<b-spinner small v-if="saving" />
<span v-else>{{ $t('global.save') }}</span>
</b-button>
<i class="d-sm-none fas fa-trash fa-fw" aria-hidden />
<span class="d-none d-sm-inline">{{ $t('global.delete') }}</span>
</b-button>
<b-button
variant="danger"
class="mr-1"
v-if="notes[game.id] && !saving"
:disabled="deleting"
@click="deleteNote"
>
<b-spinner small v-if="deleting" />
<b-form-textarea
v-model.trim="note"
placeholder="Type note here"
rows="3"
max-rows="20"
/>
<i class="d-sm-none fas fa-trash fa-fw" aria-hidden />
<span class="d-none d-sm-inline">{{ $t('global.delete') }}</span>
</b-button>
<b-form-text id="input-live-help" v-b-modal.markdown-cheatsheet>
<i class="fab fa-markdown fa-fw" />
Markdown supported
</b-form-text>
<b-form-textarea
v-model.trim="note"
placeholder="Type note here"
rows="3"
max-rows="20"
/>
<b-modal id="markdown-cheatsheet" title="BootstrapVue">
<markdown-cheatsheet />
</b-modal>
</game-sub-page>
<b-form-text id="input-live-help" v-b-modal.markdown-cheatsheet>
<i class="fab fa-markdown fa-fw" />
Markdown supported
</b-form-text>
<b-modal id="markdown-cheatsheet" title="BootstrapVue">
<markdown-cheatsheet />
</b-modal>
</b-col>
</b-row>
</b-container>
</template>
@ -53,14 +79,13 @@
import { mapState } from 'vuex';
import GameNote from '@/components/GameNote';
import GameSubPage from '@/components/Game/GameSubPage';
import MarkdownCheatsheet from '@/components/MarkdownCheatsheet';
// TODO: consolidate getGameCoverUrl
import { getGameCoverUrl } from '@/utils';
export default {
components: {
GameNote,
GameSubPage,
MarkdownCheatsheet,
},
@ -73,7 +98,7 @@ export default {
},
computed: {
...mapState(['notes', 'game']),
...mapState(['notes', 'game', 'games']),
gameCoverUrl() {
return getGameCoverUrl(this.game);
@ -95,6 +120,14 @@ data() {
},
methods: {
getCoverUrl(gameId) {
const game = this.games[gameId];
return game && game.cover && game.cover.image_id
? `https://images.igdb.com/igdb/image/upload/t_cover_small_2x/${game.cover.image_id}.jpg`
: '/no-image.jpg';
},
loadNote() {
if (this.game.id !== this.$route.params.id) {
this.loadGame();

View file

@ -27,9 +27,7 @@
</b-button>
</portal>
<div v-if="loading" class="text-center mt-5 ml-auto">
<b-spinner/>
</div>
<b-spinner v-if="loading" class="spinner-centered" />
<b-row v-else>
<b-col cols="6">

View file

@ -15,6 +15,7 @@
Notes
</div>
</portal>
<portal to="headerActions">
<b-form-input
v-if="!showEmptyState"
@ -32,15 +33,34 @@
message="Looks like you don't have any notes yet."
/>
<template v-else>
<div class="notes">
<game-note
v-for="(note, index) in filteredNotes"
<b-row v-else>
<b-col cols="6" v-if="noteGames.length">
<!-- TODO: make computed for note selector -->
<div
v-for="(game, index) in noteGames"
:key="index"
:note="note"
/>
</div>
</template>
>
<b-img
v-if="game && game.id"
:src="getCoverUrl(game.id)"
class="cursor-pointer"
thumbnail
@click="selectedNote = filteredNotes[index]"
/>
<b-button
v-if="game && game.name"
@click="selectedNote = filteredNotes[index]"
>
{{ game.name }}
</b-button>
</div>
</b-col>
<b-col>
<game-note :note="selectedNote" v-if="selectedNote" />
</b-col>
</b-row>
</b-container>
</template>
@ -57,6 +77,7 @@ export default {
data() {
return {
selectedNote: null,
loaded: false,
search: '',
};
@ -69,6 +90,10 @@ export default {
return this.loaded && !Object.keys(this.notes).length;
},
noteGames() {
return Object.keys(this.notes).map((id) => this.games[id]);
},
// TODO: move to getter?
filteredNotes() {
return Object.values(this.notes)
@ -96,21 +121,11 @@ export default {
mounted() {
this.loadGames();
if (this.filteredNotes.length > 0) this.selectedNote = this.filteredNotes[0];
},
methods: {
getNoteHeight(noteLength) {
if (noteLength < 50) {
return 100;
}
if (noteLength < 200) {
return 300;
}
return 200;
},
async loadGames() {
const gamesList = Object.keys(this.notes).length
? Object.keys(this.notes).toString()
@ -142,24 +157,3 @@ export default {
},
};
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.notes {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 1rem;
@media(max-width: 1200px) {
grid-template-columns: 1fr 1fr 1fr;
}
@media(max-width: 780px) {
grid-template-columns: 1fr 1fr;
}
@media(max-width: 500px) {
grid-template-columns: 1fr;
}
}
</style>