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 @@ + + + + + + + Welcome to Vuetify 3 + + +
+ + + diff --git a/stfrontend/package.json b/stfrontend/package.json new file mode 100644 index 0000000..281aabe --- /dev/null +++ b/stfrontend/package.json @@ -0,0 +1,48 @@ +{ + "name": "stfrontend", + "private": true, + "type": "module", + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "build-only": "vite build", + "type-check": "vue-tsc --build --force", + "lint": "eslint . --fix" + }, + "dependencies": { + "@mdi/font": "7.4.47", + "core-js": "^3.37.1", + "roboto-fontface": "*", + "vue": "^3.4.31", + "vuetify": "^3.6.14" + }, + "devDependencies": { + "@eslint/js": "^9.14.0", + "@tsconfig/node22": "^22.0.0", + "@types/node": "^22.9.0", + "@vitejs/plugin-vue": "^5.1.4", + "@vue/eslint-config-typescript": "^14.1.3", + "@vue/tsconfig": "^0.5.1", + "eslint": "^9.14.0", + "eslint-plugin-vue": "^9.30.0", + "npm-run-all2": "^7.0.1", + "pinia": "^2.1.7", + "sass": "1.77.8", + "sass-embedded": "^1.77.8", + "typescript": "~5.6.3", + "unplugin-auto-import": "^0.17.6", + "unplugin-fonts": "^1.1.1", + "unplugin-vue-components": "^0.27.2", + "unplugin-vue-router": "^0.10.0", + "vite": "^5.4.10", + "vite-plugin-vue-layouts": "^0.11.0", + "vite-plugin-vuetify": "^2.0.3", + "vue-router": "^4.4.0", + "vue-tsc": "^2.1.10" + }, + "trustedDependencies": [ + "core-js" + ] +} diff --git a/stfrontend/public/favicon.ico b/stfrontend/public/favicon.ico new file mode 100644 index 0000000..8fb9f91 Binary files /dev/null and b/stfrontend/public/favicon.ico differ diff --git a/stfrontend/src/App.vue b/stfrontend/src/App.vue new file mode 100644 index 0000000..6ceb9da --- /dev/null +++ b/stfrontend/src/App.vue @@ -0,0 +1,11 @@ + + + diff --git a/stfrontend/src/assets/logo.png b/stfrontend/src/assets/logo.png new file mode 100644 index 0000000..a5f23ae Binary files /dev/null and b/stfrontend/src/assets/logo.png differ diff --git a/stfrontend/src/assets/logo.svg b/stfrontend/src/assets/logo.svg new file mode 100644 index 0000000..d57771c --- /dev/null +++ b/stfrontend/src/assets/logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/stfrontend/src/auto-imports.d.ts b/stfrontend/src/auto-imports.d.ts new file mode 100644 index 0000000..15741ac --- /dev/null +++ b/stfrontend/src/auto-imports.d.ts @@ -0,0 +1,140 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const computed: typeof import('vue')['computed'] + const createApp: typeof import('vue')['createApp'] + const customRef: typeof import('vue')['customRef'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const effectScope: typeof import('vue')['effectScope'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const inject: typeof import('vue')['inject'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] + const provide: typeof import('vue')['provide'] + const reactive: typeof import('vue')['reactive'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const toRaw: typeof import('vue')['toRaw'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const toValue: typeof import('vue')['toValue'] + const triggerRef: typeof import('vue')['triggerRef'] + const unref: typeof import('vue')['unref'] + const useAttrs: typeof import('vue')['useAttrs'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVars: typeof import('vue')['useCssVars'] + const useId: typeof import('vue')['useId'] + const useLink: typeof import('vue-router')['useLink'] + const useModel: typeof import('vue')['useModel'] + const useRoute: typeof import('vue-router/auto')['useRoute'] + const useRouter: typeof import('vue-router/auto')['useRouter'] + const useSlots: typeof import('vue')['useSlots'] + const useTemplateRef: typeof import('vue')['useTemplateRef'] + const watch: typeof import('vue')['watch'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] +} +// for type re-export +declare global { + // @ts-ignore + export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + import('vue') +} +// for vue template auto import +import { UnwrapRef } from 'vue' +declare module 'vue' { + interface GlobalComponents {} + interface ComponentCustomProperties { + readonly EffectScope: UnwrapRef + readonly computed: UnwrapRef + readonly createApp: UnwrapRef + readonly customRef: UnwrapRef + readonly defineAsyncComponent: UnwrapRef + readonly defineComponent: UnwrapRef + readonly effectScope: UnwrapRef + readonly getCurrentInstance: UnwrapRef + readonly getCurrentScope: UnwrapRef + readonly h: UnwrapRef + readonly inject: UnwrapRef + readonly isProxy: UnwrapRef + readonly isReactive: UnwrapRef + readonly isReadonly: UnwrapRef + readonly isRef: UnwrapRef + readonly markRaw: UnwrapRef + readonly nextTick: UnwrapRef + readonly onActivated: UnwrapRef + readonly onBeforeMount: UnwrapRef + readonly onBeforeUnmount: UnwrapRef + readonly onBeforeUpdate: UnwrapRef + readonly onDeactivated: UnwrapRef + readonly onErrorCaptured: UnwrapRef + readonly onMounted: UnwrapRef + readonly onRenderTracked: UnwrapRef + readonly onRenderTriggered: UnwrapRef + readonly onScopeDispose: UnwrapRef + readonly onServerPrefetch: UnwrapRef + readonly onUnmounted: UnwrapRef + readonly onUpdated: UnwrapRef + readonly onWatcherCleanup: UnwrapRef + readonly provide: UnwrapRef + readonly reactive: UnwrapRef + readonly readonly: UnwrapRef + readonly ref: UnwrapRef + readonly resolveComponent: UnwrapRef + readonly shallowReactive: UnwrapRef + readonly shallowReadonly: UnwrapRef + readonly shallowRef: UnwrapRef + readonly toRaw: UnwrapRef + readonly toRef: UnwrapRef + readonly toRefs: UnwrapRef + readonly toValue: UnwrapRef + readonly triggerRef: UnwrapRef + readonly unref: UnwrapRef + readonly useAttrs: UnwrapRef + readonly useCssModule: UnwrapRef + readonly useCssVars: UnwrapRef + readonly useId: UnwrapRef + readonly useModel: UnwrapRef + readonly useRoute: UnwrapRef + readonly useRouter: UnwrapRef + readonly useSlots: UnwrapRef + readonly useTemplateRef: UnwrapRef + readonly watch: UnwrapRef + readonly watchEffect: UnwrapRef + readonly watchPostEffect: UnwrapRef + readonly watchSyncEffect: UnwrapRef + } +} diff --git a/stfrontend/src/components.d.ts b/stfrontend/src/components.d.ts new file mode 100644 index 0000000..779dbae --- /dev/null +++ b/stfrontend/src/components.d.ts @@ -0,0 +1,18 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + AppBar: typeof import('./components/AppBar.vue')['default'] + AppFooter: typeof import('./components/AppFooter.vue')['default'] + AppHeader: typeof import('./components/AppHeader.vue')['default'] + HelloWorld: typeof import('./components/HelloWorld.vue')['default'] + NavBar: typeof import('./components/NavBar.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + } +} diff --git a/stfrontend/src/components/AppBar.vue b/stfrontend/src/components/AppBar.vue new file mode 100644 index 0000000..e8a83df --- /dev/null +++ b/stfrontend/src/components/AppBar.vue @@ -0,0 +1,66 @@ + + + \ No newline at end of file diff --git a/stfrontend/src/components/AppFooter.vue b/stfrontend/src/components/AppFooter.vue new file mode 100644 index 0000000..e7c5df3 --- /dev/null +++ b/stfrontend/src/components/AppFooter.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/stfrontend/src/components/HelloWorld.vue b/stfrontend/src/components/HelloWorld.vue new file mode 100644 index 0000000..4ff10db --- /dev/null +++ b/stfrontend/src/components/HelloWorld.vue @@ -0,0 +1,157 @@ + + + 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', + }, + }, + }, +})