216 lines
8.0 KiB
Vue
216 lines
8.0 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="submitModalForm" 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">Tijd {{ modelData.eventName }}</h1>
|
|
|
|
<label class="font-bold">Locatie</label>
|
|
<input :disabled="!userData.wedstrijdAdmin" v-model="modelData.contest.location" type="text" class="input dark:bg-neutral-700 bg-neutral-300 mb-5" />
|
|
|
|
<label class="font-bold">Datum</label>
|
|
<input :disabled="!userData.wedstrijdAdmin" :value="dateToYYYYMMDD(modelData.contest.date)" @input="modelData.contest.date = $event.target.valueAsDate" required="true" class="input dark:bg-neutral-700 bg-neutral-300 w-min hover:cursor-pointer pr-0 mb-5 " type="date">
|
|
|
|
<label class="font-bold">Type zwembad</label>
|
|
<select :disabled="!userData.wedstrijdAdmin" v-model="modelData.contest.type" required="true" class="input dark:bg-neutral-700 bg-neutral-300 mb-5">
|
|
<option value="50m">50 Meter</option>
|
|
<option value="25m">25 Meter</option>
|
|
</select>
|
|
|
|
<label class="font-bold">Tijd</label>
|
|
<div class="mb-1">
|
|
<input :disabled="!userData.wedstrijdAdmin" 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 :disabled="!userData.wedstrijdAdmin" 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 :disabled="!userData.wedstrijdAdmin" 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 :disabled="!userData.wedstrijdAdmin" type="checkbox" v-model="modelData.dsq" class="mr-1 checkbox">
|
|
<span class="text-default">Diskwalificatie</span>
|
|
</div>
|
|
|
|
<label class="font-bold">Info </label>
|
|
<input :disabled="!userData.wedstrijdAdmin" v-model="modelData.info" type="text" placeholder="Bijv. Een diskwalificatie" class="input dark:bg-neutral-700 bg-neutral-300 mb-10" />
|
|
|
|
<input v-if="userData.wedstrijdAdmin" :disabled="disableButtons" type="submit" class="btn" value="Bewerken" />
|
|
</form>
|
|
</div>
|
|
<div v-if="timings[0]" class="flex flex-col justify-center items-center gap-y-3 px-2 overflow-hidden">
|
|
<div v-for="event in events" class="container w-full max-w-md py-2 px-4">
|
|
<div @click="event.open = !event.open" class="flex hover:cursor-pointer">
|
|
<h2 class="font-bold">{{ event.name }}</h2>
|
|
<span v-if="timings.filter(a => a.event === event.id).length > 0" class="ml-auto">{{ filteredTimings.filter(a => a.event === event.id)[0].time.minutes }}:{{ filteredTimings.filter(a => a.event === event.id)[0].time.seconds }}:{{ filteredTimings.filter(a => a.event === event.id)[0].time.milliseconds }}</span>
|
|
<span v-else class="ml-auto">Geen tijd</span>
|
|
<Icon size="1.2em" name="ion:arrow-down-b" class="my-auto ml-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/7">Tijd</th>
|
|
<th class="w-1/7">Datum</th>
|
|
<th class="w-3/7">Type</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr @click="handleModel(time, event, index)" v-for="(time, index) in filteredTimings.filter(a => a.event === event.id)" class="even:dark:bg-neutral-700 even:bg-neutral-300 hover:cursor-pointer">
|
|
<td class="pl-1" :class="time.dsq ? 'line-through' : ''">{{ time.time.minutes }}:{{ time.time.seconds }}:{{ time.time.milliseconds}}</td>
|
|
<td>{{ time.contest.date.toLocaleDateString('nl-NL') }}</td>
|
|
<td>{{ time.contest.type }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { collection, query, where, getDocs, doc, updateDoc} from "firebase/firestore";
|
|
import { useToast } from 'vue-toastification'
|
|
|
|
definePageMeta({
|
|
title: 'Eigen Tijden',
|
|
key: 'back'
|
|
})
|
|
|
|
const { db, userData } = inject('firebase')
|
|
const toast = useToast()
|
|
|
|
const timings = ref([])
|
|
const showModel = ref(false)
|
|
const disableButtons = ref(false)
|
|
|
|
const filteredTimings = computed(() => {
|
|
timings.value = timings.value.sort((a, b) => a.time.combined.localeCompare(b.time.combined))
|
|
timings.value.forEach((time, index) => {
|
|
if (time.dsq === true) {
|
|
timings.value.push(timings.value.splice(index, 1)[0])
|
|
}
|
|
})
|
|
return timings.value
|
|
})
|
|
|
|
const modelData = ref({
|
|
time: {
|
|
minutes: null,
|
|
seconds: null,
|
|
milliseconds: null,
|
|
},
|
|
dsq: false,
|
|
info: '',
|
|
contest: {
|
|
type: '',
|
|
location: '',
|
|
date: '',
|
|
}
|
|
})
|
|
|
|
const events = ref({
|
|
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: [],
|
|
},
|
|
})
|
|
|
|
onMounted(async () => {
|
|
const citiesRef = collection(db, "timings");
|
|
|
|
const q = query(citiesRef, where("relatiecode", "in", userData.value.relatiecodes ));
|
|
|
|
const querySnapshot = await getDocs(q);
|
|
|
|
querySnapshot.forEach((doc) => {
|
|
// doc.data() is never undefined for query doc snapshots
|
|
const data = doc.data()
|
|
data.id = doc.id
|
|
|
|
data.contest.date = data.contest.date.toDate()
|
|
|
|
timings.value.push(data)
|
|
});
|
|
|
|
timings.value = timings.value.sort((a, b) => a.time.combined.localeCompare(b.time.combined))
|
|
})
|
|
|
|
|
|
const handleModel = (competitor, e, index) => {
|
|
modelData.value = competitor
|
|
modelData.value.index = index
|
|
modelData.value.eventId = e.id
|
|
showModel.value = true
|
|
}
|
|
|
|
const dateToYYYYMMDD = (d) => {
|
|
return d && new Date(d.getTime()-(d.getTimezoneOffset()*60*1000)).toISOString().split('T')[0]
|
|
}
|
|
|
|
const submitModalForm = async () => {
|
|
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 id = modelData.value.id
|
|
|
|
delete modelData.value.index
|
|
delete modelData.value.eventId
|
|
delete modelData.value.id
|
|
|
|
disableButtons.value = true
|
|
const combinedTime = modelData.value.time.minutes.toString().padStart(2, '0') + modelData.value.time.seconds.toString().padStart(2, '0') + modelData.value.time.milliseconds.toString().padStart(2, '0')
|
|
modelData.value.time.combinedTime = combinedTime
|
|
|
|
const docRef = doc(db, "timings", id);
|
|
|
|
await updateDoc(docRef, modelData.value);
|
|
|
|
toast.success('Tijd is bewerkt')
|
|
showModel.value = false
|
|
disableButtons.value = false
|
|
}
|
|
</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>
|