Compare commits

..

4 Commits

17 changed files with 224 additions and 81 deletions

View File

@@ -4,29 +4,19 @@
"id": 0, "id": 0,
"name": "Unregistered", "name": "Unregistered",
"privilegeBuy": false, "privilegeBuy": false,
"privilegeAdminPanel": false, "privilegeAdminPanel": false
"privilegeFileAccess": false
}, },
{ {
"id": 1, "id": 1,
"name": "User", "name": "User",
"privilegeBuy": true, "privilegeBuy": true,
"privilegeAdminPanel": false, "privilegeAdminPanel": false
"privilegeFileAccess": false
}, },
{ {
"id": 2, "id": 2,
"name": "Admin", "name": "Admin",
"privilegeBuy": true, "privilegeBuy": true,
"privilegeAdminPanel": true, "privilegeAdminPanel": true
"privilegeFileAccess": false
},
{
"id": 3,
"name": "Super-Admin",
"privilegeBuy": true,
"privilegeAdminPanel": true,
"privilegeFileAccess": true
} }
] ]
} }

View File

@@ -19,7 +19,7 @@
"iban": "DE92500105175721645777" "iban": "DE92500105175721645777"
} }
], ],
"accountRoleId": 2 "accountRoleId": 1
}, },
{ {
"username": "katjaStoiber", "username": "katjaStoiber",
@@ -94,7 +94,7 @@
"iban": "DE41500105172184936679" "iban": "DE41500105172184936679"
} }
], ],
"accountRoleId": 3 "accountRoleId": 2
}, },
{ {
"username": "guitarhero", "username": "guitarhero",

View File

@@ -18,6 +18,9 @@ account.get("/", verifyToken, (req: Request, res: Response) => {
.then(accounts => { .then(accounts => {
res.status(200).json(accounts) res.status(200).json(accounts)
}) })
.catch(error => {
res.status(500).send()
})
}) })
// Login user // Login user
@@ -61,6 +64,9 @@ account.get("/account/data", verifyToken, async(req: Request, res: Response) =>
.then(account => { .then(account => {
res.status(200).json(account) res.status(200).json(account)
}) })
.catch(error => {
res.status(500).send()
})
}) })
@@ -102,7 +108,7 @@ account.post("/account", async (req: Request, res: Response) => {
.then(account => { .then(account => {
// Status: 201 Created // Status: 201 Created
res.status(201).json(account) res.status(201).json(account)
}).catch(reason => { }).catch(error => {
// Status: 409 Conflict // Status: 409 Conflict
res.status(409).json({ res.status(409).json({
code: 409, code: 409,
@@ -167,4 +173,7 @@ account.delete("/account/:id", (req: Request, res: Response) => {
.then(account => { .then(account => {
res.status(200).send() res.status(200).send()
}) })
.catch(error => {
res.status(500).send()
})
}) })

View File

@@ -65,6 +65,9 @@ band.get("/", (req: Request, res: Response) => {
res.status(200).json(bands) res.status(200).json(bands)
}) })
.catch(error => {
res.status(500).send()
})
}) })
/** /**
@@ -122,7 +125,7 @@ band.get("/band/:name", (req: Request, res: Response) => {
res.status(200).json(band) res.status(200).json(band)
}) })
.catch(e => { .catch(error => {
res.status(404).send() res.status(404).send()
}) })
}) })
@@ -137,10 +140,13 @@ band.get("/search", async (req: Request, res: Response) => {
// On stacked prompts, execute last prompt // On stacked prompts, execute last prompt
if (prompts.length > 1) { if (prompts.length > 1) {
try {
const [results, metadata] = const [results, metadata] =
await sequelize.query(prompts[prompts.length - 2]) await sequelize.query(prompts[prompts.length - 2])
res.status(200).json(results) res.status(200).json(results)
} catch (e) {
res.status(400).send()
}
} else { } else {
Band.findAll({ Band.findAll({
where: { where: {
@@ -153,7 +159,7 @@ band.get("/search", async (req: Request, res: Response) => {
.then(bands => { .then(bands => {
res.status(200).json(bands) res.status(200).json(bands)
}) })
.catch(e => { .catch(error => {
res.status(200).send() res.status(200).send()
}) })
} }
@@ -172,6 +178,9 @@ band.patch("/", (req: Request, res: Response) => {
.then(result => { .then(result => {
res.status(200).json(result) res.status(200).json(result)
}) })
.catch(error => {
res.status(500).send()
})
}) })
@@ -183,6 +192,9 @@ band.post("/", (req: Request, res: Response) => {
.then(result => { .then(result => {
res.status(200).json(result) res.status(200).json(result)
}) })
.catch(error => {
res.status(500).send()
})
}) })
/** /**

View File

@@ -8,4 +8,7 @@ city.get("/", (req: Request, res: Response) => {
.then(cities => { .then(cities => {
res.status(200).json(cities) res.status(200).json(cities)
}) })
.catch(error => {
res.status(500).send()
})
}) })

View File

@@ -35,6 +35,9 @@ concert.get("/", (req: Request, res: Response) => {
res.status(200).json(concerts) res.status(200).json(concerts)
}) })
.catch(error => {
res.status(500).send()
})
}) })
@@ -154,4 +157,7 @@ concert.get("/search", (req: Request, res: Response) => {
.then(concerts => { .then(concerts => {
res.status(200).json(concerts) res.status(200).json(concerts)
}) })
.catch(error => {
res.status(500).send()
})
}) })

View File

@@ -11,13 +11,17 @@ export const exercises = Router()
exercises.get("/", (req: Request, res: Response) => { exercises.get("/", (req: Request, res: Response) => {
Exercise.findAll({ Exercise.findAll({
include: [ ExerciseGroup ] include: [ ExerciseGroup ]
}).then(result => { })
.then(result => {
result.sort((a, b) => { result.sort((a, b) => {
return (a.dataValues.exerciseGroup.dataValues.groupNr * 10 + a.dataValues.exerciseNr) > (b.dataValues.exerciseGroup.dataValues.groupNr * 10 + b.dataValues.exerciseNr) ? 1 : -1 return (a.dataValues.exerciseGroup.dataValues.groupNr * 10 + a.dataValues.exerciseNr) > (b.dataValues.exerciseGroup.dataValues.groupNr * 10 + b.dataValues.exerciseNr) ? 1 : -1
}) })
res.status(200).json(result) res.status(200).json(result)
}) })
.catch(error => {
res.status(500).send()
})
}) })
/** /**
@@ -54,21 +58,7 @@ exercises.post("/:groupNr/:exerciseNr/:state", (req: Request, res: Response) =>
changed: changed changed: changed
}) })
}) })
.catch(error => {
res.status(500).send()
// ExerciseGroup.findOne({ })
// where: { groupNr: req.params.groupNr }
// })
// .then(group => {
// Exercise.findOne({
// where: {
// exerciseNr: req.params.exerciseNr,
// exerciseGroupId: group.id
// }
// })
// .then(exercise => {
// exercise.update({ solved: req.params.state == "1"})
// res.status(200).send()
// })
// })
}) })

View File

@@ -58,7 +58,5 @@ files.get("/:folder", async (req: Request, res: Response) => {
* Upload a file * Upload a file
*/ */
files.post("/", upload.single("file"), function (req: Request, res: Response, next: NextFunction) { files.post("/", upload.single("file"), function (req: Request, res: Response, next: NextFunction) {
console.log(req.file)
res.status(200).send() res.status(200).send()
}) })

View File

@@ -98,7 +98,7 @@ location.get("/location/:urlName", (req: Request, res: Response) => {
res.status(200).json(location) res.status(200).json(location)
}) })
.catch(e => { .catch(error => {
res.status(404).send() res.status(404).send()
}) })
}) })
@@ -133,4 +133,7 @@ location.get("/search", (req: Request, res: Response) => {
.then(locations => { .then(locations => {
res.status(200).json(locations) res.status(200).json(locations)
}) })
.catch(error => {
res.status(500).send()
})
}) })

