feat : word edition
This commit is contained in:
+51
-31
@@ -1,56 +1,76 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { WordResponseDTO } from '~/netcode/events/dto/wordresponse.dto';
|
import type { WordResponseDTO } from "~/netcode/events/dto/wordresponse.dto";
|
||||||
import { useWordStore } from '~/store/word.store';
|
import { useUserStore } from "~/store/user.store";
|
||||||
|
import { useWordStore } from "~/store/word.store";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
word: WordResponseDTO;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const wordStore = useWordStore();
|
const wordStore = useWordStore();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
const word = wordStore.words[props.id];
|
||||||
|
|
||||||
async function changeWordState() {
|
async function changeWordState() {
|
||||||
if (loading.value) {
|
if (word.loading) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true
|
word.loading = true;
|
||||||
let data
|
if (word.enabled) {
|
||||||
if (props.word.enabled) {
|
await wordStore.disableWord(word);
|
||||||
data = await wordStore.disableWord(props.word.id)
|
} else {
|
||||||
} else {
|
await wordStore.enableWord(word);
|
||||||
data = await wordStore.enableWord(props.word.id)
|
}
|
||||||
}
|
word.loading = false;
|
||||||
loading.value = false
|
}
|
||||||
props.word.enabled = data.enabled
|
|
||||||
|
|
||||||
|
async function deleteWord() {
|
||||||
|
if (word.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
word.loading = true;
|
||||||
|
try {
|
||||||
|
await wordStore.deleteWord(word);
|
||||||
|
} finally {
|
||||||
|
word.loading = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="word">
|
<div class="word">
|
||||||
<span>{{ word.value }}</span>
|
<span>{{ word.value }}</span>
|
||||||
<input type="checkbox" :class="{ loading }" :checked="word.enabled" :disabled="loading"
|
<input
|
||||||
@click.prevent="changeWordState" />
|
type="checkbox"
|
||||||
<User :id="word.ownerId"></User>
|
:checked="word.enabled"
|
||||||
|
:disabled="word.loading || !userStore.self"
|
||||||
</div>
|
@click.prevent="changeWordState"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
:disabled="word.loading || !userStore.self"
|
||||||
|
type="button"
|
||||||
|
@click="deleteWord"
|
||||||
|
value="Delete"
|
||||||
|
/>
|
||||||
|
<User :id="word.ownerId"></User>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
div.word {
|
div.word {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
min-height: 28px;
|
min-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.loading {
|
input:disabled {
|
||||||
cursor: wait
|
cursor: wait;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
+1
-1
Submodule netcode/events updated: fff2abf0a1...72935ba3f5
+46
-6
@@ -1,10 +1,38 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useWordStore } from "~/store/word.store";
|
||||||
|
|
||||||
import { useWordStore } from '~/store/word.store';
|
const newWord = ref("");
|
||||||
|
|
||||||
const wordStore = useWordStore();
|
const wordStore = useWordStore();
|
||||||
|
|
||||||
await wordStore.fetchWordList()
|
await wordStore.fetchWordList();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const wordInput = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
async function createWord(e: Event) {
|
||||||
|
if (loading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
await wordStore.createWord(newWord.value);
|
||||||
|
newWord.value = "";
|
||||||
|
} finally {
|
||||||
|
nextTick(() => {
|
||||||
|
loading.value = false;
|
||||||
|
nextTick(() => {
|
||||||
|
wordInput.value?.focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// watch(wordInput, (e) =>
|
||||||
|
// setInterval(() => {
|
||||||
|
// // e.focus();
|
||||||
|
// console.log(wordInput.value);
|
||||||
|
// }, 1000)
|
||||||
|
// );
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -12,11 +40,23 @@ await wordStore.fetchWordList()
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<span>Word</span>
|
<span>Word</span>
|
||||||
<span>Status</span>
|
<span>Status</span>
|
||||||
|
<span></span>
|
||||||
<span>Submitter</span>
|
<span>Submitter</span>
|
||||||
</div>
|
</div>
|
||||||
<Word v-for="word in wordStore.words" :word="word" />
|
<Word v-for="word in wordStore.words" :id="word.id" :key="word.id" />
|
||||||
|
<div class="new-word">
|
||||||
|
<span>
|
||||||
|
<input
|
||||||
|
ref="wordInput"
|
||||||
|
type="text"
|
||||||
|
:disabled="loading"
|
||||||
|
@keypress.enter="createWord"
|
||||||
|
v-model="newWord"
|
||||||
|
/>
|
||||||
|
<button :disabled="loading" @click="createWord">Submit</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
@@ -27,7 +67,7 @@ div#words {
|
|||||||
|
|
||||||
div.header {
|
div.header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
+25
-4
@@ -19,21 +19,42 @@ export const useWordStore = defineStore("word", {
|
|||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
async enableWord(id: number) {
|
async enableWord(word: WordResponseDTO) {
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/` + id + "/enable", {
|
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/` + word.id + "/enable", {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
method: "PUT"
|
method: "PUT"
|
||||||
})
|
})
|
||||||
|
word.enabled = true
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
async disableWord(id: number) {
|
async disableWord(word: WordResponseDTO) {
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/` + id + "/disable", {
|
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/` + word.id + "/disable", {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
method: "PUT"
|
method: "PUT"
|
||||||
})
|
})
|
||||||
|
word.enabled = false
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
async createWord(value: string) {
|
||||||
|
const config = useRuntimeConfig();
|
||||||
|
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/`, {
|
||||||
|
credentials: "include",
|
||||||
|
body: { value },
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
this.words[data.id] = data
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async deleteWord(word: WordResponseDTO){
|
||||||
|
const config = useRuntimeConfig();
|
||||||
|
const data = await $fetch<WordResponseDTO>(config.public.endpoint + `/words/`+word.id, {
|
||||||
|
credentials: "include",
|
||||||
|
method: "DELETE"
|
||||||
|
})
|
||||||
|
delete this.words[word.id]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user