Compare commits
9 Commits
da484b08a9
...
v.0.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
| a58adbcc8d | |||
| 8a18b95031 | |||
| c867d9d51f | |||
| 4905ef607b | |||
| 2c18c59f51 | |||
| d622fda7a9 | |||
| 831a667a27 | |||
| 947ed225b6 | |||
| b74da2dc3b |
@@ -1,4 +1,4 @@
|
|||||||
# HackMyCart
|
# EventMaster
|
||||||
|
|
||||||
The most hackable Web Shop!
|
The most hackable Web Shop!
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -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",
|
||||||
|
|||||||
@@ -18,35 +18,42 @@ 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
|
||||||
account.get("/account/login", async (req: Request, res: Response) => {
|
account.get("/account/login", async (req: Request, res: Response) => {
|
||||||
const encryptedPassword = encryptString(String(req.query.password))
|
const encryptedPassword = encryptString(String(req.query.password))
|
||||||
|
|
||||||
// Using raw SQL code for SQL injections!
|
try {
|
||||||
const [results, metadata] =
|
// Using raw SQL code for SQL injections!
|
||||||
await sequelize.query(
|
const [results, metadata] =
|
||||||
"SELECT * FROM Accounts " +
|
await sequelize.query(
|
||||||
"WHERE (username='" + req.query.username +
|
"SELECT * FROM Accounts " +
|
||||||
"' AND password='" + encryptedPassword + "')"
|
"WHERE (username='" + req.query.username +
|
||||||
)
|
"' AND password='" + encryptedPassword + "')"
|
||||||
|
)
|
||||||
|
|
||||||
if (results.length != 0) {
|
if (results.length != 0) {
|
||||||
// Creating session token
|
// Creating session token
|
||||||
const token = jwt.sign({ userId: results[0]["id"] }, 'sjcucjdkdf')
|
const token = jwt.sign({ userId: results[0]["id"] }, 'sjcucjdkdf')
|
||||||
|
|
||||||
// Status: 200 OK
|
// Status: 200 OK
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
token: token
|
token: token
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Status: 401 Unauthorized
|
// Status: 401 Unauthorized
|
||||||
res.status(401).json({
|
res.status(401).json({
|
||||||
code: 401,
|
code: 401,
|
||||||
message: "Unauthorized"
|
message: "Unauthorized"
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
res.status(500).send()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -61,6 +68,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 +112,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,
|
||||||
@@ -117,32 +127,28 @@ account.patch("/account", verifyToken, (req: Request, res: Response) => {
|
|||||||
where: { id: req.body.id }
|
where: { id: req.body.id }
|
||||||
})
|
})
|
||||||
.then(async result => {
|
.then(async result => {
|
||||||
for (let payment of req.body.payments) {
|
Payment.destroy({
|
||||||
if (payment.id == undefined) {
|
where: {
|
||||||
payment["accountId"] = req.body.id
|
accountId: req.body.id
|
||||||
|
|
||||||
await Payment.create(payment)
|
|
||||||
} else {
|
|
||||||
await Payment.update(payment,
|
|
||||||
{
|
|
||||||
where: { id: payment.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) {
|
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)
|
await Address.create(address)
|
||||||
} else {
|
|
||||||
await Address.update(address,
|
|
||||||
{
|
|
||||||
where: { id: address.id }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status: 200 OK
|
// Status: 200 OK
|
||||||
@@ -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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -21,16 +21,14 @@ band.get("/", (req: Request, res: Response) => {
|
|||||||
|
|
||||||
Band.findAll({
|
Band.findAll({
|
||||||
include: [
|
include: [
|
||||||
{
|
|
||||||
model: Rating,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
model: Genre,
|
model: Genre,
|
||||||
attributes: {
|
attributes: {
|
||||||
exclude: [ "id" ]
|
exclude: [ "id" ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Concert
|
Concert,
|
||||||
|
Rating
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.then(bands => {
|
.then(bands => {
|
||||||
@@ -65,6 +63,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 +123,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 +138,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) {
|
||||||
const [results, metadata] =
|
try {
|
||||||
await sequelize.query(prompts[prompts.length - 2])
|
const [results, metadata] =
|
||||||
|
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 +157,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 +176,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 +190,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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -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 => {
|
|
||||||
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
|
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()
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
})
|
})
|
||||||
@@ -3,6 +3,7 @@ import fs, { createReadStream } from "fs"
|
|||||||
import multer from "multer"
|
import multer from "multer"
|
||||||
const upload = multer({ dest: './backend/images/' })
|
const upload = multer({ dest: './backend/images/' })
|
||||||
import licenses from "../data/licenses.json"
|
import licenses from "../data/licenses.json"
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
export const files = Router()
|
export const files = Router()
|
||||||
|
|
||||||
@@ -10,13 +11,13 @@ export const files = Router()
|
|||||||
* Get all folders
|
* Get all folders
|
||||||
*/
|
*/
|
||||||
files.get("/folders", async (req: Request, res: Response) => {
|
files.get("/folders", async (req: Request, res: Response) => {
|
||||||
let dirNames = fs.readdirSync("./backend/images")
|
let dirNames = fs.readdirSync(path.resolve(__dirname, "../images"))
|
||||||
let result = []
|
let result = []
|
||||||
|
|
||||||
dirNames.forEach(dir => {
|
dirNames.forEach(dir => {
|
||||||
result.push({
|
result.push({
|
||||||
name: dir,
|
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) => {
|
files.get("/:folder", async (req: Request, res: Response) => {
|
||||||
let result = []
|
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 => {
|
try {
|
||||||
let resData = ""
|
fileNames.forEach(file => {
|
||||||
let url = "http://localhost:3000/static/" + req.params.folder + "/" + file
|
let resData = ""
|
||||||
|
let url = "http://localhost:3000/static/" + req.params.folder + "/" + file
|
||||||
|
|
||||||
if (file.endsWith("html") || file.endsWith("js")) {
|
if (file.endsWith("html") || file.endsWith("js")) {
|
||||||
resData = fs.readFileSync("./backend/images/" + req.params.folder + "/" + file, "utf8")
|
resData = fs.readFileSync(path.resolve(__dirname, "../images/" + req.params.folder + "/" + file), "utf8")
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
name: file,
|
name: file,
|
||||||
size: fs.statSync("./backend/images/" + req.params.folder + "/" + file).size,
|
size: fs.statSync(path.resolve(__dirname, "../images/" + req.params.folder + "/" + file)).size,
|
||||||
content: resData,
|
content: resData,
|
||||||
url: url,
|
url: url,
|
||||||
copyright: licenses.find(data => data.image == file)
|
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
|
* 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()
|
||||||
})
|
})
|
||||||
@@ -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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -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()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eventmaster",
|
"name": "eventmaster",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"author": "Tobias Zoghaib",
|
"author": "Tobias Zoghaib",
|
||||||
"description": "Hackable ticket store for educational purposes",
|
"description": "Hackable ticket store for educational purposes",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ defineProps({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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-row class="d-flex justify-center align-center">
|
||||||
<v-col class="text-caption text-left" v-if="descriptionText.length > 0">
|
<v-col class="text-caption text-left" v-if="descriptionText.length > 0">
|
||||||
{{ descriptionText }}
|
{{ descriptionText }}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ defineProps({
|
|||||||
{{ secondLine }}
|
{{ secondLine }}
|
||||||
</v-skeleton-loader>
|
</v-skeleton-loader>
|
||||||
|
|
||||||
<template #actions>
|
<template #actions v-if="!$slots.actions">
|
||||||
<outlined-button
|
<outlined-button
|
||||||
@click="router.push(buttonRoute)"
|
@click="router.push(buttonRoute)"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
@@ -45,6 +45,10 @@ defineProps({
|
|||||||
{{ $t('misc.actions.more') }}
|
{{ $t('misc.actions.more') }}
|
||||||
</outlined-button>
|
</outlined-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #actions v-else>
|
||||||
|
<slot name="actions"></slot>
|
||||||
|
</template>
|
||||||
</card-view>
|
</card-view>
|
||||||
</v-col>
|
</v-col>
|
||||||
</template>
|
</template>
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"emailIsNotValid": "Ungültige E-Mail Addresse",
|
"emailIsNotValid": "Ungültige E-Mail Addresse",
|
||||||
"emailRequired": "E-Mail-Adresse benötigt",
|
"emailRequired": "E-Mail-Adresse benötigt",
|
||||||
"accountManagement": "Account verwalten",
|
"accountManagement": "Account verwalten",
|
||||||
"accountManagementDescription": "Persönliche Daten, Adressen, Bezahlmethoden",
|
"accountManagementDescription": "Persönliche Daten, Konto löschen",
|
||||||
"login": {
|
"login": {
|
||||||
"pleaseLoginToOrder": "Bitte anmelden zum bestellen",
|
"pleaseLoginToOrder": "Bitte anmelden zum bestellen",
|
||||||
"backToLogin": "Zurück zum Login",
|
"backToLogin": "Zurück zum Login",
|
||||||
@@ -109,7 +109,16 @@
|
|||||||
"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"
|
"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": {
|
"order": {
|
||||||
"oclock": "Uhr",
|
"oclock": "Uhr",
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"emailIsNotValid": "E-Mail not valid",
|
"emailIsNotValid": "E-Mail not valid",
|
||||||
"emailRequired": "E-Mail required",
|
"emailRequired": "E-Mail required",
|
||||||
"accountManagement": "Manage Account",
|
"accountManagement": "Manage Account",
|
||||||
"accountManagementDescription": "Personal data, addresses, payments",
|
"accountManagementDescription": "Personal data, delete account",
|
||||||
"login": {
|
"login": {
|
||||||
"pleaseLoginToOrder": "Please login to order",
|
"pleaseLoginToOrder": "Please login to order",
|
||||||
"backToLogin": "Back to Login",
|
"backToLogin": "Back to Login",
|
||||||
@@ -109,7 +109,16 @@
|
|||||||
"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"
|
"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": {
|
"order": {
|
||||||
"oclock": "o'clock",
|
"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"
|
v-model="accountStore.userAccount.firstName"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:rules="stringRules"
|
:rules="stringRules"
|
||||||
hide-details
|
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col>
|
<v-col>
|
||||||
@@ -90,7 +89,6 @@ const stringRules = [
|
|||||||
v-model="accountStore.userAccount.lastName"
|
v-model="accountStore.userAccount.lastName"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
:rules="stringRules"
|
:rules="stringRules"
|
||||||
hide-details
|
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</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">
|
<script setup lang="ts">
|
||||||
import accountDataCard from './accountDataCard.vue';
|
import accountDataCard from './accountDataCard.vue';
|
||||||
import accountManagingCard from './accountManagingCard.vue';
|
import accountManagingCard from './accountManagingCard.vue';
|
||||||
import addressesCard from './addressesCard.vue';
|
|
||||||
import paymentsCard from './paymentsCard.vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import accountSubPageLayout from '@/layouts/accountSubPageLayout.vue';
|
import accountSubPageLayout from '@/layouts/accountSubPageLayout.vue';
|
||||||
|
|
||||||
@@ -17,18 +15,6 @@ const router = useRouter()
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</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-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<account-managing-card />
|
<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">
|
<script setup lang="ts">
|
||||||
import { useAccountStore } from '@/stores/account.store';
|
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 { useRouter } from 'vue-router';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { millisecondsToHumanReadableString } from '@/scripts/dateTimeScripts';
|
||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
|
const orderStore = useOrderStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
orderStore.getOrdersOfAccount(accountStore.userAccount)
|
||||||
|
accountStore.refreshAccount()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-container max-width="1000">
|
<v-container>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>
|
<dashboard-card
|
||||||
<card-view
|
:title="$t('order.order', 2)"
|
||||||
:title="$t('misc.greeting', { msg: accountStore.userAccount.username })"
|
icon="mdi-basket-check"
|
||||||
icon="mdi-hand-wave"
|
:first-line="orderStore.orders.length + ' ' + $t('order.order', 2)"
|
||||||
>
|
:second-line="$t('order.ordersDescription')"
|
||||||
<v-container>
|
button-route="/account/orders"
|
||||||
<v-row>
|
:loading="orderStore.fetchInProgress"
|
||||||
<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>
|
|
||||||
|
|
||||||
<v-row>
|
<dashboard-card
|
||||||
<v-col>
|
:title="$t('account.accountManagement')"
|
||||||
<card-view
|
icon="mdi-account"
|
||||||
:title="$t('account.accountManagement')"
|
:first-line="accountStore.userAccount.username"
|
||||||
icon="mdi-account"
|
:second-line="$t('account.accountManagementDescription')"
|
||||||
@click="router.push('/account/data')"
|
:loading="accountStore.fetchInProgress"
|
||||||
>
|
button-route="/account/data"
|
||||||
{{ $t('account.accountManagementDescription') }}
|
/>
|
||||||
</card-view>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
|
|
||||||
<v-row>
|
<dashboard-card
|
||||||
<v-col>
|
:title="$t('account.addressManagement')"
|
||||||
<card-view
|
icon="mdi-city"
|
||||||
:title="$t('account.logout.logout')"
|
:first-line="accountStore.userAccount.addresses?.length + ' ' +
|
||||||
icon="mdi-logout"
|
$t('account.userData.address', accountStore.userAccount.addresses?.length)"
|
||||||
@click="accountStore.logout(); router.push('/account/login')"
|
:second-line="$t('account.addressManagementDetails')"
|
||||||
>
|
:loading="accountStore.fetchInProgress"
|
||||||
{{ $t('account.logout.logoutDescription') }}
|
button-route="/account/addresses"
|
||||||
</card-view>
|
/>
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</v-container>
|
|
||||||
</card-view>
|
|
||||||
|
|
||||||
</v-col>
|
<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-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</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() {
|
async function registerAccount() {
|
||||||
accountStore.registerAccount()
|
accountStore.registerAccount()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
|
console.log(result)
|
||||||
if (result) {
|
if (result) {
|
||||||
showRegisterCard.value = false
|
showRegisterCard.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAccountStore } from '@/stores/account.store';
|
import { useAccountStore } from '@/stores/account.store';
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
|
|
||||||
const accountStore = useAccountStore()
|
const accountStore = useAccountStore()
|
||||||
@@ -19,7 +19,7 @@ accountStore.getAllAccounts()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:add-button-string="$t('account.addNewAccount')"
|
:add-button-string="$t('account.addNewAccount')"
|
||||||
:fetch-in-progress="accountStore.fetchInProgress"
|
:fetch-in-progress="accountStore.fetchInProgress"
|
||||||
>
|
>
|
||||||
@@ -44,5 +44,5 @@ accountStore.getAllAccounts()
|
|||||||
/> -->
|
/> -->
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
</template>
|
</template>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useBandStore } from '@/stores/band.store';
|
import { useBandStore } from '@/stores/band.store';
|
||||||
import bandEditDialog from './bandEditDialog.vue';
|
import bandEditDialog from './bandEditDialog.vue';
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
|
|
||||||
const bandStore = useBandStore()
|
const bandStore = useBandStore()
|
||||||
@@ -22,7 +22,7 @@ bandStore.getBands()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:add-button-string="$t('band.addNewBand')"
|
:add-button-string="$t('band.addNewBand')"
|
||||||
:fetch-in-progress="bandStore.fetchInProgress"
|
:fetch-in-progress="bandStore.fetchInProgress"
|
||||||
:on-add-click="() => bandStore.newBand()"
|
:on-add-click="() => bandStore.newBand()"
|
||||||
@@ -72,7 +72,7 @@ bandStore.getBands()
|
|||||||
/> -->
|
/> -->
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
|
|
||||||
<band-edit-dialog />
|
<band-edit-dialog />
|
||||||
</template>
|
</template>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import { useBandStore } from '@/stores/band.store';
|
import { useBandStore } from '@/stores/band.store';
|
||||||
import { useConcertStore } from '@/stores/concert.store';
|
import { useConcertStore } from '@/stores/concert.store';
|
||||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
const concertStore = useConcertStore()
|
const concertStore = useConcertStore()
|
||||||
@@ -25,7 +25,7 @@ concertStore.getConcerts()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:add-button-string="$t('concert.addNewConcert')"
|
:add-button-string="$t('concert.addNewConcert')"
|
||||||
:fetch-in-progress="concertStore.fetchInProgress"
|
:fetch-in-progress="concertStore.fetchInProgress"
|
||||||
:on-add-click="() => concertStore.newConcert()"
|
:on-add-click="() => concertStore.newConcert()"
|
||||||
@@ -73,5 +73,5 @@ concertStore.getConcerts()
|
|||||||
/> -->
|
/> -->
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
</template>
|
</template>
|
||||||
@@ -5,7 +5,7 @@ import { useAccountStore } from '@/stores/account.store';
|
|||||||
import { useLocationStore } from '@/stores/location.store';
|
import { useLocationStore } from '@/stores/location.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 dashboardCard from '../../../components/pageParts/dashboardCard.vue';
|
||||||
import { useOrderStore } from '@/stores/order.store';
|
import { useOrderStore } from '@/stores/order.store';
|
||||||
import { useFilesStore } from '@/stores/files.store';
|
import { useFilesStore } from '@/stores/files.store';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import FileUploadDialog from './fileUploadDialog.vue';
|
import FileUploadDialog from './fileUploadDialog.vue';
|
||||||
import { useFilesStore } from '@/stores/files.store';
|
import { useFilesStore } from '@/stores/files.store';
|
||||||
@@ -12,7 +12,7 @@ filesStore.getStaticFolders()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:add-button-string="$t('misc.uploadFile')"
|
:add-button-string="$t('misc.uploadFile')"
|
||||||
:fetch-in-progress="filesStore.fetchInProgress"
|
:fetch-in-progress="filesStore.fetchInProgress"
|
||||||
:on-add-click="() => { filesStore.showFileUploadDialog = true }"
|
:on-add-click="() => { filesStore.showFileUploadDialog = true }"
|
||||||
@@ -112,7 +112,7 @@ filesStore.getStaticFolders()
|
|||||||
</v-row>
|
</v-row>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
|
|
||||||
<file-preview-dialog
|
<file-preview-dialog
|
||||||
v-model:show-dialog="showPreviewDialog"
|
v-model:show-dialog="showPreviewDialog"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import genreEditDialog from './genreEditDialog.vue';
|
import genreEditDialog from './genreEditDialog.vue';
|
||||||
import { useGenreStore } from '@/stores/genre.store';
|
import { useGenreStore } from '@/stores/genre.store';
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ genreStore.getGenres()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:add-button-string="$t('band.addNewGenre')"
|
:add-button-string="$t('band.addNewGenre')"
|
||||||
:fetch-in-progress="genreStore.fetchInProgress"
|
:fetch-in-progress="genreStore.fetchInProgress"
|
||||||
:on-add-click="() => { genreStore.newGenre() }"
|
:on-add-click="() => { genreStore.newGenre() }"
|
||||||
@@ -48,7 +48,7 @@ genreStore.getGenres()
|
|||||||
/> -->
|
/> -->
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
|
|
||||||
<genre-edit-dialog />
|
<genre-edit-dialog />
|
||||||
</template>
|
</template>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
import { useLocationStore } from '@/stores/location.store';
|
import { useLocationStore } from '@/stores/location.store';
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ locationStore.getLocations()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:fetch-in-progress="locationStore.fetchInProgress"
|
:fetch-in-progress="locationStore.fetchInProgress"
|
||||||
:add-button-string="$t('location.addLocation')"
|
:add-button-string="$t('location.addLocation')"
|
||||||
:on-add-click="() => { locationStore.newLocation() }"
|
:on-add-click="() => { locationStore.newLocation() }"
|
||||||
@@ -66,5 +66,5 @@ locationStore.getLocations()
|
|||||||
/> -->
|
/> -->
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
</template>
|
</template>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import adminDataLayout from '@/layouts/adminDataLayout.vue';
|
import dataLayout from '@/layouts/dataLayout.vue';
|
||||||
import { useOrderStore } from '@/stores/order.store';
|
import { useOrderStore } from '@/stores/order.store';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import OrderDetailDialog from './orderDetailDialog.vue';
|
import OrderDetailDialog from './orderDetailDialog.vue';
|
||||||
@@ -13,19 +13,21 @@ 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()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<admin-data-layout
|
<data-layout
|
||||||
:hide-add-button="true"
|
:hide-add-button="true"
|
||||||
>
|
>
|
||||||
<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,27 +48,27 @@ 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>
|
||||||
</admin-data-layout>
|
</data-layout>
|
||||||
|
|
||||||
<order-detail-dialog />
|
<order-detail-dialog />
|
||||||
</template>
|
</template>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -19,6 +19,22 @@ function getDotColor(exerciseGroupNr: number) {
|
|||||||
case 3: return "pink"
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -26,20 +42,7 @@ function getDotColor(exerciseGroupNr: number) {
|
|||||||
<v-row>
|
<v-row>
|
||||||
<v-spacer />
|
<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-col cols="auto">
|
||||||
<v-tooltip :text="$t('misc.fulfillYourPersonalDataFirst')">
|
|
||||||
<template #activator="{ props }"></template>
|
|
||||||
|
|
||||||
</v-tooltip>
|
|
||||||
<outlined-button
|
<outlined-button
|
||||||
prepend-icon="mdi-file-pdf-box"
|
prepend-icon="mdi-file-pdf-box"
|
||||||
@click="generateResultsPdf()"
|
@click="generateResultsPdf()"
|
||||||
@@ -50,6 +53,17 @@ function getDotColor(exerciseGroupNr: number) {
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</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-row>
|
||||||
<v-col>
|
<v-col>
|
||||||
<card-view
|
<card-view
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import actionDialog from '@/components/basics/actionDialog.vue';
|
import actionDialog from '@/components/basics/actionDialog.vue';
|
||||||
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
import outlinedButton from '@/components/basics/outlinedButton.vue';
|
||||||
import ServerStateText from '@/components/pageParts/serverStateText.vue';
|
import ServerStateText from '@/components/pageParts/serverStateText.vue';
|
||||||
|
import { getRegisterNumberRules, getStringRules } from '@/scripts/validationRules';
|
||||||
import { useFeedbackStore } from '@/stores/feedback.store';
|
import { useFeedbackStore } from '@/stores/feedback.store';
|
||||||
import { usePreferencesStore } from '@/stores/preferences.store';
|
import { usePreferencesStore } from '@/stores/preferences.store';
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch } from 'vue';
|
||||||
@@ -135,9 +136,9 @@ watch(() => currentStep.value, () => {
|
|||||||
<v-col>
|
<v-col>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
hide-details
|
|
||||||
:label="$t('misc.yourFullName')"
|
:label="$t('misc.yourFullName')"
|
||||||
v-model="preferencesStore.studentName"
|
v-model="preferencesStore.studentName"
|
||||||
|
:rules="getStringRules(4)"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -146,9 +147,9 @@ watch(() => currentStep.value, () => {
|
|||||||
<v-col>
|
<v-col>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
hide-details
|
|
||||||
:label="$t('misc.registrationNumber')"
|
:label="$t('misc.registrationNumber')"
|
||||||
v-model="preferencesStore.registrationNumber"
|
v-model="preferencesStore.registrationNumber"
|
||||||
|
:rules="getRegisterNumberRules()"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -177,8 +178,8 @@ watch(() => currentStep.value, () => {
|
|||||||
<outlined-button
|
<outlined-button
|
||||||
v-else
|
v-else
|
||||||
@click="showDialog = false; preferencesStore.firstStartup = false"
|
@click="showDialog = false; preferencesStore.firstStartup = false"
|
||||||
:disabled="preferencesStore.studentName.length == 0 ||
|
:disabled="preferencesStore.studentName.length < 5 ||
|
||||||
preferencesStore.registrationNumber.length == 0"
|
preferencesStore.registrationNumber.length < 8"
|
||||||
prepend-icon="mdi-check"
|
prepend-icon="mdi-check"
|
||||||
color="success"
|
color="success"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import PreferencesPage from "@/pages/misc/preferencesPage/index.vue";
|
|||||||
import HelpPage from "@/pages/misc/helpPage/index.vue"
|
import HelpPage from "@/pages/misc/helpPage/index.vue"
|
||||||
import ErrorPage from "@/pages/misc/errorPage/index.vue"
|
import ErrorPage from "@/pages/misc/errorPage/index.vue"
|
||||||
import ImageLicensePage from "@/pages/misc/imageLicensePage/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 = [
|
const routes = [
|
||||||
// Main page
|
// Main page
|
||||||
@@ -32,6 +34,8 @@ const routes = [
|
|||||||
{ path: '/account/orders', component: OrdersPage },
|
{ path: '/account/orders', component: OrdersPage },
|
||||||
{ path: '/account/data', component: AccountDataPage },
|
{ path: '/account/data', component: AccountDataPage },
|
||||||
{ path: '/account/login', component: LoginPage },
|
{ path: '/account/login', component: LoginPage },
|
||||||
|
{ path: '/account/payments', component: AccountPaymentsPage },
|
||||||
|
{ path: '/account/addresses', component: AccountAddressesPage },
|
||||||
|
|
||||||
// Admin
|
// Admin
|
||||||
...adminRoutes,
|
...adminRoutes,
|
||||||
|
|||||||
@@ -21,3 +21,15 @@ export function dateToHumanReadableString(date: Date) {
|
|||||||
export function dateStringToHumanReadableString(string: string) {
|
export function dateStringToHumanReadableString(string: string) {
|
||||||
return dateToHumanReadableString(new Date(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") + ''
|
||||||
|
}
|
||||||
@@ -169,3 +169,31 @@ 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 { ref } from "vue";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { useExerciseStore } from "./exercise.store";
|
import { useExerciseStore } from "./exercise.store";
|
||||||
|
import moment, { Moment } from "moment";
|
||||||
|
|
||||||
export const useAccountStore = defineStore("accountStore", {
|
export const useAccountStore = defineStore("accountStore", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@@ -17,10 +18,10 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
accounts: ref<Array<AccountApiModel>>([]),
|
accounts: ref<Array<AccountApiModel>>([]),
|
||||||
|
|
||||||
/** Server token of currently logged in account */
|
/** Server token of currently logged in account */
|
||||||
userAccountToken: useLocalStorage("hackmycart/accountStore/userAccountToken", ""),
|
userAccountToken: useLocalStorage("eventMaster/accountStore/userAccountToken", ""),
|
||||||
|
|
||||||
/** Useraccount which is currently logged in */
|
/** 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 */
|
/** User input on login screen */
|
||||||
loginData: ref<{ username: String, password: String}>(
|
loginData: ref<{ username: String, password: String}>(
|
||||||
@@ -37,7 +38,15 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
adminPanelVisible: ref(false),
|
adminPanelVisible: ref(false),
|
||||||
|
|
||||||
/** Flag to activate buy option on basket page */
|
/** 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: {
|
actions: {
|
||||||
@@ -80,6 +89,7 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
await getLogin(this.loginData.username, this.loginData.password)
|
await getLogin(this.loginData.username, this.loginData.password)
|
||||||
.then(async result => {
|
.then(async result => {
|
||||||
this.userAccountToken = result.data.token
|
this.userAccountToken = result.data.token
|
||||||
|
this.loggedInTimeStamp = moment().format("YYYY-MM-DDTHH:mm:ss.SSS")
|
||||||
|
|
||||||
getAccount(this.userAccountToken)
|
getAccount(this.userAccountToken)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
@@ -91,7 +101,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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -113,14 +123,16 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
* Reload account information about current logged in user
|
* Reload account information about current logged in user
|
||||||
*/
|
*/
|
||||||
async refreshAccount() {
|
async refreshAccount() {
|
||||||
|
this.fetchInProgress = true
|
||||||
|
|
||||||
getAccount(this.userAccountToken)
|
getAccount(this.userAccountToken)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.userAccount = response.data
|
this.userAccount = response.data
|
||||||
|
|
||||||
this.fetchInProgress = false
|
|
||||||
|
|
||||||
this.privilegeBuy = true
|
this.privilegeBuy = true
|
||||||
this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel
|
this.adminPanelVisible = response.data.accountRole.privilegeAdminPanel
|
||||||
|
|
||||||
|
this.fetchInProgress = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -133,6 +145,7 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
async registerAccount(): Promise<boolean> {
|
async registerAccount(): Promise<boolean> {
|
||||||
const feedbackStore = useFeedbackStore()
|
const feedbackStore = useFeedbackStore()
|
||||||
const exerciseStore = useExerciseStore()
|
const exerciseStore = useExerciseStore()
|
||||||
|
let success = false
|
||||||
this.fetchInProgress = true
|
this.fetchInProgress = true
|
||||||
|
|
||||||
if (this.registerData.username == null || this.registerData.username.length < 4) {
|
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,}))$/)) {
|
} 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)
|
feedbackStore.addSnackbar(BannerStateEnum.ACCOUNTMAILADDRESSUNVALID)
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
await registerAccount(this.registerData)
|
await registerAccount(this.registerData)
|
||||||
.then(async res => {
|
.then(async res => {
|
||||||
if (res.status == 201) {
|
if (res.status == 201) {
|
||||||
@@ -156,6 +170,7 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.fetchInProgress = false
|
this.fetchInProgress = false
|
||||||
|
success = true
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
if (error.status == 400) {
|
if (error.status == 400) {
|
||||||
@@ -165,12 +180,11 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.fetchInProgress = false
|
this.fetchInProgress = false
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fetchInProgress = false
|
this.fetchInProgress = false
|
||||||
return false
|
return success
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,6 +193,7 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
async updateAccount() {
|
async updateAccount() {
|
||||||
const feedbackStore = useFeedbackStore()
|
const feedbackStore = useFeedbackStore()
|
||||||
const exerciseStore = useExerciseStore()
|
const exerciseStore = useExerciseStore()
|
||||||
|
this.fetchInProgress = true
|
||||||
|
|
||||||
// Check for exercise 0.2 completion
|
// Check for exercise 0.2 completion
|
||||||
let accountComplete = this.userAccount.firstName != "" && this.userAccount.lastName != "" &&
|
let accountComplete = this.userAccount.firstName != "" && this.userAccount.lastName != "" &&
|
||||||
@@ -196,6 +211,7 @@ export const useAccountStore = defineStore("accountStore", {
|
|||||||
feedbackStore.addSnackbar(BannerStateEnum.ACCOUNTUPDATESUCCESSFUL)
|
feedbackStore.addSnackbar(BannerStateEnum.ACCOUNTUPDATESUCCESSFUL)
|
||||||
|
|
||||||
this.userAccount = res.data
|
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
|
* 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) =>
|
this.userAccount.addresses = this.userAccount.addresses.filter((addr: AddressModel) =>
|
||||||
addr != address
|
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
|
* @param address Payment dataset to remove
|
||||||
*/
|
*/
|
||||||
removePayment(payment: PaymentModel) {
|
async removePayment(payment: PaymentModel) {
|
||||||
this.userAccount.payments = this.userAccount.payments.filter((paym: PaymentModel) =>
|
this.userAccount.payments = await this.userAccount.payments.filter((paym: PaymentModel) =>
|
||||||
paym != payment
|
paym != payment
|
||||||
)
|
)
|
||||||
|
|
||||||
|
this.updateAccount()
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { useExerciseStore } from "./exercise.store";
|
|||||||
export const useBasketStore = defineStore('basketStore', {
|
export const useBasketStore = defineStore('basketStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
/** Items in customers basket */
|
/** Items in customers basket */
|
||||||
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/itemsInBasket", []),
|
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("eventMaster/basketStore/itemsInBasket", []),
|
||||||
|
|
||||||
/** Address used in the order dialog */
|
/** Address used in the order dialog */
|
||||||
usedAddress: ref<AddressModel>(null),
|
usedAddress: ref<AddressModel>(null),
|
||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -15,10 +15,10 @@ import { AccountApiModel } from "@/data/models/user/accountApiModel";
|
|||||||
export const usePreferencesStore = defineStore('preferencesStore', {
|
export const usePreferencesStore = defineStore('preferencesStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
/** Selected theme by user */
|
/** Selected theme by user */
|
||||||
theme: useLocalStorage<ThemeEnum>("hackmycart/preferencesStore/theme", ThemeEnum.DARK),
|
theme: useLocalStorage<ThemeEnum>("eventMaster/preferencesStore/theme", ThemeEnum.DARK),
|
||||||
|
|
||||||
/** Selected language by user */
|
/** 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 */
|
/** Request to server sent, waiting for data response */
|
||||||
fetchInProgress: ref(false),
|
fetchInProgress: ref(false),
|
||||||
@@ -36,13 +36,13 @@ export const usePreferencesStore = defineStore('preferencesStore', {
|
|||||||
showFactoryResetDialog: ref(false),
|
showFactoryResetDialog: ref(false),
|
||||||
|
|
||||||
/** Marks the first run of the app */
|
/** 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 */
|
/** Full name of student */
|
||||||
studentName: useLocalStorage<string>("hackmycart/preferencesStore/studentName", ""),
|
studentName: useLocalStorage<string>("eventMaster/preferencesStore/studentName", ""),
|
||||||
|
|
||||||
/** Matrikel number */
|
/** Matrikel number */
|
||||||
registrationNumber: useLocalStorage<string>("hackmycart/preferencesStore/registrationNumber", "")
|
registrationNumber: useLocalStorage<string>("eventMaster/preferencesStore/registrationNumber", "")
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|||||||
Reference in New Issue
Block a user