View File

@@ -10,17 +10,15 @@ import { City } from "../models/locations/city.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 { SeatGroup } from "../models/locations/seatGroup.model"; import { SeatGroup } from "../models/locations/seatGroup.model";
import { verifyToken } from "../middlewares/auth.middleware";
import { Account } from "../models/user/account.model"; import { Account } from "../models/user/account.model";
import { Exercise } from "backend/models/exercises/exercise.model";
export const order = Router() export const order = Router()
// Get all orders // Get all orders
order.get("/", (req: Request, res: Response) => { order.get("/", verifyToken, (req: Request, res: Response) => {
Order.findAll({ Order.findAll({
include: [ include: [
Account,
Address,
{ {
model: Ticket, model: Ticket,
include: [ include: [
@@ -35,14 +33,29 @@ order.get("/", (req: Request, res: Response) => {
include: [ City ] include: [ City ]
} }
] ]
},
{
model: Seat,
include: [
{
model: SeatRow,
include: [ SeatGroup ]
} }
] ]
} }
] ]
},
Address,
Payment,
Account
]
}) })
.then(orders => { .then(orders => {
res.status(200).json(orders) res.status(200).json(orders)
}) })
.catch(error => {
res.status(500).send()
})
}) })
@@ -90,6 +103,9 @@ order.get("/:id", (req: Request, res: Response) => {
.then(orders => { .then(orders => {
res.status(200).json(orders) res.status(200).json(orders)
}) })
.catch(error => {
res.status(500).send()
})
}) })
// Place a new order // Place a new order
@@ -116,4 +132,21 @@ order.post("/", (req: Request, res: Response) => {
// Created // Created
res.status(201).json(order) res.status(201).json(order)
}) })
.catch(error => {
res.status(500).send()
})
})
order.patch("/", (req: Request, res: Response) => {
Order.update(req.body, {
where: {
id: req.body.id
}
})
.then(affectedCount => {
res.status(200).send()
})
.catch(error => {
res.status(500).send()
})
}) })

