UX Updates

This commit is contained in:
Gamebrary 2022-07-05 14:08:15 -07:00
parent 53f10564b5
commit de132c2286
16 changed files with 341 additions and 277 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -1,3 +1,4 @@
<!-- TODO: Use moment? or use dayjs without wrapper -->
<!-- TODO: remove toasts --> <!-- TODO: remove toasts -->
<!-- TODO: add mega search shift + k --> <!-- TODO: add mega search shift + k -->
<!-- TODO: re-translate strings --> <!-- TODO: re-translate strings -->
@ -23,17 +24,18 @@
@shortkey="handleShortcutAction" @shortkey="handleShortcutAction"
> >
<page-header /> <page-header />
<router-view class="viewport" />
<main :class="[{ 'authorizing': !user }, 'bg-light']"> <auth-modal />
<global-modals /> <keyboard-shortcuts-modal />
<router-view /> <add-remove-game />
</main>
</div> </div>
</template> </template>
<script> <script>
import AuthModal from '@/components/AuthModal';
import AddRemoveGame from '@/components/AddRemoveGame';
import KeyboardShortcutsModal from '@/components/KeyboardShortcutsModal';
import PageHeader from '@/components/PageHeader'; import PageHeader from '@/components/PageHeader';
import GlobalModals from '@/components/GlobalModals';
import sessionMixin from '@/mixins/sessionMixin'; import sessionMixin from '@/mixins/sessionMixin';
import firebase from 'firebase/app'; import firebase from 'firebase/app';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
@ -46,7 +48,9 @@ export default {
components: { components: {
PageHeader, PageHeader,
GlobalModals, AuthModal,
AddRemoveGame,
KeyboardShortcutsModal,
}, },
mixins: [sessionMixin], mixins: [sessionMixin],
@ -130,17 +134,14 @@ export default {
<style lang="scss" rel="stylesheet/scss" scoped> <style lang="scss" rel="stylesheet/scss" scoped>
#app { #app {
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(0,212,255,1) 100%); // background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(0,212,255,1) 100%);
height: 100vh; min-height: 100vh;
display: grid; display: grid;
} }
header { .viewport {
grid-column: 1/-1; // padding-top: 54px !important;
}
main {
overflow-y: auto; overflow-y: auto;
height: calc(100vh - 54px); // height: calc(100vh - 54px);
} }
</style> </style>

View file

@ -22,7 +22,7 @@
</header> </header>
<!-- TODO: show active board at top --> <!-- TODO: show active board at top -->
Boards: <h4 class="mx-2">Boards:</h4>
<b-list-group flush> <b-list-group flush>
<b-list-group-item <b-list-group-item
v-for="board in formattedBoards" v-for="board in formattedBoards"
@ -32,7 +32,7 @@
@click="expandedBoard = board.id === expandedBoard ? null : board.id" @click="expandedBoard = board.id === expandedBoard ? null : board.id"
> >
<header class="p-2 d-flex justify-content-between align-items-center"> <header class="p-2 d-flex justify-content-between align-items-center">
<aside> <aside class="d-flex">
<b-avatar <b-avatar
rounded rounded
:class="['board-thumbnail mr-2', { 'bg-dark' : !board.backgroundColor }]" :class="['board-thumbnail mr-2', { 'bg-dark' : !board.backgroundColor }]"
@ -44,7 +44,12 @@
`" `"
:to="{ name: 'board', params: { id: board.id } }" :to="{ name: 'board', params: { id: board.id } }"
/> />
{{ board.name }}
<div class="d-flex flex-column">
{{ board.name }}
<br />
<small>{{ board.lists.length }} Lists</small>
</div>
<!-- TODO: show "In XX lists" --> <!-- TODO: show "In XX lists" -->
</aside> </aside>

View file

@ -10,13 +10,12 @@
Edit board Edit board
</b-button> </b-button>
<b-button <!-- <b-button
v-b-modal.add-list
block block
variant="primary" variant="primary"
> >
Add list Add list
</b-button> </b-button> -->
</div> </div>
</template> </template>

View file

@ -1,5 +1,5 @@
<template lang="html"> <template lang="html">
<div v-if="game" class="mt-4 d-block"> <div v-if="game">
<b-button <b-button
v-for="{ url, id, icon, svg } in links" v-for="{ url, id, icon, svg } in links"
:href="url" :href="url"

