OrderStore

This commit is contained in:
2024-11-07 17:18:49 +01:00
parent fbae1b9f3a
commit 2c9b2cc509
12 changed files with 196 additions and 174 deletions

View File

@@ -13,6 +13,15 @@ import { SeatGroup } from "../models/locations/seatGroup.model";
export const order = Router() export const order = Router()
// Get all orders
order.get("/", (req: Request, res: Response) => {
Order.findAll()
.then(orders => {
res.status(200).json(orders)
})
})
// Get all orders of one account by it's user id // Get all orders of one account by it's user id
order.get("/:id", (req: Request, res: Response) => { order.get("/:id", (req: Request, res: Response) => {
Order.findAll({ Order.findAll({

View File

@@ -272,7 +272,7 @@ export async function prepopulateDatabase() {
date: concert.date, date: concert.date,
name: concertGroup.name, name: concertGroup.name,
price: concert.price, price: concert.price,
image: concertGroup.image, image: "http://localhost:3000/static/" + concertGroup.image,
inStock: concert.inStock, inStock: concert.inStock,
offered: true, offered: true,
bandId: dataset.dataValues.id, bandId: dataset.dataValues.id,

View File

@@ -32,3 +32,7 @@ export async function createOrder(
addressId: addressId addressId: addressId
}) })
} }
export async function fetchAllOrders() {
return axios.get(BASE_URL)
}

View File

@@ -58,7 +58,8 @@
"imageMember": "Bilder Mitglieder", "imageMember": "Bilder Mitglieder",
"addNewGenre": "Neues Genre hinzufügen", "addNewGenre": "Neues Genre hinzufügen",
"editGenre": "Genre bearbeiten", "editGenre": "Genre bearbeiten",
"bandDetails": "Band Details" "bandDetails": "Band Details",
"withoutConcert": "ohne Konzert"
}, },
"ticket": { "ticket": {
"tickets": "Ticket | Tickets" "tickets": "Ticket | Tickets"
@@ -107,7 +108,8 @@
}, },
"addNewAccount": "Neuen Account hinzufügen", "addNewAccount": "Neuen Account hinzufügen",
"accountRole": "Account Rolle", "accountRole": "Account Rolle",
"noRealPaymentsNeeded": "Keine echten Kontodaten nötig!" "noRealPaymentsNeeded": "Keine echten Kontodaten nötig!",
"administrator": "Administrator | Administratoren"
}, },
"order": { "order": {
"orders": "Bestellung | Bestellungen", "orders": "Bestellung | Bestellungen",

View File

@@ -58,7 +58,8 @@
"imageMember": "Images Members", "imageMember": "Images Members",
"addNewGenre": "Add new Genre", "addNewGenre": "Add new Genre",
"editGenre": "Edit Genre", "editGenre": "Edit Genre",
"bandDetails": "Band Details" "bandDetails": "Band Details",
"withoutConcert": "without concert"
}, },
"ticket": { "ticket": {
"tickets": "Ticket | Tickets" "tickets": "Ticket | Tickets"
@@ -107,7 +108,8 @@
}, },
"addNewAccount": "Add new account", "addNewAccount": "Add new account",
"accountRole": "Account Role", "accountRole": "Account Role",
"noRealPaymentsNeeded": "No real payment data required!" "noRealPaymentsNeeded": "No real payment data required!",
"administrator": "Administrator"
}, },
"order": { "order": {
"orders": "Order | Orders", "orders": "Order | Orders",

View File

@@ -3,10 +3,13 @@ import { useAccountStore } from '@/stores/account.store';
import orderItem from './orderItem.vue'; import orderItem from './orderItem.vue';
import accountSubPageLayout from '@/layouts/accountSubPageLayout.vue'; import accountSubPageLayout from '@/layouts/accountSubPageLayout.vue';
import circularProgressIndeterminate from '@/components/basics/circularProgressIndeterminate.vue'; import circularProgressIndeterminate from '@/components/basics/circularProgressIndeterminate.vue';
import { useOrderStore } from '@/stores/order.store';
const accountStore = useAccountStore() const accountStore = useAccountStore()
const orderStore = useOrderStore()
accountStore.refreshOrders() accountStore.refreshOrders()
orderStore.getOrdersOfAccount(accountStore.userAccount)
</script> </script>
<template> <template>
@@ -22,8 +25,8 @@ accountStore.refreshOrders()
<!-- Display all orders --> <!-- Display all orders -->
<v-row <v-row
v-else-if="accountStore.orders.length > 0" v-else-if="orderStore.orders.length > 0"
v-for="order in accountStore.orders" v-for="order in orderStore.orders"
> >
<v-col> <v-col>
<order-item <order-item

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
import cardView from '@/components/basics/cardView.vue';
import { useRouter } from 'vue-router';
import outlinedButton from '@/components/basics/outlinedButton.vue';
const router = useRouter()
defineProps({
title: String,
icon: String,
firstLine: String,
secondLine: String,
buttonRoute: String,
loading: Boolean
})
</script>
<template>
<v-col cols="12" md="6" lg="4">
<card-view
:title="title"
:icon="icon"
>
<div class="text-h4 text-center">
{{ firstLine }}
</div>
<div class="text-h6 text-center text-disabled">
{{ secondLine }}
</div>
<template #actions>
<outlined-button
@click="router.push(buttonRoute)"
:loading="loading"
>
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
</template>

View File

@@ -1,7 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRouter } from 'vue-router';
import outlinedButton from '@/components/basics/outlinedButton.vue';
import cardView from '@/components/basics/cardView.vue';
import { useConcertStore } from '@/stores/concert.store'; import { useConcertStore } from '@/stores/concert.store';
import { useBandStore } from '@/stores/band.store'; import { useBandStore } from '@/stores/band.store';
import { useAccountStore } from '@/stores/account.store'; import { useAccountStore } from '@/stores/account.store';
@@ -9,8 +6,9 @@ import { useLocationStore } from '@/stores/location.store';
import { useExerciseStore } from '@/stores/exercise.store'; import { useExerciseStore } from '@/stores/exercise.store';
import { useGenreStore } from '@/stores/genre.store'; import { useGenreStore } from '@/stores/genre.store';
import { usePreferencesStore } from '@/stores/preferences.store'; import { usePreferencesStore } from '@/stores/preferences.store';
import dashboardCard from './dashboardCard.vue';
import { useOrderStore } from '@/stores/order.store';
const router = useRouter()
const concertStore = useConcertStore() const concertStore = useConcertStore()
const bandStore = useBandStore() const bandStore = useBandStore()
const accountStore = useAccountStore() const accountStore = useAccountStore()
@@ -18,6 +16,7 @@ const genreStore = useGenreStore()
const locationStore = useLocationStore() const locationStore = useLocationStore()
const exerciseStore = useExerciseStore() const exerciseStore = useExerciseStore()
const preferencesStore = usePreferencesStore() const preferencesStore = usePreferencesStore()
const orderStore = useOrderStore()
exerciseStore.solveExercise(2, 1) exerciseStore.solveExercise(2, 1)
@@ -27,171 +26,94 @@ locationStore.getLocations()
genreStore.getGenres() genreStore.getGenres()
accountStore.getAllAccounts() accountStore.getAllAccounts()
concertStore.getConcerts() concertStore.getConcerts()
orderStore.getAllOrders()
</script> </script>
<template> <template>
<v-container> <v-container>
<v-row> <v-row>
<v-col> <dashboard-card
<card-view
:title="$t('band.band', 2)" :title="$t('band.band', 2)"
icon="mdi-guitar-electric" icon="mdi-guitar-electric"
> :first-line="bandStore.bands.length + ' ' + $t('band.band', 2)"
<div class="text-h4 text-center"> :second-line="bandStore.bands.reduce((counter, band) => {
{{ bandStore.bands.length }} {{ $t('band.band', 2) }} return band.concerts.length == 0 ? counter += 1 : counter
</div> }, 0) + ' ' + $t('band.withoutConcert', 2)"
button-route="/admin/bands"
<template #actions>
<outlined-button
@click="router.push('/admin/bands')"
:loading="bandStore.fetchInProgress" :loading="bandStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
<v-col> <dashboard-card
<card-view
:title="$t('concert.concert', 2)" :title="$t('concert.concert', 2)"
icon="mdi-ticket" icon="mdi-ticket"
> :first-line="concertStore.concerts.length + ' ' + $t('concert.concert', 2)"
<div class="text-h4 text-center"> :second-line="concertStore.concerts.reduce((counter, obj) => {
{{ concertStore.concerts.length }} {{ $t('concert.concert', 2) }}
</div>
<div class="text-h6 text-disabled text-center">
{{ concertStore.concerts.reduce((counter, obj) => {
if (obj.inStock == 0) { if (obj.inStock == 0) {
counter += 1 counter += 1
} }
return counter return counter
}, 0) }} {{ $t('concert.concertSoldOut') }} }, 0) + ' ' + $t('concert.concertSoldOut')"
</div> button-route="/admin/concerts"
<template #actions>
<outlined-button
@click="router.push('/admin/concerts')"
:loading="concertStore.fetchInProgress" :loading="concertStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
<v-col> <dashboard-card
<card-view
:title="$t('location.location', 2)" :title="$t('location.location', 2)"
icon="mdi-city" icon="mdi-city"
> :first-line="locationStore.locations.length + ' ' + $t('location.location', 2)"
<div class="text-h4 text-center"> :second-line="locationStore.locations.reduce((city, obj) => {
{{ locationStore.locations.length }} {{ $t('location.location', 2) }}
</div>
<div class="text-h6 text-disabled text-center">
{{
locationStore.locations.reduce((city, obj) => {
city[obj.city.name] = city[obj.city.name] =
city[obj.city.name] === undefined ? city.push(obj.city.name) : city[obj.city.name] += 1 city[obj.city.name] === undefined ? city.push(obj.city.name) : city[obj.city.name] += 1
return city return city
}, []).length }, []).length + ' ' + $t('location.city', 2)"
}} button-route="/admin/locations"
{{ $t('location.city', 2) }}
</div>
<template #actions>
<outlined-button
@click="router.push('/admin/locations')"
:loading="locationStore.fetchInProgress" :loading="locationStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
</v-row>
<dashboard-card
<v-row>
<v-col>
<card-view
:title="$t('account.account', 2)" :title="$t('account.account', 2)"
icon="mdi-account" icon="mdi-account"
> :first-line="accountStore.accounts.length + ' ' + $t('account.account', 2)"
<div class="text-h4 text-center"> :second-line="accountStore.accounts.reduce((counter, obj) => {
{{ accountStore.accounts.length }} {{ $t('account.account', accountStore.accounts.length) }} return obj.accountRole.privilegeAdminPanel ? counter += 1 : counter
</div> }, 0) + ' ' + $t('account.administrator', 2)"
button-route="/admin/accounts"
<template #actions>
<outlined-button
@click="router.push('/admin/accounts')"
:loading="accountStore.fetchInProgress" :loading="accountStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
<v-col> <dashboard-card
<card-view
:title="$t('band.genre', 2)" :title="$t('band.genre', 2)"
icon="mdi-music-clef-treble" icon="mdi-music-clef-treble"
> :first-line="genreStore.genres.length + ' ' + $t('band.genre', 2)"
<div class="text-h4 text-center"> :second-line="genreStore.genres.reduce((counter, obj) => {
{{ genreStore.genres.length }} {{ $t('band.genre', 2) }}
</div>
<div class="text-h6 text-center text-disabled">
{{ genreStore.genres.reduce((counter, obj) => {
return obj.bands.length == 0 ? counter += 1 : counter return obj.bands.length == 0 ? counter += 1 : counter
}, 0) }} {{ $t('genre.withoutBand') }} }, 0) + ' ' + $t('genre.withoutBand', 2)"
</div> button-route="/admin/genres"
<template #actions>
<outlined-button
@click="router.push('/admin/genres')"
:loading="genreStore.fetchInProgress" :loading="genreStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button>
</template>
</card-view>
</v-col>
<v-col> <dashboard-card
<card-view
:title="$t('misc.file', 2)" :title="$t('misc.file', 2)"
icon="mdi-file" icon="mdi-file"
> :first-line="preferencesStore.staticFiles.reduce((counter, obj) => {
<div class="text-h4 text-center">
{{ preferencesStore.staticFiles.reduce((counter, obj) => {
return counter += obj.files.length return counter += obj.files.length
}, 0) }} {{ $t('misc.file', 2) }} }, 0) + ' ' + $t('misc.file', 2)"
</div> :second-line="preferencesStore.staticFiles.length + ' ' + $t('misc.folder', 2)"
button-route="/admin/files"
<div class="text-h6 text-center text-disabled">
{{ preferencesStore.staticFiles.length }} {{ $t('misc.folder', 2) }}
</div>
<template #actions>
<outlined-button
@click="router.push('/admin/files')"
:loading="preferencesStore.fetchInProgress" :loading="preferencesStore.fetchInProgress"
> />
{{ $t('misc.actions.more') }}
</outlined-button> <dashboard-card
</template> :title="$t('order.orders', 2)"
</card-view> icon="mdi-basket"
</v-col> :first-line="orderStore.orders.length + ' ' + $t('order.orders', 2)"
second-line="todo"
button-route="/admin/orders"
:loading="orderStore.fetchInProgress"
/>
</v-row> </v-row>
<!-- todo: Orders -->
</v-container> </v-container>
</template> </template>