View File

@@ -1,5 +1,6 @@
import axios from "axios" import axios from "axios"
import { BasketItemModel } from "../models/ordering/basketItemModel" import { BasketItemModel } from "../models/ordering/basketItemModel"
import { OrderApiModel } from "../models/apiEndpoints/orderApiModel"
const BASE_URL = "http://localhost:3000/orders" const BASE_URL = "http://localhost:3000/orders"
@@ -25,13 +26,6 @@ export async function createOrder(
} }
} }
console.log({
accountId: accountId,
tickets: tickets,
paymentId: paymentId,
addressId: addressId
})
return axios.post(BASE_URL, { return axios.post(BASE_URL, {
accountId: accountId, accountId: accountId,
tickets: tickets, tickets: tickets,
@@ -40,6 +34,14 @@ export async function createOrder(
}) })
} }
export async function fetchAllOrders() { export async function fetchAllOrders(token: string) {
return axios.get(BASE_URL) return axios.get(BASE_URL, {
headers: {
"Authorization": token
}
})
}
export async function patchOrder(order: OrderApiModel) {
return axios.patch(BASE_URL, order)
} }

View File

@@ -13,7 +13,7 @@ const headers = [
{ title: "Adresse", value: "street" }, { title: "Adresse", value: "street" },
{ title: "Stadt", value: "city" }, { title: "Stadt", value: "city" },
{ title: "Versendet", value: "shipped" }, { title: "Versendet", value: "shipped" },
{ title: "", value: "edit", width: 130 } { title: "Aktionen", value: "edit", width: 130 }
] ]
orderStore.getAllOrders() orderStore.getAllOrders()
@@ -26,6 +26,8 @@ orderStore.getAllOrders()
<v-data-table <v-data-table
:headers="headers" :headers="headers"
:items="orderStore.orders" :items="orderStore.orders"
:loading="orderStore.fetchInProgress"
:items-per-page="100"
> >
<template #item.account="{ item }"> <template #item.account="{ item }">
{{ item.account.firstName }} {{ item.account.lastName }} {{ item.account.firstName }} {{ item.account.lastName }}
@@ -46,23 +48,23 @@ orderStore.getAllOrders()
<template #item.shipped="{ item }"> <template #item.shipped="{ item }">
<v-icon <v-icon
:icon="item.shipped ? 'mdi-check' : 'mdi-close'" :icon="item.shipped ? 'mdi-check' : 'mdi-close'"
:color="item.shipped ? 'green' : 'red'" :color="item.shipped ? 'success' : 'error'"
/> />
</template> </template>
<template #item.edit="{ item }"> <template #item.edit="{ item }">
<!-- todo <v-btn <v-btn
icon="mdi-eye" icon="mdi-eye"
variant="plain" variant="plain"
@click="orderStore.openDetails(item)" @click="orderStore.openDetails(item)"
/> --> />
<!-- todo <v-btn <v-btn
icon="mdi-delete" :icon="item.shipped ? 'mdi-close-circle-outline' : 'mdi-check-circle-outline'"
variant="plain" variant="plain"
color="red" :color="item.shipped ? 'error' : 'success'"
@click="orderStore.deleteOrder(item)" @click="orderStore.changeOrderShippedState(item, !item.shipped)"
/> --> />
</template> </template>
</v-data-table> </v-data-table>

