diff --git a/stfrontend/.browserslistrc b/stfrontend/.browserslistrc
new file mode 100644
index 0000000..dc3bc09
--- /dev/null
+++ b/stfrontend/.browserslistrc
@@ -0,0 +1,4 @@
+> 1%
+last 2 versions
+not dead
+not ie 11
diff --git a/stfrontend/.editorconfig b/stfrontend/.editorconfig
new file mode 100644
index 0000000..ecea360
--- /dev/null
+++ b/stfrontend/.editorconfig
@@ -0,0 +1,6 @@
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
+charset = utf-8
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/stfrontend/.eslintrc-auto-import.json b/stfrontend/.eslintrc-auto-import.json
new file mode 100644
index 0000000..c37cd11
--- /dev/null
+++ b/stfrontend/.eslintrc-auto-import.json
@@ -0,0 +1,76 @@
+{
+ "globals": {
+ "Component": true,
+ "ComponentPublicInstance": true,
+ "ComputedRef": true,
+ "EffectScope": true,
+ "ExtractDefaultPropTypes": true,
+ "ExtractPropTypes": true,
+ "ExtractPublicPropTypes": true,
+ "InjectionKey": true,
+ "PropType": true,
+ "Ref": true,
+ "VNode": true,
+ "WritableComputedRef": true,
+ "computed": true,
+ "createApp": true,
+ "customRef": true,
+ "defineAsyncComponent": true,
+ "defineComponent": true,
+ "effectScope": true,
+ "getCurrentInstance": true,
+ "getCurrentScope": true,
+ "h": true,
+ "inject": true,
+ "isProxy": true,
+ "isReactive": true,
+ "isReadonly": true,
+ "isRef": true,
+ "markRaw": true,
+ "nextTick": true,
+ "onActivated": true,
+ "onBeforeMount": true,
+ "onBeforeUnmount": true,
+ "onBeforeUpdate": true,
+ "onDeactivated": true,
+ "onErrorCaptured": true,
+ "onMounted": true,
+ "onRenderTracked": true,
+ "onRenderTriggered": true,
+ "onScopeDispose": true,
+ "onServerPrefetch": true,
+ "onUnmounted": true,
+ "onUpdated": true,
+ "provide": true,
+ "reactive": true,
+ "readonly": true,
+ "ref": true,
+ "resolveComponent": true,
+ "shallowReactive": true,
+ "shallowReadonly": true,
+ "shallowRef": true,
+ "toRaw": true,
+ "toRef": true,
+ "toRefs": true,
+ "toValue": true,
+ "triggerRef": true,
+ "unref": true,
+ "useAttrs": true,
+ "useCssModule": true,
+ "useCssVars": true,
+ "useRoute": true,
+ "useRouter": true,
+ "useSlots": true,
+ "watch": true,
+ "watchEffect": true,
+ "watchPostEffect": true,
+ "watchSyncEffect": true,
+ "DirectiveBinding": true,
+ "MaybeRef": true,
+ "MaybeRefOrGetter": true,
+ "onWatcherCleanup": true,
+ "useId": true,
+ "useModel": true,
+ "useTemplateRef": true
+ }
+}
diff --git a/stfrontend/.gitignore b/stfrontend/.gitignore
new file mode 100644
index 0000000..11f5d71
--- /dev/null
+++ b/stfrontend/.gitignore
@@ -0,0 +1,22 @@
+.DS_Store
+node_modules
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/stfrontend/README.md b/stfrontend/README.md
new file mode 100644
index 0000000..0519646
--- /dev/null
+++ b/stfrontend/README.md
@@ -0,0 +1,81 @@
+# Vuetify (Default)
+
+This is the official scaffolding tool for Vuetify, designed to give you a head start in building your new Vuetify application. It sets up a base template with all the necessary configurations and standard directory structure, enabling you to begin development without the hassle of setting up the project from scratch.
+
+## ❗️ Important Links
+
+- 📄 [Docs](https://vuetifyjs.com/)
+- 🚨 [Issues](https://issues.vuetifyjs.com/)
+- 🏬 [Store](https://store.vuetifyjs.com/)
+- 🎮 [Playground](https://play.vuetifyjs.com/)
+- 💬 [Discord](https://community.vuetifyjs.com)
+
+## 💿 Install
+
+Set up your project using your preferred package manager. Use the corresponding command to install the dependencies:
+
+| Package Manager | Command |
+|---------------------------------------------------------------|----------------|
+| [yarn](https://yarnpkg.com/getting-started) | `yarn install` |
+| [npm](https://docs.npmjs.com/cli/v7/commands/npm-install) | `npm install` |
+| [pnpm](https://pnpm.io/installation) | `pnpm install` |
+| [bun](https://bun.sh/#getting-started) | `bun install` |
+
+After completing the installation, your environment is ready for Vuetify development.
+
+## ✨ Features
+
+- 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify 3 for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify 3](https://vuetifyjs.com/en/)
+- 🗃️ **State Management**: Integrated with [Pinia](https://pinia.vuejs.org/), the intuitive, modular state management solution for Vue.
+- 🚦 **Routing and Layouts**: Utilizes Vue Router for SPA navigation and vite-plugin-vue-layouts for organizing Vue file layouts. [Vue Router](https://router.vuejs.org/) | [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts)
+- 💻 **Enhanced Development Experience**: Benefit from TypeScript's static type checking and the ESLint plugin suite for Vue, ensuring code quality and consistency. [TypeScript](https://www.typescriptlang.org/) | [ESLint Plugin Vue](https://eslint.vuejs.org/)
+- ⚡ **Next-Gen Tooling**: Powered by Vite, experience fast cold starts and instant HMR (Hot Module Replacement). [Vite](https://vitejs.dev/)
+- 🧩 **Automated Component Importing**: Streamline your workflow with unplugin-vue-components, automatically importing components as you use them. [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
+- 🛠️ **Strongly-Typed Vue**: Use vue-tsc for type-checking your Vue components, and enjoy a robust development experience. [vue-tsc](https://github.com/johnsoncodehk/volar/tree/master/packages/vue-tsc)
+
+These features are curated to provide a seamless development experience from setup to deployment, ensuring that your Vuetify application is both powerful and maintainable.
+
+## 💡 Usage
+
+This section covers how to start the development server and build your project for production.
+
+### Starting the Development Server
+
+To start the development server with hot-reload, run the following command. The server will be accessible at [http://localhost:3000](http://localhost:3000):
+
+```bash
+yarn dev
+```
+
+(Repeat for npm, pnpm, and bun with respective commands.)
+
+> Add NODE_OPTIONS='--no-warnings' to suppress the JSON import warnings that happen as part of the Vuetify import mapping. If you are on Node [v21.3.0](https://nodejs.org/en/blog/release/v21.3.0) or higher, you can change this to NODE_OPTIONS='--disable-warning=5401'. If you don't mind the warning, you can remove this from your package.json dev script.
+
+### Building for Production
+
+To build your project for production, use:
+
+```bash
+yarn build
+```
+
+(Repeat for npm, pnpm, and bun with respective commands.)
+
+Once the build process is completed, your application will be ready for deployment in a production environment.
+
+## 💪 Support Vuetify Development
+
+This project is built with [Vuetify](https://vuetifyjs.com/en/), a UI Library with a comprehensive collection of Vue components. Vuetify is an MIT licensed Open Source project that has been made possible due to the generous contributions by our [sponsors and backers](https://vuetifyjs.com/introduction/sponsors-and-backers/). If you are interested in supporting this project, please consider:
+
+- [Requesting Enterprise Support](https://support.vuetifyjs.com/)
+- [Sponsoring John on Github](https://github.com/users/johnleider/sponsorship)
+- [Sponsoring Kael on Github](https://github.com/users/kaelwd/sponsorship)
+- [Supporting the team on Open Collective](https://opencollective.com/vuetify)
+- [Becoming a sponsor on Patreon](https://www.patreon.com/vuetify)
+- [Becoming a subscriber on Tidelift](https://tidelift.com/subscription/npm/vuetify)
+- [Making a one-time donation with Paypal](https://paypal.me/vuetify)
+
+## 📑 License
+[MIT](http://opensource.org/licenses/MIT)
+
+Copyright (c) 2016-present Vuetify, LLC
diff --git a/stfrontend/bun.lockb b/stfrontend/bun.lockb
new file mode 100755
index 0000000..1eee36e
Binary files /dev/null and b/stfrontend/bun.lockb differ
diff --git a/stfrontend/env.d.ts b/stfrontend/env.d.ts
new file mode 100644
index 0000000..aa1c669
--- /dev/null
+++ b/stfrontend/env.d.ts
@@ -0,0 +1,3 @@
+///
+///
+///
diff --git a/stfrontend/eslint.config.js b/stfrontend/eslint.config.js
new file mode 100644
index 0000000..038a47b
--- /dev/null
+++ b/stfrontend/eslint.config.js
@@ -0,0 +1,36 @@
+/**
+ * .eslint.js
+ *
+ * ESLint configuration file.
+ */
+
+import pluginVue from 'eslint-plugin-vue'
+import vueTsEslintConfig from '@vue/eslint-config-typescript'
+
+export default [
+ {
+ name: 'app/files-to-lint',
+ files: ['**/*.{ts,mts,tsx,vue}'],
+ },
+
+ {
+ name: 'app/files-to-ignore',
+ ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
+ },
+
+ ...pluginVue.configs['flat/recommended'],
+ ...vueTsEslintConfig(),
+
+ {
+ rules: {
+ '@typescript-eslint/no-unused-expressions': [
+ 'error',
+ {
+ allowShortCircuit: true,
+ allowTernary: true,
+ },
+ ],
+ 'vue/multi-word-component-names': 'off',
+ }
+ }
+]
diff --git a/stfrontend/index.html b/stfrontend/index.html
new file mode 100644
index 0000000..8abc79c
--- /dev/null
+++ b/stfrontend/index.html
@@ -0,0 +1,13 @@
+
+
+
+ Replace this page by removing {{ `` }} in pages/index.vue.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stfrontend/src/components/README.md b/stfrontend/src/components/README.md
new file mode 100644
index 0000000..d1dc92f
--- /dev/null
+++ b/stfrontend/src/components/README.md
@@ -0,0 +1,35 @@
+# Components
+
+Vue template files in this folder are automatically imported.
+
+## 🚀 Usage
+
+Importing is handled by [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components). This plugin automatically imports `.vue` files created in the `src/components` directory, and registers them as global components. This means that you can use any component in your application without having to manually import it.
+
+The following example assumes a component located at `src/components/MyComponent.vue`:
+
+```vue
+
+
+
+
+
+
+
+```
+
+When your template is rendered, the component's import will automatically be inlined, which renders to this:
+
+```vue
+
+
+
+
+
+
+
+```
diff --git a/stfrontend/src/layouts/README.md b/stfrontend/src/layouts/README.md
new file mode 100644
index 0000000..4016af3
--- /dev/null
+++ b/stfrontend/src/layouts/README.md
@@ -0,0 +1,5 @@
+# Layouts
+
+Layouts are reusable components that wrap around pages. They are used to provide a consistent look and feel across multiple pages.
+
+Full documentation for this feature can be found in the Official [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) repository.
diff --git a/stfrontend/src/layouts/default.vue b/stfrontend/src/layouts/default.vue
new file mode 100644
index 0000000..ff632fb
--- /dev/null
+++ b/stfrontend/src/layouts/default.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stfrontend/src/main.ts b/stfrontend/src/main.ts
new file mode 100644
index 0000000..c8fc172
--- /dev/null
+++ b/stfrontend/src/main.ts
@@ -0,0 +1,20 @@
+/**
+ * main.ts
+ *
+ * Bootstraps Vuetify and other plugins then mounts the App`
+ */
+
+// Plugins
+import { registerPlugins } from '@/plugins'
+
+// Components
+import App from './App.vue'
+
+// Composables
+import { createApp } from 'vue'
+
+const app = createApp(App)
+
+registerPlugins(app)
+
+app.mount('#app')
diff --git a/stfrontend/src/pages/README.md b/stfrontend/src/pages/README.md
new file mode 100644
index 0000000..341536c
--- /dev/null
+++ b/stfrontend/src/pages/README.md
@@ -0,0 +1,5 @@
+# Pages
+
+Vue components created in this folder will automatically be converted to navigatable routes.
+
+Full documentation for this feature can be found in the Official [unplugin-vue-router](https://github.com/posva/unplugin-vue-router) repository.
diff --git a/stfrontend/src/pages/index.vue b/stfrontend/src/pages/index.vue
new file mode 100644
index 0000000..dac59c7
--- /dev/null
+++ b/stfrontend/src/pages/index.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/stfrontend/src/plugins/README.md b/stfrontend/src/plugins/README.md
new file mode 100644
index 0000000..62201c7
--- /dev/null
+++ b/stfrontend/src/plugins/README.md
@@ -0,0 +1,3 @@
+# Plugins
+
+Plugins are a way to extend the functionality of your Vue application. Use this folder for registering plugins that you want to use globally.
diff --git a/stfrontend/src/plugins/index.ts b/stfrontend/src/plugins/index.ts
new file mode 100644
index 0000000..c75aa61
--- /dev/null
+++ b/stfrontend/src/plugins/index.ts
@@ -0,0 +1,20 @@
+/**
+ * plugins/index.ts
+ *
+ * Automatically included in `./src/main.ts`
+ */
+
+// Plugins
+import vuetify from './vuetify'
+import pinia from '../stores'
+import router from '../router'
+
+// Types
+import type { App } from 'vue'
+
+export function registerPlugins (app: App) {
+ app
+ .use(vuetify)
+ .use(router)
+ .use(pinia)
+}
diff --git a/stfrontend/src/plugins/vuetify.ts b/stfrontend/src/plugins/vuetify.ts
new file mode 100644
index 0000000..7652788
--- /dev/null
+++ b/stfrontend/src/plugins/vuetify.ts
@@ -0,0 +1,19 @@
+/**
+ * plugins/vuetify.ts
+ *
+ * Framework documentation: https://vuetifyjs.com`
+ */
+
+// Styles
+import '@mdi/font/css/materialdesignicons.css'
+import 'vuetify/styles'
+
+// Composables
+import { createVuetify } from 'vuetify'
+
+// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
+export default createVuetify({
+ theme: {
+ defaultTheme: 'dark',
+ },
+})
diff --git a/stfrontend/src/router/index.ts b/stfrontend/src/router/index.ts
new file mode 100644
index 0000000..5d4b8bc
--- /dev/null
+++ b/stfrontend/src/router/index.ts
@@ -0,0 +1,36 @@
+/**
+ * router/index.ts
+ *
+ * Automatic routes for `./src/pages/*.vue`
+ */
+
+// Composables
+import { createRouter, createWebHistory } from 'vue-router/auto'
+import { setupLayouts } from 'virtual:generated-layouts'
+import { routes } from 'vue-router/auto-routes'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: setupLayouts(routes),
+})
+
+// Workaround for https://github.com/vitejs/vite/issues/11804
+router.onError((err, to) => {
+ if (err?.message?.includes?.('Failed to fetch dynamically imported module')) {
+ if (!localStorage.getItem('vuetify:dynamic-reload')) {
+ console.log('Reloading page to fix dynamic import error')
+ localStorage.setItem('vuetify:dynamic-reload', 'true')
+ location.assign(to.fullPath)
+ } else {
+ console.error('Dynamic import error, reloading page did not fix it', err)
+ }
+ } else {
+ console.error(err)
+ }
+})
+
+router.isReady().then(() => {
+ localStorage.removeItem('vuetify:dynamic-reload')
+})
+
+export default router
diff --git a/stfrontend/src/stores/README.md b/stfrontend/src/stores/README.md
new file mode 100644
index 0000000..54f8e03
--- /dev/null
+++ b/stfrontend/src/stores/README.md
@@ -0,0 +1,5 @@
+# Store
+
+Pinia stores are used to store reactive state and expose actions to mutate it.
+
+Full documentation for this feature can be found in the Official [Pinia](https://pinia.esm.dev/) repository.
diff --git a/stfrontend/src/stores/app.ts b/stfrontend/src/stores/app.ts
new file mode 100644
index 0000000..7429543
--- /dev/null
+++ b/stfrontend/src/stores/app.ts
@@ -0,0 +1,8 @@
+// Utilities
+import { defineStore } from 'pinia'
+
+export const useAppStore = defineStore('app', {
+ state: () => ({
+ //
+ }),
+})
diff --git a/stfrontend/src/stores/index.ts b/stfrontend/src/stores/index.ts
new file mode 100644
index 0000000..1536252
--- /dev/null
+++ b/stfrontend/src/stores/index.ts
@@ -0,0 +1,4 @@
+// Utilities
+import { createPinia } from 'pinia'
+
+export default createPinia()
diff --git a/stfrontend/src/styles/README.md b/stfrontend/src/styles/README.md
new file mode 100644
index 0000000..ea86179
--- /dev/null
+++ b/stfrontend/src/styles/README.md
@@ -0,0 +1,3 @@
+# Styles
+
+This directory is for configuring the styles of the application.
diff --git a/stfrontend/src/styles/settings.scss b/stfrontend/src/styles/settings.scss
new file mode 100644
index 0000000..3e36a27
--- /dev/null
+++ b/stfrontend/src/styles/settings.scss
@@ -0,0 +1,10 @@
+/**
+ * src/styles/settings.scss
+ *
+ * Configures SASS variables and Vuetify overwrites
+ */
+
+// https://vuetifyjs.com/features/sass-variables/`
+// @use 'vuetify/settings' with (
+// $color-pack: false
+// );
diff --git a/stfrontend/src/typed-router.d.ts b/stfrontend/src/typed-router.d.ts
new file mode 100644
index 0000000..331ee51
--- /dev/null
+++ b/stfrontend/src/typed-router.d.ts
@@ -0,0 +1,23 @@
+/* eslint-disable */
+/* prettier-ignore */
+// @ts-nocheck
+// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
+// It's recommended to commit this file.
+// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
+
+declare module 'vue-router/auto-routes' {
+ import type {
+ RouteRecordInfo,
+ ParamValue,
+ ParamValueOneOrMore,
+ ParamValueZeroOrMore,
+ ParamValueZeroOrOne,
+ } from 'vue-router'
+
+ /**
+ * Route name map generated by unplugin-vue-router
+ */
+ export interface RouteNamedMap {
+ '/': RouteRecordInfo<'/', '/', Record, Record>,
+ }
+}
diff --git a/stfrontend/tsconfig.app.json b/stfrontend/tsconfig.app.json
new file mode 100644
index 0000000..e14c754
--- /dev/null
+++ b/stfrontend/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/stfrontend/tsconfig.json b/stfrontend/tsconfig.json
new file mode 100644
index 0000000..66b5e57
--- /dev/null
+++ b/stfrontend/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/stfrontend/tsconfig.node.json b/stfrontend/tsconfig.node.json
new file mode 100644
index 0000000..5a0c6a5
--- /dev/null
+++ b/stfrontend/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node22/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/stfrontend/vite.config.mts b/stfrontend/vite.config.mts
new file mode 100644
index 0000000..9c92f25
--- /dev/null
+++ b/stfrontend/vite.config.mts
@@ -0,0 +1,81 @@
+// Plugins
+import AutoImport from 'unplugin-auto-import/vite'
+import Components from 'unplugin-vue-components/vite'
+import Fonts from 'unplugin-fonts/vite'
+import Layouts from 'vite-plugin-vue-layouts'
+import Vue from '@vitejs/plugin-vue'
+import VueRouter from 'unplugin-vue-router/vite'
+import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
+
+// Utilities
+import { defineConfig } from 'vite'
+import { fileURLToPath, URL } from 'node:url'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ VueRouter({
+ dts: 'src/typed-router.d.ts',
+ }),
+ Layouts(),
+ AutoImport({
+ imports: [
+ 'vue',
+ {
+ 'vue-router/auto': ['useRoute', 'useRouter'],
+ }
+ ],
+ dts: 'src/auto-imports.d.ts',
+ eslintrc: {
+ enabled: true,
+ },
+ vueTemplate: true,
+ }),
+ Components({
+ dts: 'src/components.d.ts',
+ }),
+ Vue({
+ template: { transformAssetUrls },
+ }),
+ // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme
+ Vuetify({
+ autoImport: true,
+ styles: {
+ configFile: 'src/styles/settings.scss',
+ },
+ }),
+ Fonts({
+ google: {
+ families: [ {
+ name: 'Roboto',
+ styles: 'wght@100;300;400;500;700;900',
+ }],
+ },
+ }),
+ ],
+ define: { 'process.env': {} },
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
+ },
+ extensions: [
+ '.js',
+ '.json',
+ '.jsx',
+ '.mjs',
+ '.ts',
+ '.tsx',
+ '.vue',
+ ],
+ },
+ server: {
+ port: 3000,
+ },
+ css: {
+ preprocessorOptions: {
+ sass: {
+ api: 'modern-compiler',
+ },
+ },
+ },
+})