knowyt/client/src/components/admin/PlayersTile.vue

147 lines
4.2 KiB
Vue

<template>
<div>
<AdminInfoTile title="Players" icon-top="reload" @icon-top-click="reload" icon-bottom="add" @icon-bottom-click="addPlayer">
<table class="players-tile__table">
<tr>
<th class="players-tile__table-head">{{ $t('name') }}:</th>
<th class="players-tile__table-head">{{ $t('num-quotes') }}</th>
<th class="players-tile__table-head">{{ $t('score') }}</th>
<th class="players-tile__table-head">{{ $t('last-logged-in') }}</th>
</tr>
<tr v-for="player in players" class="players-tile__row" :key="player.id" @click="editPlayer(player)">
<td class="players-tile__cell">
{{ player.name }}
<div v-if="player.role === 'gamemaster'" class="players-tile__is-gamemaster">
<Icon name="crown" />
</div>
</td>
<td class="players-tile__cell">{{ player.numQuotes }}</td>
<td class="players-tile__cell">{{ player.score }}</td>
<td class="players-tile__cell">{{ !player.isIdle ? 'online' : player.lastLoggedIn === 0 ? '-' : datetime(player.lastLoggedIn) }}</td>
</tr>
</table>
</AdminInfoTile>
<AdminPlayerDialog v-if="showPlayerDialog" :title="playerDialogTitle" :buttons="playerDialogButtons"
:player="playerDialogPlayer" @close="showPlayerDialog = false" @submit="playerDialogSubmit" />
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import useI18n from '@/composables/useI18n'
import useDateFormatter from '@/composables/useDateFormatter'
import useEngine from '@/composables/useEngine'
import { useUserinfoStore } from "@/stores/UserinfoStore"
import type { GameInfo, PlayerEdit } from '@/composables/engine.d'
import type { Button, ButtonAction } from '@/components/admin/PlayerModal'
const props = defineProps<{
gameinfo: GameInfo
}>()
const emit = defineEmits(['update'])
const { $t } = useI18n({
name: { en: 'Name', de: 'Name' },
'num-quotes': { en: '# quotes', de: '# Quotes' },
'score': { en: 'Score', de: 'Score' },
'last-logged-in': { en: 'last logged in', de: 'zuletzt eingeloggt' },
})
const { datetime } = useDateFormatter()
const reload = () => emit('update')
const players = computed(() => {
return props.gameinfo.players.sort((a, b) => a.name.localeCompare(b.name))
})
const showPlayerDialog = ref(false)
const playerDialogPlayer = ref({} as PlayerEdit)
const playerDialogTitle = ref('')
const playerDialogButtons = ref([] as Array<Button>)
const addPlayer = () => {
showPlayerDialog.value = true
playerDialogTitle.value = 'Add new player'
playerDialogButtons.value = [
{ id: 'create', name: 'Create Player', type: 'primary' },
{ id: 'cancel', name: 'Cancel', type: 'normal' },
],
playerDialogPlayer.value = {
id: '',
name: '',
score: 0,
authcode: '',
}
}
const user = useUserinfoStore()
const editPlayer = async (player: PlayerEdit): Promise<void> => {
showPlayerDialog.value = true
playerDialogTitle.value = 'Edit player'
playerDialogButtons.value = [
{ id: 'edit', name: 'Save', type: 'primary' },
]
if (player.id != user.id) {
playerDialogButtons.value.push({ id: 'delete', name: 'Delete', type: 'caution' })
}
playerDialogPlayer.value = {
...player,
}
}
const playerDialogSubmit = async (action: ButtonAction): Promise<void> => {
showPlayerDialog.value = false
switch (action) {
case 'cancel':
break
case 'create':
case 'edit':
await useEngine().savePlayer(playerDialogPlayer.value)
emit('update')
break
case 'delete':
if (confirm(`"${playerDialogPlayer.value.name}" löschen?`)) {
await useEngine().deletePlayer(playerDialogPlayer.value.id)
emit('update')
}
break
}
}
</script>
<style lang="scss">
.players-tile {
&__container {
width: 100%;
height: 100%;
}
&__table {
margin: 0 0 16px 0;
border-spacing: 0;
}
&__table-head {
text-align: left;
padding-right: 8px;
}
&__row {
height: 24px;
cursor: pointer;
&:hover {
background-color: #606060;
}
}
&__cell {
padding-right: 8px;
}
&__is-gamemaster {
display: inline-block;
margin-left: 4px;
width: 16px;
height: 14px;
}
}
</style>