feat: individual transportation types for participants

This commit is contained in:
Björn Fromme
2024-09-09 20:25:55 +02:00
parent 59e6bebdca
commit 3f325df133
4 changed files with 67 additions and 47 deletions
@@ -119,13 +119,17 @@
:participant="participant" :participant="participant"
:mutable="mutableFields.services.mutable" :mutable="mutableFields.services.mutable"
v-on:updated="onParticipantDataUpdated($event, index)"/> v-on:updated="onParticipantDataUpdated($event, index)"/>
<transportation-select :services="services.transportation"
:participant="participant"
:mutable="mutableFields.transportation.mutable"
v-on:updated="onTransportationUpdated($event)"
/>
<pickup-select <pickup-select
:pickups="services.pickups" :pickups="services.pickups"
:participant="participant" :participant="participant"
:mutable="mutableFields.transportation.mutable" :mutable="mutableFields.transportation.mutable"
v-on:selected="onPickupSelected($event, index)" v-on:selected="onPickupSelected($event, index)"
v-if="services.pickups" v-if="services.pickups"
v-show="showPickups"
/> />
</div> </div>
<div class="grid lg:grid-cols-2 gap-4 p-2"> <div class="grid lg:grid-cols-2 gap-4 p-2">
@@ -402,9 +406,14 @@
this.dirty = true; this.dirty = true;
}, },
onTransportationUpdated (event) { onTransportationUpdated (event) {
let factor = event.action === 'select' ? -1 : 1; let services = this.services.transportation
this.services.transportation[event.service.id].available += this.participantData.length * factor; if (event.action === 'select') {
this.bookingData.selectedTransportationIds = event.selectedTransportationIds; services[event.service.id].available--;
} else {
services[event.service.id].available++;
}
this.services.transportation = services
this.dirty = true; this.dirty = true;
}, },
hasSelectedRentals (participant) { hasSelectedRentals (participant) {
@@ -463,7 +472,6 @@
method: 'PUT', method: 'PUT',
body: JSON.stringify({ body: JSON.stringify({
participantData: this.participantData, participantData: this.participantData,
selectedTransportations: this.selectedTransportations,
remarks: this.bookingData.remarks, remarks: this.bookingData.remarks,
}) })
} }
@@ -501,22 +509,6 @@
} }
return filteredContingents; return filteredContingents;
}, },
selectedTransportations () {
let selectedTransportations = [];
for (let id of this.bookingData.selectedTransportationIds) {
selectedTransportations.push(this.services.transportation[id]);
}
return selectedTransportations;
},
showPickups () {
for (let id of this.bookingData.selectedTransportationIds) {
if ('BUS' === this.services.transportation[id].subType) {
return true;
}
}
return false;
},
totalPrice () { totalPrice () {
let totalPrice = 0; let totalPrice = 0;
this.participantData.forEach(participant => { this.participantData.forEach(participant => {
@@ -7,17 +7,17 @@
<svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg> <svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
</button> </button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible"> <div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs space-y-2" v-show="visible">
<input class="form-input w-full" type="text" placeholder="Körpergröße (120-220cm)" <input class="form-input w-full" type="number" placeholder="Körpergröße (140-210cm)"
v-model.number="participant.data.height" :disabled="!mutable" v-model.number="participant.data.height" :disabled="!mutable"
@change="validate(participant.data.height, 120, 220, 'Körpergröße')" @change="validate(participant.data.height, 140, 210, 'Körpergröße')"
> >
<input class="form-input w-full" type="text" placeholder="Schuhgröße (36-50)" <input class="form-input w-full" type="number" placeholder="Schuhgröße (35-49, EU-Größe)"
v-model.number="participant.data.shoeSize" :disabled="!mutable" v-model.number="participant.data.shoeSize" :disabled="!mutable"
@change="validate(participant.data.shoeSize, 36, 50, 'Schuhgröße')" @change="validate(participant.data.shoeSize, 35, 49, 'Schuhgröße')"
> >
<input class="form-input w-full" type="text" placeholder="Gewicht (50 - 200kg)" <input class="form-input w-full" type="number" placeholder="Gewicht (40 - 130kg)"
v-model.number="participant.data.weight" :disabled="!mutable" v-model.number="participant.data.weight" :disabled="!mutable"
@change="validate(participant.data.weight, 50, 200, 'Gewicht')" @change="validate(participant.data.weight, 40, 130, 'Gewicht')"
> >
</div> </div>
</div> </div>
@@ -1,5 +1,5 @@
<template> <template>
<div class="relative" ref="target"> <div class="relative" ref="target" v-show="hasSelectedBus">
<button class="button bg-button button--small" @click.prevent="visible = !visible"> <button class="button bg-button button--small" @click.prevent="visible = !visible">
<span> <span>
Zustieg Zustieg
@@ -47,6 +47,13 @@
pickupId: this.participant.pickupId pickupId: this.participant.pickupId
} }
}, },
computed: {
hasSelectedBus () {
return this.participant.transportations.some((transportation) => {
return 'BUS' === transportation.subType
})
},
},
mounted () { mounted () {
let self = this let self = this
document.addEventListener('click', e => { document.addEventListener('click', e => {
@@ -1,4 +1,15 @@
<template> <template>
<div class="relative" ref="target">
<button class="button bg-button button--small" @click.prevent="visible = !visible">
<span>
Anreise
</span>
<svg class="w-4 h-4" fill="none" :class="{ 'rotate-180': visible }" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
<div class="absolute top-100 left-0 z-50 mt-4 border shadow-md p-4 bg-white w-screen max-w-xs" v-show="visible">
<div class="flex flex-col space-y-2" v-if="hasServices"> <div class="flex flex-col space-y-2" v-if="hasServices">
<label class="flex items-center" <label class="flex items-center"
v-for="service in services" :key="service.id"> v-for="service in services" :key="service.id">
@@ -8,11 +19,11 @@
:value="service.id" :value="service.id"
:disabled="isServiceUnavailable(service) || !mutable" :disabled="isServiceUnavailable(service) || !mutable"
@change="selectService(service, $event)"/> @change="selectService(service, $event)"/>
<span class="ml-2"> <span class="ml-2">{{ service.name }}</span>
{{ service.name }}
</span>
</label> </label>
</div> </div>
</div>
</div>
</template> </template>
<script> <script>
@@ -23,9 +34,9 @@
type: Object, type: Object,
required: true required: true
}, },
initialTransportationIds: { participant: {
type: Array, type: Object,
required: true required: true,
}, },
mutable: { mutable: {
type: Boolean, type: Boolean,
@@ -34,13 +45,20 @@
}, },
data () { data () {
return { return {
selectedTransportationIds: this.initialTransportationIds visible: false,
selectedTransportationIds: this.participant.transportations.map((transportation) => transportation.busproId),
} }
}, },
methods: { methods: {
selectService(service, event) { selectService(service, event) {
// uncheck transportation ids with same direction to make them unique
let direction = service.direction
let serviceIdsToUncheck = Object.entries(this.services).filter(item => direction === item[1].direction && item[1].id !== service.id).map(item => item[1].id)
this.selectedTransportationIds = this.selectedTransportationIds.filter(id => !serviceIdsToUncheck.includes(id))
this.participant.transportations = this.selectedTransportations
let action = event.target.checked ? 'select' : 'unselect'; let action = event.target.checked ? 'select' : 'unselect';
this.$emit('updated', { action, service, selectedTransportationIds: this.selectedTransportationIds }); this.$emit('updated', { action, service });
}, },
isServiceUnavailable(service) { isServiceUnavailable(service) {
return service.available === 0 return service.available === 0
@@ -49,7 +67,10 @@
computed: { computed: {
hasServices() { hasServices() {
return Object.keys(this.services).length > 0; return Object.keys(this.services).length > 0;
} },
selectedTransportations() {
return this.selectedTransportationIds.map((id) => this.services[id])
},
} }
} }
</script> </script>