Compare commits
9 Commits
da484b08a9
...
v.0.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
| a58adbcc8d | |||
| 8a18b95031 | |||
| c867d9d51f | |||
| 4905ef607b | |||
| 2c18c59f51 | |||
| d622fda7a9 | |||
| 831a667a27 | |||
| 947ed225b6 | |||
| b74da2dc3b |
@@ -4,29 +4,19 @@
|
||||
"id": 0,
|
||||
"name": "Unregistered",
|
||||
"privilegeBuy": false,
|
||||
"privilegeAdminPanel": false,
|
||||
"privilegeFileAccess": false
|
||||
"privilegeAdminPanel": false
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "User",
|
||||
"privilegeBuy": true,
|
||||
"privilegeAdminPanel": false,
|
||||
"privilegeFileAccess": false
|
||||
"privilegeAdminPanel": false
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Admin",
|
||||
"privilegeBuy": true,
|
||||
"privilegeAdminPanel": true,
|
||||
"privilegeFileAccess": false
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Super-Admin",
|
||||
"privilegeBuy": true,
|
||||
"privilegeAdminPanel": true,
|
||||
"privilegeFileAccess": true
|
||||
"privilegeAdminPanel": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"iban": "DE92500105175721645777"
|
||||
}
|
||||
],
|
||||
"accountRoleId": 2
|
||||
"accountRoleId": 1
|
||||
},
|
||||
{
|
||||
"username": "katjaStoiber",
|
||||
@@ -94,7 +94,7 @@
|
||||
"iban": "DE41500105172184936679"
|
||||
}
|
||||
],
|
||||
"accountRoleId": 3
|
||||
"accountRoleId": 2
|
||||
},
|
||||
{
|
||||
"username": "guitarhero",
|
||||
|
||||
@@ -18,35 +18,42 @@ account.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
.then(accounts => {
|
||||
res.status(200).json(accounts)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
// Login user
|
||||
account.get("/account/login", async (req: Request, res: Response) => {
|
||||
const encryptedPassword = encryptString(String(req.query.password))
|
||||
|
||||
// Using raw SQL code for SQL injections!
|
||||
const [results, metadata] =
|
||||
await sequelize.query(
|
||||
"SELECT * FROM Accounts " +
|
||||
"WHERE (username='" + req.query.username +
|
||||
"' AND password='" + encryptedPassword + "')"
|
||||
)
|
||||
try {
|
||||
// Using raw SQL code for SQL injections!
|
||||
const [results, metadata] =
|
||||
await sequelize.query(
|
||||
"SELECT * FROM Accounts " +
|
||||
"WHERE (username='" + req.query.username +
|
||||
"' AND password='" + encryptedPassword + "')"
|
||||
)
|
||||
|
||||
if (results.length != 0) {
|
||||
// Creating session token
|
||||
const token = jwt.sign({ userId: results[0]["id"] }, 'sjcucjdkdf')
|
||||
if (results.length != 0) {
|
||||
// Creating session token
|
||||
const token = jwt.sign({ userId: results[0]["id"] }, 'sjcucjdkdf')
|
||||
|
||||
// Status: 200 OK
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
token: token
|
||||
})
|
||||
} else {
|
||||
// Status: 401 Unauthorized
|
||||
res.status(401).json({
|
||||
code: 401,
|
||||
message: "Unauthorized"
|
||||
})
|
||||
// Status: 200 OK
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
token: token
|
||||
})
|
||||
} else {
|
||||
// Status: 401 Unauthorized
|
||||
res.status(401).json({
|
||||
code: 401,
|
||||
message: "Unauthorized"
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -61,6 +68,9 @@ account.get("/account/data", verifyToken, async(req: Request, res: Response) =>
|
||||
.then(account => {
|
||||
res.status(200).json(account)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -102,7 +112,7 @@ account.post("/account", async (req: Request, res: Response) => {
|
||||
.then(account => {
|
||||
// Status: 201 Created
|
||||
res.status(201).json(account)
|
||||
}).catch(reason => {
|
||||
}).catch(error => {
|
||||
// Status: 409 Conflict
|
||||
res.status(409).json({
|
||||
code: 409,
|
||||
@@ -117,32 +127,28 @@ account.patch("/account", verifyToken, (req: Request, res: Response) => {
|
||||
where: { id: req.body.id }
|
||||
})
|
||||
.then(async result => {
|
||||
for (let payment of req.body.payments) {
|
||||
if (payment.id == undefined) {
|
||||
payment["accountId"] = req.body.id
|
||||
|
||||
await Payment.create(payment)
|
||||
} else {
|
||||
await Payment.update(payment,
|
||||
{
|
||||
where: { id: payment.id }
|
||||
}
|
||||
)
|
||||
Payment.destroy({
|
||||
where: {
|
||||
accountId: req.body.id
|
||||
}
|
||||
})
|
||||
|
||||
Address.destroy({
|
||||
where: {
|
||||
accountId: req.body.id
|
||||
}
|
||||
})
|
||||
|
||||
for (let payment of req.body.payments) {
|
||||
payment["accountId"] = req.body.id
|
||||
|
||||
await Payment.create(payment)
|
||||
}
|
||||
|
||||
for (let address of req.body.addresses) {
|
||||
if (address.id == undefined) {
|
||||
address["accountId"] = req.body.id
|
||||
address["accountId"] = req.body.id
|
||||
|
||||
await Address.create(address)
|
||||
} else {
|
||||
await Address.update(address,
|
||||
{
|
||||
where: { id: address.id }
|
||||
}
|
||||
)
|
||||
}
|
||||
await Address.create(address)
|
||||
}
|
||||
|
||||
// Status: 200 OK
|
||||
@@ -167,4 +173,7 @@ account.delete("/account/:id", (req: Request, res: Response) => {
|
||||
.then(account => {
|
||||
res.status(200).send()
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -21,16 +21,14 @@ band.get("/", (req: Request, res: Response) => {
|
||||
|
||||
Band.findAll({
|
||||
include: [
|
||||
{
|
||||
model: Rating,
|
||||
},
|
||||
{
|
||||
model: Genre,
|
||||
attributes: {
|
||||
exclude: [ "id" ]
|
||||
}
|
||||
},
|
||||
Concert
|
||||
Concert,
|
||||
Rating
|
||||
]
|
||||
})
|
||||
.then(bands => {
|
||||
@@ -65,6 +63,9 @@ band.get("/", (req: Request, res: Response) => {
|
||||
|
||||
res.status(200).json(bands)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -122,7 +123,7 @@ band.get("/band/:name", (req: Request, res: Response) => {
|
||||
|
||||
res.status(200).json(band)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch(error => {
|
||||
res.status(404).send()
|
||||
})
|
||||
})
|
||||
@@ -137,10 +138,13 @@ band.get("/search", async (req: Request, res: Response) => {
|
||||
|
||||
// On stacked prompts, execute last prompt
|
||||
if (prompts.length > 1) {
|
||||
const [results, metadata] =
|
||||
await sequelize.query(prompts[prompts.length - 2])
|
||||
|
||||
res.status(200).json(results)
|
||||
try {
|
||||
const [results, metadata] =
|
||||
await sequelize.query(prompts[prompts.length - 2])
|
||||
res.status(200).json(results)
|
||||
} catch (e) {
|
||||
res.status(400).send()
|
||||
}
|
||||
} else {
|
||||
Band.findAll({
|
||||
where: {
|
||||
@@ -153,7 +157,7 @@ band.get("/search", async (req: Request, res: Response) => {
|
||||
.then(bands => {
|
||||
res.status(200).json(bands)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch(error => {
|
||||
res.status(200).send()
|
||||
})
|
||||
}
|
||||
@@ -172,6 +176,9 @@ band.patch("/", (req: Request, res: Response) => {
|
||||
.then(result => {
|
||||
res.status(200).json(result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -183,6 +190,9 @@ band.post("/", (req: Request, res: Response) => {
|
||||
.then(result => {
|
||||
res.status(200).json(result)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,4 +8,7 @@ city.get("/", (req: Request, res: Response) => {
|
||||
.then(cities => {
|
||||
res.status(200).json(cities)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -35,6 +35,9 @@ concert.get("/", (req: Request, res: Response) => {
|
||||
|
||||
res.status(200).json(concerts)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -154,4 +157,7 @@ concert.get("/search", (req: Request, res: Response) => {
|
||||
.then(concerts => {
|
||||
res.status(200).json(concerts)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -11,13 +11,17 @@ export const exercises = Router()
|
||||
exercises.get("/", (req: Request, res: Response) => {
|
||||
Exercise.findAll({
|
||||
include: [ ExerciseGroup ]
|
||||
}).then(result => {
|
||||
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
|
||||
})
|
||||
|
||||
res.status(200).json(result)
|
||||
})
|
||||
.then(result => {
|
||||
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
|
||||
})
|
||||
|
||||
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
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// 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()
|
||||
// })
|
||||
// })
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -3,6 +3,7 @@ import fs, { createReadStream } from "fs"
|
||||
import multer from "multer"
|
||||
const upload = multer({ dest: './backend/images/' })
|
||||
import licenses from "../data/licenses.json"
|
||||
import path from 'path'
|
||||
|
||||
export const files = Router()
|
||||
|
||||
@@ -10,13 +11,13 @@ export const files = Router()
|
||||
* Get all folders
|
||||
*/
|
||||
files.get("/folders", async (req: Request, res: Response) => {
|
||||
let dirNames = fs.readdirSync("./backend/images")
|
||||
let dirNames = fs.readdirSync(path.resolve(__dirname, "../images"))
|
||||
let result = []
|
||||
|
||||
dirNames.forEach(dir => {
|
||||
result.push({
|
||||
name: dir,
|
||||
nrOfItems: fs.readdirSync("./backend/images/" + dir).length
|
||||
nrOfItems: fs.readdirSync(path.resolve(__dirname, "../images/" + dir)).length
|
||||
})
|
||||
})
|
||||
|
||||
@@ -31,26 +32,30 @@ files.get("/folders", async (req: Request, res: Response) => {
|
||||
*/
|
||||
files.get("/:folder", async (req: Request, res: Response) => {
|
||||
let result = []
|
||||
let fileNames = fs.readdirSync("./backend/images/" + req.params.folder + "/")
|
||||
let fileNames = fs.readdirSync(path.resolve(__dirname, "../images/" + req.params.folder))
|
||||
|
||||
fileNames.forEach(file => {
|
||||
let resData = ""
|
||||
let url = "http://localhost:3000/static/" + req.params.folder + "/" + file
|
||||
try {
|
||||
fileNames.forEach(file => {
|
||||
let resData = ""
|
||||
let url = "http://localhost:3000/static/" + req.params.folder + "/" + file
|
||||
|
||||
if (file.endsWith("html") || file.endsWith("js")) {
|
||||
resData = fs.readFileSync("./backend/images/" + req.params.folder + "/" + file, "utf8")
|
||||
}
|
||||
if (file.endsWith("html") || file.endsWith("js")) {
|
||||
resData = fs.readFileSync(path.resolve(__dirname, "../images/" + req.params.folder + "/" + file), "utf8")
|
||||
}
|
||||
|
||||
result.push({
|
||||
name: file,
|
||||
size: fs.statSync("./backend/images/" + req.params.folder + "/" + file).size,
|
||||
content: resData,
|
||||
url: url,
|
||||
copyright: licenses.find(data => data.image == file)
|
||||
result.push({
|
||||
name: file,
|
||||
size: fs.statSync(path.resolve(__dirname, "../images/" + req.params.folder + "/" + file)).size,
|
||||
content: resData,
|
||||
url: url,
|
||||
copyright: licenses.find(data => data.image == file)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
res.status(200).json(result)
|
||||
res.status(200).json(result)
|
||||
} catch (error) {
|
||||
res.status(400).json(error)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -58,7 +63,5 @@ files.get("/:folder", async (req: Request, res: Response) => {
|
||||
* Upload a file
|
||||
*/
|
||||
files.post("/", upload.single("file"), function (req: Request, res: Response, next: NextFunction) {
|
||||
console.log(req.file)
|
||||
|
||||
res.status(200).send()
|
||||
})
|
||||
@@ -98,7 +98,7 @@ location.get("/location/:urlName", (req: Request, res: Response) => {
|
||||
|
||||
res.status(200).json(location)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch(error => {
|
||||
res.status(404).send()
|
||||
})
|
||||
})
|
||||
@@ -133,4 +133,7 @@ location.get("/search", (req: Request, res: Response) => {
|
||||
.then(locations => {
|
||||
res.status(200).json(locations)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
@@ -10,17 +10,15 @@ import { City } from "../models/locations/city.model";
|
||||
import { Seat } from "../models/locations/seat.model";
|
||||
import { SeatRow } from "../models/locations/seatRow.model";
|
||||
import { SeatGroup } from "../models/locations/seatGroup.model";
|
||||
import { verifyToken } from "../middlewares/auth.middleware";
|
||||
import { Account } from "../models/user/account.model";
|
||||
import { Exercise } from "backend/models/exercises/exercise.model";
|
||||
|
||||
export const order = Router()
|
||||
|
||||
// Get all orders
|
||||
order.get("/", (req: Request, res: Response) => {
|
||||
order.get("/", verifyToken, (req: Request, res: Response) => {
|
||||
Order.findAll({
|
||||
include: [
|
||||
Account,
|
||||
Address,
|
||||
{
|
||||
model: Ticket,
|
||||
include: [
|
||||
@@ -35,14 +33,29 @@ order.get("/", (req: Request, res: Response) => {
|
||||
include: [ City ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
model: Seat,
|
||||
include: [
|
||||
{
|
||||
model: SeatRow,
|
||||
include: [ SeatGroup ]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
Address,
|
||||
Payment,
|
||||
Account
|
||||
]
|
||||
})
|
||||
.then(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 => {
|
||||
res.status(200).json(orders)
|
||||
})
|
||||
.catch(error => {
|
||||
res.status(500).send()
|
||||
})
|
||||
})
|
||||
|
||||
// Place a new order
|
||||
@@ -116,4 +132,21 @@ order.post("/", (req: Request, res: Response) => {
|
||||
// Created
|
||||
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()
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eventmaster",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"author": "Tobias Zoghaib",
|
||||
"description": "Hackable ticket store for educational purposes",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -12,7 +12,7 @@ defineProps({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-card variant="outlined" class="my-1 mx-2 px-2">
|
||||
<v-card variant="outlined" class="my-1 px-2">
|
||||
<v-row class="d-flex justify-center align-center">
|
||||
<v-col class="text-caption text-left" v-if="descriptionText.length > 0">
|
||||
{{ descriptionText }}
|
||||
|
||||
@@ -37,7 +37,7 @@ defineProps({
|
||||
{{ secondLine }}
|
||||
</v-skeleton-loader>
|
||||
|
||||
<template #actions>
|
||||
<template #actions v-if="!$slots.actions">
|
||||
<outlined-button
|
||||
@click="router.push(buttonRoute)"
|
||||
:loading="loading"
|
||||
@@ -45,6 +45,10 @@ defineProps({
|
||||
{{ $t('misc.actions.more') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
|
||||
<template #actions v-else>
|
||||
<slot name="actions"></slot>
|
||||
</template>
|
||||
</card-view>
|
||||
</v-col>
|
||||
</template>
|
||||
@@ -1,5 +1,6 @@
|
||||
import axios from "axios"
|
||||
import { BasketItemModel } from "../models/ordering/basketItemModel"
|
||||
import { OrderApiModel } from "../models/apiEndpoints/orderApiModel"
|
||||
|
||||
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, {
|
||||
accountId: accountId,
|
||||
tickets: tickets,
|
||||
@@ -40,6 +34,14 @@ export async function createOrder(
|
||||
})
|
||||
}
|
||||
|
||||
export async function fetchAllOrders() {
|
||||
return axios.get(BASE_URL)
|
||||
export async function fetchAllOrders(token: string) {
|
||||
return axios.get(BASE_URL, {
|
||||
headers: {
|
||||
"Authorization": token
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function patchOrder(order: OrderApiModel) {
|
||||
return axios.patch(BASE_URL, order)
|
||||
}
|
||||
@@ -74,7 +74,7 @@
|
||||
"emailIsNotValid": "Ungültige E-Mail Addresse",
|
||||
"emailRequired": "E-Mail-Adresse benötigt",
|
||||
"accountManagement": "Account verwalten",
|
||||
"accountManagementDescription": "Persönliche Daten, Adressen, Bezahlmethoden",
|
||||
"accountManagementDescription": "Persönliche Daten, Konto löschen",
|
||||
"login": {
|
||||
"pleaseLoginToOrder": "Bitte anmelden zum bestellen",
|
||||
"backToLogin": "Zurück zum Login",
|
||||
@@ -109,7 +109,16 @@
|
||||
"addNewAccount": "Neuen Account hinzufügen",
|
||||
"accountRole": "Account Rolle",
|
||||
"noRealPaymentsNeeded": "Keine echten Kontodaten nötig!",
|
||||
"administrator": "Administrator | Administratoren"
|
||||
"administrator": "Administrator | Administratoren",
|
||||
"managePaymentsDescription": "Bezahlarten hinzufügen, ändern, löschen",
|
||||
"paymentsManagement": "Bezahlarten verwalten",
|
||||
"payments": {
|
||||
"editPayment": "Bezahlart bearbeiten",
|
||||
"editAddress": "Adresse bearbeiten"
|
||||
},
|
||||
"addressManagementDetails": "Adressen hinzufügen, ändern, löschen",
|
||||
"addressManagement": "Adressen verwalten",
|
||||
"sessionTime": "Session time"
|
||||
},
|
||||
"order": {
|
||||
"oclock": "Uhr",
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"emailIsNotValid": "E-Mail not valid",
|
||||
"emailRequired": "E-Mail required",
|
||||
"accountManagement": "Manage Account",
|
||||
"accountManagementDescription": "Personal data, addresses, payments",
|
||||
"accountManagementDescription": "Personal data, delete account",
|
||||
"login": {
|
||||
"pleaseLoginToOrder": "Please login to order",
|
||||
"backToLogin": "Back to Login",
|
||||
@@ -109,7 +109,16 @@
|
||||
"addNewAccount": "Add new account",
|
||||
"accountRole": "Account Role",
|
||||
"noRealPaymentsNeeded": "No real payment data required!",
|
||||
"administrator": "Administrator"
|
||||
"administrator": "Administrator",
|
||||
"managePaymentsDescription": "Add, change, remove payments",
|
||||
"paymentsManagement": "Manage payments",
|
||||
"payments": {
|
||||
"editPayment": "Edit Payment",
|
||||
"editAddress": "Edit address"
|
||||
},
|
||||
"addressManagementDetails": "Add, change, remove addresses",
|
||||
"addressManagement": "Manage addresses",
|
||||
"sessionTime": "Session time"
|
||||
},
|
||||
"order": {
|
||||
"oclock": "o'clock",
|
||||
|
||||
79
src/pages/account/accountAddressesPage/addressEditDialog.vue
Normal file
79
src/pages/account/accountAddressesPage/addressEditDialog.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||
import OutlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { getIbanRules, getNumberStartRules, getPostalRules, getStringRules } from '@/scripts/validationRules';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import cardViewOneLine from '@/components/basics/cardViewOneLine.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const valid = ref(false)
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<action-dialog
|
||||
v-model="accountStore.showEditDialog"
|
||||
max-width="800"
|
||||
:title="$t('account.payments.editAddress')"
|
||||
>
|
||||
<v-container>
|
||||
<v-form v-model="valid">
|
||||
<v-row class="pt-5">
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.street')"
|
||||
v-model="accountStore.address.street"
|
||||
:rules="getStringRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.houseNumber')"
|
||||
v-model="accountStore.address.houseNumber"
|
||||
:rules="getNumberStartRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.postalCode')"
|
||||
v-model="accountStore.address.postalCode"
|
||||
:rules="getPostalRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.placeOfResidence')"
|
||||
v-model="accountStore.address.city"
|
||||
:rules="getStringRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-form>
|
||||
|
||||
</v-container>
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
color="success"
|
||||
prepend-icon="mdi-content-save"
|
||||
:disabled="!valid"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
@click="accountStore.saveAddress"
|
||||
>
|
||||
{{ $t('misc.actions.save') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</action-dialog>
|
||||
</template>
|
||||
51
src/pages/account/accountAddressesPage/index.vue
Normal file
51
src/pages/account/accountAddressesPage/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
import addressEditDialog from './addressEditDialog.vue';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
const feedbackStore = useFeedbackStore()
|
||||
|
||||
const headers = [
|
||||
{ title: feedbackStore.i18n.t('account.userData.street'), value: "street" },
|
||||
{ title: feedbackStore.i18n.t('account.userData.houseNumber'), value: "houseNumber" },
|
||||
{ title: feedbackStore.i18n.t('account.userData.postalCode'), value: "postalCode" },
|
||||
{ title: feedbackStore.i18n.t('account.userData.placeOfResidence'), value: "city" },
|
||||
{ title: "Aktionen", value: "actions", width: 130 }
|
||||
]
|
||||
|
||||
accountStore.refreshAccount()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<data-layout
|
||||
:add-button-string="$t('misc.actions.add')"
|
||||
:fetch-in-progress="accountStore.fetchInProgress"
|
||||
:on-add-click="() => { accountStore.newAddress() }"
|
||||
>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="accountStore.userAccount.addresses"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
>
|
||||
<template #item.actions="{ item }">
|
||||
<v-btn
|
||||
icon="mdi-pencil"
|
||||
variant="plain"
|
||||
color="orange"
|
||||
@click="accountStore.editAddress(item)"
|
||||
/>
|
||||
|
||||
<v-btn
|
||||
icon="mdi-delete"
|
||||
variant="plain"
|
||||
color="red"
|
||||
@click="accountStore.removeAddress(item)"
|
||||
/>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</data-layout>
|
||||
|
||||
<address-edit-dialog />
|
||||
</template>
|
||||
@@ -81,7 +81,6 @@ const stringRules = [
|
||||
v-model="accountStore.userAccount.firstName"
|
||||
variant="outlined"
|
||||
:rules="stringRules"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
@@ -90,7 +89,6 @@ const stringRules = [
|
||||
v-model="accountStore.userAccount.lastName"
|
||||
variant="outlined"
|
||||
:rules="stringRules"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { AddressModel } from '@/data/models/user/addressModel';
|
||||
import { getNumberStartRules, getPostalRules, getStringRules } from '@/scripts/validationRules';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view
|
||||
icon="mdi-home"
|
||||
:title="$t('account.userData.address', 2)"
|
||||
>
|
||||
<v-expansion-panels v-if="accountStore.userAccount.addresses.length > 0">
|
||||
<v-expansion-panel
|
||||
v-for="address in accountStore.userAccount.addresses"
|
||||
color="primary"
|
||||
>
|
||||
<template #title>
|
||||
<div v-if="address.street != undefined">
|
||||
{{ address.street }}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div v-if="address.houseNumber != undefined">
|
||||
{{ address.houseNumber }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #text>
|
||||
<v-row class="pt-5">
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.street')"
|
||||
v-model="address.street"
|
||||
:rules="getStringRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.houseNumber')"
|
||||
v-model="address.houseNumber"
|
||||
:rules="getNumberStartRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.postalCode')"
|
||||
v-model="address.postalCode"
|
||||
:rules="getPostalRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.placeOfResidence')"
|
||||
v-model="address.city"
|
||||
:rules="getStringRules()"
|
||||
variant="outlined"
|
||||
clearable
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-center align-center">
|
||||
<outlined-button
|
||||
@click="accountStore.removeAddress(address)"
|
||||
color="error"
|
||||
prepend-icon="mdi-delete"
|
||||
>
|
||||
{{ $t('misc.actions.remove') }}
|
||||
</outlined-button>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
|
||||
<v-empty-state
|
||||
v-else
|
||||
:title="$t('account.noAddresses')"
|
||||
icon="mdi-home-off"
|
||||
/>
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
@click="accountStore.userAccount.addresses.push(new AddressModel())"
|
||||
prepend-icon="mdi-plus"
|
||||
color="success"
|
||||
>
|
||||
{{ $t('misc.actions.add') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</card-view>
|
||||
</template>
|
||||
@@ -1,8 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import accountDataCard from './accountDataCard.vue';
|
||||
import accountManagingCard from './accountManagingCard.vue';
|
||||
import addressesCard from './addressesCard.vue';
|
||||
import paymentsCard from './paymentsCard.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import accountSubPageLayout from '@/layouts/accountSubPageLayout.vue';
|
||||
|
||||
@@ -17,18 +15,6 @@ const router = useRouter()
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<addresses-card />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<payments-card />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<account-managing-card />
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { PaymentModel } from '@/data/models/user/paymentModel';
|
||||
import { getIbanRules, getStringRules } from '@/scripts/validationRules';
|
||||
import cardViewOneLine from '@/components/basics/cardViewOneLine.vue';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<card-view
|
||||
icon="mdi-currency-usd"
|
||||
:title="$t('account.userData.payment', 2)"
|
||||
>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view-one-line
|
||||
color="warning"
|
||||
prepend-icon="mdi-alert"
|
||||
:title="$t('account.noRealPaymentsNeeded')"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-if="accountStore.userAccount.payments.length > 0">
|
||||
<v-col>
|
||||
<v-expansion-panels>
|
||||
<v-expansion-panel
|
||||
v-for="payment in accountStore.userAccount.payments"
|
||||
color="primary"
|
||||
>
|
||||
<template #title>
|
||||
{{ payment.bankName }}
|
||||
</template>
|
||||
<template #text>
|
||||
<v-row class="pt-5">
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.bankName')"
|
||||
v-model="payment.bankName"
|
||||
:rules="getStringRules()"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.iban')"
|
||||
v-model="payment.iban"
|
||||
:rules="getIbanRules()"
|
||||
variant="outlined"
|
||||
hide-details
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="d-flex justify-center align-center">
|
||||
<outlined-button
|
||||
@click="accountStore.removePayment(payment)"
|
||||
color="error"
|
||||
prepend-icon="mdi-delete"
|
||||
>
|
||||
{{ $t('misc.actions.remove') }}
|
||||
</outlined-button>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row v-else>
|
||||
<v-col>
|
||||
<v-empty-state
|
||||
:title="$t('account.noPayments')"
|
||||
icon="mdi-currency-usd-off"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
@click="accountStore.userAccount.payments.push(new PaymentModel())"
|
||||
prepend-icon="mdi-plus"
|
||||
color="success"
|
||||
>
|
||||
{{ $t('misc.actions.add') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</card-view>
|
||||
</template>
|
||||
@@ -1,60 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import cardView from '@/components/basics/cardView.vue';
|
||||
import dashboardCard from '@/components/pageParts/dashboardCard.vue';
|
||||
import { useOrderStore } from '@/stores/order.store';
|
||||
import OutlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import moment from 'moment';
|
||||
import { millisecondsToHumanReadableString } from '@/scripts/dateTimeScripts';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
const orderStore = useOrderStore()
|
||||
const router = useRouter()
|
||||
|
||||
orderStore.getOrdersOfAccount(accountStore.userAccount)
|
||||
accountStore.refreshAccount()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
:title="$t('misc.greeting', { msg: accountStore.userAccount.username })"
|
||||
icon="mdi-hand-wave"
|
||||
>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
:title="$t('order.order', 2)"
|
||||
icon="mdi-basket-check"
|
||||
@click="router.push('/account/orders')"
|
||||
>
|
||||
{{ $t('order.ordersDescription') }}
|
||||
</card-view>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<dashboard-card
|
||||
:title="$t('order.order', 2)"
|
||||
icon="mdi-basket-check"
|
||||
:first-line="orderStore.orders.length + ' ' + $t('order.order', 2)"
|
||||
:second-line="$t('order.ordersDescription')"
|
||||
button-route="/account/orders"
|
||||
:loading="orderStore.fetchInProgress"
|
||||
/>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
:title="$t('account.accountManagement')"
|
||||
icon="mdi-account"
|
||||
@click="router.push('/account/data')"
|
||||
>
|
||||
{{ $t('account.accountManagementDescription') }}
|
||||
</card-view>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<dashboard-card
|
||||
:title="$t('account.accountManagement')"
|
||||
icon="mdi-account"
|
||||
:first-line="accountStore.userAccount.username"
|
||||
:second-line="$t('account.accountManagementDescription')"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
button-route="/account/data"
|
||||
/>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
:title="$t('account.logout.logout')"
|
||||
icon="mdi-logout"
|
||||
@click="accountStore.logout(); router.push('/account/login')"
|
||||
>
|
||||
{{ $t('account.logout.logoutDescription') }}
|
||||
</card-view>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</card-view>
|
||||
|
||||
</v-col>
|
||||
<dashboard-card
|
||||
:title="$t('account.addressManagement')"
|
||||
icon="mdi-city"
|
||||
:first-line="accountStore.userAccount.addresses?.length + ' ' +
|
||||
$t('account.userData.address', accountStore.userAccount.addresses?.length)"
|
||||
:second-line="$t('account.addressManagementDetails')"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
button-route="/account/addresses"
|
||||
/>
|
||||
|
||||
<dashboard-card
|
||||
:title="$t('account.paymentsManagement', 2)"
|
||||
icon="mdi-currency-eur"
|
||||
:first-line="accountStore.userAccount.payments?.length + ' ' +
|
||||
$t('account.userData.payment', accountStore.userAccount.payments?.length)"
|
||||
:second-line="$t('account.managePaymentsDescription')"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
button-route="/account/payments"
|
||||
/>
|
||||
|
||||
<dashboard-card
|
||||
:title="$t('account.logout.logout')"
|
||||
:first-line="millisecondsToHumanReadableString(moment().diff(moment(accountStore.loggedInTimeStamp))) + ' h ' + $t('account.sessionTime')"
|
||||
:second-line="$t('account.logout.logoutDescription')"
|
||||
icon="mdi-logout"
|
||||
>
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
color="error"
|
||||
@click="accountStore.logout(); router.push('/account/login')"
|
||||
>
|
||||
{{ $t('account.logout.logout') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</dashboard-card>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
49
src/pages/account/accountPaymentsPage/index.vue
Normal file
49
src/pages/account/accountPaymentsPage/index.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
import PaymentEditDialog from './paymentEditDialog.vue';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
const feedbackStore = useFeedbackStore()
|
||||
|
||||
const headers = [
|
||||
{ title: feedbackStore.i18n.t('account.userData.bankName'), value: "bankName" },
|
||||
{ title: feedbackStore.i18n.t('account.userData.iban'), value: "iban" },
|
||||
{ title: "Aktionen", value: "actions", width: 130 }
|
||||
]
|
||||
|
||||
accountStore.refreshAccount()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<data-layout
|
||||
:add-button-string="$t('misc.actions.add')"
|
||||
:fetch-in-progress="accountStore.fetchInProgress"
|
||||
:on-add-click="() => { accountStore.newPayment() }"
|
||||
>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="accountStore.userAccount.payments"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
>
|
||||
<template #item.actions="{ item }">
|
||||
<v-btn
|
||||
icon="mdi-pencil"
|
||||
variant="plain"
|
||||
color="orange"
|
||||
@click="accountStore.editPayment(item)"
|
||||
/>
|
||||
|
||||
<v-btn
|
||||
icon="mdi-delete"
|
||||
variant="plain"
|
||||
color="red"
|
||||
@click="accountStore.removePayment(item)"
|
||||
/>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</data-layout>
|
||||
|
||||
<payment-edit-dialog />
|
||||
</template>
|
||||
69
src/pages/account/accountPaymentsPage/paymentEditDialog.vue
Normal file
69
src/pages/account/accountPaymentsPage/paymentEditDialog.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||
import OutlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import { getIbanRules, getStringRules } from '@/scripts/validationRules';
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import cardViewOneLine from '@/components/basics/cardViewOneLine.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const valid = ref(false)
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<action-dialog
|
||||
v-model="accountStore.showEditDialog"
|
||||
max-width="800"
|
||||
:title="$t('account.payments.editPayment')"
|
||||
>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view-one-line
|
||||
color="warning"
|
||||
prepend-icon="mdi-alert"
|
||||
:title="$t('account.noRealPaymentsNeeded')"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-form v-model="valid">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.bankName')"
|
||||
v-model="accountStore.payment.bankName"
|
||||
:rules="getStringRules(8)"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field
|
||||
:label="$t('account.userData.iban')"
|
||||
v-model="accountStore.payment.iban"
|
||||
:rules="getIbanRules()"
|
||||
variant="outlined"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-form>
|
||||
|
||||
</v-container>
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
color="success"
|
||||
prepend-icon="mdi-content-save"
|
||||
:disabled="!valid"
|
||||
:loading="accountStore.fetchInProgress"
|
||||
@click="accountStore.savePayment"
|
||||
>
|
||||
{{ $t('misc.actions.save') }}
|
||||
</outlined-button>
|
||||
</template>
|
||||
</action-dialog>
|
||||
</template>
|
||||
@@ -10,6 +10,7 @@ const accountStore = useAccountStore()
|
||||
async function registerAccount() {
|
||||
accountStore.registerAccount()
|
||||
.then(result => {
|
||||
console.log(result)
|
||||
if (result) {
|
||||
showRegisterCard.value = false
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { useAccountStore } from '@/stores/account.store';
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
|
||||
const accountStore = useAccountStore()
|
||||
@@ -19,7 +19,7 @@ accountStore.getAllAccounts()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:add-button-string="$t('account.addNewAccount')"
|
||||
:fetch-in-progress="accountStore.fetchInProgress"
|
||||
>
|
||||
@@ -44,5 +44,5 @@ accountStore.getAllAccounts()
|
||||
/> -->
|
||||
</template>
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
</template>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { useBandStore } from '@/stores/band.store';
|
||||
import bandEditDialog from './bandEditDialog.vue';
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
|
||||
const bandStore = useBandStore()
|
||||
@@ -22,7 +22,7 @@ bandStore.getBands()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:add-button-string="$t('band.addNewBand')"
|
||||
:fetch-in-progress="bandStore.fetchInProgress"
|
||||
:on-add-click="() => bandStore.newBand()"
|
||||
@@ -72,7 +72,7 @@ bandStore.getBands()
|
||||
/> -->
|
||||
</template>
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
|
||||
<band-edit-dialog />
|
||||
</template>
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useBandStore } from '@/stores/band.store';
|
||||
import { useConcertStore } from '@/stores/concert.store';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import moment from 'moment';
|
||||
|
||||
const concertStore = useConcertStore()
|
||||
@@ -25,7 +25,7 @@ concertStore.getConcerts()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:add-button-string="$t('concert.addNewConcert')"
|
||||
:fetch-in-progress="concertStore.fetchInProgress"
|
||||
:on-add-click="() => concertStore.newConcert()"
|
||||
@@ -73,5 +73,5 @@ concertStore.getConcerts()
|
||||
/> -->
|
||||
</template>
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
</template>
|
||||
@@ -5,7 +5,7 @@ import { useAccountStore } from '@/stores/account.store';
|
||||
import { useLocationStore } from '@/stores/location.store';
|
||||
import { useGenreStore } from '@/stores/genre.store';
|
||||
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||
import dashboardCard from './dashboardCard.vue';
|
||||
import dashboardCard from '../../../components/pageParts/dashboardCard.vue';
|
||||
import { useOrderStore } from '@/stores/order.store';
|
||||
import { useFilesStore } from '@/stores/files.store';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { ref } from 'vue';
|
||||
import FileUploadDialog from './fileUploadDialog.vue';
|
||||
import { useFilesStore } from '@/stores/files.store';
|
||||
@@ -12,7 +12,7 @@ filesStore.getStaticFolders()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:add-button-string="$t('misc.uploadFile')"
|
||||
:fetch-in-progress="filesStore.fetchInProgress"
|
||||
:on-add-click="() => { filesStore.showFileUploadDialog = true }"
|
||||
@@ -112,7 +112,7 @@ filesStore.getStaticFolders()
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
|
||||
<file-preview-dialog
|
||||
v-model:show-dialog="showPreviewDialog"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import genreEditDialog from './genreEditDialog.vue';
|
||||
import { useGenreStore } from '@/stores/genre.store';
|
||||
|
||||
@@ -15,7 +15,7 @@ genreStore.getGenres()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:add-button-string="$t('band.addNewGenre')"
|
||||
:fetch-in-progress="genreStore.fetchInProgress"
|
||||
:on-add-click="() => { genreStore.newGenre() }"
|
||||
@@ -48,7 +48,7 @@ genreStore.getGenres()
|
||||
/> -->
|
||||
</template>
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
|
||||
<genre-edit-dialog />
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
import { useLocationStore } from '@/stores/location.store';
|
||||
|
||||
@@ -22,7 +22,7 @@ locationStore.getLocations()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:fetch-in-progress="locationStore.fetchInProgress"
|
||||
:add-button-string="$t('location.addLocation')"
|
||||
:on-add-click="() => { locationStore.newLocation() }"
|
||||
@@ -66,5 +66,5 @@ locationStore.getLocations()
|
||||
/> -->
|
||||
</template>
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
||||
import dataLayout from '@/layouts/dataLayout.vue';
|
||||
import { useOrderStore } from '@/stores/order.store';
|
||||
import moment from 'moment';
|
||||
import OrderDetailDialog from './orderDetailDialog.vue';
|
||||
@@ -13,19 +13,21 @@ const headers = [
|
||||
{ title: "Adresse", value: "street" },
|
||||
{ title: "Stadt", value: "city" },
|
||||
{ title: "Versendet", value: "shipped" },
|
||||
{ title: "", value: "edit", width: 130 }
|
||||
{ title: "Aktionen", value: "edit", width: 130 }
|
||||
]
|
||||
|
||||
orderStore.getAllOrders()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<admin-data-layout
|
||||
<data-layout
|
||||
:hide-add-button="true"
|
||||
>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="orderStore.orders"
|
||||
:loading="orderStore.fetchInProgress"
|
||||
:items-per-page="100"
|
||||
>
|
||||
<template #item.account="{ item }">
|
||||
{{ item.account.firstName }} {{ item.account.lastName }}
|
||||
@@ -46,27 +48,27 @@ orderStore.getAllOrders()
|
||||
<template #item.shipped="{ item }">
|
||||
<v-icon
|
||||
:icon="item.shipped ? 'mdi-check' : 'mdi-close'"
|
||||
:color="item.shipped ? 'green' : 'red'"
|
||||
:color="item.shipped ? 'success' : 'error'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #item.edit="{ item }">
|
||||
<!-- todo <v-btn
|
||||
<v-btn
|
||||
icon="mdi-eye"
|
||||
variant="plain"
|
||||
@click="orderStore.openDetails(item)"
|
||||
/> -->
|
||||
/>
|
||||
|
||||
<!-- todo <v-btn
|
||||
icon="mdi-delete"
|
||||
<v-btn
|
||||
:icon="item.shipped ? 'mdi-close-circle-outline' : 'mdi-check-circle-outline'"
|
||||
variant="plain"
|
||||
color="red"
|
||||
@click="orderStore.deleteOrder(item)"
|
||||
/> -->
|
||||
:color="item.shipped ? 'error' : 'success'"
|
||||
@click="orderStore.changeOrderShippedState(item, !item.shipped)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
</v-data-table>
|
||||
</admin-data-layout>
|
||||
</data-layout>
|
||||
|
||||
<order-detail-dialog />
|
||||
</template>
|
||||
@@ -12,15 +12,67 @@ const orderStore = useOrderStore()
|
||||
v-model="orderStore.showDetailDialog"
|
||||
:title="$t('order.order')"
|
||||
icon="mdi-basket"
|
||||
max-width="800"
|
||||
>
|
||||
<v-list>
|
||||
<v-list-subheader>
|
||||
{{ $t('ticket.ticket', 2) }}
|
||||
{{ $t('account.account') }}
|
||||
</v-list-subheader>
|
||||
|
||||
<v-list-item v-for="ticket of orderStore.order.tickets">
|
||||
{{ moment(ticket.concert.date).format("DD.MM.YYYY") }} -
|
||||
{{ ticket.concert.band.name }} - {{ ticket.concert.name }}
|
||||
<v-list-item prepend-icon="mdi-account">
|
||||
{{ orderStore.order.account.username }}
|
||||
</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>
|
||||
</action-dialog>
|
||||
|
||||
@@ -19,6 +19,22 @@ function getDotColor(exerciseGroupNr: number) {
|
||||
case 3: return "pink"
|
||||
}
|
||||
}
|
||||
|
||||
function generateExerciseKey() {
|
||||
try {
|
||||
let code = ""
|
||||
|
||||
for (let i = 0; i < 13; i++) {
|
||||
if (exerciseStore.exercises[i].solved) {
|
||||
code += "3"
|
||||
} else {
|
||||
code += "0"
|
||||
}
|
||||
}
|
||||
|
||||
return (Number(code) + Number(preferencesStore.registrationNumber)) * 237
|
||||
} catch(e) {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -26,20 +42,7 @@ function getDotColor(exerciseGroupNr: number) {
|
||||
<v-row>
|
||||
<v-spacer />
|
||||
|
||||
<v-col
|
||||
v-if="preferencesStore.studentName.length < 3 || preferencesStore.registrationNumber.length < 7"
|
||||
cols="auto"
|
||||
>
|
||||
<card-view variant="outlined" >
|
||||
{{ $t('misc.fulfillYourPersonalDataFirst') }}
|
||||
</card-view>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="auto">
|
||||
<v-tooltip :text="$t('misc.fulfillYourPersonalDataFirst')">
|
||||
<template #activator="{ props }"></template>
|
||||
|
||||
</v-tooltip>
|
||||
<outlined-button
|
||||
prepend-icon="mdi-file-pdf-box"
|
||||
@click="generateResultsPdf()"
|
||||
@@ -50,6 +53,17 @@ function getDotColor(exerciseGroupNr: number) {
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="text-h5 text-center">
|
||||
<div>
|
||||
Persönlicher Lösungsschlüssel:
|
||||
</div>
|
||||
<div>
|
||||
{{ generateExerciseKey() }}
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<card-view
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||
import ServerStateText from '@/components/pageParts/serverStateText.vue';
|
||||
import { getRegisterNumberRules, getStringRules } from '@/scripts/validationRules';
|
||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||
import { ref, watch } from 'vue';
|
||||
@@ -135,9 +136,9 @@ watch(() => currentStep.value, () => {
|
||||
<v-col>
|
||||
<v-text-field
|
||||
variant="outlined"
|
||||
hide-details
|
||||
:label="$t('misc.yourFullName')"
|
||||
v-model="preferencesStore.studentName"
|
||||
:rules="getStringRules(4)"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -146,9 +147,9 @@ watch(() => currentStep.value, () => {
|
||||
<v-col>
|
||||
<v-text-field
|
||||
variant="outlined"
|
||||
hide-details
|
||||
:label="$t('misc.registrationNumber')"
|
||||
v-model="preferencesStore.registrationNumber"
|
||||
:rules="getRegisterNumberRules()"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -177,8 +178,8 @@ watch(() => currentStep.value, () => {
|
||||
<outlined-button
|
||||
v-else
|
||||
@click="showDialog = false; preferencesStore.firstStartup = false"
|
||||
:disabled="preferencesStore.studentName.length == 0 ||
|
||||
preferencesStore.registrationNumber.length == 0"
|
||||
:disabled="preferencesStore.studentName.length < 5 ||
|
||||
preferencesStore.registrationNumber.length < 8"
|
||||
prepend-icon="mdi-check"
|
||||
color="success"
|
||||
>
|
||||
|
||||
@@ -16,6 +16,8 @@ import PreferencesPage from "@/pages/misc/preferencesPage/index.vue";
|
||||
import HelpPage from "@/pages/misc/helpPage/index.vue"
|
||||
import ErrorPage from "@/pages/misc/errorPage/index.vue"
|
||||
import ImageLicensePage from "@/pages/misc/imageLicensePage/index.vue"
|
||||
import AccountPaymentsPage from "@/pages/account/accountPaymentsPage/index.vue"
|
||||
import AccountAddressesPage from "@/pages/account/accountAddressesPage/index.vue"
|
||||
|
||||
const routes = [
|
||||
// Main page
|
||||
@@ -32,6 +34,8 @@ const routes = [
|
||||
{ path: '/account/orders', component: OrdersPage },
|
||||
{ path: '/account/data', component: AccountDataPage },
|
||||
{ path: '/account/login', component: LoginPage },
|
||||
{ path: '/account/payments', component: AccountPaymentsPage },
|
||||
{ path: '/account/addresses', component: AccountAddressesPage },
|
||||
|
||||
// Admin
|
||||
...adminRoutes,
|
||||
|
||||
@@ -20,4 +20,16 @@ export function dateToHumanReadableString(date: Date) {
|
||||
*/
|
||||
export function dateStringToHumanReadableString(string: string) {
|
||||
return dateToHumanReadableString(new Date(string))
|
||||
}
|
||||
|
||||
/**
|
||||
* Format milliseconds to a readable format
|
||||
*
|
||||
* @param milliseconds Milliseconds to format
|
||||
*
|
||||
* @returns h:mm format
|
||||
*/
|
||||
export function millisecondsToHumanReadableString(milliseconds: number): string {
|
||||
return Math.floor(milliseconds / 1000 / 60 / 60) + ':' +
|
||||
String(Math.floor(milliseconds / 60000)).padStart(2, "0") + ''
|
||||
}
|
||||
@@ -168,4 +168,32 @@ export function getIbanRules() {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export function getRegisterNumberRules() {
|
||||
const feedbackStore = useFeedbackStore()
|
||||
|
||||
return [
|
||||
value => {
|
||||
if (value) {
|
||||
return true
|
||||
} else {
|
||||
return feedbackStore.i18n.t('misc.validation.required')
|
||||
}
|
||||
},
|
||||
value => {
|
||||
if (value?.length >= 8) {
|
||||
return true
|
||||
} else {
|
||||
return feedbackStore.i18n.t('misc.validation.notEnoughChars')
|
||||
}
|
||||
},
|
||||
value => {
|
||||
if(!isNaN(value) && !isNaN(parseFloat(value))) {
|
||||
return true
|
||||
} else {
|
||||
return feedbackStore.i18n.t('misc.validation.onlyDigitsAllowed')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import { AccountApiModel } from "../data/models/user/accountApiModel";
|
||||
import { ref } from "vue";
|
||||
import { defineStore } from "pinia";
|
||||
import { useExerciseStore } from "./exercise.store";
|
||||
import moment, { Moment } from "moment";
|
||||
|
||||
export const useAccountStore = defineStore("accountStore", {
|
||||
state: () => ({
|
||||
@@ -17,10 +18,10 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
accounts: ref<Array<AccountApiModel>>([]),
|
||||
|
||||
/** Server token of currently logged in account */
|
||||
userAccountToken: useLocalStorage("hackmycart/accountStore/userAccountToken", ""),
|
||||
userAccountToken: useLocalStorage("eventMaster/accountStore/userAccountToken", ""),
|
||||
|
||||
/** Useraccount which is currently logged in */
|
||||
userAccount: useLocalStorage("hackmycart/accountStore/userAccount", new AccountApiModel()),
|
||||
userAccount: useLocalStorage("eventMaster/accountStore/userAccount", new AccountApiModel()),
|
||||
|
||||
/** User input on login screen */
|
||||
loginData: ref<{ username: String, password: String}>(
|
||||
@@ -37,7 +38,15 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
adminPanelVisible: ref(false),
|
||||
|
||||
/** Flag to activate buy option on basket page */
|
||||
privilegeBuy: ref(false)
|
||||
privilegeBuy: ref(false),
|
||||
|
||||
payment: ref(),
|
||||
|
||||
address: ref(),
|
||||
|
||||
showEditDialog: ref(false),
|
||||
|
||||
loggedInTimeStamp: useLocalStorage<string>("eventMaster/accountStore/loggedInTimeStamp", "")
|
||||
}),
|
||||
|
||||
actions: {
|
||||
@@ -80,6 +89,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
await getLogin(this.loginData.username, this.loginData.password)
|
||||
.then(async result => {
|
||||
this.userAccountToken = result.data.token
|
||||
this.loggedInTimeStamp = moment().format("YYYY-MM-DDTHH:mm:ss.SSS")
|
||||
|
||||
getAccount(this.userAccountToken)
|
||||
.then(response => {
|
||||
@@ -91,7 +101,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
this.privilegeBuy = true
|
||||
this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel
|
||||
|
||||
if (response.data.accountRoleId == 3) {
|
||||
if (response.data.accountRoleId == 2) {
|
||||
exerciseStore.solveExercise(2, 5)
|
||||
}
|
||||
})
|
||||
@@ -113,14 +123,16 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
* Reload account information about current logged in user
|
||||
*/
|
||||
async refreshAccount() {
|
||||
this.fetchInProgress = true
|
||||
|
||||
getAccount(this.userAccountToken)
|
||||
.then(response => {
|
||||
this.userAccount = response.data
|
||||
|
||||
this.fetchInProgress = false
|
||||
|
||||
this.privilegeBuy = true
|
||||
this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel
|
||||
|
||||
this.fetchInProgress = false
|
||||
})
|
||||
},
|
||||
|
||||
@@ -133,6 +145,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
async registerAccount(): Promise<boolean> {
|
||||
const feedbackStore = useFeedbackStore()
|
||||
const exerciseStore = useExerciseStore()
|
||||
let success = false
|
||||
this.fetchInProgress = true
|
||||
|
||||
if (this.registerData.username == null || this.registerData.username.length < 4) {
|
||||
@@ -142,7 +155,8 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
} else if (!this.registerData.email.match(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
|
||||
feedbackStore.addSnackbar(BannerStateEnum.ACCOUNTMAILADDRESSUNVALID)
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
await registerAccount(this.registerData)
|
||||
.then(async res => {
|
||||
if (res.status == 201) {
|
||||
@@ -156,6 +170,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
}
|
||||
|
||||
this.fetchInProgress = false
|
||||
success = true
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.status == 400) {
|
||||
@@ -165,12 +180,11 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
}
|
||||
|
||||
this.fetchInProgress = false
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
this.fetchInProgress = false
|
||||
return false
|
||||
return success
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -179,6 +193,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
async updateAccount() {
|
||||
const feedbackStore = useFeedbackStore()
|
||||
const exerciseStore = useExerciseStore()
|
||||
this.fetchInProgress = true
|
||||
|
||||
// Check for exercise 0.2 completion
|
||||
let accountComplete = this.userAccount.firstName != "" && this.userAccount.lastName != "" &&
|
||||
@@ -196,6 +211,7 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
feedbackStore.addSnackbar(BannerStateEnum.ACCOUNTUPDATESUCCESSFUL)
|
||||
|
||||
this.userAccount = res.data
|
||||
this.fetchInProgress = false
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -229,6 +245,33 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
})
|
||||
},
|
||||
|
||||
newAddress() {
|
||||
this.address = new AddressModel()
|
||||
this.showEditDialog = true
|
||||
},
|
||||
|
||||
editAddress(address: AddressModel) {
|
||||
this.address = address
|
||||
this.showEditDialog = true
|
||||
},
|
||||
|
||||
async saveAddress() {
|
||||
this.fetchInProgress = true
|
||||
|
||||
if (this.address.id == undefined) {
|
||||
this.userAccount.addresses.push(this.address)
|
||||
} else {
|
||||
this.userAccount.addresses = this.userAccount.addresses.filter(address => {
|
||||
return address.id != this.address.id
|
||||
})
|
||||
|
||||
this.userAccount.addresses.push(this.address)
|
||||
}
|
||||
|
||||
await this.updateAccount()
|
||||
this.showEditDialog = false
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an address from the user model
|
||||
*
|
||||
@@ -238,17 +281,59 @@ export const useAccountStore = defineStore("accountStore", {
|
||||
this.userAccount.addresses = this.userAccount.addresses.filter((addr: AddressModel) =>
|
||||
addr != address
|
||||
)
|
||||
|
||||
this.updateAccount()
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an payment from the user model
|
||||
* Add a new payment, opens dialog
|
||||
*/
|
||||
newPayment() {
|
||||
this.payment = new PaymentModel()
|
||||
this.showEditDialog = true
|
||||
},
|
||||
|
||||
/**
|
||||
* Edit existing payment, opens dialog
|
||||
*
|
||||
* @param payment Payment dataset to edit
|
||||
*/
|
||||
editPayment(payment: PaymentModel) {
|
||||
this.payment = payment
|
||||
this.showEditDialog = true
|
||||
},
|
||||
|
||||
/**
|
||||
* Save current edited payment
|
||||
*/
|
||||
async savePayment() {
|
||||
this.fetchInProgress = true
|
||||
|
||||
if (this.payment.id == undefined) {
|
||||
this.userAccount.payments.push(this.payment)
|
||||
} else {
|
||||
this.userAccount.payments = this.userAccount.payments.filter(payment => {
|
||||
return payment.id != this.payment.id
|
||||
})
|
||||
|
||||
this.userAccount.payments.push(this.payment)
|
||||
}
|
||||
|
||||
await this.updateAccount()
|
||||
this.showEditDialog = false
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a payment from the user model
|
||||
*
|
||||
* @param address Payment dataset to remove
|
||||
*/
|
||||
removePayment(payment: PaymentModel) {
|
||||
this.userAccount.payments = this.userAccount.payments.filter((paym: PaymentModel) =>
|
||||
async removePayment(payment: PaymentModel) {
|
||||
this.userAccount.payments = await this.userAccount.payments.filter((paym: PaymentModel) =>
|
||||
paym != payment
|
||||
)
|
||||
|
||||
this.updateAccount()
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ import { useExerciseStore } from "./exercise.store";
|
||||
export const useBasketStore = defineStore('basketStore', {
|
||||
state: () => ({
|
||||
/** Items in customers basket */
|
||||
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/itemsInBasket", []),
|
||||
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("eventMaster/basketStore/itemsInBasket", []),
|
||||
|
||||
/** Address used in the order dialog */
|
||||
usedAddress: ref<AddressModel>(null),
|
||||
@@ -119,7 +119,6 @@ export const useBasketStore = defineStore('basketStore', {
|
||||
for (let item of this.itemsInBasket) {
|
||||
if (!item.concert.offered) {
|
||||
exerciseStore.solveExercise(1, 2)
|
||||
feedbackStore.addSnackbar(BannerStateEnum.EXERCISESOLVED12)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { AccountModel } from "@/data/models/user/accountModel";
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import { useAccountStore } from "./account.store";
|
||||
|
||||
export const useOrderStore = defineStore("orderStore", {
|
||||
state: () => ({
|
||||
/** All orders of one/all users */
|
||||
orders: ref<Array<OrderApiModel>>([]),
|
||||
|
||||
/** Current selected order */
|
||||
order: ref<OrderApiModel>(new OrderApiModel),
|
||||
|
||||
/** Show detail dialog on admin page */
|
||||
showDetailDialog: ref<boolean>(false),
|
||||
|
||||
/** 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
|
||||
*/
|
||||
async getAllOrders() {
|
||||
const accountStore = useAccountStore()
|
||||
this.fetchInProgress = true
|
||||
|
||||
fetchAllOrders()
|
||||
fetchAllOrders(accountStore.userAccountToken)
|
||||
.then(res => {
|
||||
this.orders = res.data
|
||||
this.fetchInProgress = false
|
||||
@@ -46,13 +50,31 @@ export const useOrderStore = defineStore("orderStore", {
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Open detail dialog
|
||||
*
|
||||
* @param order Order to view
|
||||
*/
|
||||
openDetails(order: OrderApiModel) {
|
||||
this.order = order
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -15,10 +15,10 @@ import { AccountApiModel } from "@/data/models/user/accountApiModel";
|
||||
export const usePreferencesStore = defineStore('preferencesStore', {
|
||||
state: () => ({
|
||||
/** Selected theme by user */
|
||||
theme: useLocalStorage<ThemeEnum>("hackmycart/preferencesStore/theme", ThemeEnum.DARK),
|
||||
theme: useLocalStorage<ThemeEnum>("eventMaster/preferencesStore/theme", ThemeEnum.DARK),
|
||||
|
||||
/** Selected language by user */
|
||||
language: useLocalStorage<LanguageEnum>("hackmycart/preferencesStore/language", LanguageEnum.GERMAN),
|
||||
language: useLocalStorage<LanguageEnum>("eventMaster/preferencesStore/language", LanguageEnum.GERMAN),
|
||||
|
||||
/** Request to server sent, waiting for data response */
|
||||
fetchInProgress: ref(false),
|
||||
@@ -36,13 +36,13 @@ export const usePreferencesStore = defineStore('preferencesStore', {
|
||||
showFactoryResetDialog: ref(false),
|
||||
|
||||
/** Marks the first run of the app */
|
||||
firstStartup: useLocalStorage<Boolean>("hackmycart/preferencesStore/firstStartup", true),
|
||||
firstStartup: useLocalStorage<Boolean>("eventMaster/preferencesStore/firstStartup", true),
|
||||
|
||||
/** Full name of student */
|
||||
studentName: useLocalStorage<string>("hackmycart/preferencesStore/studentName", ""),
|
||||
studentName: useLocalStorage<string>("eventMaster/preferencesStore/studentName", ""),
|
||||
|
||||
/** Matrikel number */
|
||||
registrationNumber: useLocalStorage<string>("hackmycart/preferencesStore/registrationNumber", "")
|
||||
registrationNumber: useLocalStorage<string>("eventMaster/preferencesStore/registrationNumber", "")
|
||||
}),
|
||||
|
||||
actions: {
|
||||
|
||||
Reference in New Issue
Block a user