From 4791a5ef1d506ebbae89625add52ef435ead9d75 Mon Sep 17 00:00:00 2001 From: zervo Date: Thu, 28 Nov 2024 22:42:10 +0100 Subject: [PATCH] Add code --- stfrontend/.browserslistrc | 4 + stfrontend/.editorconfig | 6 + stfrontend/.eslintrc-auto-import.json | 76 +++++++++++ stfrontend/.gitignore | 22 ++++ stfrontend/README.md | 81 ++++++++++++ stfrontend/bun.lockb | Bin 0 -> 120444 bytes stfrontend/env.d.ts | 3 + stfrontend/eslint.config.js | 36 ++++++ stfrontend/index.html | 13 ++ stfrontend/package.json | 48 +++++++ stfrontend/public/favicon.ico | Bin 0 -> 15406 bytes stfrontend/src/App.vue | 11 ++ stfrontend/src/assets/logo.png | Bin 0 -> 11955 bytes stfrontend/src/assets/logo.svg | 6 + stfrontend/src/auto-imports.d.ts | 140 ++++++++++++++++++++ stfrontend/src/components.d.ts | 18 +++ stfrontend/src/components/AppBar.vue | 66 ++++++++++ stfrontend/src/components/AppFooter.vue | 79 ++++++++++++ stfrontend/src/components/HelloWorld.vue | 157 +++++++++++++++++++++++ stfrontend/src/components/README.md | 35 +++++ stfrontend/src/layouts/README.md | 5 + stfrontend/src/layouts/default.vue | 15 +++ stfrontend/src/main.ts | 20 +++ stfrontend/src/pages/README.md | 5 + stfrontend/src/pages/index.vue | 7 + stfrontend/src/plugins/README.md | 3 + stfrontend/src/plugins/index.ts | 20 +++ stfrontend/src/plugins/vuetify.ts | 19 +++ stfrontend/src/router/index.ts | 36 ++++++ stfrontend/src/stores/README.md | 5 + stfrontend/src/stores/app.ts | 8 ++ stfrontend/src/stores/index.ts | 4 + stfrontend/src/styles/README.md | 3 + stfrontend/src/styles/settings.scss | 10 ++ stfrontend/src/typed-router.d.ts | 23 ++++ stfrontend/tsconfig.app.json | 14 ++ stfrontend/tsconfig.json | 11 ++ stfrontend/tsconfig.node.json | 19 +++ stfrontend/vite.config.mts | 81 ++++++++++++ 39 files changed, 1109 insertions(+) create mode 100644 stfrontend/.browserslistrc create mode 100644 stfrontend/.editorconfig create mode 100644 stfrontend/.eslintrc-auto-import.json create mode 100644 stfrontend/.gitignore create mode 100644 stfrontend/README.md create mode 100755 stfrontend/bun.lockb create mode 100644 stfrontend/env.d.ts create mode 100644 stfrontend/eslint.config.js create mode 100644 stfrontend/index.html create mode 100644 stfrontend/package.json create mode 100644 stfrontend/public/favicon.ico create mode 100644 stfrontend/src/App.vue create mode 100644 stfrontend/src/assets/logo.png create mode 100644 stfrontend/src/assets/logo.svg create mode 100644 stfrontend/src/auto-imports.d.ts create mode 100644 stfrontend/src/components.d.ts create mode 100644 stfrontend/src/components/AppBar.vue create mode 100644 stfrontend/src/components/AppFooter.vue create mode 100644 stfrontend/src/components/HelloWorld.vue create mode 100644 stfrontend/src/components/README.md create mode 100644 stfrontend/src/layouts/README.md create mode 100644 stfrontend/src/layouts/default.vue create mode 100644 stfrontend/src/main.ts create mode 100644 stfrontend/src/pages/README.md create mode 100644 stfrontend/src/pages/index.vue create mode 100644 stfrontend/src/plugins/README.md create mode 100644 stfrontend/src/plugins/index.ts create mode 100644 stfrontend/src/plugins/vuetify.ts create mode 100644 stfrontend/src/router/index.ts create mode 100644 stfrontend/src/stores/README.md create mode 100644 stfrontend/src/stores/app.ts create mode 100644 stfrontend/src/stores/index.ts create mode 100644 stfrontend/src/styles/README.md create mode 100644 stfrontend/src/styles/settings.scss create mode 100644 stfrontend/src/typed-router.d.ts create mode 100644 stfrontend/tsconfig.app.json create mode 100644 stfrontend/tsconfig.json create mode 100644 stfrontend/tsconfig.node.json create mode 100644 stfrontend/vite.config.mts 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 0000000000000000000000000000000000000000..1eee36e36390afb44b0ccd268646dbbf23eb351e GIT binary patch literal 120444 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 +/// +/// 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 0000000000000000000000000000000000000000..8fb9f91b3aab4eec0c76ffc5342528033c61e247 GIT binary patch literal 15406 zcmeHO3v5%@8NNVarCoU?zSqezmT6npu}xxXJJhY(x=s~hQ>SSYYSncU&|(|9Y?QVX z@}TB1G8mASM;tRKYgJkrAW)&g7${B%c>oE7;)O>NNO_bu4G-IdNB({PbTkJL{ZGDJe2DLL+vq#sL?l$jZPe_*I2y@|4sBRjso zUy`aUlJo$60})6B%aMKN&yMG1Qvjth%4dDy{HM^34) z&_TyGJg3UC{J|n2-wr)LDYwhNWBH4VL-JgYz;erTEKiMF20`|$Cf~GysBU40j@&)u zboK>@(yL25%R|RmS~6@99bG>PviV`j>&k~M@~J%cn{`uCzUOyY^23rlWt6DH=aut3 zlZo^g63xIXwP(4)hgT<|I>hSGqh7YbLP$jL+%p0>vM2Su?wmOV;-uyLFww=KN5Ox{j<% zmi}mZc22bZyxbmI!x+Ch3+qsk+#YbHJ{CdQjDh~;LRJB63Pq&~p

