wrbapp/frontend/pages/wedstrijd/addcontest.vue
xeovalyte 25d6e63d32
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
added all times
2023-02-10 13:55:18 +01:00

241 lines
8.8 KiB
Vue

<template>
<div @click.self="showModel = false" v-if="showModel" class="fixed flex justify-center items-center h-screen w-full bg-black top-0 left-0 z-50 bg-opacity-50" >
<form @submit.prevent="submitModelForm" class="dark:bg-neutral-800 bg-neutral-200 p-10 rounded-xl flex flex-col w-full max-w-sm">
<h1 class="font-bold text-center text-lg mb-5">Deelnemer Toevoegen</h1>
<label class="font-bold text-default">Deelnemer</label>
<select :disabled="modelData.edit" required v-model="modelData.relatiecode" class="input dark:bg-neutral-700 bg-neutral-300 mb-5">
<option v-if="!modelData.edit" v-for="user in competitors.filter(x => !contest.events[modelData.event].competitors.map(y => y.relatiecode).includes(x.relatiecode))" :value="user.relatiecode">{{ user.name}} ({{ user.relatiecode }})</option>
<option v-else v-for="user in competitors" :value="user.relatiecode">{{ user.name}} ({{ user.relatiecode }})</option>
</select>
<label class="font-bold text-default">Tijd</label>
<div class="mb-1">
<input v-model="modelData.time.minutes" type="number" step="1" min="0" max="99" placeholder="mm" class="input dark:bg-neutral-700 bg-neutral-300 w-10 text-center p-1" />
<span class="text-default text-xl font-bold mx-1">:</span>
<input v-model="modelData.time.seconds" type="number" step="1" min="0" max="99" placeholder="ss" class="input dark:bg-neutral-700 bg-neutral-300 w-10 text-center p-1" />
<span class="text-default text-xl font-bold mx-1">:</span>
<input v-model="modelData.time.milliseconds" type="number" step="1" min="0" max="99" placeholder="ms" class="input dark:bg-neutral-700 bg-neutral-300 w-10 text-center p-1" />
</div>
<div class="flex items-center mb-5">
<input type="checkbox" v-model="modelData.dsq" class="mr-1 checkbox">
<span class="text-default">Diskwalificatie</span>
</div>
<label class="font-bold">Info (Optioneel)</label>
<input v-model="modelData.info" type="text" placeholder="Bijv. Een diskwalificatie" class="input dark:bg-neutral-700 bg-neutral-300 mb-10" />
<input :disabled="disableButtons" type="submit" class="btn" :value="modelData.edit ? 'Bewerken' : 'Toevoegen'" />
</form>
</div>
<div class="flex flex-col gap-5 mx-auto p-2 w-full max-w-md">
<form @submit.prevent="submitContestForm" class="flex flex-col">
<label class="font-bold">Naam Wedstrijd</label>
<input v-model="contest.name" required="true" class="input mb-5 " type="text">
<label class="font-bold">Type Zwembad</label>
<select v-model="contest.type" required="true" class="input mb-5 " type="text">
<option value="50m">50 Meter</option>
<option value="25m">25 Meter</option>
</select>
<label class="font-bold">Datum</label>
<input v-model="contest.date" required="true" class="input w-min hover:cursor-pointer pr-0 mb-5 " type="date">
<label class="font-bold">Onderdelen</label>
<div class="flex flex-col gap-y-3">
<div v-if="competitors" v-for="event in contest.events" class="container p-2">
<div @click="event.open = !event.open" class="flex hover:cursor-pointer">
<h2 class="font-bold">{{ event.name }}</h2>
<Icon size="1.2em" name="ion:arrow-down-b" class="ml-auto my-auto mr-2 transition-all" :class="{'rotate-180' : event.open }" />
</div>
<div v-if="event.open" class="mt-2">
<table class="table-fixed text-left w-full even:bg-gray-500">
<thead class="font-bold">
<tr>
<th class="w-3/6">Naam</th>
<th class="w-2/6">Tijd</th>
<th class="w-1/6">DSQ</th>
</tr>
</thead>
<tbody>
<tr @click="handleModel(competitor, event.id, true, index)" v-for="(competitor, index) in event.competitors" class="even:dark:bg-neutral-700 even:bg-neutral-300 hover:cursor-pointer">
<td class="py-1 pl-1">{{ competitors.find(x => x.relatiecode === competitor.relatiecode ).name }}</td>
<td>{{ competitor.time.minutes.toString().padStart(2, '0') }}:{{ competitor.time.seconds.toString().padStart(2, '0') }}:{{ competitor.time.milliseconds.toString().padStart(2, '0') }}</td>
<td>{{ competitor.dsq }}</td>
</tr>
<tr v-if="competitors.filter(x => !event.competitors.map(y => y.relatiecode).includes(x.relatiecode)).length > 0" class="even:dark:bg-neutral-700 even:bg-neutral-300">
<td @click="handleModel(null, event.id)" class="hover:cursor-pointer py-1 pl-1">+ Deelnemer toevoegen</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<input :disabled="disableButtons" type="submit" class="btn mt-10 px-5 w-min mx-auto" value="Wedstrijd toevoegen" />
</form>
</div>
</template>
<script setup>
import { getDocs, collection, writeBatch, doc } from "firebase/firestore"
import { useToast } from 'vue-toastification'
definePageMeta({
title: 'Wedstrijd Toevoegen',
key: 'back'
})
const toast = useToast()
const { db, competitors } = inject('firebase')
const showModel = ref(false)
const disableButtons = ref(false)
const modelData = ref({
relatiecode: '',
time: {
minutes: null,
seconds: null,
milliseconds: null,
},
dsq: false,
info: '',
})
const contest = ref({
name: '',
type: '',
date: '',
events: {
obstacleSwim: {
open: false,
name: '200m Obstacle Swim',
id: 'obstacleSwim',
competitors: [],
},
manikinCarry: {
open: false,
name: '50m Manikin Carry',
id: 'manikinCarry',
competitors: [],
},
rescueMedley: {
open: false,
name: '100m Rescue Medley',
id: 'rescueMedley',
competitors: [],
},
manikinCarryWithFins: {
open: false,
name: '100m Manikin Carry with Fins',
id: 'manikinCarryWithFins',
competitors: [],
},
manikinTowWithFins: {
open: false,
name: '100m Manikin Tow with Fins',
id: 'manikinTowWithFins',
competitors: [],
},
superLifesaver: {
open: false,
name: '200m Super Lifesaver',
id: 'superLifesaver',
competitors: [],
},
}
})
const getCompetitors = async () => {
if (competitors.value[0]) return
const querySnapshot = await getDocs(collection(db, "competitors"))
querySnapshot.forEach((doc) => {
competitors.value.push(doc.data())
})
}
const handleModel = (competitor, event, edit, index) => {
if(!competitor) competitor = {
relatiecode: '',
time: {
minutes: null,
seconds: null,
milliseconds: null,
},
dsq: false,
info: '',
}
modelData.value = competitor
modelData.value.event = event
modelData.value.edit = edit
modelData.value.index = index
showModel.value = true
}
const submitModelForm = () => {
if (!modelData.value.time.minutes) modelData.value.time.minutes = 0
if (!modelData.value.time.seconds) modelData.value.time.seconds = 0
if (!modelData.value.time.milliseconds) modelData.value.time.milliseconds = 0
const index = modelData.value.index
const edit = modelData.value.edit
delete modelData.value.index
delete modelData.value.edit
if (!edit) contest.value.events[modelData.value.event].competitors.push(modelData.value)
showModel.value = false
}
const submitContestForm = async () => {
disableButtons.value = true
const batch = writeBatch(db)
Object.values(contest.value.events).forEach(event => {
event.competitors.forEach(competitor => {
const combinedTime = competitor.time.minutes.toString().padStart(2, '0') + competitor.time.seconds.toString().padStart(2, '0') + competitor.time.milliseconds.toString().padStart(2, '0')
const docRef = doc(collection(db, 'timings'))
batch.set(docRef, {
relatiecode: competitor.relatiecode,
contest: { name: contest.value.name, date: contest.value.date.toString(), type: contest.value.type },
event: event.id,
time: { minutes: competitor.time.minutes.toString().padStart(2, '0'), seconds: competitor.time.seconds.toString().padStart(2, '0'), milliseconds: competitor.time.milliseconds.toString().padStart(2, '0'), combined: combinedTime },
dsq: competitor.dsq,
info: competitor.info || ''
})
})
})
await batch.commit()
disableButtons.value = false
toast.success('Wedstrijd is toegevoegd')
navigateTo('/wedstrijd')
}
onMounted(() => {
getCompetitors()
})
</script>
<style scoped>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
appearance: textfield;
}
</style>