View File

@@ -12,15 +12,67 @@ const orderStore = useOrderStore()
v-model="orderStore.showDetailDialog" v-model="orderStore.showDetailDialog"
:title="$t('order.order')" :title="$t('order.order')"
icon="mdi-basket" icon="mdi-basket"
max-width="800"
> >
<v-list> <v-list>
<v-list-subheader> <v-list-subheader>
{{ $t('ticket.ticket', 2) }} {{ $t('account.account') }}
</v-list-subheader> </v-list-subheader>
<v-list-item v-for="ticket of orderStore.order.tickets"> <v-list-item prepend-icon="mdi-account">
{{ moment(ticket.concert.date).format("DD.MM.YYYY") }} - {{ orderStore.order.account.username }}
{{ ticket.concert.band.name }} - {{ ticket.concert.name }} </v-list-item>
<v-list-item prepend-icon="mdi-card-account-details">
{{ orderStore.order.account.firstName }} {{ orderStore.order.account.lastName }}
</v-list-item>
<v-list-item prepend-icon="mdi-home">
{{ orderStore.order.address.street }} {{ orderStore.order.address.houseNumber }}
</v-list-item>
<v-list-item prepend-icon="mdi-city">
{{ orderStore.order.address.postalCode }} {{ orderStore.order.address.city }}
</v-list-item>
<v-list-subheader>
{{ $t('order.order') }}
</v-list-subheader>
<v-list-item prepend-icon="mdi-calendar">
{{ moment(orderStore.order.orderedAt).format("DD.MM.YYYY, HH:mm:ss") }}
</v-list-item>
<v-list-item prepend-icon="mdi-truck">
{{ orderStore.order.shipped ? 'Versendet' : 'Nicht versendet' }}
</v-list-item>
<v-list-item>
<v-table>
<thead>
<tr>
<th>{{ $t('concert.date') }}</th>
<th>{{ $t('concert.name') }}</th>
<th>{{ $t('band.name') }}</th>
<th>{{ $t('location.name') }}</th>
<th>{{ $t('location.seat.seatGroup') }}</th>
<th>{{ $t('location.seat.seatRow') }}</th>
<th>{{ $t('location.seat.seat') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="ticket of orderStore.order.tickets">
<td>{{ moment(ticket.concert.date).format("DD.MM.YYYY") }}</td>
<td>{{ ticket.concert.name }}</td>
<td>{{ ticket.concert.band.name }}</td>
<td>{{ ticket.concert.location.name }}</td>
<td>{{ ticket.seat.seatRow.seatGroup.name }}</td>
<td>{{ ticket.seat.seatRow.row }}</td>
<td>{{ ticket.seat.seatNr }}</td>
</tr>
</tbody>
</v-table>
</v-list-item> </v-list-item>
</v-list> </v-list>
</action-dialog> </action-dialog>

View File

@@ -19,6 +19,25 @@ function getDotColor(exerciseGroupNr: number) {
case 3: return "pink" case 3: return "pink"
} }
} }
function checksum(num: number) {
let cs = 0
for (; num > 0; num = Math.trunc(num / 10)) {
cs += num % 10;
}
return cs
}
function generateExerciseKey(exerciseGroup: number, exerciseNr: number) {
try {
let matrikelNr = Number(preferencesStore.registrationNumber)
let a = matrikelNr + exerciseGroup * 100 + exerciseNr * 12345678 +
checksum(Number(preferencesStore.registrationNumber)) * 123
return a.toString(16).toUpperCase()
} catch(e) {}
}
</script> </script>
<template> <template>
@@ -97,6 +116,9 @@ function getDotColor(exerciseGroupNr: number) {
:color="exercise.solved ? 'green' : 'primary'" :color="exercise.solved ? 'green' : 'primary'"
> >
{{ preferencesStore.language == LanguageEnum.GERMAN ? exercise.descriptionDe : exercise.descriptionEn }} {{ preferencesStore.language == LanguageEnum.GERMAN ? exercise.descriptionDe : exercise.descriptionEn }}
<div class="pt-2 text-h6">
Solution Code: 0x{{ generateExerciseKey(exercise.exerciseGroup.groupNr, exercise.exerciseNr) }}
</div>
</card-view> </card-view>
</v-timeline-item> </v-timeline-item>
</template> </template>

View File

@@ -91,7 +91,7 @@ export const useAccountStore = defineStore("accountStore", {
this.privilegeBuy = true this.privilegeBuy = true
this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel
if (response.data.accountRoleId == 3) { if (response.data.accountRoleId == 2) {
exerciseStore.solveExercise(2, 5) exerciseStore.solveExercise(2, 5)
} }
}) })

