feat : working UI for words

This commit is contained in:
2024-12-29 19:34:26 +01:00
parent d49813e776
commit 3830ea84c8
23 changed files with 441 additions and 129 deletions
+52
View File
@@ -0,0 +1,52 @@
<script setup lang="ts">
import { useUserStore } from '~/store/user.store';
const userStore = useUserStore();
</script>
<template>
<header>
<div id="self">
<template v-if="userStore.has_contacted">
<ClientOnly>
<template v-if="userStore.self && userStore.self.id">
<User :id="userStore.self.id"></User>
<button>Logout</button>
</template>
<button v-else>Login</button>
</ClientOnly>
</template>
<template v-else>
Contacting server...
</template>
</div>
<div id="links">
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink to="/words">Words</NuxtLink>
</div>
</header>
</template>
<style lang="css" scoped>
header,
header * {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
}
div#self {
height: 32px
}
div#links {
width: 100%;
gap: 1%;
}
</style>
+35
View File
@@ -0,0 +1,35 @@
<script setup lang="ts">
import { fetchUser } from '~/service/user.service';
import { useUserStore } from '~/store/user.store';
export interface Props {
id: string;
}
const userStore = useUserStore();
const props = defineProps<Props>()
const user = await userStore.fetchUser(props.id)
</script>
<template>
<div class="user">
<img class="user-avatar" :src="`https://cdn.discordapp.com/avatars/${user?.id}/${user?.avatar}.webp?size=32`">
{{ user?.username }}
</div>
</template>
<style lang="css">
div.user {
display: flex;
align-items: center;
}
img.user-avatar {
height: 32px;
border-radius: 50%;
}
</style>
+56
View File
@@ -0,0 +1,56 @@
<script setup lang="ts">
import type { WordResponseDTO } from '~/netcode/events/dto/wordresponse.dto';
import { useWordStore } from '~/store/word.store';
export interface Props {
word: WordResponseDTO;
}
const props = defineProps<Props>()
const loading = ref(false)
const wordStore = useWordStore();
async function changeWordState() {
if (loading.value) {
return
}
loading.value = true
let data
if (props.word.enabled) {
data = await wordStore.disableWord(props.word.id)
} else {
data = await wordStore.enableWord(props.word.id)
}
loading.value = false
props.word.enabled = data.enabled
}
</script>
<template>
<div class="word">
<span>{{ word.value }}</span>
<input type="checkbox" :class="{ loading }" :checked="word.enabled" :disabled="loading"
@click.prevent="changeWordState" />
<User :id="word.ownerId"></User>
</div>
</template>
<style lang="css" scoped>
div.word {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
}
input {
min-height: 28px;
}
input.loading {
cursor: wait
}
</style>