Redesign seat map layout

This commit is contained in:
2024-10-10 14:11:09 +02:00
parent 23b9fa3dd2
commit 8d78a9eeb7
14 changed files with 1967 additions and 90 deletions

View File

@@ -10,6 +10,7 @@
"address": "Ferdinand-Wilhelm-Fricke-Weg 8", "address": "Ferdinand-Wilhelm-Fricke-Weg 8",
"imageIndoor": "locations/swiss-life-hall-indoor.jpg", "imageIndoor": "locations/swiss-life-hall-indoor.jpg",
"imageOutdoor": "locations/swiss-life-hall-outdoor.jpg", "imageOutdoor": "locations/swiss-life-hall-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -60,6 +61,7 @@
"address": "Schwarzer Bär 2", "address": "Schwarzer Bär 2",
"imageIndoor": "locations/capitol-indoor.jpg", "imageIndoor": "locations/capitol-indoor.jpg",
"imageOutdoor": "locations/capitol-outdoor.jpg", "imageOutdoor": "locations/capitol-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -75,6 +77,7 @@
"address": "EXPO-Plaza 7", "address": "EXPO-Plaza 7",
"imageIndoor": "locations/zag-arena-indoor.jpg", "imageIndoor": "locations/zag-arena-indoor.jpg",
"imageOutdoor": "locations/zag-arena-outdoor.jpg", "imageOutdoor": "locations/zag-arena-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -116,6 +119,27 @@
"standingArea": false, "standingArea": false,
"rows": 3, "rows": 3,
"capacity": 12 "capacity": 12
},
{
"name": "G",
"surcharge": 10,
"standingArea": false,
"rows": 3,
"capacity": 30
},
{
"name": "H",
"surcharge": 10,
"standingArea": false,
"rows": 3,
"capacity": 12
},
{
"name": "I",
"surcharge": 10,
"standingArea": false,
"rows": 3,
"capacity": 12
} }
] ]
}, },
@@ -125,6 +149,7 @@
"address": "Zur Bettfedernfabrik 3", "address": "Zur Bettfedernfabrik 3",
"imageIndoor": "locations/faust-hannover-indoor.jpg", "imageIndoor": "locations/faust-hannover-indoor.jpg",
"imageOutdoor": "locations/faust-hannover-outdoor.jpg", "imageOutdoor": "locations/faust-hannover-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -146,6 +171,7 @@
"address": "Spiridon-Louis-Ring 21", "address": "Spiridon-Louis-Ring 21",
"imageIndoor": "locations/olympiahalle-munich-indoor.jpg", "imageIndoor": "locations/olympiahalle-munich-indoor.jpg",
"imageOutdoor": "locations/olympiahalle-munich-outdoor.jpg", "imageOutdoor": "locations/olympiahalle-munich-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -196,6 +222,7 @@
"address": "Zenettistraße 9", "address": "Zenettistraße 9",
"imageIndoor": "locations/schlachthof-munich-indoor.jpg", "imageIndoor": "locations/schlachthof-munich-indoor.jpg",
"imageOutdoor": "locations/schlachthof-munich-outdoor.jpg", "imageOutdoor": "locations/schlachthof-munich-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -211,6 +238,7 @@
"address": "Zellstraße 4", "address": "Zellstraße 4",
"imageIndoor": "locations/muffatwerk-indoor.jpg", "imageIndoor": "locations/muffatwerk-indoor.jpg",
"imageOutdoor": "locations/muffatwerk-outdoor.jpg", "imageOutdoor": "locations/muffatwerk-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -232,19 +260,20 @@
"address": "Sylvesterallee 7", "address": "Sylvesterallee 7",
"imageIndoor": "locations/volksparkstadion-hamburg-indoor.jpg", "imageIndoor": "locations/volksparkstadion-hamburg-indoor.jpg",
"imageOutdoor": "locations/volksparkstadion-hamburg-outdoor.jpg", "imageOutdoor": "locations/volksparkstadion-hamburg-outdoor.jpg",
"layout": 3,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
"surcharge": 20, "surcharge": 30,
"standingArea": true, "standingArea": true,
"capacity": 50 "capacity": 50
}, },
{ {
"name": "B", "name": "B",
"surcharge": 10, "surcharge": 20,
"standingArea": false, "standingArea": false,
"rows": 5, "rows": 5,
"capacity": 25 "capacity": 50
}, },
{ {
"name": "C", "name": "C",
@@ -255,24 +284,45 @@
}, },
{ {
"name": "D", "name": "D",
"surcharge": 10, "surcharge": 20,
"standingArea": false, "standingArea": false,
"rows": 3, "rows": 5,
"capacity": 20 "capacity": 30
}, },
{ {
"name": "E", "name": "E",
"surcharge": 10, "surcharge": 10,
"standingArea": false, "standingArea": false,
"rows": 3, "rows": 5,
"capacity": 16 "capacity": 25
}, },
{ {
"name": "F", "name": "F",
"surcharge": 20,
"standingArea": false,
"rows": 5,
"capacity": 50
},
{
"name": "G",
"surcharge": 10, "surcharge": 10,
"standingArea": false, "standingArea": false,
"rows": 3, "rows": 5,
"capacity": 16 "capacity": 25
},
{
"name": "H",
"surcharge": 20,
"standingArea": false,
"rows": 5,
"capacity": 30
},
{
"name": "I",
"surcharge": 10,
"standingArea": false,
"rows": 5,
"capacity": 25
} }
] ]
}, },
@@ -282,6 +332,7 @@
"address": "Sylvesterallee 10", "address": "Sylvesterallee 10",
"imageIndoor": "locations/barclays-arena-indoor.jpg", "imageIndoor": "locations/barclays-arena-indoor.jpg",
"imageOutdoor": "locations/barclays-arena-outdoor.jpg", "imageOutdoor": "locations/barclays-arena-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -317,6 +368,7 @@
"address": "Am Glockenturm", "address": "Am Glockenturm",
"imageIndoor": "locations/waldbuehne-berlin-indoor.jpg", "imageIndoor": "locations/waldbuehne-berlin-indoor.jpg",
"imageOutdoor": "locations/waldbuehne-berlin-outdoor.jpg", "imageOutdoor": "locations/waldbuehne-berlin-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -346,6 +398,7 @@
"address": "Olympischer Platz 3", "address": "Olympischer Platz 3",
"imageIndoor": "locations/olympiastadion-berlin-indoor.jpg", "imageIndoor": "locations/olympiastadion-berlin-indoor.jpg",
"imageOutdoor": "locations/olympiastadion-berlin-outdoor.jpg", "imageOutdoor": "locations/olympiastadion-berlin-outdoor.jpg",
"layout": 3,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -396,6 +449,7 @@
"address": "Uber-Platz 1", "address": "Uber-Platz 1",
"imageIndoor": "locations/uber-arena-berlin-indoor.jpg", "imageIndoor": "locations/uber-arena-berlin-indoor.jpg",
"imageOutdoor": "locations/uber-arena-berlin-outdoor.jpg", "imageOutdoor": "locations/uber-arena-berlin-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -446,6 +500,7 @@
"address": "Columbiadamm 13-21", "address": "Columbiadamm 13-21",
"imageIndoor": "locations/columbiahalle-indoor.jpg", "imageIndoor": "locations/columbiahalle-indoor.jpg",
"imageOutdoor": "locations/columbiahalle-outdoor.jpg", "imageOutdoor": "locations/columbiahalle-outdoor.jpg",
"layout": 2,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -475,6 +530,7 @@
"address": "Revaler Straße 99", "address": "Revaler Straße 99",
"imageIndoor": "locations/astra-kulturhaus-indoor.jpg", "imageIndoor": "locations/astra-kulturhaus-indoor.jpg",
"imageOutdoor": "locations/astra-kulturhaus-outdoor.jpg", "imageOutdoor": "locations/astra-kulturhaus-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -496,6 +552,7 @@
"address": "Willy-Brandt-Platz", "address": "Willy-Brandt-Platz",
"imageIndoor": "locations/lanxess-arena-indoor.jpg", "imageIndoor": "locations/lanxess-arena-indoor.jpg",
"imageOutdoor": "locations/lanxess-arena-outdoor.jpg", "imageOutdoor": "locations/lanxess-arena-outdoor.jpg",
"layout": 3,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -546,6 +603,7 @@
"address": "Schanzenstraße 40", "address": "Schanzenstraße 40",
"imageIndoor": "locations/palladium-indoor.jpg", "imageIndoor": "locations/palladium-indoor.jpg",
"imageOutdoor": "locations/palladium-outdoor.jpg", "imageOutdoor": "locations/palladium-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",
@@ -561,6 +619,7 @@
"address": "Schanzenstraße 37", "address": "Schanzenstraße 37",
"imageIndoor": "locations/e-werk-indoor.jpg", "imageIndoor": "locations/e-werk-indoor.jpg",
"imageOutdoor": "locations/e-werk-outdoor.jpg", "imageOutdoor": "locations/e-werk-outdoor.jpg",
"layout": 1,
"seatGroups": [ "seatGroups": [
{ {
"name": "A", "name": "A",

View File

@@ -24,6 +24,15 @@ export class Location extends Model {
@Column @Column
imageOutdoor: String imageOutdoor: String
/**
* Layout identifier of the location
* 1 = Stage with simple stay area
* 2 = Stage with front stay area and seat places around
* 3 = Stage in the middle of the stay area, seat places all around
*/
@Column
layout: Number
// Relations // Relations

View File

@@ -7,7 +7,6 @@ import { Band } from "../models/acts/band.model";
import { SeatGroup } from "../models/locations/seatGroup.model"; import { SeatGroup } from "../models/locations/seatGroup.model";
import { Seat } from "../models/locations/seat.model"; import { Seat } from "../models/locations/seat.model";
import { SeatRow } from "../models/locations/seatRow.model"; import { SeatRow } from "../models/locations/seatRow.model";
import { Op } from "sequelize";
export const location = Router() export const location = Router()
@@ -107,6 +106,15 @@ location.get("/:urlName", (req: Request, res: Response) => {
}) })
} }
for (let seatGroup of location.dataValues.seatGroups) {
for (let seatRow of seatGroup.dataValues.seatRows) {
for (let seat of seatRow.dataValues.seats) {
seat.dataValues["state"] = 0
}
}
}
res.status(200).json(location) res.status(200).json(location)
}) })
}) })

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,8 @@
"@types/node": "^22.5.2", "@types/node": "^22.5.2",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"nodemon": "^3.1.4", "nodemon": "^3.1.4",
"vite": "^5.3.1" "vite": "^5.3.1",
"vue-svg-loader": "^0.16.0",
"vue-template-compiler": "^2.7.16"
} }
} }