View file

@ -1,23 +1,22 @@
<template lang="html"> <template lang="html">
<b-card v-if="similarGames.length"> <div v-if="similarGames.length">
<h4 class="text-center">You may also like:</h4> <h4 class="text-center text-muted">You may also like</h4>
<div class="d-flex overflow-auto"> <div class="d-flex overflow-auto">
<b-card <b-card
v-for="game in similarGames" v-for="game in similarGames"
:key="game.id" :key="game.id"
:title="game.name" :title="game.name"
title-tag="small"
class="flex-shrink-0 mr-2 cursor-pointer" class="flex-shrink-0 mr-2 cursor-pointer"
style="max-width: 120px;" style="max-width: 180px;"
body-class="p-1 px-2" body-class="p-2 text-center text-muted"
:img-src="getCoverUrl(game)" :img-src="getCoverUrl(game)"
:img-alt="game.name" :img-alt="game.name"
img-top img-top
@click="openGame(game)" @click="openGame(game)"
/> />
</div> </div>
</b-card> </div>
</template> </template>
<script> <script>
@ -71,6 +70,3 @@ export default {
}, },
}; };
</script> </script>
<style lang="scss" rel="stylesheet/scss" scoped>
</style>

View file

@ -0,0 +1,45 @@
<template lang="html">
<b-card
no-body
:title="game.name"
:img-src="coverUrl"
:img-alt="game.name"
img-top
class="mb-2"
footer-class="p-0 text-center font-weight-bold bold strong"
@click="addGameToList"
>
<!-- :to="{ name: 'game', params: { id: game.id, slug: game.slug }}" -->
<template #footer>
<small class="text-muted">
<strong>{{ game.name }}</strong>
</small>
</template>
</b-card>
</template>
<script>
import { getGameCoverUrl } from '@/utils';
export default {
props: {
game: {
type: Object,
required: true,
},
},
computed: {
coverUrl() {
return getGameCoverUrl(this.game);
}
},
methods: {
addGameToList() {
this.$bus.$emit('ADD_GAME', this.game.id);
},
},
};
</script>

View file

@ -1,27 +0,0 @@
<template lang="html">
<div>
<auth-modal />
<keyboard-shortcuts-modal />
<add-remove-game />
</div>
</template>
<script>
import { mapState } from 'vuex';
import AuthModal from '@/components/AuthModal';
import AddRemoveGame from '@/components/AddRemoveGame';
import KeyboardShortcutsModal from '@/components/KeyboardShortcutsModal';
export default {
components: {
AuthModal,
AddRemoveGame,
KeyboardShortcutsModal,
},
computed: {
...mapState(['user']),
},
};
</script>

View file

@ -17,8 +17,8 @@
<b-button <b-button
block block
size="sm" size="sm"
variant="outline-light" variant="transparent"
class="text-dark d-flex justify-content-between align-items-center px-2" class="text-dark d-flex justify-content-between align-items-center pl-0"
:disabled="preview || (user && user.uid !== board.owner)" :disabled="preview || (user && user.uid !== board.owner)"
:to="{ name: 'board.list.edit', params: { id: board.id, listIndex } }" :to="{ name: 'board.list.edit', params: { id: board.id, listIndex } }"
> >

View file