*N){PEn7FA;EAwj=|b_AUGw z{Eb1Zt8`N8chL?vjkw~yAvg~N+W_qV|N7U7a3HGfPY0GBqUxOaLJzPO2|Qz7H&yF{ z!Y@7SbxH$-YlpxgCaImE$Fk6T4dUMU!=a+u##*PZb&m9d@{VbA<&v z;n*Hvm#Nt5zF}Ud{=9#v%+3;8${f~WV?Q`CFATe5JXp$wT(q1TOU7#0jK6PDXZ)(1 zOSF4N3hStRA?+K$*ZctH(lRF!KFSL%W20hM6%Rz+k9We?_C36J>PVG2%Y`27X;nW+ z*x`6oe7S`dXABgw#vFYvuM;-c|L9ua=7z9?9B!cL=Fyiz34xz{6kpCd?PeyG2V7mkg!!m@d$btKgDK_Ib zt|Qt#$Am-fZ&{xA0GOAnn8Ue+QQBY3NiO*vfvd{5lsp3L_K5f@hhj{}^Nk#us4?p+ ztOM)g!1L3Ff(Tk8KQe4khoQS4_&0;4zo|FQr(iM%k4L+U*z zff0J2FQWxM*K?>u4d$6_8R>l`cK8U+!w`A!D@A2^2+L%A~GSv8* z(uV!wgkD)YqY(1-;X}j zv4?n}%=LOp! z;8GgCC~I2q%*#5{$kpuKJ6-ET*}o#)Z>p>vQsxF25{?c6CQ5()gsGtn{Ul`*ykb!bDMnnlGUdfYdn+9lsY%+pJ_Z_xHs+imH? z!L`+luUT1yv*4C1Z&<#Qlui*r2~lxBI`sAm+}oX{s=OcRf9A0%Q^56>8DC==kKtgy z>D-TeE@f3uu4&Y?ZVVlM3wLg~Z>Y}xfNE|1MIAijELQN`Y2<45F5=t5>wtYuk>yuH zXEJj-vN;uZD0|537U$Eq5Oek?f#JlNGq{dN(qiDuxO185eWG@Tuk1zKUsCs)MAVm# zZTvIN+Wl0&MDXYQF#3{qXA$(Ft>uw;>&qkE2f#n|`-?1D`gl8Gqj+=j77qvaV7#CH z-mDV$x0TsBRP5B|jZ%mFQ}FDv4Rn5l$yl(|`Q7Oe;~u+P58Qvv*6uy)7U=EIpPM-5 zPv}(pkwc!Zx3$@4;Y){)0d2tO5v#db4**wJ~;d2`ShTX zw|GaKwMoD4ydIzqSN(;l&j_8}$q^eYga7tU+}ZvgxyO*m1UDkuojePFZ zG`-$PpE1`DpyrLMO}R7wCfu3t6Y|B7d%f_n+{8^32;HSdS9&hVGwt*sUYr-!%%`a~|XP)!GJa zaPfvq9vz7{ms4}`U~qpQ+@r?~G$CeSuOWUWWPj8xrxoKsi%ALkMoN~Re@yeI<`b#& zQakqh?^Bfdlv*~90r${a#kP)=j;z5r;Qua|_8~6ciamnnhpFd84r{fjgNVx%{UgRa z5XnEKlf}cZ&elidYgP}Qi}Z0^o$C^y%G~k#_Qp8=1^BDy6=xQN&GlMeiCUK;x&F$^ zjA44c!M?-)Y1kOO--Oix|DE7=F!d?WE|oc-P;ICUYO&YsIA3qS68`^+SoxzLDfxQ- z)V%&7_{XQaWqV^?8s0=b5Yxwfs(L2+kBDu`F4FIF*gxGfML8AK#-01US-npCiqalZ z?M~DOWA<^ZR|~P;79^A!*A-C1sshAC6<~Z9P|a%vs7IcNOJh792S@Vc$sCItcXG)K z1Fn?E#hswKujQD~WT#qpf3`ix0(EL{#By^?PeQ2& + + + + + + + + diff --git a/stfrontend/src/assets/logo.png b/stfrontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a5f23ae7bff64954cf3537377a9f99306baf083d GIT binary patch literal 11955 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 + + + + + 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', + }, + }, + }, +})