View File

@@ -25,12 +25,17 @@ const router = useRouter()
<v-col v-else v-for="concert in concertStore.upcomingConcerts" cols="3"> <v-col v-else v-for="concert in concertStore.upcomingConcerts" cols="3">
<card-view-top-image <card-view-top-image
:image="concert.image" :image="concert.image"
:title="concert.band.name" :title="moment(concert.date).format('DD.MM.YYYY')"
smaller-title smaller-title
@click="router.push('/bands/details/' + concert.band.name.replaceAll(' ', '-').toLowerCase())" @click="router.push('/bands/details/' + concert.band.name.replaceAll(' ', '-').toLowerCase())"
:loading="concertStore.fetchInProgress" :loading="concertStore.fetchInProgress"
> >
{{ moment(concert.date).format("DD.MM.YYYY") }}, <div>
{{ concert.name }}
</div>
<div>
{{ concert.band.name }}
</div>
{{ $t("misc.from") }} {{ (concert.price).toPrecision(4) }} {{ $t("misc.from") }} {{ (concert.price).toPrecision(4) }}
</card-view-top-image> </card-view-top-image>
</v-col> </v-col>

View File

@@ -1,7 +1,5 @@
import { useLocalStorage } from "@vueuse/core"; import { useLocalStorage } from "@vueuse/core";
import { acceptHMRUpdate, defineStore } from "pinia";
import { AccountModel } from "../data/models/user/accountModel"; import { AccountModel } from "../data/models/user/accountModel";
import { OrderModel } from "../data/models/ordering/orderModel";
import { useFeedbackStore } from "./feedback.store"; import { useFeedbackStore } from "./feedback.store";
import { deleteAccount, fetchAllAccounts, loginAccount, registerAccount, updateAccount } from "../data/api/accountApi"; import { deleteAccount, fetchAllAccounts, loginAccount, registerAccount, updateAccount } from "../data/api/accountApi";
import { fetchUserOrders } from "../data/api/orderApi"; import { fetchUserOrders } from "../data/api/orderApi";
@@ -10,8 +8,7 @@ import { AddressModel } from "../data/models/user/addressModel";
import { PaymentModel } from "../data/models/user/paymentModel"; import { PaymentModel } from "../data/models/user/paymentModel";
import { AccountApiModel } from "../data/models/user/accountApiModel"; import { AccountApiModel } from "../data/models/user/accountApiModel";
import { ref } from "vue"; import { ref } from "vue";
import { OrderApiModel } from "@/data/models/apiEndpoints/orderApiModel"; import { defineStore } from "pinia";
import { LocationApiModel } from "@/data/models/locations/locationApiModel";
export const useAccountStore = defineStore("accountStore", { export const useAccountStore = defineStore("accountStore", {
state: () => ({ state: () => ({
@@ -30,9 +27,6 @@ export const useAccountStore = defineStore("accountStore", {
/** Buffer for register data */ /** Buffer for register data */
registerData: ref<AccountModel>(new AccountModel()), registerData: ref<AccountModel>(new AccountModel()),
/** All orders of the user */
orders: ref<Array<OrderApiModel>>([]),
/** Request to server sent, waiting for data response */ /** Request to server sent, waiting for data response */
fetchInProgress: ref(false) fetchInProgress: ref(false)
}), }),

View File

@@ -308,7 +308,7 @@ export const useFeedbackStore = defineStore("feedbackStore", {
case BannerStateEnum.GENREDELETESUCCESSFUL: case BannerStateEnum.GENREDELETESUCCESSFUL:
case BannerStateEnum.GENRESAVEDERROR: case BannerStateEnum.GENRESAVEDERROR:
case BannerStateEnum.GENRESAVEDSUCCESSFUL: case BannerStateEnum.GENRESAVEDSUCCESSFUL:
this.icon = "mdi-music" this.icon = "mdi-music-clef-treble"
break; break;
} }

View File

@@ -0,0 +1,39 @@
import { fetchAllOrders, fetchUserOrders } from "@/data/api/orderApi";
import { OrderApiModel } from "@/data/models/apiEndpoints/orderApiModel";
import { AccountModel } from "@/data/models/user/accountModel";
import { defineStore } from "pinia";
import { ref } from "vue";
export const useOrderStore = defineStore("orderStore", {
state: () => ({
/** All orders of one/all users */
orders: ref<Array<OrderApiModel>>([]),
/** Request to server sent, waiting for data response */
fetchInProgress: ref(false)
}),
actions: {
/**
* Get all orders from all accounts from server
*/
async getAllOrders() {
fetchAllOrders()
.then(res => {
this.orders = res.data
})
},
/**
* Get all orders from one account from server
*
* @param user User to request orders from
*/
async getOrdersOfAccount(user: AccountModel) {
fetchUserOrders(user.id)
.then(res => {
this.orders = res.data
})
}
}
})