@ -1,8 +1,8 @@
<template lang="html"> <template lang="html">
<header class="py-1 px-2 d-flex"> <header class="py-1 px-2 d-flex position-fixed">
<home-button /> <home-button />
<boards-dropdown v-if="isBoardPage || isGamePage" /> <boards-dropdown v-if="board.id && (isBoardPage || isGamePage)" />
<game-dropdown v-if="isGamePage" /> <!-- <game-dropdown v-if="isGamePage" /> -->
<div class="global-actions"> <div class="global-actions">
<portal-target name="headerActions" /> <portal-target name="headerActions" />
@ -11,7 +11,12 @@
Upgrade Upgrade
</b-button> --> </b-button> -->
<search-box /> <b-button
variant="primary"
:to="{ name: 'search' }"
>
<i class="fas fa-search fa-fw" aria-hidden />
</b-button>
<b-dropdown <b-dropdown
v-if="user" v-if="user"
@ -24,6 +29,7 @@
<template #button-content> <template #button-content>
<b-avatar rounded variant="info" :src="user.photoURL" /> <b-avatar rounded variant="info" :src="user.photoURL" />
</template> </template>
<b-dropdown-item <b-dropdown-item
:to="{ name: 'settings' }" :to="{ name: 'settings' }"
> >
@ -58,9 +64,8 @@
</template> </template>
<script> <script>
import GameDropdown from '@/components/Game/GameDropdown'; // import GameDropdown from '@/components/Game/GameDropdown';
import BoardsDropdown from '@/components/BoardsDropdown'; import BoardsDropdown from '@/components/BoardsDropdown';
import SearchBox from '@/components/SearchBox';
import HomeButton from '@/components/Shared/HomeButton'; import HomeButton from '@/components/Shared/HomeButton';
import sessionMixin from '@/mixins/sessionMixin'; import sessionMixin from '@/mixins/sessionMixin';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
@ -69,9 +74,8 @@ export default {
mixins: [sessionMixin], mixins: [sessionMixin],
components: { components: {
GameDropdown, // GameDropdown,
BoardsDropdown, BoardsDropdown,
SearchBox,
HomeButton, HomeButton,
}, },
@ -101,6 +105,7 @@ export default {
// height: 46px; // height: 46px;
grid-template-columns: 65px 1fr; grid-template-columns: 65px 1fr;
// background-color: #574c4f; // background-color: #574c4f;
z-index: 1;
} }
.toolbar { .toolbar {

View file

@ -1,6 +1,6 @@
<template lang="html"> <template lang="html">
<div class="search-box mr-2"> <div class="search-box">
<b-form @submit.prevent="search" :class="isSearchPage ? '' : 'd-none d-md-block'"> <b-form @submit.prevent="search">
<b-input-group> <b-input-group>
<b-form-input <b-form-input
v-model="searchText" v-model="searchText"
@ -16,13 +16,20 @@
type="submit" type="submit"
variant="info" variant="info"
> >
<i class="fas fa-search fa-fw" aria-hidden /> <i
class="fas fa-search fa-fw"
aria-hidden
/>
</b-button> </b-button>
</b-input-group-append> </b-input-group-append>
</b-input-group> </b-input-group>
</b-form> </b-form>
<b-button :class="isSearchPage ? 'd-none' : 'd-md-none'" variant="primary" :to="{ name: 'search' }"> <b-button
:class="isSearchPage ? 'd-none' : 'd-md-none'"
variant="primary"
:to="{ name: 'search' }"
>
<i class="fas fa-search fa-fw" aria-hidden /> <i class="fas fa-search fa-fw" aria-hidden />
</b-button> </b-button>
</div> </div>

View file

@ -36,6 +36,10 @@ export default {
return this.list?.settings?.showGameTags && this.gameTags; return this.list?.settings?.showGameTags && this.gameTags;
}, },
showReleaseDates() {
return this.list?.settings?.showReleaseDates;
},
gameProgress() { gameProgress() {
const { gameId, progresses } = this; const { gameId, progresses } = this;

View file

@ -1,6 +1,6 @@
<template lang="html"> <template lang="html">
<div <div
:class="['board p-3', { dragging, empty }]" :class="['board px-3 pb-3', { dragging, empty }]"
:style="boardStyles" :style="boardStyles"
> >
<board-placeholder v-if="loading" /> <board-placeholder v-if="loading" />
@ -16,19 +16,7 @@
<empty-board v-if="empty" /> <empty-board v-if="empty" />
<div <add-list v-else-if="user && user.uid && user.uid === board.owner" />
v-else-if="user && user.uid && user.uid === board.owner"
class="d-flex flex-column"
>
<b-button
variant="light"
v-b-modal:add-list
>
<i class="fas fa-plus fa-fw" aria-hidden />
</b-button>
</div>
<add-list-modal />
</template> </template>
<b-alert <b-alert
@ -44,7 +32,7 @@
<script> <script>
import BoardPlaceholder from '@/components/Board/BoardPlaceholder'; import BoardPlaceholder from '@/components/Board/BoardPlaceholder';
import EmptyBoard from '@/components/Board/EmptyBoard'; import EmptyBoard from '@/components/Board/EmptyBoard';
import AddListModal from '@/components/Board/AddListModal'; import AddList from '@/components/Board/AddList';
import GameList from '@/components/Lists/GameList'; import GameList from '@/components/Lists/GameList';
import chunk from 'lodash.chunk'; import chunk from 'lodash.chunk';
import { mapState, mapGetters } from 'vuex'; import { mapState, mapGetters } from 'vuex';
@ -54,7 +42,7 @@ export default {
GameList, GameList,
BoardPlaceholder, BoardPlaceholder,
EmptyBoard, EmptyBoard,
AddListModal, AddList,
}, },
data() { data() {
@ -188,7 +176,7 @@ export default {
const { lists } = this.board; const { lists } = this.board;
if (lists && lists.length === 0) { if (lists && lists.length === 0) {
this.$bvModal.show('add-list'); // TODO: toggle add list
} }
const boardGames = lists.length const boardGames = lists.length

View file

@ -23,170 +23,153 @@
</header> </header>
<form ref="boardSettingsForm" @submit.stop.prevent="submit"> <form ref="boardSettingsForm" @submit.stop.prevent="submit">
<b-row> <b-form-group
<b-col> :label="$t('board.settings.nameLabel')"
<b-button @click="goToBoard"> label-for="name"
Back to board >
</b-button> <b-form-input
id="name"
v-model="name"
required
/>
</b-form-group>
<b-form-group <b-form-group
:label="$t('board.settings.nameLabel')" :label="$t('board.settings.descriptionLabel')"
label-for="name" label-for="description"
> >
<b-form-input <b-form-textarea
id="name" id="description"
v-model="name" v-model="description"
required maxlength="280"
/> rows="3"
</b-form-group> />
</b-form-group>
<b-form-group <b-form-checkbox v-model="isPublic" switch class="mb-2">
:label="$t('board.settings.descriptionLabel')" Make board public (beta)
label-for="description" </b-form-checkbox>
>
<b-form-textarea
id="description"
v-model="description"
maxlength="280"
rows="3"
/>
</b-form-group>
<b-form-checkbox v-model="isPublic" switch class="mb-2"> <b-alert show variant="info" v-if="isPublic" class="m-0">
Make board public (beta) <strong>Public Board URL</strong>
</b-form-checkbox> <br>
<small>{{ `https://app.gamebrary.com/#/b/${board.id}` }}</small>
</b-alert>
<b-alert show variant="info" v-if="isPublic" class="m-0"> <hr class="my-3">
<strong>Public Board URL</strong>
<br>
<small>{{ `https://app.gamebrary.com/#/b/${board.id}` }}</small>
</b-alert>
<hr class="my-3"> <edit-board-background-modal />
<hr class="my-3"> <b-button v-b-modal.boardBackground>
<i class="fas fa-images fa-fw" aria-hidden />
<br />
Change background
</b-button>
<b-button <hr class="my-3">
variant="danger"
@click="confirmDelete"
>
{{ $t('board.settings.deleteBoard') }}
</b-button>
<b-button <b-button
variant="primary" variant="danger"
:disabled="saving" @click="confirmDelete"
@click="saveSettings" >
> {{ $t('board.settings.deleteBoard') }}
<b-spinner small v-if="saving" /> </b-button>
<span v-else>{{ $t('global.save') }}</span>
</b-button>
</b-col>
<b-col> <!-- <b-button
<!-- <b-button variant="primary"
variant="primary" :disabled="saving"
:disabled="saving" @click="saveSettings"
@click="saveSettings" >
> <b-spinner small v-if="saving" />
<b-spinner small v-if="saving" /> <span v-else>{{ $t('global.save') }}</span>
<span v-else>{{ $t('global.save') }}</span> </b-button> -->
</b-button> -->
<b-alert :show="noPlatformsSelected" variant="warning"> <!-- <b-alert :show="noPlatformsSelected" variant="warning">
No platforms selected, game search will include all platforms. No platforms selected, game search will include all platforms.
</b-alert> </b-alert>
<b-alert :show="noPlatformsSelected" variant="success"> <b-alert :show="noPlatformsSelected" variant="success">
Select platforms to limit search results. Select platforms to limit search results.
</b-alert> </b-alert> -->
<!-- <platform-picker v-model="platforms" /> --> <!-- <platform-picker v-model="platforms" /> -->
<!-- <b-button-toolbar aria-label="Toolbar with button groups and dropdown menu"> <!-- <b-button-toolbar aria-label="Toolbar with button groups and dropdown menu">
<b-button-group class="mx-1"> <b-button-group class="mx-1">
<b-button>New</b-button> <b-button>New</b-button>
<b-button>Edit</b-button> <b-button>Edit</b-button>
<b-button>Undo</b-button> <b-button>Undo</b-button>
</b-button-group> </b-button-group>
<b-dropdown class="mx-1" right text="menu"> <b-dropdown class="mx-1" right text="menu">
<b-dropdown-item>Item 1</b-dropdown-item> <b-dropdown-item>Item 1</b-dropdown-item>
<b-dropdown-item>Item 2</b-dropdown-item> <b-dropdown-item>Item 2</b-dropdown-item>
<b-dropdown-item>Item 3</b-dropdown-item> <b-dropdown-item>Item 3</b-dropdown-item>
</b-dropdown> </b-dropdown>
<b-button-group class="mx-1"> <b-button-group class="mx-1">
<b-button>Save</b-button> <b-button>Save</b-button>
<b-button>Cancel</b-button> <b-button>Cancel</b-button>
</b-button-group> </b-button-group>
</b-button-toolbar> --> </b-button-toolbar> -->
<!-- <div class="d-flex mb-2"> <!-- <div class="d-flex mb-2">
<div class="filter mr-2"> <div class="filter mr-2">
<small class="d-block text-muted">Show:</small> <small class="d-block text-muted">Show:</small>
<b-button size="sm">All</b-button> <b-button size="sm">All</b-button>
<b-button size="sm">Consoles</b-button> <b-button size="sm">Consoles</b-button>
<b-button size="sm">Handhelds</b-button> <b-button size="sm">Handhelds</b-button>
<b-button size="sm">PC</b-button> <b-button size="sm">PC</b-button>
</div> </div>
<div class="sort"> <div class="sort">
<small class="d-block text-muted">Sort by:</small> <small class="d-block text-muted">Sort by:</small>
<b-button size="sm">All</b-button> <b-button size="sm">All</b-button>
<b-button size="sm">All</b-button> <b-button size="sm">All</b-button>
<b-button size="sm">All</b-button> <b-button size="sm">All</b-button>
</div> </div>
</div> --> </div> -->
<!-- <b-form-group <!-- <b-form-group
label="Stacked (vertical) switch style checkboxes" label="Stacked (vertical) switch style checkboxes"
v-slot="{ ariaDescribedby }" v-slot="{ ariaDescribedby }"
> >
<b-form-checkbox-group <b-form-checkbox-group
v-model="selected" v-model="selected"
:options="options" :options="options"
:aria-describedby="ariaDescribedby" :aria-describedby="ariaDescribedby"
switches switches
stacked stacked
/> />
</b-form-group> --> </b-form-group> -->
<b-dropdown <!-- <b-dropdown
text="Select platforms" text="Select platforms"
class="platforms-dropdown" class="platforms-dropdown"
> >
<b-dropdown-item <b-dropdown-item
v-for="platform in platforms" v-for="platform in platforms"
:key="platform.id" :key="platform.id"
> >
{{ platform.name }} {{ platform.name }}
</b-dropdown-item> </b-dropdown-item>
<!-- <pre>{{ platforms }}</pre> --> </b-dropdown> -->
<!-- <b-dropdown-item>Second Action</b-dropdown-item> -->
<!-- <b-dropdown-item>Third Action</b-dropdown-item> -->
<!-- <b-dropdown-divider></b-dropdown-divider> -->
<!-- <b-dropdown-item active>Active action</b-dropdown-item> -->
<!-- <b-dropdown-item disabled>Disabled action</b-dropdown-item> -->
</b-dropdown>
<!-- <b-button <!-- <b-button
v-for="platform in sortedPlatforms" v-for="platform in sortedPlatforms"
:variant="value.includes(platform.id) ? 'primary' : 'dark'" :variant="value.includes(platform.id) ? 'primary' : 'dark'"
:key="platform.id" :key="platform.id"
> >
<small :class="value.includes(platform.id) ? '' : 'text-muted'"> <small :class="value.includes(platform.id) ? '' : 'text-muted'">
{{ platform.name }} {{ platform.name }}
</small> </small>
</b-button> --> </b-button> -->
</b-col>
<b-col> <b-button
<edit-board-background-modal /> variant="primary"
<b-button v-b-modal.boardBackground> :disabled="saving"
<i class="fas fa-images fa-fw" aria-hidden /> @click="saveSettings"
<br /> >
Change background <b-spinner small v-if="saving" />
</b-button> <span v-else>{{ $t('global.save') }}</span>
</b-col> </b-button>
</b-row>
</form> </form>
</b-card> </b-card>
</b-col> </b-col>

View file

@ -6,11 +6,28 @@
<!-- TODO: Show lists/boards that the game belongs to --> <!-- TODO: Show lists/boards that the game belongs to -->
<template lang="html"> <template lang="html">
<b-container fluid class="p-2"> <b-container fluid class="game-page p-2">
<b-skeleton v-if="loading" /> <b-skeleton v-if="loading" />
<template v-else-if="game"> <template v-else-if="game">
<b-row> <b-row class="game-backdrop" :style="`background-image: url(${gameScrenshot})`">
<b-col
cols="12"
>
<div class="vh-100">
<!-- <b-img
:src="gameCoverUrl"
:alt="game.name"
class="cursor-pointer game-cover"
width="200"
rounded
@click.stop="openGameCover"
/> -->
</div>
</b-col>
</b-row>
<b-row class="game">
<b-col <b-col
offset="2" offset="2"
offset-sm="0" offset-sm="0"
@ -46,6 +63,7 @@
md="8" md="8"
lg="8" lg="8"
xl="9" xl="9"
class="bg-white rounded p-5"
> >
<b-row> <b-row>
<b-col <b-col
@ -127,9 +145,6 @@
<b-col <b-col
cols="12" cols="12"
sm="12"
md="6"
xl="6"
class="mt-3" class="mt-3"
> >
<similar-games <similar-games
@ -144,21 +159,21 @@
xl="6" xl="6"
class="mt-3" class="mt-3"
> >
<game-speedruns v-if="game" /> <!-- <game-speedruns v-if="game" /> -->
<!-- <pre>{{ game.speedruns }}</pre> --> <!-- <pre>{{ game.speedruns }}</pre> -->
<!-- TODO: add bundles to game detail? --> <!-- TODO: add bundles to game detail? -->
</b-col> </b-col>
<b-col <!-- <b-col
cols="12" cols="12"
class="mt-3" class="mt-3"
> >
<b-card> <b-card>
<h4>[BUNDLES]</h4> <h4>[BUNDLES]</h4>
</b-card> </b-card>
<!-- <pre>{{ game }}</pre> --> <pre>{{ game }}</pre>
<!-- {{ game.bundles ? `Found in ${game.bundles.length} compilations.` : null }} --> {{ game.bundles ? `Found in ${game.bundles.length} compilations.` : null }}
</b-col> </b-col> -->
</b-row> </b-row>
</template> </template>
@ -248,8 +263,6 @@
> >
loading... loading...
</timeline> --> </timeline> -->
<!-- <div class="game-backdrop" :style="`background-image: url(${gameScrenshot})`" /> -->
</b-container> </b-container>
</template> </template>
@ -265,7 +278,7 @@ import GameRating from '@/components/Game/GameRating';
import GameDescription from '@/components/Game/GameDescription'; import GameDescription from '@/components/Game/GameDescription';
import SimilarGames from '@/components/Game/SimilarGames'; import SimilarGames from '@/components/Game/SimilarGames';
import GameWebsites from '@/components/Game/GameWebsites'; import GameWebsites from '@/components/Game/GameWebsites';
import GameSpeedruns from '@/components/Game/GameSpeedruns'; // import GameSpeedruns from '@/components/Game/GameSpeedruns';
export default { export default {
components: { components: {
@ -277,7 +290,7 @@ export default {
GameRating, GameRating,
GameNotes, GameNotes,
GameWebsites, GameWebsites,
GameSpeedruns, // GameSpeedruns,
SimilarGames, SimilarGames,
}, },
@ -360,7 +373,7 @@ export default {
watch: { watch: {
gameId(gameId) { gameId(gameId) {
document.getElementsByTagName('main')[0].scrollTop = 0; // document.getElementsByTagName('main')[0].scrollTop = 0;
if (gameId) this.loadGame(); if (gameId) this.loadGame();
// TODO: handle missing id, redirect? 404? search? // TODO: handle missing id, redirect? 404? search?
@ -469,15 +482,17 @@ export default {
</script> </script>
<style lang="scss" rel="stylesheet/scss" scoped> <style lang="scss" rel="stylesheet/scss" scoped>
// .game-page {
// // z-index: 0;
// }
.game {
margin-top: -50vh;
}
.game-backdrop { .game-backdrop {
width: 100%;
height: 100vw;
// position: fixed;
// top: 0;
backdrop-filter: grayscale(0.5) opacity(0.8) /* ...and on and on... */; backdrop-filter: grayscale(0.5) opacity(0.8) /* ...and on and on... */;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain; background-size: contain;
// opacity: 0.1;
z-index: 0;
} }
</style> </style>

View file

@ -1,26 +1,29 @@
<template lang="html"> <template lang="html">
<b-container> <b-container>
<b-row> <b-row>
<b-col cols="3"> <b-col cols="3" class="position-sticky mt-2">
<!-- TODO: add filters --> <b-card>
<!-- TODO: add view toggle --> test
Filter <!-- TODO: add filters -->
<!-- TODO: add view toggle -->
Filter
<h3>Sort by</h3> <h3>Sort by</h3>
Latest Latest
Oldest Oldest
Relevance Relevance
<h3>Filters</h3> <h3>Filters</h3>
Tags Tags
Genre Genre
Platform Platform
Year released Year released
</b-card>
</b-col> </b-col>
<b-col cols="9"> <b-col cols="9">
<div class="search-page bg-white p-2"> <div class="search-page p-2">
<search-box />
<!-- <b-alert show variant="success"> <!-- <b-alert show variant="success">
Custom search controls go here! Custom search controls go here!
</b-alert> --> </b-alert> -->
@ -30,13 +33,38 @@
<b-skeleton v-if="loading" /> <b-skeleton v-if="loading" />
<div v-else-if="searchResults.length > 0"> <div v-else-if="searchResults.length > 0">
<h3>Search results</h3> <header class="my-2 d-flex align-items-center justify-content-between">
<h3>Search results</h3>
<game-card-search <b-button-toolbar key-nav aria-label="Toolbar with button groups">
v-for="game in searchResults" <b-button-group class="mx-1">
:key="game.id" <b-button :variant="listView ? 'primary' : 'secondary'" @click="listView = true">
:game="game" <i class="fa-solid fa-list fa-fw" aria-hidden />
/> </b-button>
<b-button :variant="listView ? 'secondary' : 'primary'" @click="listView = false">
<i class="fa-solid fa-grip fa-fw" aria-hidden />
</b-button>
</b-button-group>
</b-button-toolbar>
</header>
<template v-if="listView">
<game-card-search
v-for="game in searchResults"
:key="game.id"
:game="game"
/>
</template>
<div v-else class="masonry-container">
<game-card-search-vertical
v-for="game in searchResults"
class="masonry-item"
:key="game.id"
:game="game"
/>
</div>
</div> </div>
<b-container v-else-if="query.length > 0"> <b-container v-else-if="query.length > 0">
@ -56,16 +84,21 @@
<script> <script>
import GameCardSearch from '@/components/GameCards/GameCardSearch'; import GameCardSearch from '@/components/GameCards/GameCardSearch';
import SearchBox from '@/components/SearchBox';
import GameCardSearchVertical from '@/components/GameCards/GameCardSearchVertical';
export default { export default {
components: { components: {
GameCardSearch, GameCardSearch,
SearchBox,
GameCardSearchVertical,
}, },
data() { data() {
return { return {
searchResults: [], searchResults: [],
loading: false, loading: false,
listView: true,
}; };
}, },
@ -104,4 +137,14 @@ export default {
.search-page { .search-page {
min-height: calc(100vh - 46px); min-height: calc(100vh - 46px);
} }
.masonry-container {
column-count: 5;
column-gap: 1rem;
}
.masonry-item {
display: inline-block;
width: 100%;
}
</style> </style>