View File

@@ -4,26 +4,66 @@ import seatGroupTable from './seatGroupTable.vue';
import standingArea from './standingArea.vue'; import standingArea from './standingArea.vue';
import { ConcertModel } from '@/data/models/acts/concertModel'; import { ConcertModel } from '@/data/models/acts/concertModel';
defineProps({ let props = defineProps({
seatGroup: SeatGroupModel, seatGroup: SeatGroupModel,
concert: ConcertModel, concert: ConcertModel,
backgroundColor: String withStage: Boolean
}) })
function getCornerClass() {
switch(props.seatGroup.name) {
case 'C': return "rounded-ts-xl"
case 'E': return "rounded-bs-xl"
case 'G': return "rounded-be-xl"
case 'I': return "rounded-te-xl"
}
}
function getStructureNumber() {
switch(props.seatGroup.name) {
case 'A':
case 'B':
case 'F': return 0
case 'D':
case 'H': return 1
case 'C': return 2
case 'E': return 3
case 'G': return 4
case 'I': return 5
}
}
function getNameLocation() {
switch(props.seatGroup.name) {
case 'B':
case 'C':
case 'I': return 0
case 'E':
case 'F':
case 'G': return 1
case 'D': return 2
case 'H': return 3
}
}
</script> </script>
<template> <template>
<standing-area <standing-area
:seat-group="seatGroup" :seat-group="seatGroup"
:concert="concert" :concert="concert"
:background-color="backgroundColor" :with-stage="withStage"
v-if="seatGroup != undefined && seatGroup.standingArea" v-if="seatGroup != undefined && seatGroup.standingArea"
/> />
<v-sheet <v-sheet
v-else-if="seatGroup != undefined" v-else-if="seatGroup != undefined"
class="pa-5" class="pa-3"
:color="backgroundColor" :class="getCornerClass()"
border
style="height: 100%;"
> >
<!-- Block name above seat icons -->
<div v-if="getNameLocation() == 0">
<v-row > <v-row >
<v-col class="text-h4 text-center font-weight-black"> <v-col class="text-h4 text-center font-weight-black">
{{ seatGroup.name }} {{ seatGroup.name }}
@@ -31,13 +71,79 @@ defineProps({
</v-row> </v-row>
<v-row> <v-row>
<v-spacer v-if="seatGroup.name == 'C'" />
<v-col class="d-flex justify-center align-center"> <v-col class="d-flex justify-center align-center">
<seat-group-table <seat-group-table
:seat-rows="seatGroup.seatRows" :seat-rows="seatGroup.seatRows"
:seat-group="seatGroup" :seat-group="seatGroup"
:concert="concert" :concert="concert"
:structure="getStructureNumber()"
/>
</v-col>
<v-spacer v-if="seatGroup.name == 'I'" />
</v-row>
</div>
<!-- Block name under seat icons -->
<div v-else-if="getNameLocation() == 1">
<v-row>
<v-col class="d-flex justify-center align-center">
<v-spacer v-if="seatGroup.name == 'E'" />
<seat-group-table
:seat-rows="seatGroup.seatRows"
:seat-group="seatGroup"
:concert="concert"
:structure="getStructureNumber()"
/>
</v-col>
<v-spacer v-if="seatGroup.name == 'G'" />
</v-row>
<v-row >
<v-col class="text-h4 text-center font-weight-black">
{{ seatGroup.name }}
</v-col>
</v-row>
</div>
<!-- Block name left to seat icons -->
<div v-else-if="getNameLocation() == 2">
<v-row>
<v-col class="text-h4 font-weight-black d-flex justify-center align-center">
{{ seatGroup.name }}
</v-col>
<v-col class="d-flex justify-center align-center">
<seat-group-table
:seat-rows="seatGroup.seatRows"
:seat-group="seatGroup"
:concert="concert"
:structure="getStructureNumber()"
/> />
</v-col> </v-col>
</v-row> </v-row>
</div>
<!-- Block name right to seat icons -->
<div v-else-if="getNameLocation() == 3">
<v-row>
<v-col class="d-flex justify-center align-center">
<seat-group-table
:seat-rows="seatGroup.seatRows"
:seat-group="seatGroup"
:concert="concert"
:structure="getStructureNumber()"
/>
</v-col>
<v-col class="text-h4 font-weight-black d-flex justify-center align-center">
{{ seatGroup.name }}
</v-col>
</v-row>
</div>
</v-sheet> </v-sheet>
</template> </template>

View File

@@ -11,7 +11,22 @@ const basketStore = useBasketStore()
let props = defineProps({ let props = defineProps({
seatRows: Array<SeatRowModel>, seatRows: Array<SeatRowModel>,
concert: ConcertModel, concert: ConcertModel,
seatGroup: SeatGroupModel seatGroup: SeatGroupModel,
/**
* Structure of the seat placment
*
* 0 = Normal rectangular form, rows from top to bottom (default)
* 1 = Normal rectangular form but rows and cols are switched
* 2 = Pyramid structure from right bottom corner
* 3 = Pyramid structure from right top corner
* 4 = Pyramid structure from left top corner
* 5 = Pyramid structure from left bottom corner
*/
structure: {
type: Number,
default: 0
}
}) })
function handleSeatClick(clickedSeat: SeatModel, seatRow: SeatRowModel) { function handleSeatClick(clickedSeat: SeatModel, seatRow: SeatRowModel) {
@@ -30,24 +45,31 @@ function handleSeatClick(clickedSeat: SeatModel, seatRow: SeatRowModel) {
} }
} }
function seatColor(state: number) { function seatColor(surcharge: number, state: number) {
switch (state) { switch (state) {
case 0: return "grey" case 0: {
case 1: return "red" switch(surcharge) {
case 0: return "orange"
case 10: return "teal"
case 20: return "green"
case 30: return "red"
}
}
case 1: return "grey"
case 2: return "orange" case 2: return "orange"
} }
} }
</script> </script>
<template> <template>
<table> <table v-if="structure == 0">
<tbody> <tbody>
<tr v-for="seatRow in seatRows"> <tr v-for="seatRow in seatRows">
<td v-for="seat in seatRow.seats"> <td v-for="seat in seatRow.seats">
<v-btn <v-btn
variant="text" variant="text"
icon="mdi-circle" icon="mdi-circle"
:color="seatColor(seat.state)" :color="seatColor(seatGroup.surcharge, seat.state)"
:disabled="seat.state == 1" :disabled="seat.state == 1"
density="compact" density="compact"
@click="handleSeatClick(seat, seatRow)" @click="handleSeatClick(seat, seatRow)"
@@ -56,4 +78,93 @@ function seatColor(state: number) {
</tr> </tr>
</tbody> </tbody>
</table> </table>
<table v-else-if="structure == 1">
<tbody>
<tr v-for="i in seatRows[0].seats.length">
<td v-for="row in seatRows">
<v-btn
variant="text"
icon="mdi-circle"
:color="seatColor(seatGroup.surcharge, row.seats[i - 1].state)"
:disabled="row.seats[i - 1].state == 1"
density="compact"
@click="handleSeatClick(row.seats[i - 1], row)"
/>
</td>
</tr>
</tbody>
</table>
<table v-else-if="structure == 2">
<tbody>
<tr v-for="i in seatRows.length">
<td v-for="j in seatRows[i - 1].seats.length">
<v-btn
v-if="seatRows[i - 1].seats.length - i < j"
variant="text"
icon="mdi-circle"
:color="seatColor(seatGroup.surcharge, seatRows[i - 1].seats[j - 1].state)"
:disabled="seatRows[i - 1].seats[j - 1].state == 1"
density="compact"
@click="handleSeatClick(seatRows[i - 1].seats[j - 1], seatRows[i - 1])"
/>
</td>
</tr>
</tbody>
</table>
<table v-else-if="structure == 3">
<tbody>
<tr v-for="i in seatRows.length">
<td v-for="j in seatRows[i - 1].seats.length">
<v-btn
v-if="j >= i"
variant="text"
icon="mdi-circle"
:color="seatColor(seatGroup.surcharge, seatRows[i - 1].seats[j - 1].state)"
:disabled="seatRows[i - 1].seats[j - 1].state == 1"
density="compact"
@click="handleSeatClick(seatRows[i - 1].seats[j - 1], seatRows[i - 1])"
/>
</td>
</tr>
</tbody>
</table>
<table v-else-if="structure == 4">
<tbody>
<tr v-for="i in seatRows.length">
<td v-for="j in seatRows[i - 1].seats.length">
<v-btn
v-if="seatRows[i - 1].seats.length - i >= j - 1"
variant="text"
icon="mdi-circle"
:color="seatColor(seatGroup.surcharge, seatRows[i - 1].seats[j - 1].state)"
:disabled="seatRows[i - 1].seats[j - 1].state == 1"
density="compact"
@click="handleSeatClick(seatRows[i - 1].seats[j - 1], seatRows[i - 1])"
/>
</td>
</tr>
</tbody>
</table>
<table v-else-if="structure == 5">
<tbody>
<tr v-for="i in seatRows.length">
<td v-for="j in seatRows[i - 1].seats.length">
<v-btn
v-if="j <= i"
variant="text"
icon="mdi-circle"
:color="seatColor(seatGroup.surcharge, seatRows[i - 1].seats[j - 1].state)"
:disabled="seatRows[i - 1].seats[j - 1].state == 1"
density="compact"
@click="handleSeatClick(seatRows[i - 1].seats[j - 1], seatRows[i - 1])"
/>
</td>
</tr>
</tbody>
</table>
</template> </template>

View File

@@ -2,14 +2,18 @@
import { SeatGroupModel } from '@/data/models/locations/seatGroupModel'; import { SeatGroupModel } from '@/data/models/locations/seatGroupModel';
import seatGroupSheet from './seatGroupSheet.vue'; import seatGroupSheet from './seatGroupSheet.vue';
import { ConcertModel } from '@/data/models/acts/concertModel'; import { ConcertModel } from '@/data/models/acts/concertModel';
import { LocationModel } from '@/data/models/locations/locationModel';
let props = defineProps({ let props = defineProps({
seatGroups: Array<SeatGroupModel>, location: LocationModel,
concert: ConcertModel concert: {
type: ConcertModel,
default: new ConcertModel()
}
}) })
function findSeatCategory(name: string): SeatGroupModel { function findSeatCategory(name: string): SeatGroupModel {
return props.seatGroups.find(category => return props.location.seatGroups.find(category =>
category.name == name category.name == name
) )
} }
@@ -20,50 +24,103 @@ const seatGroupC = findSeatCategory("C")
const seatGroupD = findSeatCategory("D") const seatGroupD = findSeatCategory("D")
const seatGroupE = findSeatCategory("E") const seatGroupE = findSeatCategory("E")
const seatGroupF = findSeatCategory("F") const seatGroupF = findSeatCategory("F")
const seatGroupG = findSeatCategory("G")
const seatGroupH = findSeatCategory("H")
const seatGroupI = findSeatCategory("I")
</script> </script>
<template> <template>
<v-sheet border class="pa-5">
<v-row> <v-row>
<v-col></v-col> <v-col cols="4">
<seat-group-sheet
:seat-group="seatGroupC"
:concert="concert"
background-color="grey"
/>
</v-col>
<v-col> <v-col cols="4">
<seat-group-sheet
:seat-group="seatGroupB"
:concert="concert"
background-color="grey"
/>
</v-col>
<v-col cols="4">
<seat-group-sheet
:seat-group="seatGroupI"
:concert="concert"
background-color="grey"
/>
</v-col>
</v-row>
<v-row>
<v-col cols="4">
<seat-group-sheet
v-if="location.layout != 1"
:seat-group="seatGroupD"
:concert="concert"
background-color="grey"
/>
</v-col>
<v-col :cols="location.layout == 1 ? 10 : 4">
<seat-group-sheet
:seat-group="seatGroupA"
:concert="concert"
background-color="grey"
:withStage="location.layout == 3"
/>
</v-col>
<v-col v-if="location.layout != 3">
<v-sheet <v-sheet
color="grey-darken-3" color="grey-darken-3"
height="50" height="100%"
width="50"
class="px-5 py-2 d-flex justify-center align-center" class="px-5 py-2 d-flex justify-center align-center"
> >
{{ $t('stage') }} {{ $t('stage') }}
</v-sheet> </v-sheet>
</v-col> </v-col>
<v-col></v-col> <v-col v-else cols="4">
</v-row> <seat-group-sheet
:seat-group="seatGroupH"
<v-row> :concert="concert"
<v-col> background-color="grey"
<seat-group-sheet :seat-group="seatGroupC" :concert="concert" background-color="cyan-darken-4" /> />
</v-col>
<v-col>
<seat-group-sheet :seat-group="seatGroupA" :concert="concert" background-color="grey" />
</v-col>
<v-col>
<seat-group-sheet :seat-group="seatGroupB" :concert="concert" background-color="cyan-darken-4" />
</v-col> </v-col>
</v-row> </v-row>
<v-row>
<v-col> <v-row v-if="location.layout != 1">
<seat-group-sheet :seat-group="seatGroupF" :concert="concert" background-color="deep-purple-darken-4" /> <v-col cols="4">
<seat-group-sheet
:seat-group="seatGroupE"
:concert="concert"
background-color="grey"
/>
</v-col> </v-col>
<v-col> <v-col cols="4">
<seat-group-sheet :seat-group="seatGroupD" :concert="concert" background-color="indigo-darken-4" /> <seat-group-sheet
:seat-group="seatGroupF"
:concert="concert"
background-color="grey"
/>
</v-col> </v-col>
<v-col> <v-col cols="4">
<seat-group-sheet :seat-group="seatGroupE" :concert="concert" background-color="deep-purple-darken-4" /> <seat-group-sheet
:seat-group="seatGroupG"
:concert="concert"
background-color="grey"
/>
</v-col> </v-col>
</v-row> </v-row>
</v-sheet>
</template> </template>

View File

@@ -9,7 +9,8 @@ const basketStore = useBasketStore()
let props = defineProps({ let props = defineProps({
seatGroup: SeatGroupModel, seatGroup: SeatGroupModel,
concert: ConcertModel, concert: ConcertModel,
backgroundColor: String backgroundColor: String,
withStage: Boolean
}) })
function handleSeatClick() { function handleSeatClick() {
@@ -31,22 +32,32 @@ function handleSeatClick() {
class="pa-5" class="pa-5"
min-height="200" min-height="200"
height="100%" height="100%"
:color="isHovering ? 'red' : backgroundColor" border
:color="isHovering ? 'orange' : ''"
@click="handleSeatClick" @click="handleSeatClick"
> >
<v-row> <v-row>
<v-col class="text-h4 text-center font-weight-black"> <v-spacer />
{{ seatGroup.name }}
</v-col>
</v-row>
<v-row> <v-col class="text-center" cols="6">
<v-col class="text-center">
<v-icon <v-icon
v-if="!withStage"
icon="mdi-account-group" icon="mdi-account-group"
size="x-large" size="x-large"
/> />
<v-sheet
v-else
color="grey-darken-3"
height="100"
width="100%"
class="d-flex justify-center align-center"
>
{{ $t('stage') }}
</v-sheet>
</v-col> </v-col>
<v-spacer />
</v-row> </v-row>
<v-row> <v-row>

View File

@@ -10,6 +10,7 @@ export class LocationModel {
imageIndoor: string imageIndoor: string
imageOutdoor: string imageOutdoor: string
seatSchema: string seatSchema: string
layout: number
city: { city: {
name: string name: string
country: string country: string

View File

@@ -1,5 +1,5 @@
export class SeatModel { export class SeatModel {
id: number id: number
seatNr: string seatNr: string
state: number state: number = 0
} }

View File

@@ -81,7 +81,7 @@ getTopEvents(4)
<v-row> <v-row>
<v-col v-for="i in 8" cols="3"> <v-col v-for="i in 8" cols="3">
<card-with-top-image <card-with-top-image
:image="topLocations[i - 1].image" :image="topLocations[i - 1].imageOutdoor"
:title="topLocations[i - 1].name" :title="topLocations[i - 1].name"
smaller-title smaller-title
@click="router.push('/locations/' + topLocations[i - 1].name.replaceAll(' ', '-').toLowerCase())" @click="router.push('/locations/' + topLocations[i - 1].name.replaceAll(' ', '-').toLowerCase())"

View File

@@ -80,7 +80,6 @@ getLocation(String(router.currentRoute.value.params.locationName))
</v-row> </v-row>
<v-row> <v-row>
<v-col> <v-col>
<section-divider :title="$t('seatPlan')" /> <section-divider :title="$t('seatPlan')" />
@@ -96,7 +95,7 @@ getLocation(String(router.currentRoute.value.params.locationName))
<v-row v-else> <v-row v-else>
<v-col> <v-col>
<seat-plan-map <seat-plan-map
:seat-groups="location.seatGroups" :location="location"
/> />
</v-col> </v-col>
</v-row> </v-row>

View File

@@ -14,6 +14,9 @@ shoppingStore.getCities()
<template> <template>
<v-container> <v-container>
<v-row>
</v-row>
<v-row> <v-row>
<v-spacer /> <v-spacer />