diff --git a/README.md b/README.md index 6938b48..cb78858 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HackMyCart +# EventMaster The most hackable Web Shop! diff --git a/backend/routes/account.routes.ts b/backend/routes/account.routes.ts index 0e6d4ca..cb576e3 100644 --- a/backend/routes/account.routes.ts +++ b/backend/routes/account.routes.ts @@ -27,29 +27,33 @@ account.get("/", verifyToken, (req: Request, res: Response) => { 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() } }) @@ -123,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 diff --git a/backend/routes/band.routes.ts b/backend/routes/band.routes.ts index af28513..eb94158 100644 --- a/backend/routes/band.routes.ts +++ b/backend/routes/band.routes.ts @@ -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 => { diff --git a/package.json b/package.json index de35d03..f750895 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/basics/cardViewOneLine.vue b/src/components/basics/cardViewOneLine.vue index 9871a0c..4394982 100644 --- a/src/components/basics/cardViewOneLine.vue +++ b/src/components/basics/cardViewOneLine.vue @@ -12,7 +12,7 @@ defineProps({ - + {{ descriptionText }} diff --git a/src/pages/admin/dashboardPage/dashboardCard.vue b/src/components/pageParts/dashboardCard.vue similarity index 88% rename from src/pages/admin/dashboardPage/dashboardCard.vue rename to src/components/pageParts/dashboardCard.vue index dfb508e..fb2a5cb 100644 --- a/src/pages/admin/dashboardPage/dashboardCard.vue +++ b/src/components/pageParts/dashboardCard.vue @@ -37,7 +37,7 @@ defineProps({ {{ secondLine }} - + + + + + \ No newline at end of file diff --git a/src/layouts/adminDataLayout.vue b/src/layouts/dataLayout.vue similarity index 100% rename from src/layouts/adminDataLayout.vue rename to src/layouts/dataLayout.vue diff --git a/src/locales/de.json b/src/locales/de.json index df7ef7c..77f4e74 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -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", diff --git a/src/locales/en.json b/src/locales/en.json index ce56001..7078bb8 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -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", diff --git a/src/pages/account/accountAddressesPage/addressEditDialog.vue b/src/pages/account/accountAddressesPage/addressEditDialog.vue new file mode 100644 index 0000000..9c8690f --- /dev/null +++ b/src/pages/account/accountAddressesPage/addressEditDialog.vue @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ $t('misc.actions.save') }} + + + + \ No newline at end of file diff --git a/src/pages/account/accountAddressesPage/index.vue b/src/pages/account/accountAddressesPage/index.vue new file mode 100644 index 0000000..734e39a --- /dev/null +++ b/src/pages/account/accountAddressesPage/index.vue @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pages/account/accountDataPage/accountDataCard.vue b/src/pages/account/accountDataPage/accountDataCard.vue index d9296fd..980d8c3 100644 --- a/src/pages/account/accountDataPage/accountDataCard.vue +++ b/src/pages/account/accountDataPage/accountDataCard.vue @@ -81,7 +81,6 @@ const stringRules = [ v-model="accountStore.userAccount.firstName" variant="outlined" :rules="stringRules" - hide-details /> @@ -90,7 +89,6 @@ const stringRules = [ v-model="accountStore.userAccount.lastName" variant="outlined" :rules="stringRules" - hide-details /> diff --git a/src/pages/account/accountDataPage/addressesCard.vue b/src/pages/account/accountDataPage/addressesCard.vue deleted file mode 100644 index 690b6a0..0000000 --- a/src/pages/account/accountDataPage/addressesCard.vue +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - {{ address.street }} - - - - - - {{ address.houseNumber }} - - - - - - - - - - - - - - - - - - - - - - - - - - {{ $t('misc.actions.remove') }} - - - - - - - - - - - - {{ $t('misc.actions.add') }} - - - - \ No newline at end of file diff --git a/src/pages/account/accountDataPage/index.vue b/src/pages/account/accountDataPage/index.vue index 2155b2a..f8ea577 100644 --- a/src/pages/account/accountDataPage/index.vue +++ b/src/pages/account/accountDataPage/index.vue @@ -1,8 +1,6 @@ - - - - - - - - - - - - - - - {{ payment.bankName }} - - - - - - - - - - - - - - - {{ $t('misc.actions.remove') }} - - - - - - - - - - - - - - - - - - - - {{ $t('misc.actions.add') }} - - - - \ No newline at end of file diff --git a/src/pages/account/accountHomePage/index.vue b/src/pages/account/accountHomePage/index.vue index 93ece66..902b19f 100644 --- a/src/pages/account/accountHomePage/index.vue +++ b/src/pages/account/accountHomePage/index.vue @@ -1,60 +1,76 @@ - + - - - - - - - {{ $t('order.ordersDescription') }} - - - + - - - - {{ $t('account.accountManagementDescription') }} - - - + - - - - {{ $t('account.logout.logoutDescription') }} - - - - - - - + + + + + + + + {{ $t('account.logout.logout') }} + + + \ No newline at end of file diff --git a/src/pages/account/accountPaymentsPage/index.vue b/src/pages/account/accountPaymentsPage/index.vue new file mode 100644 index 0000000..d0b3731 --- /dev/null +++ b/src/pages/account/accountPaymentsPage/index.vue @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pages/account/accountPaymentsPage/paymentEditDialog.vue b/src/pages/account/accountPaymentsPage/paymentEditDialog.vue new file mode 100644 index 0000000..15bdd8d --- /dev/null +++ b/src/pages/account/accountPaymentsPage/paymentEditDialog.vue @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ $t('misc.actions.save') }} + + + + \ No newline at end of file diff --git a/src/pages/account/loginPage/registerForm.vue b/src/pages/account/loginPage/registerForm.vue index bf422f0..b5ea100 100644 --- a/src/pages/account/loginPage/registerForm.vue +++ b/src/pages/account/loginPage/registerForm.vue @@ -10,6 +10,7 @@ const accountStore = useAccountStore() async function registerAccount() { accountStore.registerAccount() .then(result => { + console.log(result) if (result) { showRegisterCard.value = false } diff --git a/src/pages/admin/accountsAdminPage/index.vue b/src/pages/admin/accountsAdminPage/index.vue index 2a2391e..d6930bf 100644 --- a/src/pages/admin/accountsAdminPage/index.vue +++ b/src/pages/admin/accountsAdminPage/index.vue @@ -1,6 +1,6 @@ - @@ -44,5 +44,5 @@ accountStore.getAllAccounts() /> --> - + \ No newline at end of file diff --git a/src/pages/admin/bandsAdminPage/index.vue b/src/pages/admin/bandsAdminPage/index.vue index 9d424cb..d540253 100644 --- a/src/pages/admin/bandsAdminPage/index.vue +++ b/src/pages/admin/bandsAdminPage/index.vue @@ -1,7 +1,7 @@ - --> - + \ No newline at end of file diff --git a/src/pages/admin/concertsAdminPage/index.vue b/src/pages/admin/concertsAdminPage/index.vue index 9ad75a9..966046f 100644 --- a/src/pages/admin/concertsAdminPage/index.vue +++ b/src/pages/admin/concertsAdminPage/index.vue @@ -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() - --> - + \ No newline at end of file diff --git a/src/pages/admin/dashboardPage/index.vue b/src/pages/admin/dashboardPage/index.vue index f5b29c8..2a243d2 100644 --- a/src/pages/admin/dashboardPage/index.vue +++ b/src/pages/admin/dashboardPage/index.vue @@ -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'; diff --git a/src/pages/admin/filesAdminPage/index.vue b/src/pages/admin/filesAdminPage/index.vue index 2ef7907..3bf238f 100644 --- a/src/pages/admin/filesAdminPage/index.vue +++ b/src/pages/admin/filesAdminPage/index.vue @@ -1,5 +1,5 @@ - - + -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() - --> - + \ No newline at end of file diff --git a/src/pages/admin/locationsAdminPage/index.vue b/src/pages/admin/locationsAdminPage/index.vue index 26d13db..6007ef3 100644 --- a/src/pages/admin/locationsAdminPage/index.vue +++ b/src/pages/admin/locationsAdminPage/index.vue @@ -1,5 +1,5 @@ - --> - + \ No newline at end of file diff --git a/src/pages/admin/ordersAdminPage/index.vue b/src/pages/admin/ordersAdminPage/index.vue index 95484a9..b7ee1b1 100644 --- a/src/pages/admin/ordersAdminPage/index.vue +++ b/src/pages/admin/ordersAdminPage/index.vue @@ -1,5 +1,5 @@ - - + \ No newline at end of file diff --git a/src/router/routes.ts b/src/router/routes.ts index 17b5587..e6ead66 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -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, diff --git a/src/scripts/dateTimeScripts.ts b/src/scripts/dateTimeScripts.ts index 9b23942..ae0096a 100644 --- a/src/scripts/dateTimeScripts.ts +++ b/src/scripts/dateTimeScripts.ts @@ -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") + '' } \ No newline at end of file diff --git a/src/stores/account.store.ts b/src/stores/account.store.ts index 295622d..f59917a 100644 --- a/src/stores/account.store.ts +++ b/src/stores/account.store.ts @@ -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>([]), /** 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("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 => { @@ -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 { 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() }, /** diff --git a/src/stores/basket.store.ts b/src/stores/basket.store.ts index 3d18f45..93982ce 100644 --- a/src/stores/basket.store.ts +++ b/src/stores/basket.store.ts @@ -16,7 +16,7 @@ import { useExerciseStore } from "./exercise.store"; export const useBasketStore = defineStore('basketStore', { state: () => ({ /** Items in customers basket */ - itemsInBasket: useLocalStorage>("hackmycart/basketStore/itemsInBasket", []), + itemsInBasket: useLocalStorage>("eventMaster/basketStore/itemsInBasket", []), /** Address used in the order dialog */ usedAddress: ref(null), diff --git a/src/stores/preferences.store.ts b/src/stores/preferences.store.ts index d041196..d060b39 100644 --- a/src/stores/preferences.store.ts +++ b/src/stores/preferences.store.ts @@ -15,10 +15,10 @@ import { AccountApiModel } from "@/data/models/user/accountApiModel"; export const usePreferencesStore = defineStore('preferencesStore', { state: () => ({ /** Selected theme by user */ - theme: useLocalStorage("hackmycart/preferencesStore/theme", ThemeEnum.DARK), + theme: useLocalStorage("eventMaster/preferencesStore/theme", ThemeEnum.DARK), /** Selected language by user */ - language: useLocalStorage("hackmycart/preferencesStore/language", LanguageEnum.GERMAN), + language: useLocalStorage("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("hackmycart/preferencesStore/firstStartup", true), + firstStartup: useLocalStorage("eventMaster/preferencesStore/firstStartup", true), /** Full name of student */ - studentName: useLocalStorage("hackmycart/preferencesStore/studentName", ""), + studentName: useLocalStorage("eventMaster/preferencesStore/studentName", ""), /** Matrikel number */ - registrationNumber: useLocalStorage("hackmycart/preferencesStore/registrationNumber", "") + registrationNumber: useLocalStorage("eventMaster/preferencesStore/registrationNumber", "") }), actions: {