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
|
||||
'decks/new' (): IDeck {
|
||||
return defaultDeck()
|
||||
'decks/new' (decks: Ref<IDeck[]>) {
|
||||
decks.value.push(defaultDeck())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { reactive, ref } from 'vue'
|
||||
import { State, KV } from '../types'
|
||||
import { DeckDB } from '../storage'
|
||||
import stateActions from './actions'
|
||||
import { defaultDeck } from '../lib/deck'
|
||||
import { defaultCard } from '../lib/card'
|
||||
import stateActions from './actions'
|
||||
|
||||
const state: State = {
|
||||
settings: ref({}),
|
||||
|
@ -12,11 +12,11 @@ const state: State = {
|
|||
initialized: ref(false)
|
||||
}
|
||||
|
||||
export function useState (field: string): { [key: string]: any } {
|
||||
const collection = ref(state[field])
|
||||
export function useState (prop: string): { [key: string]: any } {
|
||||
const collection = state[prop]
|
||||
const actions = Object.keys(stateActions).reduce((acc, key) => {
|
||||
if (key.startsWith(`${field}/`)) {
|
||||
const newKey = key.split('/')[1]
|
||||
if (key.startsWith(`${prop}/`)) {
|
||||
const newKey = key.slice(prop.length + 1)
|
||||
acc[newKey] = (payload: KV<any>) => stateActions[key](collection, payload)
|
||||
}
|
||||
return acc
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
<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">
|
||||
<CardBack :icon="deck.icon" :color="deck.color" :size="deck.cardSize">
|
||||
{{ deck.name }} ({{ deck.cards.length }})
|
||||
</CardBack>
|
||||
<Card :icon="deck.icon" :color="deck.color" :size="deck.cardSize">
|
||||
<template #back>{{ deck.name }} ({{ deck.cards.length }})</template>
|
||||
</Card>
|
||||
</router-link>
|
||||
<CardBack @click="newDeck" icon="plus" />
|
||||
<Card id="_add_deck" @click="newDeck" />
|
||||
</section>
|
||||
|
||||
</template>
|
||||
|
@ -16,17 +16,19 @@
|
|||
import { defineComponent } from 'vue'
|
||||
import { useState } from '@/state'
|
||||
|
||||
import CardBack from '@/components/CardBack.vue'
|
||||
import Card from '@/components/Card.vue'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Home',
|
||||
components: { CardBack },
|
||||
components: { Card },
|
||||
setup () {
|
||||
const { collection: decks, actions } = useState('decks')
|
||||
const { collection: decks, actions: deckActions } = useState('decks')
|
||||
|
||||
return {
|
||||
decks,
|
||||
newDeck: actions['decks/new']
|
||||
// TODO: open popup with Deck settings after creation
|
||||
newDeck: deckActions.new
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue