list decks and add new ones
This commit is contained in:
parent
f8a7e611a1
commit
ed8bcda86d
5 changed files with 88 additions and 39 deletions
71
src/components/Card.vue
Normal file
71
src/components/Card.vue
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<div class="card card-back" :style="cssVars" v-if="showBackSide">
|
||||||
|
<div class="icon-wrapper">
|
||||||
|
<img :src="iconPath" alt="card icon" />
|
||||||
|
</div>
|
||||||
|
<footer><slot name="back"></slot></footer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import { KV, CardSize } from '@/types'
|
||||||
|
import { cardSizeToStyle } from '@/lib/card'
|
||||||
|
import iconPath from '@/lib/iconPath'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Card',
|
||||||
|
props: {
|
||||||
|
icon: String,
|
||||||
|
color: String,
|
||||||
|
size: String
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconPath (): string {
|
||||||
|
return iconPath(this.icon || 'plus')
|
||||||
|
},
|
||||||
|
showBackSide (): boolean {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
showFrontSide (): boolean {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
cssVars (): KV<string> {
|
||||||
|
const backgroundColor = this.color || 'transparent'
|
||||||
|
const size = this.size as CardSize || CardSize.Poker
|
||||||
|
return {
|
||||||
|
backgroundColor,
|
||||||
|
...cardSizeToStyle(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.card-back {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 4rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
.card-back > footer {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
#_add_deck.card-back {
|
||||||
|
height: var(--card-height);
|
||||||
|
width: 25rem;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
#_add_deck.card-back > footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.card-back > .icon-wrapper {
|
||||||
|
width: 90%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,24 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="icon-wrapper">
|
|
||||||
<img :src="iconPath" alt="card icon" />
|
|
||||||
</div>
|
|
||||||
<slot></slot>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent, computed } from 'vue'
|
|
||||||
import iconPath from '@/lib/iconPath'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'CardBack',
|
|
||||||
props: {
|
|
||||||
icon: String,
|
|
||||||
color: String
|
|
||||||
},
|
|
||||||
setup (props) {
|
|
||||||
return {
|
|
||||||
iconPath: computed(() => iconPath(props.icon || 'plus'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
|
@ -22,7 +22,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// DECK ACTIONS
|
// DECK ACTIONS
|
||||||
'decks/new' (): IDeck {
|
'decks/new' (decks: Ref<IDeck[]>) {
|
||||||
return defaultDeck()
|
decks.value.push(defaultDeck())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { State, KV } from '../types'
|
import { State, KV } from '../types'
|
||||||
import { DeckDB } from '../storage'
|
import { DeckDB } from '../storage'
|
||||||
import stateActions from './actions'
|
|
||||||
import { defaultDeck } from '../lib/deck'
|
import { defaultDeck } from '../lib/deck'
|
||||||
import { defaultCard } from '../lib/card'
|
import { defaultCard } from '../lib/card'
|
||||||
|
import stateActions from './actions'
|
||||||
|
|
||||||
const state: State = {
|
const state: State = {
|
||||||
settings: ref({}),
|
settings: ref({}),
|
||||||
|
@ -12,11 +12,11 @@ const state: State = {
|
||||||
initialized: ref(false)
|
initialized: ref(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useState (field: string): { [key: string]: any } {
|
export function useState (prop: string): { [key: string]: any } {
|
||||||
const collection = ref(state[field])
|
const collection = state[prop]
|
||||||
const actions = Object.keys(stateActions).reduce((acc, key) => {
|
const actions = Object.keys(stateActions).reduce((acc, key) => {
|
||||||
if (key.startsWith(`${field}/`)) {
|
if (key.startsWith(`${prop}/`)) {
|
||||||
const newKey = key.split('/')[1]
|
const newKey = key.slice(prop.length + 1)
|
||||||
acc[newKey] = (payload: KV<any>) => stateActions[key](collection, payload)
|
acc[newKey] = (payload: KV<any>) => stateActions[key](collection, payload)
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
<section name="deck-covers" class="cards" :class="{ centered: !decks.length }">
|
<section name="deck-covers" class="cards" :class="{ centered: !decks.length }">
|
||||||
<router-link :to="{ name: 'Deck', params: { id: deck.id } }" :key="deck.id" v-for="deck in decks">
|
<router-link :to="{ name: 'Deck', params: { id: deck.id } }" :key="deck.id" v-for="deck in decks">
|
||||||
<CardBack :icon="deck.icon" :color="deck.color" :size="deck.cardSize">
|
<Card :icon="deck.icon" :color="deck.color" :size="deck.cardSize">
|
||||||
{{ deck.name }} ({{ deck.cards.length }})
|
<template #back>{{ deck.name }} ({{ deck.cards.length }})</template>
|
||||||
</CardBack>
|
</Card>
|
||||||
</router-link>
|
</router-link>
|
||||||
<CardBack @click="newDeck" icon="plus" />
|
<Card id="_add_deck" @click="newDeck" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -16,17 +16,19 @@
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { useState } from '@/state'
|
import { useState } from '@/state'
|
||||||
|
|
||||||
import CardBack from '@/components/CardBack.vue'
|
import Card from '@/components/Card.vue'
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
components: { CardBack },
|
components: { Card },
|
||||||
setup () {
|
setup () {
|
||||||
const { collection: decks, actions } = useState('decks')
|
const { collection: decks, actions: deckActions } = useState('decks')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
decks,
|
decks,
|
||||||
newDeck: actions['decks/new']
|
// TODO: open popup with Deck settings after creation
|
||||||
|
newDeck: deckActions.new
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue