Skip to content

Commit

Permalink
Reimplement storing words, separate it from list store
Browse files Browse the repository at this point in the history
  • Loading branch information
pasikonik committed Mar 17, 2023
1 parent 75503c9 commit 0a560b7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 60 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The application for consolidate newly discovered words.

- [ ] PHASE 1 - MVP:
- [x] basic manage lists
- [ ] basic manage words
- [x] basic manage words
- [ ] import words from csv file
- [ ] memorizing view
- [ ] PHASE 2 - Rough diamond
Expand Down
26 changes: 8 additions & 18 deletions src/components/ListHeader.vue
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
<script setup lang="ts">
import { ref, watchEffect, watch } from 'vue'
import { ref } from 'vue'
import List from '@/types/list'
import { useRouter } from 'vue-router'
import { useListStore } from '@/stores/list'
import { storeToRefs } from 'pinia'
const router = useRouter()
const store = useListStore()
const { getListById } = storeToRefs(store)
const props = defineProps<{ listId: number }>()
let list = getListById.value(props.listId) as List
const props = defineProps<{ list: List }>()
const isEditing = ref(false)
const newName = ref(list.name)
watch(isEditing, (newVal, oldVal) => {
if (newVal == false && oldVal == true) {
list = getListById.value(props.listId) as List
}
})
const newName = ref(props.list.name)
const deleteList = async () => {
await store.deleteList(list.id)
await store.deleteList(props.list.id)
router.push('/lists')
}
const updateList = async () => {
await store.updateList({ id: list.id, name: newName.value })
await store.updateList({ id: props.list.id, name: newName.value })
isEditing.value = false
}
const cancelEditing = () => {
isEditing.value = false
newName.value = list.name
newName.value = props.list.name
}
</script>

Expand All @@ -52,7 +42,7 @@ const cancelEditing = () => {
@keyup.esc="cancelEditing"
@keyup.enter="updateList"
></v-text-field>
<h1 v-else class="text-h3 ml-3 title" @click="isEditing = true">
<h1 v-else class="text-h3 ml-3 list-name" @click="isEditing = true">
{{ list.name }}
</h1>

Expand Down Expand Up @@ -94,7 +84,7 @@ const cancelEditing = () => {
padding-bottom: 0;
}
.title {
.list-name {
cursor: pointer;
padding: 11px 0;
}
Expand Down
48 changes: 29 additions & 19 deletions src/stores/word.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
import api from '@/lib/api'
import { defineStore } from 'pinia'
import Word from '@/types/word'
import { useListStore } from './list'
import { ref } from 'vue'
import { useListStore } from './list'
import { ref, computed } from 'vue'

interface WordParams {
origin: string,
translation: string,
list_id: number
origin: string
translation: string
list_id: number
}

export const useWordStore = defineStore('word', () => {
const listStore = useListStore()
const listStore = useListStore()

const all = ref<Map<number, Word>>(new Map())
const all = ref<Map<number, Word>>(new Map())

async function createWord(wordParams: WordParams) {
const newWord = await api.post('words', wordParams)
const wordsForList = computed(() => {
return (listId: number): Word[] =>
Array.from(all.value.values()).filter((word) => word.list_id == listId)
})

listStore.all.get(newWord.list_id)?.words?.push(newWord)
all.value.set(newWord.id, newWord)
return newWord
}

async function deleteWord(wordId: number) {
await api.delete(`words/${wordId}`)
async function fetchWords(listId: number) {
const words = await api.get(`lists/${listId}/words`)

all.value.delete(wordId)
for (const word of words) {
all.value.set(word.id, word)
}
}

return { all, createWord, deleteWord }
})
async function createWord(wordParams: WordParams) {
const newWord = await api.post('words', wordParams)

listStore.all.get(newWord.list_id)?.words?.push(newWord)
all.value.set(newWord.id, newWord)
return newWord
}

async function deleteWord(wordId: number) {
await api.delete(`words/${wordId}`)

all.value.delete(wordId)
}

return { all, wordsForList, fetchWords, createWord, deleteWord }
})
1 change: 1 addition & 0 deletions src/types/word.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export default interface Word {
origin: string
translation: string
proficiency: number
list_id: number
}
41 changes: 20 additions & 21 deletions src/views/List.vue
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
<script setup lang="ts">
import { Ref, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useListStore } from '@/stores/list'
import { useWordStore } from '@/stores/word'
import List from '@/types/list'
import Word from '@/types/word'
import NewWordForm from '@/components/NewWordForm.vue'
import WordListing from '@/components/WordListing.vue'
import ListHeader from '@/components/ListHeader.vue'
const list: Ref<List | null> = ref(null)
const props = defineProps<{ listId: number }>()
const route = useRoute()
const store = useListStore()
const isFetching = ref(true)
watch(
() => route.params.id as string,
async (newId) => {
list.value = await store.fetchList(newId)
},
{ immediate: true }
)
const listStore = useListStore()
const wordStore = useWordStore()
const { getListById } = storeToRefs(listStore)
const { wordsForList } = storeToRefs(wordStore)
wordStore.fetchWords(props.listId).then(() => {
isFetching.value = false
})
</script>
wordStore

<template>
<section v-if="list" class="">
<list-header :list="list" :list-id="list.id" />
<section v-if="!isFetching" class="">
<list-header :list="getListById(listId) as List" />

<h4 v-if="list.words" class="text-h6 ml-4">
words: {{ list.words.length }}
</h4>
<h4 class="text-h6 ml-4">words: {{ wordsForList(listId).length }}</h4>

<new-word-form :list-id="list.id" />
<new-word-form :list-id="listId" />

<word-listing v-if="list.words?.length" :words="list.words as Word[]" />
<word-listing :words="wordsForList(listId) as Word[]" />
</section>
</template>
<style scoped lang="scss"></style>
5 changes: 4 additions & 1 deletion src/views/Lists.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ async function addNewList() {

<div class="container">
<div class="main">
<list v-if="route.params.id"></list>
<list
v-if="route.params.id"
:list-id="parseInt(route.params.id as string)"
></list>
<no-list v-else-if="!isLoading"></no-list>
</div>
</div>
Expand Down

0 comments on commit 0a560b7

Please sign in to comment.