diff --git a/software/backend/data/bands.json b/software/backend/data/bands.json index 6ee4ecb..52d5136 100644 --- a/software/backend/data/bands.json +++ b/software/backend/data/bands.json @@ -8,7 +8,7 @@ "descriptionDe": "Red Hot Chili Peppers (Abkürzung: RHCP) ist eine 1983 gegründete US-amerikanische Funk- und Alternative-Rockband. Sie zählt zu den kommerziell erfolgreichsten Vertretern des Crossover. Ihr Album Blood Sugar Sex Magik gilt als eines der bedeutendsten dieses Genres.", "images": [ "red-hot-chili-peppers-1.jpg" ], "logo": "red-hot-chili-peppers-logo.png", - "genreId": 0, + "genreId": [ 0, 2, 3 ], "members": [ { "name": "Anthony Kiedis", @@ -47,7 +47,7 @@ "descriptionDe": "Radiohead ist eine britische Rockband, die 1985 in Oxford, England gegründet wurde. Die Band besteht aus Thom Yorke (Gesang, Rhythmusgitarre, Piano), Jonny Greenwood (Lead-Gitarre, Keyboard, Ondes Martenot), Colin Greenwood (E-Bass, Keyboard), Ed O’Brien (Gitarre, Backgroundvocals) und Phil Selway (Schlagzeug, Backgroundvocals). Radioheads experimenteller Ansatz gilt als Wegbereiter für den Sound des Alternative Rocks.", "images": [ "radiohead-1.jpg" ], "logo": "radiohead-logo.jpg", - "genreId": 1, + "genreId": [ 1, 2, 4, 5, 6 ], "members": [ { "name": "Thom Yorke", @@ -96,7 +96,7 @@ "descriptionDe": "Die Arctic Monkeys sind eine vierköpfige britische Alternative-Rock-Band mit Einflüssen aus Post-Punk und Garage Rock. Sie wurde 2002 im englischen Sheffield gegründet und veröffentlichte 2006 ihr Debütalbum, das Platz eins der britischen Charts erreichte. 2007, 2009, 2011, 2013 und 2018 erschienen jeweils weitere Alben der Musikgruppe, die alle ebenfalls die Spitzenposition in Großbritannien erreichten. Aktuelles Album der Band ist das am 21. Oktober 2022 erschienene The Car.", "images": [ "arctic-monkeys-1.jpg", "arctic-monkeys-2.jpg" ], "logo": "arctic-monkeys-logo.png", - "genreId": 2, + "genreId": [ 2, 7, 8 ], "members": [ { "name": "Glyn Jones", @@ -150,7 +150,7 @@ "descriptionDe": "Coldplay ist eine britische Pop-Rock-Band, bestehend aus Chris Martin, Jonny Buckland, Will Champion und Guy Berryman. Sie ist eine der weltweit erfolgreichsten Bands der 2000er-Jahre und hat knapp 80 Millionen Tonträger weltweit verkauft, davon 50 Millionen Alben.", "images": [ "coldplay-1.jpg" ], "logo": "coldplay-logo.jpg", - "genreId": 2, + "genreId": [ 2, 9 ], "members": [ { "name": "Chris Martin", @@ -174,7 +174,7 @@ }, { "name": "Phil Harvey", - "bandId": 2, + "bandId": 3, "image": "phil-harvey.jpg" } ], @@ -199,7 +199,7 @@ "descriptionDe": "Foo Fighters ist eine US-amerikanische Rockband. Prominentestes Mitglied und Band-Gründer ist der ehemalige Nirvana-Schlagzeuger Dave Grohl. ", "images": [ "foo-fighters-1.jpg" ], "logo": "foo-fighters-logo.png", - "genreId": 2, + "genreId": [ 2, 10 ], "members": [ { "name": "Dave Grohl", diff --git a/software/backend/data/genres.json b/software/backend/data/genres.json index 39d2765..11d86c8 100644 --- a/software/backend/data/genres.json +++ b/software/backend/data/genres.json @@ -2,15 +2,47 @@ "data": [ { "id": 0, - "name": "Funk rock" + "name": "Funk Rock" }, { "id": 1, - "name": "Art rock" + "name": "Art Rock" }, { "id": 2, "name": "Alternative Rock" + }, + { + "id": 3, + "name": "Crossover" + }, + { + "id": 4, + "name": "Electronica" + }, + { + "id": 5, + "name": "Post-Rock" + }, + { + "id": 6, + "name": "Britpop" + }, + { + "id": 7, + "name": "Post-Punk" + }, + { + "id": 8, + "name": "Garage Rock" + }, + { + "id": 9, + "name": "Pop-Rock" + }, + { + "id": 10, + "name": "Post-Grunge" } ] } \ No newline at end of file diff --git a/software/backend/database.ts b/software/backend/database.ts index 86f08c9..5398d8d 100644 --- a/software/backend/database.ts +++ b/software/backend/database.ts @@ -16,6 +16,7 @@ import { Member } from "./models/acts/member.model" import { Rating } from "./models/acts/rating.model" import { Tour } from "./models/acts/tour.model" import { City } from "./models/acts/city.model" +import { BandGenre } from "./models/acts/bandGenre.model" const dbName = "database" const dbUser = "root" @@ -30,7 +31,7 @@ export const sequelize = new Sequelize({ storage: "database.sqlite", models: [ AccountRole, Account, Payment, Address, - City, Location, Genre, Band, Rating, Member, Tour, Show, + City, Location, Genre, Band, BandGenre, Rating, Member, Tour, Show, Order, OrderItem ] }) diff --git a/software/backend/models/acts/band.model.ts b/software/backend/models/acts/band.model.ts index 2885260..a8bb3f9 100644 --- a/software/backend/models/acts/band.model.ts +++ b/software/backend/models/acts/band.model.ts @@ -1,8 +1,9 @@ -import { BelongsTo, Column, DataType, ForeignKey, HasMany, Model, Table } from "sequelize-typescript"; +import { BelongsTo, BelongsToMany, Column, DataType, ForeignKey, HasMany, Model, Table } from "sequelize-typescript"; import { Member } from "./member.model"; import { Genre } from "./genre.model"; import { Rating } from "./rating.model"; import { Tour } from "./tour.model"; +import { BandGenre } from "./bandGenre.model"; @Table({ timestamps: false }) export class Band extends Model { @@ -32,10 +33,6 @@ export class Band extends Model { @Column logo: String - @ForeignKey(() => Genre) - @Column - genreId: Number - // Relations @@ -48,6 +45,6 @@ export class Band extends Model { @HasMany(() => Tour) tours: Tour[] - @BelongsTo(() => Genre) - genre: Genre + @BelongsToMany(() => Genre, () => BandGenre) + genres: Genre[] } \ No newline at end of file diff --git a/software/backend/models/acts/bandGenre.model.ts b/software/backend/models/acts/bandGenre.model.ts new file mode 100644 index 0000000..2908164 --- /dev/null +++ b/software/backend/models/acts/bandGenre.model.ts @@ -0,0 +1,16 @@ +import { AutoIncrement, Column, ForeignKey, Model, PrimaryKey, Table, Unique } from "sequelize-typescript"; +import { Genre } from "./genre.model"; +import { Band } from "./band.model"; + +@Table({ timestamps: false }) +export class BandGenre extends Model { + @PrimaryKey + @Column({autoIncrement: true}) + declare id: number + + @ForeignKey(() => Genre) + genreId: number + + @ForeignKey(() => Band) + bandId: number +} \ No newline at end of file diff --git a/software/backend/models/acts/genre.model.ts b/software/backend/models/acts/genre.model.ts index 3793826..43358bd 100644 --- a/software/backend/models/acts/genre.model.ts +++ b/software/backend/models/acts/genre.model.ts @@ -1,5 +1,6 @@ -import { Column, HasMany, Model, Table } from "sequelize-typescript"; +import { BelongsToMany, Column, Model, Table } from "sequelize-typescript"; import { Band } from "./band.model"; +import { BandGenre } from "./bandGenre.model"; @Table({ timestamps: false }) export class Genre extends Model { @@ -9,6 +10,6 @@ export class Genre extends Model { // Relations - @HasMany(() => Band) + @BelongsToMany(() => Band, () => BandGenre) bands: Band[] } \ No newline at end of file diff --git a/software/backend/routes/genre.routes.ts b/software/backend/routes/genre.routes.ts index 9598575..ef0296d 100644 --- a/software/backend/routes/genre.routes.ts +++ b/software/backend/routes/genre.routes.ts @@ -1,10 +1,19 @@ +import { Rating } from "../models/acts/rating.model"; +import { Band } from "../models/acts/band.model"; import { Genre } from "../models/acts/genre.model"; import { Request, Response, Router } from "express"; export const genre = Router() genre.get("/", (req: Request, res: Response) => { - Genre.findAll() + Genre.findAll({ + include: [ + { + model: Band, + include: [ Rating ] + } + ] + }) .then(genres => { res.status(200).json(genres) }) diff --git a/software/backend/scripts/databaseHelper.ts b/software/backend/scripts/databaseHelper.ts index 4938621..99924f7 100644 --- a/software/backend/scripts/databaseHelper.ts +++ b/software/backend/scripts/databaseHelper.ts @@ -12,6 +12,7 @@ import { Location } from '../models/acts/location.model' import { Show } from '../models/acts/show.model' import { Tour } from '../models/acts/tour.model' import { City } from '../models/acts/city.model' +import { BandGenre } from '../models/acts/bandGenre.model' import accounts from "./../data/accounts.json" import orders from "./../data/orders.json" @@ -69,8 +70,17 @@ export async function prepopulateDatabase() { for(let band of bands.data) { + // Create a band dataset await Band.create(band) - .then(dataset => { + .then(async dataset => { + // Create the m:n associations for the genres + for (let genreId of band.genreId) { + await BandGenre.create({ + genreId: Number(genreId), + bandId: dataset.dataValues.id + }) + } + Rating.bulkCreate(band.ratings) Member.bulkCreate(band.members) }) diff --git a/software/src/App.vue b/software/src/App.vue index 583720c..a22c8cc 100644 --- a/software/src/App.vue +++ b/software/src/App.vue @@ -65,16 +65,10 @@ watch(() => preferencesStore.language, () => { - + - - - \ No newline at end of file + \ No newline at end of file diff --git a/software/src/components/cardWithTopImage.vue b/software/src/components/cardWithTopImage.vue index 550146e..8ed7f69 100644 --- a/software/src/components/cardWithTopImage.vue +++ b/software/src/components/cardWithTopImage.vue @@ -7,7 +7,7 @@ defineProps({ - {{ $t('menu.shopping.allEvents', 2) }} + {{ $t('menu.allEvents', 2) }} + + + + + + + {{ $t('menu.allBands') }} @@ -28,20 +41,7 @@ height="100%" :rounded="false" > - {{ $t('menu.shopping.allLocations', 2) }} - - - - - - - {{ $t('menu.shopping.allGenres', 2) }} + {{ $t('menu.allLocations', 2) }} diff --git a/software/src/components/outlinedButton.vue b/software/src/components/outlinedButton.vue index 9c1f144..3914ae9 100644 --- a/software/src/components/outlinedButton.vue +++ b/software/src/components/outlinedButton.vue @@ -3,7 +3,7 @@ defineProps({ prependIcon: String, color: { type: String, - default: "primary" + default: "secondary" } }) diff --git a/software/src/components/sectionDivider.vue b/software/src/components/sectionDivider.vue index 4ff9c7b..d10ac7c 100644 --- a/software/src/components/sectionDivider.vue +++ b/software/src/components/sectionDivider.vue @@ -3,13 +3,6 @@ defineProps({ title: String, image: String }) - -function backgroundStyle(image: string) { - return { - "background-image": 'http://localhost:3000/static/cities/hannover.jpg', - height: `100px` - } -} @@ -29,7 +22,7 @@ function backgroundStyle(image: string) { - {{ title }} + {{ title }} @@ -44,7 +37,7 @@ function backgroundStyle(image: string) { - {{ title }} + {{ title }} diff --git a/software/src/data/api/orderApi.ts b/software/src/data/api/orderApi.ts index 389828b..c0928f6 100644 --- a/software/src/data/api/orderApi.ts +++ b/software/src/data/api/orderApi.ts @@ -1,7 +1,6 @@ import axios from "axios" import { OrderModel } from "../models/orderModel" import { BasketItemModel } from "../models/basketItemModel" -import { calcPrice } from "@/scripts/productScripts" const BASE_URL = "http://localhost:3000/orders" @@ -17,13 +16,13 @@ export async function addOrder( ) { let orderItems = [] - for (let basketItem of basketItems) { - orderItems.push({ - productId: basketItem.product.id, - quantity: basketItem.quantity, - orderPrice: calcPrice(basketItem.product.price, basketItem.product.discount) - }) - } + // for (let basketItem of basketItems) { + // orderItems.push({ + // productId: basketItem.product.id, + // quantity: basketItem.quantity, + // orderPrice: calcPrice(basketItem.product.price, basketItem.product.discount) + // }) + // } return axios.post(BASE_URL, { accountId: accountId, diff --git a/software/src/data/enums/themeEnums.ts b/software/src/data/enums/themeEnums.ts index 25ddfbe..d1dd0a8 100644 --- a/software/src/data/enums/themeEnums.ts +++ b/software/src/data/enums/themeEnums.ts @@ -1,9 +1,5 @@ export enum ThemeEnum { - DARKRED = "darkRed", - LIGHTRED = "lightRed", - DARKBLUE = "darkBlue", - LIGHTBLUE = "lightBlue", - DARKGREEN = "darkGreen", - LIGHTGREEN = "lightGreen" + DARKBLUE = "dark", + LIGHTBLUE = "light", } \ No newline at end of file diff --git a/software/src/data/models/bandModel.ts b/software/src/data/models/bandModel.ts index 3716f0f..2f29dbb 100644 --- a/software/src/data/models/bandModel.ts +++ b/software/src/data/models/bandModel.ts @@ -10,7 +10,9 @@ export class BandModel { descriptionDe: string images: Array logo: string - genre: GenreModel ratings: Array members: Array + genre: { + name: string + } } \ No newline at end of file diff --git a/software/src/data/models/genreModel.ts b/software/src/data/models/genreModel.ts index dc9e82a..4447307 100644 --- a/software/src/data/models/genreModel.ts +++ b/software/src/data/models/genreModel.ts @@ -1,4 +1,19 @@ +import { MemberModel } from "./memberModel" +import { RatingModel } from "./ratingModel" + export class GenreModel { id: number name: string + bands: Array< + { + name: string + foundingYear: number + descriptionEn: string + descriptionDe: string + images: Array + logo: string + ratings: Array + members: Array + } + > } \ No newline at end of file diff --git a/software/src/data/stores/accountStore.ts b/software/src/data/stores/accountStore.ts index be6897e..4d13e58 100644 --- a/software/src/data/stores/accountStore.ts +++ b/software/src/data/stores/accountStore.ts @@ -6,7 +6,6 @@ import { useFeedbackStore } from "./feedbackStore"; import { loginAccount, registerAccount, updateAccount } from "../api/accountApi"; import { getUserOrders } from "../api/orderApi"; import { BannerStateEnum } from "../enums/bannerStateEnum"; -import { calcPrice } from "@/scripts/productScripts"; import { AddressModel } from "../models/addressModel"; import { PaymentModel } from "../models/paymentModel"; @@ -86,9 +85,9 @@ export const useAccountStore = defineStore("accountStore", { let totalPrice = 0 let order: OrderModel = this.orders.find((order: OrderModel) => order.id == orderId) - for (let item of order.orderItems) { - totalPrice += calcPrice(item.orderPrice, 0, item.quantity) - } + // for (let item of order.orderItems) { + // totalPrice += calcPrice(item.orderPrice, 0, item.quantity) + // } return Math.round(totalPrice * 100) / 100 }, diff --git a/software/src/data/stores/basketStore.ts b/software/src/data/stores/basketStore.ts index 9b38e60..08bb383 100644 --- a/software/src/data/stores/basketStore.ts +++ b/software/src/data/stores/basketStore.ts @@ -1,6 +1,5 @@ import { defineStore } from "pinia"; import { useLocalStorage } from "@vueuse/core"; -import { calcPrice } from "@/scripts/productScripts"; import { BasketItemModel } from "../models/basketItemModel"; import { useFeedbackStore } from "./feedbackStore"; import { BannerStateEnum } from "../enums/bannerStateEnum"; @@ -26,9 +25,9 @@ export const useBasketStore = defineStore('basketStore', { getTotalPrice() { let result = 0 - for (let item of this.itemsInBasket) { - result += calcPrice(item.product.price, item.product.discount, item.quantity) - } + // for (let item of this.itemsInBasket) { + // result += calcPrice(item.product.price, item.product.discount, item.quantity) + // } return Math.round(result * 100) / 100 } diff --git a/software/src/locales/de.json b/software/src/locales/de.json index a2dcd3b..b473e95 100644 --- a/software/src/locales/de.json +++ b/software/src/locales/de.json @@ -1,13 +1,14 @@ { "menu": { - "shopping": { - "allEvents": "Alle Events", - "allLocations": "Alle Orte", - "allGenres": "Alle Genres" - } + "allEvents": "Alle Events", + "allLocations": "Alle Veranstaltungsorte", + "allBands": "Alle Bands" }, "shows": { - "tickets": "Ticket | Tickets" + "tickets": "Ticket | Tickets", + "topEvents": "Top Events", + "topBands": "Top Bands", + "topLocations": "Top Veranstaltungsorte" }, diff --git a/software/src/locales/en.json b/software/src/locales/en.json index 4ae80e2..12cb5b8 100644 --- a/software/src/locales/en.json +++ b/software/src/locales/en.json @@ -1,13 +1,14 @@ { "menu": { - "shopping": { - "allEvents": "All Events", - "allLocations": "All Locations", - "allGenres": "All Genres" - } + "allEvents": "All Events", + "allLocations": "All Locations", + "allBands": "All Bands" }, "shows": { - "tickets": "Ticket | Tickets" + "tickets": "Ticket | Tickets", + "topEvents": "Top Events", + "topBands": "Top Bands", + "topLocations": "Top Locations" }, diff --git a/software/src/pages/basketPage/productsTable.vue b/software/src/pages/basketPage/productsTable.vue index 45e0859..3684f80 100644 --- a/software/src/pages/basketPage/productsTable.vue +++ b/software/src/pages/basketPage/productsTable.vue @@ -1,7 +1,6 @@ @@ -24,7 +16,7 @@ function calcRating(ratings: Array) { - + @@ -41,7 +33,20 @@ function calcRating(ratings: Array) { - + + {{ $t('menu.allEvents') }} + + + + + + + + @@ -69,21 +74,46 @@ function calcRating(ratings: Array) { - + + {{ $t('menu.allBands') }} + + + + + + + + - + - {{ location.address }} - {{ location.city.name }}, {{ location.city.country }} + {{ showStore.locations[i + 2].address }} + {{ showStore.locations[i + 2].city.name }}, {{ showStore.locations[i + 2].city.country }} + + + + + {{ $t('menu.allLocations') }} + + + diff --git a/software/src/pages/shows/bandsPage/index.vue b/software/src/pages/shows/bandsPage/index.vue new file mode 100644 index 0000000..a703dfa --- /dev/null +++ b/software/src/pages/shows/bandsPage/index.vue @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/software/src/pages/shows/genresPage/index.vue b/software/src/pages/shows/genresPage/index.vue deleted file mode 100644 index ea81832..0000000 --- a/software/src/pages/shows/genresPage/index.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/software/src/pages/shows/locationsPage/index.vue b/software/src/pages/shows/locationsPage/index.vue index c852792..d726e63 100644 --- a/software/src/pages/shows/locationsPage/index.vue +++ b/software/src/pages/shows/locationsPage/index.vue @@ -13,7 +13,6 @@ const showStore = useShowStore() diff --git a/software/src/plugins/vuetify.ts b/software/src/plugins/vuetify.ts index 6917739..12d63e3 100644 --- a/software/src/plugins/vuetify.ts +++ b/software/src/plugins/vuetify.ts @@ -13,48 +13,22 @@ const vuetify = createVuetify({ theme: { defaultTheme: 'dark', themes: { - darkRed: { - dark: true, - colors: { - primary: colors.red.darken1, - secondary: colors.red.lighten2 - } - }, - lightRed: { - dark: false, - colors: { - primary: colors.red.darken1, - secondary: colors.red.darken4 - } - }, - darkBlue: { + dark: { dark: true, colors: { primary: colors.blue.darken4, - secondary: colors.blue.lighten2 + secondary: colors.blue.lighten2, + sheet: colors.grey.darken4 } }, - lightBlue: { + light: { dark: false, colors: { - primary: colors.blue.darken1, - secondary: colors.blue.darken4 + primary: colors.blue.darken4, + secondary: colors.blue.darken2, + sheet: colors.grey.lighten3 } }, - darkGreen: { - dark: true, - colors: { - primary: colors.green.darken1, - secondary: colors.green.lighten2 - } - }, - lightGreen: { - dark: false, - colors: { - primary: colors.green.darken1, - secondary: colors.green.darken4 - } - } } } }) diff --git a/software/src/router/show.routes.ts b/software/src/router/show.routes.ts index 711fd32..e48825e 100644 --- a/software/src/router/show.routes.ts +++ b/software/src/router/show.routes.ts @@ -1,11 +1,11 @@ import EventsPage from "@/pages/shows/eventsPage/index.vue"; -import GenresPage from "@/pages/shows/genresPage/index.vue"; +import BandsPage from "@/pages/shows/bandsPage/index.vue"; import LocationsPage from "@/pages/shows/locationsPage/index.vue" import SearchPage from "@/pages/shows/searchPage/index.vue" export const showRoutes = [ { path: '/shows/events', component: EventsPage }, - { path: '/shows/genres', component: GenresPage }, + { path: '/shows/bands', component: BandsPage }, { path: '/shows/locations', component: LocationsPage }, { path: '/shows/search', component: SearchPage }, ] \ No newline at end of file diff --git a/software/src/scripts/productScripts.ts b/software/src/scripts/showsScripts.ts similarity index 51% rename from software/src/scripts/productScripts.ts rename to software/src/scripts/showsScripts.ts index e998944..77f6c33 100644 --- a/software/src/scripts/productScripts.ts +++ b/software/src/scripts/showsScripts.ts @@ -1,3 +1,5 @@ +import { RatingModel } from "@/data/models/ratingModel" + /** * Calculate a price based on parameters * @@ -9,4 +11,21 @@ */ export function calcPrice(price: number, discount: number = 0, quantity: number = 1): number { return Math.round(quantity * price * ((100 - discount) / 100) * 100) / 100 +} + +/** + * Calculate the average of an Array of ratings + * + * @param ratings Array of ratings + * + * @returns Average rating as number + */ +export function calcRating(ratings: Array) { + let sum = 0 + + for (let rating of ratings) { + sum += rating.rating + } + + return sum / ratings.length } \ No newline at end of file