From 63b946131bcd8ee72d50b3d2038e93eb85770c6f Mon Sep 17 00:00:00 2001 From: Anis Koubaa <mohamed.koubaa@kit.edu> Date: Sun, 23 Feb 2025 13:08:55 +0100 Subject: [PATCH] make vuetify as framework. --- services/.idea/.gitignore | 8 + services/frontend/.eslintrc-auto-import.json | 79 +++++++++ services/frontend/README.md | 2 +- services/frontend/eslint.config.js | 23 +++ services/frontend/index.html | 13 ++ services/frontend/jsconfig.json | 3 +- services/frontend/package.json | 73 ++++---- services/frontend/src/App.vue | 16 +- services/frontend/src/assets/logo.svg | 6 + .../frontend/src/components/AppFooter.vue | 82 +++++++++ .../frontend/src/components/HelloWorld.vue | 163 ++++++++++++++++++ services/frontend/src/components/README.md | 35 ++++ services/frontend/src/layouts/README.md | 5 + services/frontend/src/layouts/default.vue | 12 ++ services/frontend/src/main.js | 26 +-- services/frontend/src/pages/README.md | 5 + services/frontend/src/pages/index.vue | 18 ++ services/frontend/src/plugins/README.md | 3 + services/frontend/src/plugins/index.js | 17 ++ services/frontend/src/plugins/vuetify.js | 19 ++ services/frontend/src/router/index.js | 55 +++--- services/frontend/src/stores/README.md | 5 + services/frontend/src/stores/app.js | 8 + services/frontend/src/stores/index.js | 4 + services/frontend/src/styles/README.md | 3 + services/frontend/src/styles/settings.scss | 10 ++ services/frontend/vite.config.mjs | 74 ++++++++ services/frontend/vue.config.js | 4 - 28 files changed, 676 insertions(+), 95 deletions(-) create mode 100644 services/.idea/.gitignore create mode 100644 services/frontend/.eslintrc-auto-import.json create mode 100644 services/frontend/eslint.config.js create mode 100644 services/frontend/index.html create mode 100644 services/frontend/src/assets/logo.svg create mode 100644 services/frontend/src/components/AppFooter.vue create mode 100644 services/frontend/src/components/HelloWorld.vue create mode 100644 services/frontend/src/components/README.md create mode 100644 services/frontend/src/layouts/README.md create mode 100644 services/frontend/src/layouts/default.vue create mode 100644 services/frontend/src/pages/README.md create mode 100644 services/frontend/src/pages/index.vue create mode 100644 services/frontend/src/plugins/README.md create mode 100644 services/frontend/src/plugins/index.js create mode 100644 services/frontend/src/plugins/vuetify.js create mode 100644 services/frontend/src/stores/README.md create mode 100644 services/frontend/src/stores/app.js create mode 100644 services/frontend/src/stores/index.js create mode 100644 services/frontend/src/styles/README.md create mode 100644 services/frontend/src/styles/settings.scss create mode 100644 services/frontend/vite.config.mjs delete mode 100644 services/frontend/vue.config.js diff --git a/services/.idea/.gitignore b/services/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/services/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/services/frontend/.eslintrc-auto-import.json b/services/frontend/.eslintrc-auto-import.json new file mode 100644 index 0000000..0a9140c --- /dev/null +++ b/services/frontend/.eslintrc-auto-import.json @@ -0,0 +1,79 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "DirectiveBinding": true, + "EffectScope": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "InjectionKey": true, + "MaybeRef": true, + "MaybeRefOrGetter": 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, + "onBeforeRouteLeave": true, + "onBeforeRouteUpdate": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onDeactivated": true, + "onErrorCaptured": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onUnmounted": true, + "onUpdated": true, + "onWatcherCleanup": 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, + "useId": true, + "useLink": true, + "useModel": true, + "useRoute": true, + "useRouter": true, + "useSlots": true, + "useTemplateRef": true, + "watch": true, + "watchEffect": true, + "watchPostEffect": true, + "watchSyncEffect": true + } +} diff --git a/services/frontend/README.md b/services/frontend/README.md index 576b980..3d9295b 100644 --- a/services/frontend/README.md +++ b/services/frontend/README.md @@ -7,7 +7,7 @@ npm install ### Compiles and hot-reloads for development ``` -npm run serve +npm run dev ``` ### Compiles and minifies for production diff --git a/services/frontend/eslint.config.js b/services/frontend/eslint.config.js new file mode 100644 index 0000000..944e82b --- /dev/null +++ b/services/frontend/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import pluginVue from 'eslint-plugin-vue' + +export default [ + { + name: 'app/files-to-lint', + files: ['**/*.{js,mjs,jsx,vue}'], + }, + + { + name: 'app/files-to-ignore', + ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'], + }, + + js.configs.recommended, + ...pluginVue.configs['flat/recommended'], + + { + rules: { + 'vue/multi-word-component-names': 'off', + }, + } +] diff --git a/services/frontend/index.html b/services/frontend/index.html new file mode 100644 index 0000000..0a84a1c --- /dev/null +++ b/services/frontend/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <link rel="icon" href="/favicon.ico"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Welcome to Vuetify 3</title> + </head> + <body> + <div id="app"></div> + <script type="module" src="/src/main.js"></script> + </body> +</html> diff --git a/services/frontend/jsconfig.json b/services/frontend/jsconfig.json index 4aafc5f..dad0634 100644 --- a/services/frontend/jsconfig.json +++ b/services/frontend/jsconfig.json @@ -1,9 +1,10 @@ { "compilerOptions": { + "allowJs": true, "target": "es5", "module": "esnext", "baseUrl": "./", - "moduleResolution": "node", + "moduleResolution": "bundler", "paths": { "@/*": [ "src/*" diff --git a/services/frontend/package.json b/services/frontend/package.json index 62fd8cd..915cc08 100644 --- a/services/frontend/package.json +++ b/services/frontend/package.json @@ -1,49 +1,40 @@ { - "name": "frontend", - "version": "0.1.0", + "name": "regimo", "private": true, + "type": "module", + "version": "0.0.0", "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint" + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "lint": "eslint . --fix" }, "dependencies": { - "axios": "^1.2.1", - "bootstrap": "^5.3.3", - "bootstrap-vue": "^2.23.1", - "core-js": "^3.8.3", - "vue": "^3.4.27", - "vue-router": "^4.0.3", - "vuex": "^4.1.0" + "@mdi/font": "7.4.47", + "roboto-fontface": "*", + "vue": "^3.4.31", + "vuetify": "^3.6.14" }, "devDependencies": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "@vue/cli-plugin-babel": "~5.0.0", - "@vue/cli-plugin-eslint": "~5.0.0", - "@vue/cli-plugin-router": "~5.0.0", - "@vue/cli-service": "~5.0.0", - "eslint": "^7.32.0", - "eslint-plugin-vue": "^8.0.3" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/vue3-essential", - "eslint:recommended" - ], - "parserOptions": { - "parser": "@babel/eslint-parser" - }, - "rules": {} - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead", - "not ie 11" - ] + "@eslint/js": "^9.14.0", + "@vitejs/plugin-vue": "^5.0.5", + "eslint": "^9.14.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.4.0", + "eslint-plugin-vue": "^9.30.0", + "eslint-visitor-keys": "^4.2.0", + "pinia": "^2.1.7", + "sass": "1.77.8", + "sass-embedded": "^1.77.8", + "unplugin-auto-import": "^0.17.6", + "unplugin-fonts": "^1.1.1", + "unplugin-vue-components": "^0.27.2", + "unplugin-vue-router": "^0.10.0", + "vite": "^6.1.1", + "vite-plugin-vue-layouts": "^0.11.0", + "vite-plugin-vuetify": "^2.0.3", + "vue-router": "^4.4.0" + } } diff --git a/services/frontend/src/App.vue b/services/frontend/src/App.vue index b2897ab..4f21c35 100644 --- a/services/frontend/src/App.vue +++ b/services/frontend/src/App.vue @@ -1,15 +1,5 @@ <template> - <div id="app"> - <router-view/> - </div> + <v-app> + <router-view /> + </v-app> </template> - -<style> -#app { - font-family: Avenir, Helvetica, Arial, sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-align: center; - color: #2c3e50; -} -</style> \ No newline at end of file diff --git a/services/frontend/src/assets/logo.svg b/services/frontend/src/assets/logo.svg new file mode 100644 index 0000000..d57771c --- /dev/null +++ b/services/frontend/src/assets/logo.svg @@ -0,0 +1,6 @@ +<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M261.126 140.65L164.624 307.732L256.001 466L377.028 256.5L498.001 47H315.192L261.126 140.65Z" fill="#1697F6"/> +<path d="M135.027 256.5L141.365 267.518L231.64 111.178L268.731 47H256H14L135.027 256.5Z" fill="#AEDDFF"/> +<path d="M315.191 47C360.935 197.446 256 466 256 466L164.624 307.732L315.191 47Z" fill="#1867C0"/> +<path d="M268.731 47C76.0026 47 141.366 267.518 141.366 267.518L268.731 47Z" fill="#7BC6FF"/> +</svg> diff --git a/services/frontend/src/components/AppFooter.vue b/services/frontend/src/components/AppFooter.vue new file mode 100644 index 0000000..0561fef --- /dev/null +++ b/services/frontend/src/components/AppFooter.vue @@ -0,0 +1,82 @@ +<template> + <v-footer + height="40" + app + > + <a + v-for="item in items" + :key="item.title" + :href="item.href" + :title="item.title" + class="d-inline-block mx-2 social-link" + rel="noopener noreferrer" + target="_blank" + > + <v-icon + :icon="item.icon" + :size="item.icon === '$vuetify' ? 24 : 16" + /> + </a> + + <div + class="text-caption text-disabled" + style="position: absolute; right: 16px;" + > + © 2016-{{ (new Date()).getFullYear() }} <span class="d-none d-sm-inline-block">Vuetify, LLC</span> + — + <a + class="text-decoration-none on-surface" + href="https://vuetifyjs.com/about/licensing/" + rel="noopener noreferrer" + target="_blank" + > + MIT License + </a> + </div> + </v-footer> +</template> + +<script setup> +const items = [ + { + title: 'Vuetify Documentation', + icon: `$vuetify`, + href: 'https://vuetifyjs.com/', + }, + { + title: 'Vuetify Support', + icon: 'mdi-shield-star-outline', + href: 'https://support.vuetifyjs.com/', + }, + { + title: 'Vuetify X', + icon: ['M2.04875 3.00002L9.77052 13.3248L1.99998 21.7192H3.74882L10.5519 14.3697L16.0486 21.7192H22L13.8437 10.8137L21.0765 3.00002H19.3277L13.0624 9.76874L8.0001 3.00002H2.04875ZM4.62054 4.28821H7.35461L19.4278 20.4308H16.6937L4.62054 4.28821Z'], + href: 'https://x.com/vuetifyjs', + }, + { + title: 'Vuetify GitHub', + icon: `mdi-github`, + href: 'https://github.com/vuetifyjs/vuetify', + }, + { + title: 'Vuetify Discord', + icon: ['M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z'], + href: 'https://community.vuetifyjs.com/', + }, + { + title: 'Vuetify Reddit', + icon: `mdi-reddit`, + href: 'https://reddit.com/r/vuetifyjs', + }, +] +</script> + +<style scoped lang="sass"> +.social-link :deep(.v-icon) + color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity)) + text-decoration: none + transition: .2s ease-in-out + + &:hover + color: rgba(25, 118, 210, 1) +</style> diff --git a/services/frontend/src/components/HelloWorld.vue b/services/frontend/src/components/HelloWorld.vue new file mode 100644 index 0000000..0f1cc41 --- /dev/null +++ b/services/frontend/src/components/HelloWorld.vue @@ -0,0 +1,163 @@ +<template> + <v-container class="fill-height"> + <v-responsive + class="align-centerfill-height mx-auto" + max-width="900" + > + <v-img + class="mb-4" + height="150" + src="@/assets/logo.png" + /> + + <div class="text-center"> + <div class="text-body-2 font-weight-light mb-n1"> + Welcome to + </div> + + <h1 class="text-h2 font-weight-bold"> + Vuetify + </h1> + </div> + + <div class="py-4" /> + + <v-row> + <v-col cols="12"> + <v-card + class="py-4" + color="surface-variant" + image="https://cdn.vuetifyjs.com/docs/images/one/create/feature.png" + prepend-icon="mdi-rocket-launch-outline" + rounded="lg" + variant="outlined" + > + <template #image> + <v-img position="top right" /> + </template> + + <template #title> + <h2 class="text-h5 font-weight-bold"> + Get started + </h2> + </template> + + <template #subtitle> + <div class="text-subtitle-1"> + Replace this page by removing <v-kbd>{{`<HelloWorld></HelloWorld>`}}</v-kbd> in <v-kbd>pages/index.vue</v-kbd>. + </div> + </template> + + <v-overlay + opacity=".12" + scrim="primary" + contained + model-value + persistent + /> + </v-card> + </v-col> + + <v-col cols="6"> + <v-card + append-icon="mdi-open-in-new" + class="py-4" + color="surface-variant" + href="https://vuetifyjs.com/" + prepend-icon="mdi-text-box-outline" + rel="noopener noreferrer" + rounded="lg" + subtitle="Learn about all things Vuetify in our documentation." + target="_blank" + title="Documentation" + variant="text" + > + <v-overlay + opacity=".06" + scrim="primary" + contained + model-value + persistent + /> + </v-card> + </v-col> + + <v-col cols="6"> + <v-card + append-icon="mdi-open-in-new" + class="py-4" + color="surface-variant" + href="https://vuetifyjs.com/introduction/why-vuetify/#feature-guides" + prepend-icon="mdi-star-circle-outline" + rel="noopener noreferrer" + rounded="lg" + subtitle="Explore available framework Features." + target="_blank" + title="Features" + variant="text" + > + <v-overlay + opacity=".06" + scrim="primary" + contained + model-value + persistent + /> + </v-card> + </v-col> + + <v-col cols="6"> + <v-card + append-icon="mdi-open-in-new" + class="py-4" + color="surface-variant" + href="https://vuetifyjs.com/components/all" + prepend-icon="mdi-widgets-outline" + rel="noopener noreferrer" + rounded="lg" + subtitle="Discover components in the API Explorer." + target="_blank" + title="Components" + variant="text" + > + <v-overlay + opacity=".06" + scrim="primary" + contained + model-value + persistent + /> + </v-card> + </v-col> + + <v-col cols="6"> + <v-card + append-icon="mdi-open-in-new" + class="py-4" + color="surface-variant" + href="https://discord.vuetifyjs.com" + prepend-icon="mdi-account-group-outline" + rel="noopener noreferrer" + rounded="lg" + subtitle="Connect with Vuetify developers." + target="_blank" + title="Community" + variant="text" + > + <v-overlay + opacity=".06" + scrim="primary" + contained + model-value + persistent + /> + </v-card> + </v-col> + </v-row> + </v-responsive> + </v-container> +</template> + +<script setup> +// +</script> diff --git a/services/frontend/src/components/README.md b/services/frontend/src/components/README.md new file mode 100644 index 0000000..84e56cf --- /dev/null +++ b/services/frontend/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 +<template> + <div> + <MyComponent /> + </div> +</template> + +<script lang="ts" setup> + // +</script> +``` + +When your template is rendered, the component's import will automatically be inlined, which renders to this: + +```vue +<template> + <div> + <MyComponent /> + </div> +</template> + +<script lang="ts" setup> + import HelloWorld from 'HelloWorld.vue' +</script> +``` diff --git a/services/frontend/src/layouts/README.md b/services/frontend/src/layouts/README.md new file mode 100644 index 0000000..4016af3 --- /dev/null +++ b/services/frontend/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/services/frontend/src/layouts/default.vue b/services/frontend/src/layouts/default.vue new file mode 100644 index 0000000..055c1ff --- /dev/null +++ b/services/frontend/src/layouts/default.vue @@ -0,0 +1,12 @@ +<template> + <v-main> + <router-view /> + </v-main> + + <AppFooter /> +</template> + +<script setup> + // +import AppFooter from "@/components/AppFooter.vue"; +</script> diff --git a/services/frontend/src/main.js b/services/frontend/src/main.js index e333042..a2ef932 100644 --- a/services/frontend/src/main.js +++ b/services/frontend/src/main.js @@ -1,14 +1,20 @@ -import 'bootstrap/dist/css/bootstrap.css'; -import { createApp } from "vue"; -import axios from 'axios'; +/** + * main.js + * + * Bootstraps Vuetify and other plugins then mounts the App` + */ -import App from './App.vue'; -import router from './router'; +// Plugins +import { registerPlugins } from '@/plugins' -const app = createApp(App); +// Components +import App from './App.vue' -axios.defaults.withCredentials = true; -axios.defaults.baseURL = 'http://localhost:8000/'; // the FastAPI backend +// Composable +import { createApp } from 'vue' -app.use(router); -app.mount("#app"); +const app = createApp(App) + +registerPlugins(app) + +app.mount('#app') diff --git a/services/frontend/src/pages/README.md b/services/frontend/src/pages/README.md new file mode 100644 index 0000000..341536c --- /dev/null +++ b/services/frontend/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/services/frontend/src/pages/index.vue b/services/frontend/src/pages/index.vue new file mode 100644 index 0000000..291b3db --- /dev/null +++ b/services/frontend/src/pages/index.vue @@ -0,0 +1,18 @@ +<template> + <v-layout class="rounded rounded-md"> + <v-app-bar title="Application bar" /> + + <v-navigation-drawer> + <v-list> + <v-list-item title="Navigation drawer" /> + </v-list> + </v-navigation-drawer> + + <v-main + class="d-flex align-center justify-center" + style="min-height: 300px;" + > + Main Content + </v-main> + </v-layout> +</template> \ No newline at end of file diff --git a/services/frontend/src/plugins/README.md b/services/frontend/src/plugins/README.md new file mode 100644 index 0000000..62201c7 --- /dev/null +++ b/services/frontend/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/services/frontend/src/plugins/index.js b/services/frontend/src/plugins/index.js new file mode 100644 index 0000000..be6e2da --- /dev/null +++ b/services/frontend/src/plugins/index.js @@ -0,0 +1,17 @@ +/** + * plugins/index.js + * + * Automatically included in `./src/main.js` + */ + +// Plugins +import vuetify from './vuetify' +import pinia from '@/stores' +import router from '@/router' + +export function registerPlugins (app) { + app + .use(vuetify) + .use(router) + .use(pinia) +} diff --git a/services/frontend/src/plugins/vuetify.js b/services/frontend/src/plugins/vuetify.js new file mode 100644 index 0000000..247a149 --- /dev/null +++ b/services/frontend/src/plugins/vuetify.js @@ -0,0 +1,19 @@ +/** + * plugins/vuetify.js + * + * 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/services/frontend/src/router/index.js b/services/frontend/src/router/index.js index 90e1b84..a65e6b9 100644 --- a/services/frontend/src/router/index.js +++ b/services/frontend/src/router/index.js @@ -1,31 +1,36 @@ -import { createRouter, createWebHistory } from 'vue-router' -import HomeView from '../views/HomeView.vue' -import RegisterView from '../views/RegisterView.vue' +/** + * router/index.ts + * + * Automatic routes for `./src/pages/*.vue` + */ -const routes = [ - { - path: '/', - name: 'home', - component: HomeView - }, - { - path: '/register', - name: 'register', - component: RegisterView - }, - { - path: '/about', - name: 'about', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue') - } -] +// Composable +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(process.env.BASE_URL), - routes + 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/services/frontend/src/stores/README.md b/services/frontend/src/stores/README.md new file mode 100644 index 0000000..54f8e03 --- /dev/null +++ b/services/frontend/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/services/frontend/src/stores/app.js b/services/frontend/src/stores/app.js new file mode 100644 index 0000000..7429543 --- /dev/null +++ b/services/frontend/src/stores/app.js @@ -0,0 +1,8 @@ +// Utilities +import { defineStore } from 'pinia' + +export const useAppStore = defineStore('app', { + state: () => ({ + // + }), +}) diff --git a/services/frontend/src/stores/index.js b/services/frontend/src/stores/index.js new file mode 100644 index 0000000..1536252 --- /dev/null +++ b/services/frontend/src/stores/index.js @@ -0,0 +1,4 @@ +// Utilities +import { createPinia } from 'pinia' + +export default createPinia() diff --git a/services/frontend/src/styles/README.md b/services/frontend/src/styles/README.md new file mode 100644 index 0000000..ea86179 --- /dev/null +++ b/services/frontend/src/styles/README.md @@ -0,0 +1,3 @@ +# Styles + +This directory is for configuring the styles of the application. diff --git a/services/frontend/src/styles/settings.scss b/services/frontend/src/styles/settings.scss new file mode 100644 index 0000000..3e36a27 --- /dev/null +++ b/services/frontend/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/services/frontend/vite.config.mjs b/services/frontend/vite.config.mjs new file mode 100644 index 0000000..73375db --- /dev/null +++ b/services/frontend/vite.config.mjs @@ -0,0 +1,74 @@ +// 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(), + Layouts(), + Vue({ + template: { transformAssetUrls } + }), + // https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin#readme + Vuetify({ + autoImport: true, + styles: { + configFile: 'src/styles/settings.scss', + }, + }), + Components(), + Fonts({ + google: { + families: [{ + name: 'Roboto', + styles: 'wght@100;300;400;500;700;900', + }], + }, + }), + AutoImport({ + imports: [ + 'vue', + 'vue-router', + ], + eslintrc: { + enabled: true, + }, + vueTemplate: true, + }), + ], + 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', + }, + }, + }, +}) diff --git a/services/frontend/vue.config.js b/services/frontend/vue.config.js deleted file mode 100644 index 910e297..0000000 --- a/services/frontend/vue.config.js +++ /dev/null @@ -1,4 +0,0 @@ -const { defineConfig } = require('@vue/cli-service') -module.exports = defineConfig({ - transpileDependencies: true -}) -- GitLab