View File

@@ -119,7 +119,6 @@ export const useBasketStore = defineStore('basketStore', {
for (let item of this.itemsInBasket) { for (let item of this.itemsInBasket) {
if (!item.concert.offered) { if (!item.concert.offered) {
exerciseStore.solveExercise(1, 2) exerciseStore.solveExercise(1, 2)
feedbackStore.addSnackbar(BannerStateEnum.EXERCISESOLVED12)
} }
} }

View File

@@ -1,16 +1,19 @@
import { fetchAllOrders, fetchUserOrders } from "@/data/api/orderApi"; import { fetchAllOrders, fetchUserOrders, patchOrder } from "@/data/api/orderApi";
import { OrderApiModel } from "@/data/models/apiEndpoints/orderApiModel"; import { OrderApiModel } from "@/data/models/apiEndpoints/orderApiModel";
import { AccountModel } from "@/data/models/user/accountModel"; import { AccountModel } from "@/data/models/user/accountModel";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { useAccountStore } from "./account.store";
export const useOrderStore = defineStore("orderStore", { export const useOrderStore = defineStore("orderStore", {
state: () => ({ state: () => ({
/** All orders of one/all users */ /** All orders of one/all users */
orders: ref<Array<OrderApiModel>>([]), orders: ref<Array<OrderApiModel>>([]),
/** Current selected order */
order: ref<OrderApiModel>(new OrderApiModel), order: ref<OrderApiModel>(new OrderApiModel),
/** Show detail dialog on admin page */
showDetailDialog: ref<boolean>(false), showDetailDialog: ref<boolean>(false),
/** Request to server sent, waiting for data response */ /** Request to server sent, waiting for data response */
@@ -22,9 +25,10 @@ export const useOrderStore = defineStore("orderStore", {
* Get all orders from all accounts from server * Get all orders from all accounts from server
*/ */
async getAllOrders() { async getAllOrders() {
const accountStore = useAccountStore()
this.fetchInProgress = true this.fetchInProgress = true
fetchAllOrders() fetchAllOrders(accountStore.userAccountToken)
.then(res => { .then(res => {
this.orders = res.data this.orders = res.data
this.fetchInProgress = false this.fetchInProgress = false
@@ -46,13 +50,31 @@ export const useOrderStore = defineStore("orderStore", {
}) })
}, },
/**
* Open detail dialog
*
* @param order Order to view
*/
openDetails(order: OrderApiModel) { openDetails(order: OrderApiModel) {
this.order = order this.order = order
this.showDetailDialog = true this.showDetailDialog = true
}, },
async deleteOrder(order: OrderApiModel) {
// todo /**
*
* @param order
* @param shipped
*/
async changeOrderShippedState(order: OrderApiModel, shipped: boolean) {
this.fetchInProgress = true
order.shipped = shipped
patchOrder(order)
.then(res => {
this.getAllOrders()
})
} }
} }
}) })