mirror of
https://github.com/romancm/gamebrary
synced 2024-11-24 20:23:06 +00:00
Simplified add list
This commit is contained in:
parent
516a5f3396
commit
cb38320acf
6 changed files with 215 additions and 173 deletions
|
@ -1,51 +0,0 @@
|
|||
<template lang="html">
|
||||
<div :class="['onboard', { dark: darkModeEnabled}]">
|
||||
<h2>Your {{ platform.name }} <br> collection is empty</h2>
|
||||
<h3>Create your first list!</h3>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from 'vuex';
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(['platform']),
|
||||
...mapGetters(['darkModeEnabled']),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles.scss";
|
||||
|
||||
.onboard {
|
||||
flex-shrink: 0;
|
||||
margin-right: $gp;
|
||||
padding-right: 60px;
|
||||
text-align: center;
|
||||
background: url('/static/img/arrow-black.png') no-repeat center right;
|
||||
background-size: 50px;
|
||||
|
||||
@media($small) {
|
||||
background-size: 30px;
|
||||
padding-right: 40px;
|
||||
margin-right: $gp / 2;
|
||||
|
||||
h2 {
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background: url('/static/img/arrow-white.png') no-repeat center right;
|
||||
background-size: 50px;
|
||||
color: $color-gray;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,58 +1,14 @@
|
|||
<template lang="html">
|
||||
<div class="list-actions">
|
||||
<div class="actions">
|
||||
<modal
|
||||
ref="addList"
|
||||
message="Pick an option below"
|
||||
padded
|
||||
show-close
|
||||
:action-text="$t('global.create')"
|
||||
:title="$t('list.add')"
|
||||
:action-disabled="isDuplicate || !newListName"
|
||||
@action="addList"
|
||||
@close="reset"
|
||||
@open="focusField"
|
||||
>
|
||||
<button
|
||||
class="small info"
|
||||
:title="$t('list.add')"
|
||||
@click="addList"
|
||||
>
|
||||
<i class="fas fa-plus" />
|
||||
</button>
|
||||
|
||||
<form slot="content">
|
||||
<div class="suggestions">
|
||||
<button
|
||||
class="small primary hollow"
|
||||
v-for="suggestion in listNameSuggestions"
|
||||
:key="suggestion"
|
||||
type="button"
|
||||
:disabled="listNames.includes(suggestion.toLowerCase())"
|
||||
@click="addList(suggestion)"
|
||||
>
|
||||
{{ suggestion }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p>Or enter your own list name</p>
|
||||
|
||||
<input
|
||||
v-model="newListName"
|
||||
type="text"
|
||||
ref="newListName"
|
||||
autofocus
|
||||
required
|
||||
:placeholder="$t('list.input')"
|
||||
/>
|
||||
|
||||
<panel
|
||||
class="warning"
|
||||
v-if="isDuplicate"
|
||||
v-html="errorMessage"
|
||||
/>
|
||||
</form>
|
||||
</modal>
|
||||
|
||||
<modal
|
||||
title="Game tags"
|
||||
ref="tags"
|
||||
|
@ -97,34 +53,20 @@ import Panel from '@/components/Panel/Panel';
|
|||
import Modal from '@/components/Modal/Modal';
|
||||
import Tags from '@/components/Tags/Tags';
|
||||
import ShareList from '@/components/ShareList/ShareList';
|
||||
import ListAdd from '@/components/Lists/ListAdd';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Modal,
|
||||
Tags,
|
||||
ShareList,
|
||||
ListAdd,
|
||||
Panel,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
newListName: '',
|
||||
listNameSuggestions: [
|
||||
'Owned',
|
||||
'Wishlist',
|
||||
'Currently Playing',
|
||||
'Completed',
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'gameLists', 'platform']),
|
||||
|
||||
errorMessage() {
|
||||
return `You already have a list named <strong>${this.newListName}</strong>. Please use a different name.`;
|
||||
},
|
||||
|
||||
list() {
|
||||
return this.gameLists[this.platform.code];
|
||||
},
|
||||
|
@ -136,27 +78,11 @@ export default {
|
|||
this.list.filter(({ name }) => name.toLowerCase() === newListName).length > 0
|
||||
: false;
|
||||
},
|
||||
|
||||
listNames() {
|
||||
return this.list ?
|
||||
this.list.map(({ name }) => name.toLowerCase())
|
||||
: [];
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.list) {
|
||||
this.$refs.addList.open();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
focusField() {
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.newListName) {
|
||||
this.$refs.newListName.focus();
|
||||
}
|
||||
});
|
||||
addList() {
|
||||
this.$store.commit('SET_ADDING_LIST_STATUS', true);
|
||||
},
|
||||
|
||||
deletePlatform() {
|
||||
|
@ -164,46 +90,12 @@ export default {
|
|||
this.$router.push({ name: 'platforms' });
|
||||
this.$emit('update', true);
|
||||
},
|
||||
|
||||
addList(suggestion) {
|
||||
const listName = suggestion || this.newListName;
|
||||
this.$store.commit('ADD_LIST', listName);
|
||||
|
||||
this.$ga.event({
|
||||
eventCategory: 'list',
|
||||
eventAction: 'add',
|
||||
eventLabel: 'listAdded',
|
||||
eventValue: listName,
|
||||
});
|
||||
|
||||
this.$emit('update');
|
||||
this.$emit('scroll');
|
||||
this.reset();
|
||||
|
||||
this.$bus.$emit('TOAST', { message: 'List added' });
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('scroll');
|
||||
});
|
||||
|
||||
if (suggestion) {
|
||||
this.$refs.addList.close();
|
||||
}
|
||||
|
||||
this.$store.commit('CLEAR_SEARCH_RESULTS');
|
||||
this.$store.commit('SET_ACTIVE_LIST_INDEX', this.list.length - 1);
|
||||
this.$store.commit('SET_SEARCH_ACTIVE', true);
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.newListName = '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "~styles/styles.scss";
|
||||
@import "src/styles/styles.scss";
|
||||
|
||||
.list-actions {
|
||||
padding-right: $gp;
|
||||
|
|
191
src/components/Lists/ListAdd.vue
Normal file
191
src/components/Lists/ListAdd.vue
Normal file
|
@ -0,0 +1,191 @@
|
|||
<template lang="html">
|
||||
<main>
|
||||
<form class="list-add">
|
||||
<header>Add list</header>
|
||||
|
||||
<section>
|
||||
<input
|
||||
v-model="newListName"
|
||||
type="text"
|
||||
ref="newListName"
|
||||
autofocus
|
||||
required
|
||||
placeholder="List name (e.g. Owned)"
|
||||
/>
|
||||
|
||||
<panel
|
||||
class="warning"
|
||||
v-if="isDuplicate"
|
||||
v-html="errorMessage"
|
||||
/>
|
||||
|
||||
<div class="suggestions">
|
||||
<small>Suggestions:</small>
|
||||
|
||||
<button
|
||||
class="small tiny tag primary hollow"
|
||||
v-for="suggestion in listNameSuggestions"
|
||||
:key="suggestion"
|
||||
type="button"
|
||||
:disabled="listNames.includes(suggestion.toLowerCase())"
|
||||
@click="addList(suggestion)"
|
||||
>
|
||||
{{ suggestion }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<button
|
||||
class="small info"
|
||||
@click="reset"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="small primary action"
|
||||
:disabled="isDuplicate || !newListName"
|
||||
@click="addList"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</footer>
|
||||
</form>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
newListName: '',
|
||||
listNameSuggestions: [
|
||||
'Owned',
|
||||
'Wishlist',
|
||||
'Currently Playing',
|
||||
'Completed',
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['gameLists', 'platform']),
|
||||
|
||||
list() {
|
||||
return this.gameLists[this.platform.code];
|
||||
},
|
||||
|
||||
errorMessage() {
|
||||
return `You already have a list named <strong>${this.newListName}</strong>. Please use a different name.`;
|
||||
},
|
||||
|
||||
listNames() {
|
||||
return this.list ?
|
||||
this.list.map(({ name }) => name.toLowerCase())
|
||||
: [];
|
||||
},
|
||||
|
||||
isDuplicate() {
|
||||
const newListName = this.newListName.toLowerCase();
|
||||
|
||||
return this.list ?
|
||||
this.list.filter(({ name }) => name.toLowerCase() === newListName).length > 0
|
||||
: false;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.focusField();
|
||||
},
|
||||
|
||||
methods: {
|
||||
focusField() {
|
||||
this.$nextTick(() => {
|
||||
this.$emit('scroll');
|
||||
});
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.newListName = '';
|
||||
this.$store.commit('SET_ADDING_LIST_STATUS', false);
|
||||
},
|
||||
|
||||
addList(e, suggestion) {
|
||||
const listName = suggestion || this.newListName;
|
||||
this.$store.commit('ADD_LIST', listName);
|
||||
|
||||
this.$ga.event({
|
||||
eventCategory: 'list',
|
||||
eventAction: 'add',
|
||||
eventLabel: 'listAdded',
|
||||
eventValue: listName,
|
||||
});
|
||||
|
||||
this.$emit('update');
|
||||
this.$emit('scroll');
|
||||
this.reset();
|
||||
|
||||
this.$bus.$emit('TOAST', { message: 'List added' });
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$emit('scroll');
|
||||
});
|
||||
|
||||
if (suggestion) {
|
||||
this.$refs.addList.close();
|
||||
}
|
||||
|
||||
this.$store.commit('CLEAR_SEARCH_RESULTS');
|
||||
this.$store.commit('SET_ACTIVE_LIST_INDEX', this.list.length - 1);
|
||||
this.$store.commit('SET_SEARCH_ACTIVE', true);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" rel="stylesheet/scss" scoped>
|
||||
@import "src/styles/styles.scss";
|
||||
|
||||
main {
|
||||
flex-shrink: 0;
|
||||
padding-right: $gp;
|
||||
}
|
||||
|
||||
.list-add {
|
||||
background: $color-light-gray;
|
||||
width: 300px;
|
||||
border-radius: $border-radius;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: $color-green;
|
||||
color: $color-white;
|
||||
height: $list-header-height;
|
||||
padding-left: $gp / 2;
|
||||
}
|
||||
|
||||
section {
|
||||
padding: $gp / 2;
|
||||
|
||||
small {
|
||||
display: flex;
|
||||
margin-bottom: $gp / 4;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-bottom: $gp / 2;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 0 $gp / 2 $gp / 2;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
|
@ -65,9 +65,14 @@
|
|||
@end="dragEnd"
|
||||
/>
|
||||
|
||||
<onboard v-if="!list" />
|
||||
<list-add
|
||||
v-if="addingList || !list"
|
||||
@scroll="scroll"
|
||||
@update="updateLists"
|
||||
/>
|
||||
|
||||
<list-actions
|
||||
v-else
|
||||
@update="updateLists"
|
||||
@scroll="scroll"
|
||||
/>
|
||||
|
@ -78,7 +83,7 @@
|
|||
<script>
|
||||
import ListActions from '@/components/Lists/ListActions';
|
||||
import GameBoardPlaceholder from '@/components/GameBoard/GameBoardPlaceholder';
|
||||
import Onboard from '@/components/GameBoard/Onboard';
|
||||
import ListAdd from '@/components/Lists/ListAdd';
|
||||
import Panel from '@/components/Panel/Panel';
|
||||
import GameDetail from '@/pages/GameDetail/GameDetail';
|
||||
import Modal from '@/components/Modal/Modal';
|
||||
|
@ -96,7 +101,7 @@ export default {
|
|||
List,
|
||||
ListActions,
|
||||
GameBoardPlaceholder,
|
||||
Onboard,
|
||||
ListAdd,
|
||||
Panel,
|
||||
GameDetail,
|
||||
Modal,
|
||||
|
@ -121,7 +126,7 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user', 'gameLists', 'platform', 'tags', 'games']),
|
||||
...mapState(['user', 'gameLists', 'addingList', 'platform', 'tags', 'games']),
|
||||
...mapGetters(['darkModeEnabled']),
|
||||
|
||||
list() {
|
||||
|
|
|
@ -71,6 +71,10 @@ export default {
|
|||
state.searchActive = status;
|
||||
},
|
||||
|
||||
SET_ADDING_LIST_STATUS(state, status) {
|
||||
state.addingList = status;
|
||||
},
|
||||
|
||||
SET_ACTIVE_LIST_INDEX(state, listIndex) {
|
||||
state.activeListIndex = listIndex;
|
||||
},
|
||||
|
|
|
@ -4,6 +4,7 @@ export default {
|
|||
tags: {},
|
||||
activeListIndex: null,
|
||||
searchActive: false,
|
||||
addingList: false,
|
||||
gameLists: {},
|
||||
settings: null,
|
||||
platform: null,
|
||||
|
|
Loading…
Reference in a new issue