diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..6313b56
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto eol=lf
diff --git a/.gitignore b/.gitignore
index 087a183..1042d71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,4 +32,38 @@ target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
-release.properties
\ No newline at end of file
+release.properties
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/src/frontend/.editorconfig b/src/frontend/.editorconfig
new file mode 100644
index 0000000..5a5809d
--- /dev/null
+++ b/src/frontend/.editorconfig
@@ -0,0 +1,9 @@
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
+charset = utf-8
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+end_of_line = lf
+max_line_length = 100
diff --git a/src/frontend/README.md b/src/frontend/README.md
new file mode 100644
index 0000000..b926770
--- /dev/null
+++ b/src/frontend/README.md
@@ -0,0 +1,64 @@
+# organizajogos-frontend
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vite.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Lint with [ESLint](https://eslint.org/)
+
+```sh
+pnpm lint
+```
diff --git a/src/frontend/e2e/tsconfig.json b/src/frontend/e2e/tsconfig.json
new file mode 100644
index 0000000..f31fe71
--- /dev/null
+++ b/src/frontend/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node22/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/src/frontend/e2e/vue.spec.ts b/src/frontend/e2e/vue.spec.ts
new file mode 100644
index 0000000..fc116a9
--- /dev/null
+++ b/src/frontend/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('h1')).toHaveText('You did it!');
+})
diff --git a/src/frontend/env.d.ts b/src/frontend/env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/src/frontend/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/src/frontend/eslint.config.ts b/src/frontend/eslint.config.ts
new file mode 100644
index 0000000..8bd27d9
--- /dev/null
+++ b/src/frontend/eslint.config.ts
@@ -0,0 +1,32 @@
+import { globalIgnores } from 'eslint/config'
+import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
+import pluginVue from 'eslint-plugin-vue'
+import pluginVitest from '@vitest/eslint-plugin'
+import pluginPlaywright from 'eslint-plugin-playwright'
+
+// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
+// import { configureVueProject } from '@vue/eslint-config-typescript'
+// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
+// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup
+
+export default defineConfigWithVueTs(
+ {
+ name: 'app/files-to-lint',
+ files: ['**/*.{ts,mts,tsx,vue}'],
+ },
+
+ globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
+
+ pluginVue.configs['flat/essential'],
+ vueTsConfigs.recommended,
+
+ {
+ ...pluginVitest.configs.recommended,
+ files: ['src/**/__tests__/*'],
+ },
+
+ {
+ ...pluginPlaywright.configs['flat/recommended'],
+ files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'],
+ },
+)
diff --git a/src/frontend/index.html b/src/frontend/index.html
new file mode 100644
index 0000000..9e5fc8f
--- /dev/null
+++ b/src/frontend/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/src/frontend/package.json b/src/frontend/package.json
new file mode 100644
index 0000000..7f3d041
--- /dev/null
+++ b/src/frontend/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "organizajogos-frontend",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build",
+ "lint": "eslint . --fix"
+ },
+ "dependencies": {
+ "vue": "^3.5.17"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.53.1",
+ "@tsconfig/node22": "^22.0.2",
+ "@types/jsdom": "^21.1.7",
+ "@types/node": "^22.15.32",
+ "@vitejs/plugin-vue": "^6.0.0",
+ "@vitejs/plugin-vue-jsx": "^5.0.0",
+ "@vitest/eslint-plugin": "^1.2.7",
+ "@vue/eslint-config-typescript": "^14.5.1",
+ "@vue/test-utils": "^2.4.6",
+ "@vue/tsconfig": "^0.7.0",
+ "eslint": "^9.29.0",
+ "eslint-plugin-playwright": "^2.2.0",
+ "eslint-plugin-vue": "~10.2.0",
+ "jiti": "^2.4.2",
+ "jsdom": "^26.1.0",
+ "npm-run-all2": "^8.0.4",
+ "typescript": "~5.8.0",
+ "vite": "^7.0.0",
+ "vite-plugin-vue-devtools": "^7.7.7",
+ "vitest": "^3.2.4",
+ "vue-tsc": "^2.2.10"
+ }
+}
diff --git a/src/frontend/playwright.config.ts b/src/frontend/playwright.config.ts
new file mode 100644
index 0000000..5ece956
--- /dev/null
+++ b/src/frontend/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000,
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: process.env.CI ? 'http://localhost:4173' : 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI,
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome'],
+ },
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox'],
+ },
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari'],
+ },
+ },
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'npm run preview' : 'npm run dev',
+ port: process.env.CI ? 4173 : 5173,
+ reuseExistingServer: !process.env.CI,
+ },
+})
diff --git a/src/frontend/public/favicon.ico b/src/frontend/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/src/frontend/public/favicon.ico differ
diff --git a/src/frontend/src/App.vue b/src/frontend/src/App.vue
new file mode 100644
index 0000000..d05208d
--- /dev/null
+++ b/src/frontend/src/App.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontend/src/assets/base.css b/src/frontend/src/assets/base.css
new file mode 100644
index 0000000..8816868
--- /dev/null
+++ b/src/frontend/src/assets/base.css
@@ -0,0 +1,86 @@
+/* color palette from */
+:root {
+ --vt-c-white: #ffffff;
+ --vt-c-white-soft: #f8f8f8;
+ --vt-c-white-mute: #f2f2f2;
+
+ --vt-c-black: #181818;
+ --vt-c-black-soft: #222222;
+ --vt-c-black-mute: #282828;
+
+ --vt-c-indigo: #2c3e50;
+
+ --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
+ --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
+ --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
+ --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
+
+ --vt-c-text-light-1: var(--vt-c-indigo);
+ --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
+ --vt-c-text-dark-1: var(--vt-c-white);
+ --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
+}
+
+/* semantic color variables for this project */
+:root {
+ --color-background: var(--vt-c-white);
+ --color-background-soft: var(--vt-c-white-soft);
+ --color-background-mute: var(--vt-c-white-mute);
+
+ --color-border: var(--vt-c-divider-light-2);
+ --color-border-hover: var(--vt-c-divider-light-1);
+
+ --color-heading: var(--vt-c-text-light-1);
+ --color-text: var(--vt-c-text-light-1);
+
+ --section-gap: 160px;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --color-background: var(--vt-c-black);
+ --color-background-soft: var(--vt-c-black-soft);
+ --color-background-mute: var(--vt-c-black-mute);
+
+ --color-border: var(--vt-c-divider-dark-2);
+ --color-border-hover: var(--vt-c-divider-dark-1);
+
+ --color-heading: var(--vt-c-text-dark-1);
+ --color-text: var(--vt-c-text-dark-2);
+ }
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ margin: 0;
+ font-weight: normal;
+}
+
+body {
+ min-height: 100vh;
+ color: var(--color-text);
+ background: var(--color-background);
+ transition:
+ color 0.5s,
+ background-color 0.5s;
+ line-height: 1.6;
+ font-family:
+ Inter,
+ -apple-system,
+ BlinkMacSystemFont,
+ 'Segoe UI',
+ Roboto,
+ Oxygen,
+ Ubuntu,
+ Cantarell,
+ 'Fira Sans',
+ 'Droid Sans',
+ 'Helvetica Neue',
+ sans-serif;
+ font-size: 15px;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/src/frontend/src/assets/logo.svg b/src/frontend/src/assets/logo.svg
new file mode 100644
index 0000000..7565660
--- /dev/null
+++ b/src/frontend/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/src/frontend/src/assets/main.css b/src/frontend/src/assets/main.css
new file mode 100644
index 0000000..36fb845
--- /dev/null
+++ b/src/frontend/src/assets/main.css
@@ -0,0 +1,35 @@
+@import './base.css';
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ font-weight: normal;
+}
+
+a,
+.green {
+ text-decoration: none;
+ color: hsla(160, 100%, 37%, 1);
+ transition: 0.4s;
+ padding: 3px;
+}
+
+@media (hover: hover) {
+ a:hover {
+ background-color: hsla(160, 100%, 37%, 0.2);
+ }
+}
+
+@media (min-width: 1024px) {
+ body {
+ display: flex;
+ place-items: center;
+ }
+
+ #app {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ padding: 0 2rem;
+ }
+}
diff --git a/src/frontend/src/components/HelloWorld.vue b/src/frontend/src/components/HelloWorld.vue
new file mode 100644
index 0000000..a2eabd1
--- /dev/null
+++ b/src/frontend/src/components/HelloWorld.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
{{ msg }}
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3 .
+
+
+
+
+
diff --git a/src/frontend/src/components/TheWelcome.vue b/src/frontend/src/components/TheWelcome.vue
new file mode 100644
index 0000000..6092dff
--- /dev/null
+++ b/src/frontend/src/components/TheWelcome.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite . The
+ recommended IDE setup is
+ VSCode
+ +
+ Vue - Official . If
+ you need to test your components and web pages, check out
+ Vitest
+ and
+ Cypress
+ /
+ Playwright .
+
+
+
+ More instructions are available in
+ README.md
.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia ,
+ Vue Router ,
+ Vue Test Utils , and
+ Vue Dev Tools . If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land
+ (our official Discord server), or
+ StackOverflow . You should also follow the official
+ @vuejs.org
+ Bluesky account or the
+ @vuejs
+ X account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor .
+
+
diff --git a/src/frontend/src/components/WelcomeItem.vue b/src/frontend/src/components/WelcomeItem.vue
new file mode 100644
index 0000000..6d7086a
--- /dev/null
+++ b/src/frontend/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
diff --git a/src/frontend/src/components/__tests__/HelloWorld.spec.ts b/src/frontend/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 0000000..2533202
--- /dev/null
+++ b/src/frontend/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/src/frontend/src/components/icons/IconCommunity.vue b/src/frontend/src/components/icons/IconCommunity.vue
new file mode 100644
index 0000000..2dc8b05
--- /dev/null
+++ b/src/frontend/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/frontend/src/components/icons/IconDocumentation.vue b/src/frontend/src/components/icons/IconDocumentation.vue
new file mode 100644
index 0000000..6d4791c
--- /dev/null
+++ b/src/frontend/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/frontend/src/components/icons/IconEcosystem.vue b/src/frontend/src/components/icons/IconEcosystem.vue
new file mode 100644
index 0000000..c3a4f07
--- /dev/null
+++ b/src/frontend/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/frontend/src/components/icons/IconSupport.vue b/src/frontend/src/components/icons/IconSupport.vue
new file mode 100644
index 0000000..7452834
--- /dev/null
+++ b/src/frontend/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/frontend/src/components/icons/IconTooling.vue b/src/frontend/src/components/icons/IconTooling.vue
new file mode 100644
index 0000000..660598d
--- /dev/null
+++ b/src/frontend/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/src/frontend/src/main.ts b/src/frontend/src/main.ts
new file mode 100644
index 0000000..0ac3a5f
--- /dev/null
+++ b/src/frontend/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/src/frontend/tsconfig.app.json b/src/frontend/tsconfig.app.json
new file mode 100644
index 0000000..913b8f2
--- /dev/null
+++ b/src/frontend/tsconfig.app.json
@@ -0,0 +1,12 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/src/frontend/tsconfig.json b/src/frontend/tsconfig.json
new file mode 100644
index 0000000..100cf6a
--- /dev/null
+++ b/src/frontend/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/src/frontend/tsconfig.node.json b/src/frontend/tsconfig.node.json
new file mode 100644
index 0000000..a83dfc9
--- /dev/null
+++ b/src/frontend/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node22/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*",
+ "eslint.config.*"
+ ],
+ "compilerOptions": {
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/src/frontend/tsconfig.vitest.json b/src/frontend/tsconfig.vitest.json
new file mode 100644
index 0000000..7d1d8ce
--- /dev/null
+++ b/src/frontend/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "include": ["src/**/__tests__/*", "env.d.ts"],
+ "exclude": [],
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts
new file mode 100644
index 0000000..d49d708
--- /dev/null
+++ b/src/frontend/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import vueDevTools from 'vite-plugin-vue-devtools'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ vueDevTools(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ },
+ },
+})
diff --git a/src/frontend/vitest.config.ts b/src/frontend/vitest.config.ts
new file mode 100644
index 0000000..c328717
--- /dev/null
+++ b/src/frontend/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/**'],
+ root: fileURLToPath(new URL('./', import.meta.url)),
+ },
+ }),
+)