feat: add create team dialog
This commit is contained in:
parent
2fb3833dd8
commit
c6f09831e3
@ -1,28 +1,41 @@
|
||||
<template>
|
||||
<template v-if="authcode">
|
||||
<ModalDialog :no-close-button="true" @close="closeModalDialog">
|
||||
<div class="create-team-dialog__auth-message">{{ $t('pin') }}</div>
|
||||
<div class="create-team-dialog__pin">{{ authcode }}</div>
|
||||
<div class="create-team-dialog__auth-message">{{ $t('remember-and-log-in') }}</div>
|
||||
<div class="create-team-dialog__login-box">
|
||||
<LoginBox />
|
||||
</div>
|
||||
</ModalDialog>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ModalDialog @close="closeModalDialog" :title="$t('create-team')">
|
||||
<div class="create-team-dialog__description">{{ $t('description') }}</div>
|
||||
<div class="create-team-dialog__form">
|
||||
<label class="create-team-dialog__label">{{ $t('your-name') }}</label>
|
||||
<input id="create-team-dialog-name" class="create-team-dialog__input" v-model="playerName" size="40"/>
|
||||
<input id="create-team-dialog-name" class="create-team-dialog__input" v-model="playerName" size="40" />
|
||||
<label class="create-team-dialog__label">{{ $t('team-name') }}</label>
|
||||
<input class="create-team-dialog__input" v-model="teamName" size="40"/>
|
||||
<input class="create-team-dialog__input" v-model="teamName" size="40" />
|
||||
<label class="create-team-dialog__label">{{ $t('language') }}</label>
|
||||
<select class="create-team-dialog__select" v-model="lang">
|
||||
<option value="en">EN</option>
|
||||
<option value="de">DE</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<template v-slot:footer>
|
||||
<Button class="create-team-dialog__button" :border="true" @click="createTeam">{{ $t('create-team') }}</Button>
|
||||
<Button class="create-team-dialog__button" :border="false" @click="closeModalDialog">{{ $t('cancel') }}</Button>
|
||||
</template>
|
||||
</ModalDialog>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import useI18n from '@/composables/useI18n'
|
||||
import useEngine from '../composables/useEngine';
|
||||
import LoginBox from './LoginBox.vue';
|
||||
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
@ -34,19 +47,35 @@ const { $t, getLang } = useI18n({
|
||||
'team-name': { en: 'Team name', de: 'Teamname' },
|
||||
'language': { en: 'Language', de: 'Sprache' },
|
||||
'names-missing': { en: 'Please enter a user name and a team name.', de: 'Bitte wähle einen Benutzernamen und Teamnamen.' },
|
||||
'failed-to-create': { en: 'Failed to create team, sorry. Please contact Settel to investigate.', de: 'Team konnte nicht angelegt werden. Bitte kontaktiere Settel zur genaueren Untersuchung.' },
|
||||
'pin': { en: 'Your pin code is:', de: 'Deine PIN lautet:' },
|
||||
'remember-and-log-in': { en: 'Write it down now, then log in with your pin code.', de: 'Schreibe sie Dir gleich auf und logge dich anschließend damit ein.' },
|
||||
})
|
||||
|
||||
const closeModalDialog = () => { emit('close') }
|
||||
const playerName = ref('')
|
||||
const teamName = ref('')
|
||||
const lang = ref(getLang())
|
||||
const authcode = ref('')
|
||||
|
||||
const createTeam = () => {
|
||||
const createTeam = async (): Promise<void> => {
|
||||
if (playerName.value.length == 0 || teamName.value.length == 0) {
|
||||
alert($t('names-missing'))
|
||||
return
|
||||
}
|
||||
alert('not yet implemented')
|
||||
|
||||
const status = await useEngine().createGame(
|
||||
playerName.value,
|
||||
teamName.value,
|
||||
lang.value,
|
||||
)
|
||||
|
||||
if (status.status !== 'ok') {
|
||||
alert($t('failed-to-create'))
|
||||
return
|
||||
}
|
||||
|
||||
authcode.value = status.authcode
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -90,5 +119,25 @@ onMounted(() => {
|
||||
&__button~&__button {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
&__auth-message {
|
||||
font-family: $font-secondary;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
margin: 32px;
|
||||
}
|
||||
|
||||
&__pin {
|
||||
font-family: $font-secondary;
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__login-box {
|
||||
display: flex;
|
||||
margin-top: 96px;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -3,7 +3,7 @@
|
||||
<div class="modal-dialog__box">
|
||||
<div class="modal-dialog__header">
|
||||
<div class="modal-dialog__title">{{ title }}</div>
|
||||
<Button :border="false" @click="emit('close')">x</Button>
|
||||
<Button v-if="!noCloseButton" :border="false" @click="emit('close')">x</Button>
|
||||
</div>
|
||||
<div class="modal-dialog__body">
|
||||
<slot />
|
||||
@ -19,6 +19,7 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title?: string
|
||||
noCloseButton?: boolean
|
||||
}>()
|
||||
const emit = defineEmits(['close'])
|
||||
</script>
|
||||
@ -55,21 +56,21 @@ const emit = defineEmits(['close'])
|
||||
|
||||
&__title {
|
||||
flex-grow: 1;
|
||||
margin: 16px 16px 8px 16px;
|
||||
margin: 36px 36px 8px 36px;
|
||||
font-family: $font-primary;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
&__body {
|
||||
flex-grow: 1;
|
||||
margin: 16px;
|
||||
margin: 36px;
|
||||
font-family: $font-secondary;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
// justify-content: end;
|
||||
margin: 24px 16px;
|
||||
margin: 24px 36px;
|
||||
}
|
||||
|
||||
&__backdrop {
|
||||
|
@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<ModalDialog :title="title" @close="emit('close')">
|
||||
<label class="player-dialog__label">Name</label>
|
||||
<input id="player-dialog-name" class="player-dialog__input" v-model="player.name" size="40"/>
|
||||
<input id="player-dialog-name" class="player-dialog__input" v-model="player.name" size="60" />
|
||||
<label class="player-dialog__label">Score</label>
|
||||
<input class="player-dialog__input" v-model="player.score" size="40" maxlength="4" />
|
||||
<input class="player-dialog__input" v-model="player.score" size="60" maxlength="4" />
|
||||
<label class="player-dialog__label">Authcode</label>
|
||||
<div class="player-dialog__input-box">
|
||||
<input class="player-dialog__input" v-model="player.authcode" size="10" maxlength="6" />
|
||||
<Button :border="false" css-class="mini" @click="generate">generate</Button>
|
||||
<input class="player-dialog__input" v-model="player.authcode" size="40" maxlength="6" />
|
||||
<Button class="player-dialog__generate" :border="false" css-class="mini" @click="generate">generate</Button>
|
||||
</div>
|
||||
<div class="player-dialog__id-container" @click="showId = true">
|
||||
<span class="player-dialog__id" :class="{ 'player-dialog__id__show': showId }">{{ player.id }}</span>
|
||||
</div>
|
||||
<template v-slot:footer>
|
||||
<Button v-for="button in buttons" :key="button.id" class="player-dialog__button"
|
||||
:css-class="button.type === 'caution' ? button.type : ''" :border="['primary', 'caution'].indexOf(button.type) >= 0"
|
||||
@click="emit('submit', button.id)">{{ button.name
|
||||
:css-class="button.type === 'caution' ? button.type : ''"
|
||||
:border="['primary', 'caution'].indexOf(button.type) >= 0" @click="emit('submit', button.id)">{{ button.name
|
||||
}}</Button>
|
||||
</template>
|
||||
</ModalDialog>
|
||||
@ -76,6 +76,14 @@ const generate = () => {
|
||||
}
|
||||
}
|
||||
|
||||
&__input-box {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__generate {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
&__button~&__button {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
@ -29,8 +29,9 @@
|
||||
<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 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'
|
||||
|
||||
@ -70,13 +71,17 @@ const addPlayer = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const user = useUserinfoStore()
|
||||
|
||||
const editPlayer = async (player: PlayerEdit): Promise<void> => {
|
||||
showPlayerDialog.value = true
|
||||
playerDialogTitle.value = 'Edit player'
|
||||
playerDialogButtons.value =[
|
||||
playerDialogButtons.value = [
|
||||
{ id: 'edit', name: 'Save', type: 'primary' },
|
||||
{ id: 'delete', name: 'Delete', type: 'caution' },
|
||||
]
|
||||
if (player.id != user.id) {
|
||||
playerDialogButtons.value.push({ id: 'delete', name: 'Delete', type: 'caution' })
|
||||
}
|
||||
playerDialogPlayer.value = {
|
||||
...player,
|
||||
}
|
||||
|
5
client/src/composables/engine.d.ts
vendored
5
client/src/composables/engine.d.ts
vendored
@ -75,3 +75,8 @@ export type GameInfo = {
|
||||
numQuotesLeft: number
|
||||
numQuotesTotal: number
|
||||
}
|
||||
|
||||
export type CreateGameStatus = {
|
||||
status: string
|
||||
authcode: string
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { EngineContext } from '@/composables/useEngine'
|
||||
import type { GameInfo, PlayerEdit } from '@/composables/engine.d'
|
||||
import { useUserinfoStore } from "@/stores/UserinfoStore"
|
||||
import type { GameInfo, PlayerEdit, Lang, CreateGameStatus } from '@/composables/engine.d'
|
||||
|
||||
export async function fetchGameInfo(this: EngineContext): Promise<GameInfo> {
|
||||
const userInfoStore = useUserinfoStore()
|
||||
@ -44,3 +44,10 @@ export async function deletePlayer(this: EngineContext, id: string): Promise<voi
|
||||
})
|
||||
}
|
||||
|
||||
export async function createGame(this: EngineContext, name: string, teamname: string, lang: Lang): Promise<CreateGameStatus> {
|
||||
return await this.callApi('/api/createGame', {
|
||||
name,
|
||||
teamname,
|
||||
lang,
|
||||
}) as CreateGameStatus
|
||||
}
|
@ -3,10 +3,10 @@ import { callApi, QueryParams } from '@/composables/engine/callApi'
|
||||
import { start, stop } from '@/composables/engine/startStop'
|
||||
import { fetchUpdate } from '@/composables/engine/fetchUpdate'
|
||||
import { loadQuotes, getQuotesRef, deleteQuote, saveQuote } from '@/composables/engine/quotes'
|
||||
import { fetchGameInfo, setGameLang, setGameName, savePlayer, deletePlayer } from '@/composables/engine/gamemaster'
|
||||
import { fetchGameInfo, setGameLang, setGameName, savePlayer, deletePlayer, createGame } from '@/composables/engine/gameManagement'
|
||||
import { collectQuotes, startGame, continueGame, resetGame, finishGame } from '@/composables/engine/gameState'
|
||||
import { saveSelection } from '@/composables/engine/play'
|
||||
import type { Quotes, GameInfo, PlayerEdit } from '@/composables/engine.d'
|
||||
import type { Quotes, GameInfo, PlayerEdit, Lang, CreateGameStatus } from '@/composables/engine.d'
|
||||
|
||||
export interface EngineContext {
|
||||
isActive: boolean
|
||||
@ -42,6 +42,7 @@ export interface useEngine {
|
||||
setGameName: (name: string) => Promise<void>
|
||||
savePlayer: (player: PlayerEdit) => Promise<void>
|
||||
deletePlayer: (id: string) => Promise<void>
|
||||
createGame: (name: string, teamname: string, lang: Lang) => Promise<CreateGameStatus>
|
||||
}
|
||||
|
||||
export default (): useEngine => {
|
||||
@ -80,5 +81,6 @@ export default (): useEngine => {
|
||||
setGameName: (name: string) => setGameName.apply(context, [name]),
|
||||
savePlayer: (player: PlayerEdit) => savePlayer.apply(context, [player]),
|
||||
deletePlayer: (id: string) => deletePlayer.apply(context, [id]),
|
||||
createGame: (name: string, teamname: string, lang: Lang) => createGame.apply(context, [name, teamname, lang]),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user