mirror of
https://github.com/romancm/gamebrary
synced 2024-11-10 05:34:15 +00:00
Implement new pages and update titles
This commit is contained in:
parent
87c8010d74
commit
6e0075ff11
43 changed files with 652 additions and 697 deletions
|
@ -6,7 +6,7 @@
|
|||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve --port 4000 --open --host localhost",
|
||||
"dev": "vue-cli-service serve --port 10293 --open --host localhost",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"test:e2e": "vue-cli-service test:e2e",
|
||||
|
@ -40,7 +40,6 @@
|
|||
"lodash.orderby": "^4.6.0",
|
||||
"lodash.sortby": "^4.7.0",
|
||||
"marked": "^4.0.14",
|
||||
"packery": "^2.1.2",
|
||||
"portal-vue": "^2.1.7",
|
||||
"raven-js": "^3.27.0",
|
||||
"register-service-worker": "^1.7.2",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO: make portal name dynamic and change target based on nav orientation -->
|
||||
<!-- TODO: integrate with keap -->
|
||||
<template>
|
||||
<main
|
||||
id="app"
|
||||
|
|
|
@ -85,13 +85,7 @@
|
|||
</template>
|
||||
|
||||
<div class="game-media" :class="{ 'selected': activeIndex !== null }">
|
||||
<pre>{{ activeIndex }}</pre>
|
||||
<masonry
|
||||
gutter="16px"
|
||||
:cols="activeIndex === null
|
||||
? { default: 1 }
|
||||
: { default: 5, 1000: 3, 700: 2, 400: 1 }"
|
||||
>
|
||||
<div class="thumbnails">
|
||||
<b-img
|
||||
v-for="({ imageUrl }, index) in gameMedia"
|
||||
:key="index"
|
||||
|
@ -101,7 +95,8 @@
|
|||
class="mb-3"
|
||||
@click="viewMedia(index)"
|
||||
/>
|
||||
</masonry>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="activeIndex !== null" class="text-center w-100">
|
||||
<b-embed
|
||||
|
@ -193,6 +188,11 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
// TODO: remove
|
||||
mounted () {
|
||||
this.viewMedia(0);
|
||||
},
|
||||
|
||||
methods: {
|
||||
viewMedia(index) {
|
||||
this.activeIndex = index;
|
||||
|
|
|
@ -1,34 +1,91 @@
|
|||
<!-- TODO: bring settings to nav, remove page. -->
|
||||
<!-- TODO: highlight menu item if active -->
|
||||
<template>
|
||||
<div class="main-menu" :class="{ 'd-flex flex-column': isVerticalNav }">
|
||||
<div class="main-menu w-100 d-flex" :class="{ 'd-flex flex-column': isVerticalNav }">
|
||||
<b-dropdown id="dropdown-form" text="Dropdown with form" ref="dropdown" class="m-2">
|
||||
<b-dropdown-form>
|
||||
<b-form-group label="Email" label-for="dropdown-form-email" @submit.stop.prevent>
|
||||
<b-form-checkbox v-model="checked" name="check-button" switch>
|
||||
Switch Checkbox <b>(Checked: {{ checked }})</b>
|
||||
</b-form-checkbox>
|
||||
|
||||
<b-form-select v-model="selected" :options="options"></b-form-select>
|
||||
|
||||
<div @click.native.stop.prevent>
|
||||
<b-dropdown @click.native.stop.prevent id="dropdown-1" text="Dropdown Button" class="m-md-2">
|
||||
<b-dropdown-item @click.native.stop.prevent>First Action</b-dropdown-item>
|
||||
<b-dropdown-item @click.native.stop.prevent>Second Action</b-dropdown-item>
|
||||
<b-dropdown-item @click.native.stop.prevent>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>
|
||||
</div>
|
||||
|
||||
|
||||
<b-form-input
|
||||
id="dropdown-form-email"
|
||||
size="sm"
|
||||
placeholder="email@example.com"
|
||||
></b-form-input>
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group label="Password" label-for="dropdown-form-password">
|
||||
<b-form-input
|
||||
id="dropdown-form-password"
|
||||
type="password"
|
||||
size="sm"
|
||||
placeholder="Password"
|
||||
></b-form-input>
|
||||
</b-form-group>
|
||||
|
||||
<b-form-checkbox class="mb-3">Remember me</b-form-checkbox>
|
||||
<b-button variant="primary" size="sm" @click="onClick">Sign In</b-button>
|
||||
</b-dropdown-form>
|
||||
<b-dropdown-divider></b-dropdown-divider>
|
||||
<b-dropdown-item-button>New around here? Sign up</b-dropdown-item-button>
|
||||
<b-dropdown-item-button>Forgot Password?</b-dropdown-item-button>
|
||||
</b-dropdown>
|
||||
|
||||
<b-button
|
||||
v-b-tooltip.hover.auto
|
||||
v-b-tooltip.hover
|
||||
v-bind="dropdownProps"
|
||||
title="Home"
|
||||
:to="{ name: 'home' }"
|
||||
>
|
||||
<i class="fa-solid fa-house"></i>
|
||||
<img src="logo.png" alt="" height="26" />
|
||||
</b-button>
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
v-b-tooltip.hover
|
||||
:title="boardButtonTitle"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
no-caret
|
||||
v-bind="dropdownProps"
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw" />
|
||||
|
||||
<template v-if="!isVerticalNav">
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
{{ boardButtonTitle }}
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'home' }"
|
||||
:to="{ name: 'boards' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My boards</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-group v-if="user">
|
||||
<b-dropdown-item
|
||||
v-for="board in recentlyUpdatedBoards"
|
||||
:key="board.id"
|
||||
:to="{ name: 'board', params: { id: board.id } }"
|
||||
>
|
||||
<small>{{ board.name }}</small>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown-group>
|
||||
|
||||
<b-dropdown-item
|
||||
v-if="isBoardEditPage"
|
||||
:to="{ name: 'board', params: { id: board.id } }"
|
||||
|
@ -51,92 +108,28 @@
|
|||
<i class="fa-regular fa-plus fa-fw" />
|
||||
<span class="ml-2">Create board</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
v-if="showBoardActions"
|
||||
disabled
|
||||
>
|
||||
<i class="fa-solid fa-clone fa-fw"></i>
|
||||
<span class="ml-2">Copy board</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
title="Tags"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:dropup="navPosition === 'bottom'"
|
||||
:dropright="navPosition === 'left'"
|
||||
:dropleft="navPosition === 'right'"
|
||||
no-caret
|
||||
title="Games"
|
||||
toggle-class="px-2 py-0"
|
||||
v-bind="dropdownProps"
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa-solid fa-tags fa-fw" />
|
||||
|
||||
<template v-if="!isVerticalNav">
|
||||
Tags
|
||||
</template>
|
||||
</template>
|
||||
<i class="fa-solid fa-gamepad fa-fw" />
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'tags' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My tags</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
v-if="user"
|
||||
:to="{ name: 'tag.create' }"
|
||||
>
|
||||
<i class="fa-regular fa-plus fa-fw" />
|
||||
<span class="ml-2">Add tag</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
title="Wallpapers"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:dropup="navPosition === 'bottom'"
|
||||
:dropright="navPosition === 'left'"
|
||||
:dropleft="navPosition === 'right'"
|
||||
no-caret
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa fa-images fa-fw" aria-hidden="true" />
|
||||
|
||||
<template v-if="!isVerticalNav">
|
||||
Wallpapers
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'wallpapers' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My wallpapers</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<UploadWallpaperButton v-if="user" />
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:dropup="navPosition === 'bottom'"
|
||||
:dropright="navPosition === 'left'"
|
||||
:dropleft="navPosition === 'right'"
|
||||
no-caret
|
||||
>
|
||||
<template #button-content>
|
||||
|
||||
<b-img
|
||||
v-if="isGamePage"
|
||||
:src="$options.getImageUrl(game)"
|
||||
:alt="game.name"
|
||||
bordered
|
||||
class="mr-2"
|
||||
style="max-height: 40px; width: auto;"
|
||||
/>
|
||||
|
||||
<i v-else class="fa-solid fa-gamepad fa-fw" />
|
||||
|
||||
<template v-if="!isVerticalNav">
|
||||
<!-- {{ gameButtonTitle }} -->
|
||||
Games
|
||||
</template>
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
{{ gameButtonTitle }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-if="isGamePage">
|
||||
|
@ -166,43 +159,48 @@
|
|||
Find games
|
||||
</b-dropdown-item>
|
||||
|
||||
<!-- <b-dropdown-item
|
||||
v-if="isBoardPage && isBoardOwner"
|
||||
:to="{ name: 'board.edit', params: { id: board.id } }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw" />
|
||||
<span class="ml-2">Edit board</span>
|
||||
</b-dropdown-item> -->
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'create.board' }"
|
||||
:to="{ name: 'home' }"
|
||||
disabled
|
||||
>
|
||||
<i class="fa-regular fa-plus fa-fw" />
|
||||
<span class="ml-2">Create board</span>
|
||||
<i
|
||||
class="fa-solid fa-stopwatch fa-fw"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span class="ml-2">Progresses</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
:title="boardButtonTitle"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
no-caret
|
||||
v-b-tooltip.hover
|
||||
title="Tags"
|
||||
v-bind="dropdownProps"
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa-solid fa-cog fa-fw" />
|
||||
<i class="fa-solid fa-tags fa-fw" />
|
||||
|
||||
<template v-if="!isVerticalNav">
|
||||
Settings
|
||||
</template>
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
Tags
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
<b-dropdown-text
|
||||
v-for="({ textColor, bgColor, name }, index) in tags"
|
||||
:key="name"
|
||||
block
|
||||
class="rounded mb-1"
|
||||
:style="`background-color: ${bgColor};`"
|
||||
@click="$router.push({ name: 'tag.edit', params: { id: index } })"
|
||||
>
|
||||
<span :style="`color: ${textColor}`">{{ name }}</span>
|
||||
</b-dropdown-text>
|
||||
|
||||
<!-- <b-dropdown-item
|
||||
:to="{ name: 'tags' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My tags</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown-item> -->
|
||||
|
||||
<b-dropdown-item
|
||||
v-if="user"
|
||||
|
@ -213,6 +211,51 @@
|
|||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
title="Notes"
|
||||
v-bind="dropdownProps"
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa fa-sticky-note fa-fw" aria-hidden="true" />
|
||||
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
Wallpapers
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'notes' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My notes</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
v-b-tooltip.hover.auto
|
||||
title="Wallpapers"
|
||||
v-bind="dropdownProps"
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa fa-images fa-fw" aria-hidden="true" />
|
||||
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
Wallpapers
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'wallpapers' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My wallpapers</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<UploadWallpaperButton v-if="user" />
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown
|
||||
v-if="user"
|
||||
v-b-tooltip.hover.auto
|
||||
|
@ -221,7 +264,7 @@
|
|||
no-caret
|
||||
>
|
||||
<template #button-content>
|
||||
<template v-if="!isVerticalNav">
|
||||
<template>
|
||||
<b-avatar
|
||||
rounded
|
||||
v-if="avatarImage"
|
||||
|
@ -235,135 +278,98 @@
|
|||
aria-hidden
|
||||
/>
|
||||
|
||||
{{ profileTitle }}
|
||||
<!-- {{ profileTitle }} -->
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'tags' }"
|
||||
:to="{ name: 'profile' }"
|
||||
>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">My tags</span>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">Edit profile</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'tag.create' }"
|
||||
:to="{ name: 'public.profile', params: { userName: profile.userName } }"
|
||||
>
|
||||
<i class="fa-regular fa-plus fa-fw" />
|
||||
<span class="ml-2">Add tag</span>
|
||||
<span class="ml-2">View profile</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
<b-dropdown-item v-if="user" :to="{ name: 'profile' }">
|
||||
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:dropup="navPosition === 'bottom'"
|
||||
:dropright="navPosition === 'left'"
|
||||
:dropleft="navPosition === 'right'"
|
||||
no-caret
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa-sharp fa-solid fa-bars" />
|
||||
</template>
|
||||
|
||||
<!-- <b-dropdown-item
|
||||
v-if="user"
|
||||
:to="{ name: 'create.board' }"
|
||||
class="ml-2"
|
||||
v-b-tooltip.hover.auto
|
||||
title="Preferences"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
no-caret
|
||||
>
|
||||
<i class="fa-regular fa-plus" />
|
||||
<span class="ml-2">New board</span>
|
||||
</b-dropdown-item> -->
|
||||
|
||||
<!-- <div :class="['py-1 rounded', darkTheme ? 'bg-black' : 'bg-light']" v-if="showBoardActions">
|
||||
<p :class="['strong text-uppercase mb-0 ml-2 mt-1', darkTheme ? 'text-success' : 'text-dark']">{{ board.name }}</p>
|
||||
<template #button-content>
|
||||
<i class="fa-solid fa-sliders fa-fw" />
|
||||
|
||||
<span v-if="!isVerticalNav" class="d-none d-md-inline">
|
||||
Settings
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<b-dropdown-item
|
||||
v-if="isBoardOwner"
|
||||
class="mx-1"
|
||||
:to="{ name: 'board.edit', params: { id: board.id } }"
|
||||
:to="{ name: 'settings' }"
|
||||
>
|
||||
Edit board
|
||||
<i class="fa-regular fa-rectangle-list fa-fw"></i>
|
||||
<span class="ml-2">Settings</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'board.edit', params: { id: board.id } }"
|
||||
class="mx-1"
|
||||
href="https://github.com/romancm/gamebrary/"
|
||||
target="_blank"
|
||||
>
|
||||
Copy board
|
||||
<i class="fa-brands fa-github fa-fw"></i>
|
||||
GitHub
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item v-b-modal.keyboard-shortcuts>
|
||||
<i class="fa-solid fa-keyboard fa-fw" />
|
||||
<span class="ml-2">Keyboard Shortcuts</span>
|
||||
</b-dropdown-item>
|
||||
</div> -->
|
||||
|
||||
<!-- <b-dropdown-group v-if="user && routeName === 'home'">
|
||||
<b-dropdown-item
|
||||
v-for="board in recentlyUpdatedBoards"
|
||||
:key="board.id"
|
||||
:to="{ name: 'board', params: { id: board.id } }"
|
||||
:to="{ name: 'help' }"
|
||||
id="help"
|
||||
>
|
||||
<small>{{ board.name }}</small>
|
||||
<i class="fa-regular fa-circle-question fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Help</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown-group> -->
|
||||
|
||||
<!-- <b-dropdown-item :to="{ name: 'progresses' }">
|
||||
<i class="fa fa-book fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Progresses</span>
|
||||
</b-dropdown-item> -->
|
||||
<b-dropdown-item disabled>
|
||||
<i class="fa-solid fa-language" />
|
||||
<span class="ml-2">Change language</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item :to="{ name: 'search' }">
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'steam.settings' }"
|
||||
disabled
|
||||
>
|
||||
<i class="fab fa-steam fa-fe" aria-hidden />
|
||||
<span class="ml-2">Steam</span>
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
<b-button
|
||||
class="ml-auto"
|
||||
:to="{ name: 'search' }"
|
||||
v-b-tooltip.hover.auto
|
||||
title="Search"
|
||||
>
|
||||
<i class="fa fa-search fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Search</span>
|
||||
</b-dropdown-item>
|
||||
</b-button>
|
||||
|
||||
<b-dropdown-divider />
|
||||
|
||||
<b-dropdown-item v-if="user" :to="{ name: 'settings' }">
|
||||
<i class="fa fa-cog fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Settings</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
<b-button
|
||||
v-if="!user"
|
||||
class="ml-2"
|
||||
class="ml-auto"
|
||||
variant="danger"
|
||||
:to="{ name: 'auth' }"
|
||||
>
|
||||
Get started <span class="d-none d-sm-inline"> — it's free!</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<b-dropdown-item
|
||||
:to="{ name: 'help' }"
|
||||
block
|
||||
id="help"
|
||||
>
|
||||
<i class="fa fa-regular fa-circle-question fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Help</span>
|
||||
</b-dropdown-item>
|
||||
|
||||
<!-- <b-dropdown-item
|
||||
class="mr-2"
|
||||
v-b-tooltip.hover
|
||||
title="Change language"
|
||||
>
|
||||
<i class="fa-solid fa-language" />
|
||||
</b-dropdown-item> -->
|
||||
|
||||
<!-- <b-list-group-item exact exact-active-class="bg-primary text-white" :to="{ name: 'steam.settings' }">
|
||||
<i class="mr-2 fab fa-steam" aria-hidden />
|
||||
<small>Steam</small>
|
||||
</b-list-group-item> -->
|
||||
|
||||
<!-- <b-dropdown-text>
|
||||
<b-link
|
||||
href="https://github.com/romancm/gamebrary/"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub
|
||||
</b-link>
|
||||
</b-dropdown-text> -->
|
||||
</b-dropdown>
|
||||
</b-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -383,6 +389,13 @@ export default {
|
|||
return {
|
||||
profile: {},
|
||||
avatarImage: null,
|
||||
options: [
|
||||
{ value: null, text: 'Please select an option' },
|
||||
{ value: 'a', text: 'This is First option' },
|
||||
{ value: 'b', text: 'Selected Option' },
|
||||
{ value: { C: '3PO' }, text: 'This is an option with object value' },
|
||||
{ value: 'd', text: 'This one is disabled', disabled: true }
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -390,6 +403,16 @@ export default {
|
|||
...mapState(['board', 'boards', 'settings', 'user', 'games', 'notes', 'tags', 'wallpapers', 'game']),
|
||||
...mapGetters(['darkTheme', 'navPosition', 'sortedBoards', 'latestRelease', 'isVerticalNav', 'isBoardOwner']),
|
||||
|
||||
dropdownProps() {
|
||||
return {
|
||||
variant: this.darkTheme ? 'black' : 'light',
|
||||
dropup: this.navPosition === 'bottom',
|
||||
dropright: this.navPosition === 'left',
|
||||
dropleft: this.navPosition === 'right',
|
||||
noCaret: true,
|
||||
};
|
||||
},
|
||||
|
||||
year() {
|
||||
return new Date().getFullYear();
|
||||
},
|
||||
|
@ -409,7 +432,7 @@ export default {
|
|||
},
|
||||
|
||||
recentlyUpdatedBoards() {
|
||||
return this.sortedBoards.filter(({ lastUpdated }) => Boolean(lastUpdated)).slice(0, 5);
|
||||
return this.sortedBoards.filter(({ lastUpdated }) => Boolean(lastUpdated)).slice(0, 3);
|
||||
},
|
||||
|
||||
profileTitle() {
|
||||
|
@ -440,11 +463,11 @@ export default {
|
|||
return 'Boards';
|
||||
},
|
||||
|
||||
// gameButtonTitle() {
|
||||
// if (this.isGamePage) return this.game.name;
|
||||
gameButtonTitle() {
|
||||
if (this.isGamePage) return this.game.name;
|
||||
|
||||
// return 'Games';
|
||||
// }
|
||||
return 'Games';
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
|
|
@ -32,16 +32,9 @@ Elevate your gaming experience with PlayStats – because your gaming journey is
|
|||
-->
|
||||
|
||||
<template lang="html">
|
||||
<header :class="[darkTheme ? 'bg-dark' : 'bg-light', isVerticalNav ? 'p-2' : 'px-2 py-2', `nav-${navPosition}`]">
|
||||
<!-- <VerticalMenu v-if="isVerticalNav" /> -->
|
||||
<header :class="[darkTheme ? 'bg-dark' : 'bg-light', `nav-${navPosition}`]" class="p-1">
|
||||
<main-menu />
|
||||
|
||||
<portal-target
|
||||
v-if="!isVerticalNav"
|
||||
class="ml-2"
|
||||
name="pageTitle"
|
||||
/>
|
||||
|
||||
<div :class="['align-items-center d-flex ml-auto', isVerticalNav ? 'h-100 flex-column' : '']">
|
||||
<portal-target name="headerActions" multiple />
|
||||
|
||||
|
@ -54,48 +47,21 @@ Elevate your gaming experience with PlayStats – because your gaming journey is
|
|||
Get started
|
||||
</b-button>
|
||||
</div>
|
||||
<!-- <b-collapse id="header">
|
||||
|
||||
</b-collapse> -->
|
||||
|
||||
<!-- <b-button
|
||||
v-b-toggle.header
|
||||
variant="light"
|
||||
size="sm"
|
||||
pill
|
||||
class="header-toggle mt-n2"
|
||||
>
|
||||
<i class="fa-solid fa-caret-down" />
|
||||
</b-button> -->
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import MainMenu from '@/components/MainMenu';
|
||||
// import VerticalMenu from '@/components/VerticalMenu';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MainMenu,
|
||||
// VerticalMenu,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'settings']),
|
||||
...mapState(['user']),
|
||||
...mapGetters(['darkTheme', 'navPosition', 'isVerticalNav']),
|
||||
|
||||
isTopNav() {
|
||||
return this.navPosition === 'top';
|
||||
},
|
||||
|
||||
isBottomNav() {
|
||||
return this.navPosition === 'bottom';
|
||||
},
|
||||
|
||||
isSearchPage() {
|
||||
return this.$route.name === 'search';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template lang="html">
|
||||
<header
|
||||
v-if="isVerticalNav"
|
||||
class="d-flex justify-content-between align-items-center mb-2"
|
||||
hasLongText
|
||||
>
|
||||
|
@ -9,15 +8,10 @@
|
|||
</h2>
|
||||
<slot />
|
||||
</header>
|
||||
|
||||
<portal v-else to="pageTitle">
|
||||
<h3>{{ title }}</h3>
|
||||
<slot />
|
||||
</portal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<template lang="html">
|
||||
<b-card
|
||||
class="cursor-pointer mb-3"
|
||||
<b-link
|
||||
class="cursor-pointer mb-3 d-flex"
|
||||
body-class="p-2"
|
||||
@click="$router.push({ name: 'public.profile', params: { userName: profile.userName } })"
|
||||
>
|
||||
<b-avatar
|
||||
:src="avatarImage"
|
||||
class="mr-3"
|
||||
size="120px"
|
||||
size="80px"
|
||||
rounded
|
||||
/>
|
||||
|
||||
<b-link>@{{ profile.userName }}</b-link>
|
||||
</b-card>
|
||||
<b-link class="small text-center d-block">@{{ profile.userName }}</b-link>
|
||||
</b-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<b-button
|
||||
:disabled="outOfSpace"
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
:class="{ 'mr-3' : !isVerticalNav }"
|
||||
block
|
||||
@click="triggerFileUpload"
|
||||
>
|
||||
<b-spinner small v-if="saving" />
|
||||
|
|
|
@ -1,223 +0,0 @@
|
|||
<template>
|
||||
<div class="d-flex flex-column">
|
||||
<b-dropdown
|
||||
split
|
||||
text="Split Dropdown"
|
||||
class="m-2"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:split-to="{ name: 'home' }"
|
||||
dropright
|
||||
>
|
||||
<template #button-content>
|
||||
<i class="fa-regular fa-rectangle-list fa-fw" />
|
||||
<!-- Boards -->
|
||||
</template>
|
||||
|
||||
<b-dropdown-item href="#">{{ board.title }}</b-dropdown-item>
|
||||
<b-dropdown-item :to="{ name: 'create.board' }">Create new board</b-dropdown-item>
|
||||
<b-dropdown-item href="#">Edit board</b-dropdown-item>
|
||||
<b-dropdown-item href="#">Something else here...</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
|
||||
|
||||
<!-- <b-button
|
||||
v-if="user"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:to="{ name: 'create.board' }"
|
||||
>
|
||||
New board
|
||||
</b-button> -->
|
||||
|
||||
<!-- <div :class="['py-1 rounded', darkTheme ? 'bg-black' : 'bg-light']" v-if="showBoardActions">
|
||||
<p :class="['strong text-uppercase mb-0 ml-2 mt-1', darkTheme ? 'text-success' : 'text-dark']">{{ board.name }}</p>
|
||||
|
||||
<b-button
|
||||
v-if="isBoardOwner"
|
||||
class="mx-1"
|
||||
:to="{ name: 'board.edit', params: { id: board.id } }"
|
||||
>
|
||||
Edit board
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'board.edit', params: { id: board.id } }"
|
||||
class="mx-1"
|
||||
>
|
||||
Copy board
|
||||
</b-button>
|
||||
</div> -->
|
||||
|
||||
<!-- <b-dropdown-group v-if="user && routeName === 'home'">
|
||||
<b-button
|
||||
v-for="board in recentlyUpdatedBoards"
|
||||
:key="board.id"
|
||||
:to="{ name: 'board', params: { id: board.id } }"
|
||||
>
|
||||
<small>{{ board.name }}</small>
|
||||
</b-button>
|
||||
</b-dropdown-group> -->
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'games' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
title="Games"
|
||||
>
|
||||
<i class="fa-regular fa-heart fa-fw" />
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'notes' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
alt="Notes"
|
||||
>
|
||||
<i class="fa fa-book fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<!-- <b-button :to="{ name: 'progresses' }">
|
||||
<i class="fa fa-book fa-fw" aria-hidden="true" />
|
||||
<span class="ml-2">Progresses</span>
|
||||
</b-button> -->
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'tags' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
title="Tags"
|
||||
>
|
||||
<i class="fa fa-tags fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'wallpapers' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
title="Wallpapers"
|
||||
>
|
||||
<i class="fa fa-images fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'search' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
title="Search"
|
||||
>
|
||||
<i class="fa fa-search fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
v-if="user" :to="{ name: 'profile' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:title="profileTitle"
|
||||
>
|
||||
<b-avatar
|
||||
rounded
|
||||
v-if="avatarImage"
|
||||
:src="avatarImage"
|
||||
size="22"
|
||||
/>
|
||||
|
||||
<i
|
||||
v-else
|
||||
class="fa fa-solid fa-user fa-fw"
|
||||
aria-hidden
|
||||
/>
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
v-if="user"
|
||||
title="Settings"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
:to="{ name: 'settings' }"
|
||||
>
|
||||
<i class="fa fa-cog fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<b-button
|
||||
:to="{ name: 'help' }"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
title="Help"
|
||||
id="help"
|
||||
>
|
||||
<i class="fa fa-regular fa-circle-question fa-fw" aria-hidden="true" />
|
||||
</b-button>
|
||||
|
||||
<!-- <b-button
|
||||
class="mr-2"
|
||||
v-b-tooltip.hover
|
||||
title="Change language"
|
||||
>
|
||||
<i class="fa-solid fa-language" />
|
||||
</b-button> -->
|
||||
|
||||
<!-- <b-list-group-item exact exact-active-class="bg-primary text-white" :to="{ name: 'steam.settings' }">
|
||||
<i class="mr-2 fab fa-steam" aria-hidden />
|
||||
<small>Steam</small>
|
||||
</b-list-group-item> -->
|
||||
|
||||
<!-- <b-dropdown-text>
|
||||
<b-link
|
||||
href="https://github.com/romancm/gamebrary/"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub
|
||||
</b-link>
|
||||
</b-dropdown-text> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import { getImageThumbnail } from '@/utils';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
profile: {},
|
||||
avatarImage: null,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['board', 'boards', 'settings', 'user', 'games', 'notes', 'tags', 'wallpapers']),
|
||||
...mapGetters(['darkTheme', 'navPosition', 'sortedBoards', 'latestRelease', 'isVerticalNav', 'isBoardOwner']),
|
||||
|
||||
year() {
|
||||
return new Date().getFullYear();
|
||||
},
|
||||
|
||||
routeName() {
|
||||
return this.$route.name;
|
||||
},
|
||||
|
||||
showBoardActions() {
|
||||
return Boolean(this.routeName === 'board' && this.user?.uid);
|
||||
},
|
||||
|
||||
recentlyUpdatedBoards() {
|
||||
return this.sortedBoards.filter(({ lastUpdated }) => Boolean(lastUpdated)).slice(0, 5);
|
||||
},
|
||||
|
||||
profileTitle() {
|
||||
return this.profile?.userName
|
||||
? `@${this.profile.userName}`
|
||||
: 'Profile';
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.user) this.load();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async load() {
|
||||
this.profile = await this.$store.dispatch('LOAD_PROFILE').catch(() => {});
|
||||
|
||||
if (this.profile?.avatar) this.loadAvatarImage();
|
||||
},
|
||||
|
||||
async loadAvatarImage() {
|
||||
const thumbnailRef = getImageThumbnail(this.profile?.avatar);
|
||||
|
||||
this.avatarImage = await this.$store.dispatch('LOAD_FIREBASE_IMAGE', thumbnailRef);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -51,14 +51,7 @@
|
|||
@click="loginWithGoogle"
|
||||
>
|
||||
<img
|
||||
v-if="newUser"
|
||||
src="img/google-sign-in-button-light.svg"
|
||||
alt="Login with Google"
|
||||
/>
|
||||
|
||||
<img
|
||||
v-else
|
||||
src="img/google-sign-up-button-light.svg"
|
||||
:src="`img/google-sign-${newUser ? 'up' : 'in'}-button-light.svg`"
|
||||
alt="Sign up with Google"
|
||||
/>
|
||||
</b-button>
|
134
src/pages/BoardsPage.vue
Normal file
134
src/pages/BoardsPage.vue
Normal file
|
@ -0,0 +1,134 @@
|
|||
<template lang="html">
|
||||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
|
||||
<div v-else>
|
||||
<empty-state
|
||||
v-if="isEmpty && !isPublicBoard"
|
||||
title="Boards"
|
||||
message="Utilize boards to neatly organize your video games!"
|
||||
>
|
||||
<b-button
|
||||
:to="{ name: 'create.board' }"
|
||||
variant="primary"
|
||||
>
|
||||
{{ $t('boards.create') }}
|
||||
</b-button>
|
||||
</empty-state>
|
||||
|
||||
<template v-else>
|
||||
<portal to="headerActions">
|
||||
<b-button
|
||||
v-if="user"
|
||||
:variant="darkTheme ? 'success' : 'light'"
|
||||
v-b-tooltip.hover
|
||||
title="Create board"
|
||||
:to="{ name: 'create.board' }"
|
||||
>
|
||||
<i class="fa-solid fa-plus" />
|
||||
</b-button>
|
||||
</portal>
|
||||
|
||||
<div class="board-grid">
|
||||
<mini-board
|
||||
v-for="board in sortedBoards"
|
||||
:key="board.id"
|
||||
:board="board"
|
||||
@click.native="$router.push({ name: 'board', params: { id: board.id } })"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MiniBoard from '@/components/Board/MiniBoard';
|
||||
import EmptyState from '@/components/EmptyState';
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MiniBoard,
|
||||
EmptyState,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'boards', 'wallpapers']),
|
||||
...mapGetters(['isBoardOwner', 'sortedBoards', 'sortedPublicBoards', 'darkTheme', 'isVerticalNav', 'navPosition']),
|
||||
|
||||
recentlyUpdatedPublicBoards() {
|
||||
return this.sortedPublicBoards.filter(({ lastUpdated }) => Boolean(lastUpdated)).slice(0, 20);
|
||||
},
|
||||
|
||||
isEmpty() {
|
||||
return !this.loading && this.gameBoards?.length === 0;
|
||||
},
|
||||
|
||||
isPublicBoard() {
|
||||
return this.$route.name === 'home' && !this.user;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
|
||||
methods: {
|
||||
load() {
|
||||
this.loading = this.gameBoards?.length === 0;
|
||||
|
||||
if (this.isPublicBoard) {
|
||||
this.loadPublicBoards();
|
||||
} else {
|
||||
this.loadBoards()
|
||||
}
|
||||
},
|
||||
|
||||
async loadBoards() {
|
||||
await this.$store.dispatch('LOAD_BOARDS')
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
this.$store.commit('SET_SESSION_EXPIRED', true);
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
|
||||
if(!this.boards?.length) this.$emit('empty');
|
||||
},
|
||||
|
||||
async loadPublicBoards() {
|
||||
await this.$store.dispatch('LOAD_PUBLIC_BOARDS')
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$store.commit('SET_SESSION_EXPIRED', true);
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
viewPublicBoard(id) {
|
||||
this.$router.push({ name: 'public.board', params: { id } });
|
||||
},
|
||||
|
||||
async deleteBoard(id) {
|
||||
this.loading = true;
|
||||
|
||||
await this.$store.dispatch('DELETE_BOARD', id)
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
|
||||
this.$bvToast.toast('There was an error deleting board', { variant: 'error' });
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
this.$bvToast.toast('Board removed');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -15,18 +15,16 @@
|
|||
<h3 v-else-if="!loading">Edit tag</h3>
|
||||
</portal>
|
||||
|
||||
<portal to="headerActions">
|
||||
<game-selector
|
||||
:filter="tag.games"
|
||||
title="Tag game"
|
||||
variant="primary"
|
||||
class="mr-2"
|
||||
@select-game="selectGame"
|
||||
>
|
||||
<span class="d-none d-sm-block">Tag game</span>
|
||||
<i class="fa-solid fa-plus d-sm-none" />
|
||||
</game-selector>
|
||||
</portal>
|
||||
<game-selector
|
||||
:filter="tag.games"
|
||||
title="Tag game"
|
||||
variant="primary"
|
||||
class="mr-2"
|
||||
@select-game="selectGame"
|
||||
>
|
||||
<span>Tag game</span>
|
||||
<i class="fa-solid fa-plus d-sm-none" />
|
||||
</game-selector>
|
||||
|
||||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
class="mb-3"
|
||||
aria-label="Toolbar with button groups"
|
||||
>
|
||||
<b-button-group class="mr-3 mb-3 mb-sm-0">
|
||||
<b-button-group>
|
||||
<b-button
|
||||
@click="editor.chain().focus().setParagraph().run()"
|
||||
v-b-tooltip.hover
|
||||
|
@ -89,7 +89,7 @@
|
|||
</b-button>
|
||||
</b-button-group>
|
||||
|
||||
<b-button-group>
|
||||
<b-button-group class="mx-3">
|
||||
<b-button
|
||||
@click="editor.chain().focus().toggleBold().run()"
|
||||
v-b-tooltip.hover
|
|
@ -1,27 +1,12 @@
|
|||
<template lang="html">
|
||||
<div>
|
||||
<portal
|
||||
v-if="!isVerticalNav"
|
||||
to="headerActions"
|
||||
>
|
||||
<PageTitle title="Games">
|
||||
<b-button
|
||||
@click="toggleView"
|
||||
class="mr-3"
|
||||
:variant="darkTheme ? 'black' : 'light'"
|
||||
>
|
||||
<i :class="`fa-solid ${view === 'grid' ? 'fa-list' : 'fa-table-cells'}`" />
|
||||
</b-button>
|
||||
</portal>
|
||||
|
||||
<PageTitle title="Games">
|
||||
<b-button
|
||||
v-if="isVerticalNav"
|
||||
@click="toggleView"
|
||||
:variant="darkTheme ? 'dark' : 'light'"
|
||||
>
|
||||
<i v-if="view === 'grid'" class="fa-solid fa-list" />
|
||||
<i v-else class="fa-solid fa-table-cells" />
|
||||
</b-button>
|
||||
</PageTitle>
|
||||
|
||||
<!-- <b-button class="mr-3">
|
||||
|
|
99
src/pages/HomePage.vue
Normal file
99
src/pages/HomePage.vue
Normal file
|
@ -0,0 +1,99 @@
|
|||
<template lang="html">
|
||||
<div>
|
||||
<page-title :title="user ? 'Boards' : null" />
|
||||
|
||||
<div
|
||||
class="mt-auto py-3 mb-3"
|
||||
>
|
||||
<h4 class="text-center mb-2">Elevate Your Play, Organize Your Way!</h4>
|
||||
|
||||
<div class="bg-light p-3 rounded">
|
||||
<h4 class="text-center text-primary mb-2">Powered by</h4>
|
||||
|
||||
<div class="d-flex flex-wrap align-items-start justify-content-center overflow-auto">
|
||||
<!-- YouTube -->
|
||||
<img src="/logos/data-sources/wikipedia.svg" alt="wikipedia" width="60" class="mx-3">
|
||||
<img src="/logos/data-sources/igdb.svg" alt="igdb" width="80" class="mx-3">
|
||||
<img src="/logos/data-sources/fandom.svg" alt="fandom" width="80" class="mx-3 mt-2">
|
||||
<img src="/logos/data-sources/amazon.svg" alt="amazon" width="80" class="mx-3 mt-3">
|
||||
<img src="/logos/data-sources/twitch.svg" alt="twitch" width="80" class="mx-3 mt-2">
|
||||
<img src="/logos/data-sources/speedrun.png" alt="speedrun" width="80" class="mx-3 mt-3">
|
||||
<img src="/logos/data-sources/gog.svg" alt="gog" width="60" class="mx-3">
|
||||
<img src="/logos/data-sources/steam.svg" alt="steam" width="60" class="mx-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-success p-3 rounded">
|
||||
<h4 class="text-center">Join the community and start creating your own boards!</h4>
|
||||
|
||||
<div>
|
||||
<profile-card
|
||||
v-for="profile in profiles"
|
||||
:key="profile.userName"
|
||||
:profile="profile"
|
||||
/>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TODO: put public boards here -->
|
||||
<!-- TODO: put public reviews here -->
|
||||
<!-- TODO: put latest news here -->
|
||||
<!-- TODO: put latest deals here -->
|
||||
|
||||
<!-- <BoardsPage /> -->
|
||||
<div class="board-grid">
|
||||
<mini-board
|
||||
v-for="board in recentlyUpdatedPublicBoards"
|
||||
:key="board.id"
|
||||
:board="board"
|
||||
@click.native="$router.push({ name: 'board', params: { id: board.id } })"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- <div class="game-deals">
|
||||
<twitter-feed twitter-user="wario64" />
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
// import TwitterFeed from '@/components/TwitterFeed';
|
||||
import MiniBoard from '@/components/Board/MiniBoard';
|
||||
import ProfileCard from '@/components/ProfileCard';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MiniBoard,
|
||||
// TwitterFeed,
|
||||
ProfileCard,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'profiles']),
|
||||
...mapGetters(['darkTheme', 'isVerticalNav', 'navPosition', 'sortedPublicBoards']),
|
||||
|
||||
recentlyUpdatedPublicBoards() {
|
||||
return this.sortedPublicBoards.filter(({ lastUpdated }) => Boolean(lastUpdated)).slice(0, 20);
|
||||
},
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.loadPublicBoards();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async loadPublicBoards() {
|
||||
try {
|
||||
await this.$store.dispatch('LOAD_PROFILES');
|
||||
await this.$store.dispatch('LOAD_PUBLIC_BOARDS');
|
||||
} catch (e) {
|
||||
// this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -16,9 +16,8 @@
|
|||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
|
||||
<template v-else>
|
||||
<portal to="headerActions">
|
||||
<game-selector
|
||||
v-if="!isEmpty && !isVerticalNav"
|
||||
<game-selector
|
||||
v-if="!isEmpty"
|
||||
title="Select game to add a note"
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
:class="{ 'mr-3': !isVerticalNav }"
|
||||
|
@ -26,8 +25,7 @@
|
|||
>
|
||||
<i class="d-sm-none fa-solid fa-plus" />
|
||||
<span class="d-none d-sm-inline">Create note</span>
|
||||
</game-selector>
|
||||
</portal>
|
||||
</game-selector>
|
||||
|
||||
<empty-state
|
||||
v-if="isEmpty"
|
|
@ -11,16 +11,6 @@
|
|||
class="field"
|
||||
@submit.prevent="save"
|
||||
>
|
||||
<!-- <pre>{{ profile }}</pre> -->
|
||||
<portal to="headerActions" v-if="!isVerticalNav">
|
||||
<b-button
|
||||
:to="{ name: 'public.profile', params: { userName: profile.userName } }"
|
||||
class="mr-2"
|
||||
>
|
||||
View profile
|
||||
</b-button>
|
||||
</portal>
|
||||
|
||||
<b-spinner v-if="uploading" />
|
||||
|
||||
<b-avatar
|
|
@ -6,16 +6,6 @@
|
|||
<div
|
||||
v-else-if="profile"
|
||||
>
|
||||
<portal to="headerActions">
|
||||
<b-button
|
||||
v-if="isProfileOwner"
|
||||
class="mr-2"
|
||||
:to="{ name: 'profile' }"
|
||||
>
|
||||
Edit
|
||||
</b-button>
|
||||
</portal>
|
||||
|
||||
<div class="text-center">
|
||||
<b-avatar
|
||||
:src="avatarImage"
|
|
@ -7,17 +7,11 @@
|
|||
<b-container>
|
||||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
|
||||
<masonry
|
||||
v-else
|
||||
gutter="1rem"
|
||||
:cols="{default: 4, 1000: 3, 700: 2, 400: 1}"
|
||||
>
|
||||
<profile-card
|
||||
<profile-card
|
||||
v-for="profile in profiles"
|
||||
:key="profile.userName"
|
||||
:profile="profile"
|
||||
/>
|
||||
</masonry>
|
||||
</b-container>
|
||||
</section>
|
||||
</template>
|
|
@ -136,12 +136,6 @@
|
|||
Log out
|
||||
</b-button>
|
||||
|
||||
<hr />
|
||||
|
||||
<b-link v-b-modal.keyboard-shortcuts>
|
||||
<i class="fa-solid fa-keyboard fa-fw" /> Keyboard Shortcuts
|
||||
</b-link>
|
||||
|
||||
<br />
|
||||
|
||||
<b-link :to="{ name: 'dev.tools' }">
|
147
src/pages/TagsPage.vue
Normal file
147
src/pages/TagsPage.vue
Normal file
|
@ -0,0 +1,147 @@
|
|||
<template lang="html">
|
||||
<b-container>
|
||||
<PageTitle title="Tags">
|
||||
<b-button
|
||||
v-if="user"
|
||||
:variant="darkTheme ? 'success' : 'black'"
|
||||
:to="{ name: 'tag.create' }"
|
||||
>
|
||||
<i class="d-sm-none fa-solid fa-plus" />
|
||||
<span class="ml-2">Add tag</span>
|
||||
</b-button>
|
||||
</PageTitle>
|
||||
|
||||
<b-spinner v-if="loading" class="spinner-centered" />
|
||||
|
||||
<empty-state
|
||||
v-else-if="tags.length === 0"
|
||||
illustration="tags"
|
||||
message="Using tags is a fantastic way to keep your collection well-organized!"
|
||||
>
|
||||
<b-button
|
||||
v-if="user"
|
||||
variant="primary"
|
||||
:to="{ name: 'tag.create' }"
|
||||
>
|
||||
Add tag
|
||||
</b-button>
|
||||
</empty-state>
|
||||
|
||||
<b-row v-else>
|
||||
<b-col
|
||||
v-for="({ textColor, bgColor, name, games: taggedGames }, index) in tags"
|
||||
cols="12"
|
||||
sm="12"
|
||||
md="12"
|
||||
lg="8"
|
||||
offset-lg="2"
|
||||
:key="name"
|
||||
>
|
||||
|
||||
<b-card
|
||||
:bg-variant="darkTheme ? 'dark' : 'light'"
|
||||
:text-variant="darkTheme ? 'light' : 'dark'"
|
||||
class="mb-2"
|
||||
>
|
||||
<b-button
|
||||
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||
@click="$router.push({ name: 'tag.edit', params: { id: index } })"
|
||||
>
|
||||
{{ name }}
|
||||
</b-button>
|
||||
|
||||
<b-form-row v-if="taggedGames.length" class="mt-2">
|
||||
<b-col
|
||||
v-for="game in taggedGames.slice(0, 6)"
|
||||
:key="game"
|
||||
cols="3"
|
||||
sm="4"
|
||||
md="3"
|
||||
lg="2"
|
||||
>
|
||||
<!-- <b-img
|
||||
:src="$options.getImageUrl(cachedGames[game], $options.IMAGE_SIZE_COVER_SMALL)"
|
||||
class="cursor-pointer rounded mb-2"
|
||||
fluid
|
||||
@click="$router.push({ name: 'game', params: { id: cachedGames[game].id, slug: cachedGames[game].slug }})"
|
||||
/> -->
|
||||
</b-col>
|
||||
</b-form-row>
|
||||
|
||||
<b-link
|
||||
v-if="taggedGames.length > 6"
|
||||
:to="{ name: 'tag.edit', params: { id: index } }"
|
||||
>
|
||||
{{ taggedGames.length }} more...
|
||||
</b-link>
|
||||
</b-card>
|
||||
</b-col>
|
||||
|
||||
<!-- <b-button
|
||||
v-for="({ textColor, bgColor, name, games }, index) in tags"
|
||||
@click="$router.push({ name: 'tag.edit', params: { id: index } })"
|
||||
rounded
|
||||
block
|
||||
variant="transparent"
|
||||
:style="`background-color: ${bgColor}; color: ${textColor}`"
|
||||
:key="name"
|
||||
>
|
||||
{{ name }} {{ games.length ? `(${games.length})` : '' }}
|
||||
</b-button> -->
|
||||
</b-row>
|
||||
</b-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import { getImageUrl } from '@/utils';
|
||||
import { IMAGE_SIZE_COVER_SMALL } from '@/constants';
|
||||
|
||||
import EmptyState from '@/components/EmptyState';
|
||||
|
||||
export default {
|
||||
IMAGE_SIZE_COVER_SMALL,
|
||||
getImageUrl,
|
||||
|
||||
components: {
|
||||
EmptyState,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['tags', 'user', 'cachedGames']),
|
||||
...mapGetters(['darkTheme', 'isVerticalNav']),
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.user?.uid) this.load();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async load() {
|
||||
try {
|
||||
this.loading = true;
|
||||
|
||||
await this.$store.dispatch('LOAD_TAGS');
|
||||
|
||||
const allGames = Array.from(new Set(this.tags.map(({ games }) => games).flat()));
|
||||
const cachedGames = Object.keys(this.cachedGames);
|
||||
const gamesNotCached = allGames?.filter((game) => !cachedGames.includes(String(game)))?.toString();
|
||||
|
||||
if (gamesNotCached) {
|
||||
await this.$store.dispatch('LOAD_IGDB_GAMES', gamesNotCached);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('e', e);
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,70 +0,0 @@
|
|||
<template lang="html">
|
||||
<div>
|
||||
<page-title :title="user ? 'Boards' : 'Gamebrary'" />
|
||||
|
||||
<!-- <portal to="headerActions">
|
||||
<b-button
|
||||
v-if="user"
|
||||
:class="isVerticalNav ? 'mt-2' : 'mr-3'"
|
||||
@click="showPublic = !showPublic"
|
||||
v-b-tooltip.hover
|
||||
variant="black"
|
||||
:title="showPublic ? 'My boards' : 'All boards'"
|
||||
>
|
||||
<i v-if="showPublic" class="fa-solid fa-user" />
|
||||
<i v-else class="fa-solid fa-users" />
|
||||
</b-button>
|
||||
</portal> -->
|
||||
|
||||
<div
|
||||
v-if="!user"
|
||||
class="mt-auto py-3 mb-3"
|
||||
>
|
||||
<h4 class="text-center mb-2">Organize your game library your way!</h4>
|
||||
|
||||
<h4 class="text-center text-primary mb-2">Powered by:</h4>
|
||||
|
||||
<div class="d-flex flex-wrap align-items-start justify-content-center overflow-auto">
|
||||
<!-- YouTube -->
|
||||
<img src="/logos/data-sources/wikipedia.svg" alt="wikipedia" width="60" class="mx-3">
|
||||
<img src="/logos/data-sources/igdb.svg" alt="igdb" width="80" class="mx-3">
|
||||
<img src="/logos/data-sources/fandom.svg" alt="fandom" width="80" class="mx-3 mt-2">
|
||||
<img src="/logos/data-sources/amazon.svg" alt="amazon" width="80" class="mx-3 mt-3">
|
||||
<img src="/logos/data-sources/twitch.svg" alt="twitch" width="80" class="mx-3 mt-2">
|
||||
<img src="/logos/data-sources/speedrun.png" alt="speedrun" width="80" class="mx-3 mt-3">
|
||||
<img src="/logos/data-sources/gog.svg" alt="gog" width="60" class="mx-3">
|
||||
<img src="/logos/data-sources/steam.svg" alt="steam" width="60" class="mx-3">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BoardsPage />
|
||||
|
||||
<!-- <div class="game-deals">
|
||||
<twitter-feed twitter-user="wario64" />
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
import BoardsPage from '@/components/BoardsPage';
|
||||
import TwitterFeed from '@/components/TwitterFeed';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BoardsPage,
|
||||
// TwitterFeed,
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
...mapGetters(['darkTheme', 'isVerticalNav', 'navPosition']),
|
||||
|
||||
offVariant() {
|
||||
return this.darkTheme
|
||||
? 'black'
|
||||
: 'light';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -10,7 +10,8 @@ const router = new VueRouter({
|
|||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to?.meta?.title) document.title = `${to.meta.title} - Gamebrary`;
|
||||
if (to?.meta?.title) document.title = `Keap`;
|
||||
// if (to?.meta?.title) document.title = `${to.meta.title} - Gamebrary`;
|
||||
|
||||
next();
|
||||
});
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
<template lang="html">
|
||||
<b-container>
|
||||
<PageTitle title="Tags">
|
||||
<!-- <b-button
|
||||
:variant="darkTheme ? 'success' : 'primary'"
|
||||
:to="{ name: 'tag.create' }"
|
||||
>
|
||||
<i class="d-sm-none fa-solid fa-plus" />
|
||||
<span class="d-none d-sm-inline">Add tag</span>
|
||||
</b-button> -->
|
||||
</PageTitle>
|
||||
<PageTitle title="Tags" />
|
||||
|
||||
<portal v-if="!isVerticalNav && !loading && tags.length > 0" to="headerActions">
|
||||
<b-button
|
||||
|
|
49
yarn.lock
49
yarn.lock
|
@ -4830,11 +4830,6 @@ dequal@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
|
||||
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
|
||||
|
||||
desandro-matches-selector@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz#717beed4dc13e7d8f3762f707a6d58a6774218e1"
|
||||
integrity sha1-cXvu1NwT59jzdi9wem1YpndCGOE=
|
||||
|
||||
destroy@~1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
|
@ -5462,11 +5457,6 @@ etag@~1.8.1:
|
|||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
ev-emitter@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a"
|
||||
integrity sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q==
|
||||
|
||||
event-pubsub@4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e"
|
||||
|
@ -5864,13 +5854,6 @@ firebaseui@^4.8.0:
|
|||
dialog-polyfill "^0.4.7"
|
||||
material-design-lite "^1.2.0"
|
||||
|
||||
fizzy-ui-utils@^2.0.0:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz#7df45dcc4eb374a08b65d39bb9a4beedf7330505"
|
||||
integrity sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg==
|
||||
dependencies:
|
||||
desandro-matches-selector "^2.0.0"
|
||||
|
||||
flat-cache@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
|
||||
|
@ -6010,11 +5993,6 @@ get-package-type@^0.1.0:
|
|||
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
|
||||
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
|
||||
|
||||
get-size@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/get-size/-/get-size-2.0.3.tgz#54a1d0256b20ea7ac646516756202769941ad2ef"
|
||||
integrity sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q==
|
||||
|
||||
get-stream@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||
|
@ -8705,15 +8683,6 @@ ospath@^1.2.2:
|
|||
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
|
||||
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=
|
||||
|
||||
outlayer@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/outlayer/-/outlayer-2.1.1.tgz#29863b6de10ea5dadfffcadfa0d728907387e9a2"
|
||||
integrity sha1-KYY7beEOpdrf/8rfoNcokHOH6aI=
|
||||
dependencies:
|
||||
ev-emitter "^1.0.0"
|
||||
fizzy-ui-utils "^2.0.0"
|
||||
get-size "^2.0.2"
|
||||
|
||||
p-finally@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
||||
|
@ -8779,14 +8748,6 @@ p-try@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
packery@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/packery/-/packery-2.1.2.tgz#92a3cc3303e781f151d93ee34d13325790c4f13f"
|
||||
integrity sha512-Coc+8Atz03c0iu1RK0PZIJMKcKrE4i9Z8UBBywqz7Dhy40mMPM5wMQfqO9P2eqFP+lxKjGMTHgRAwjBQc+AQ5w==
|
||||
dependencies:
|
||||
get-size "^2.0.2"
|
||||
outlayer "^2.0.0"
|
||||
|
||||
param-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
|
||||
|
@ -11226,11 +11187,6 @@ vue-masonry-css@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/vue-masonry-css/-/vue-masonry-css-1.0.3.tgz#a5e7bb248570eeedcd358637d3f1f4fc7f0c5f86"
|
||||
integrity sha512-viecHQiHVLez7HlYUQsv1wJb2MT/RDSzkDp6m3In41vPrk6OsBmT2qRE8LZqYIA4daIwrnx/Xm8h4fjOpuE3hw==
|
||||
|
||||
vue-progress-path@^0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-progress-path/-/vue-progress-path-0.0.2.tgz#d780fc7a96dbc7f784eb52895aeef7a5f0af6325"
|
||||
integrity sha512-olD0dTbxZkwpodYbvPU/O2tJT7CbZt8NHP1ewtM6iXrzsjnfi9KZ6+CsUadsW87jCemSPIu9ez1iHcrvpqIJeg==
|
||||
|
||||
vue-raven@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vue-raven/-/vue-raven-1.0.3.tgz#cce941a9255e9694a5793c384fd8ab2e576ce764"
|
||||
|
@ -11299,11 +11255,6 @@ vuefire@^1.4.5:
|
|||
resolved "https://registry.yarnpkg.com/vuefire/-/vuefire-1.4.5.tgz#2f31028b18f25e0f581bb68fb94b88302d62ebf8"
|
||||
integrity sha512-lYk0Yk7ExwGN8G/datDMKxNeLLxfkL/cCU/B5Dw5ggNabCPwKnUEv3OE3ShMwberDDN+9wzm8AEPiLvI9aG/9Q==
|
||||
|
||||
vuejs-progress-bar@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/vuejs-progress-bar/-/vuejs-progress-bar-1.2.8.tgz#0e88291ad2c215ca165e63907dca356a9463e75c"
|
||||
integrity sha512-FSXg42UlV0X6EMI0Tk6JFf9U55cWjlLVFQVoZef+o0oiAX7dvYKqVJSrsO5tR09FiN3KbVJGASbpuUoK/iNw9w==
|
||||
|
||||
vuex-persist@^1.2.2:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/vuex-persist/-/vuex-persist-1.8.0.tgz#958ce00e83b0feba4a695f7a2be76d3f3ce32720"
|
||||
|
|
Loading…
Reference in a new issue