diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..d48f257
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+NUXT_PUBLIC_API_BASE_URL=http://localhost:3000
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..720eeb0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.nuxt/
+.output/
+.env
+dist/
+coverage/
diff --git a/app.vue b/app.vue
new file mode 100644
index 0000000..62cd98b
--- /dev/null
+++ b/app.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/middleware/auth.ts b/middleware/auth.ts
new file mode 100644
index 0000000..f558d49
--- /dev/null
+++ b/middleware/auth.ts
@@ -0,0 +1,6 @@
+import { useAuthStore } from '~/stores/auth';
+
+export default defineNuxtRouteMiddleware(() => {
+ const auth = useAuthStore();
+ if (!auth.isAuthenticated) return navigateTo('/login');
+});
diff --git a/nuxt.config.ts b/nuxt.config.ts
new file mode 100644
index 0000000..7c11e34
--- /dev/null
+++ b/nuxt.config.ts
@@ -0,0 +1,9 @@
+export default defineNuxtConfig({
+ devtools: { enabled: true },
+ modules: ['@nuxtjs/tailwindcss', '@pinia/nuxt'],
+ runtimeConfig: {
+ public: {
+ apiBaseUrl: '', // set via NUXT_PUBLIC_API_BASE_URL
+ },
+ },
+})
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b572b4a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "nest-intranet",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "build": "nuxt build",
+ "dev": "nuxt dev",
+ "generate": "nuxt generate",
+ "preview": "nuxt preview",
+ "test": "vitest run",
+ "test:watch": "vitest",
+ "test:update": "vitest --update-snapshots"
+ },
+ "dependencies": {
+ "@pinia/nuxt": "^0.10.0",
+ "nuxt": "^3.15.0",
+ "pinia": "^2.3.0",
+ "vue": "^3.5.0"
+ },
+ "devDependencies": {
+ "@nuxt/test-utils": "^3.15.0",
+ "@nuxtjs/tailwindcss": "^6.13.0",
+ "@vitest/coverage-v8": "^3.0.0",
+ "typescript": "^5.7.0",
+ "vitest": "^3.0.0"
+ }
+}
diff --git a/pages/dashboard.vue b/pages/dashboard.vue
new file mode 100644
index 0000000..0ba8e06
--- /dev/null
+++ b/pages/dashboard.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
Dashboard
+
+
diff --git a/pages/login.vue b/pages/login.vue
new file mode 100644
index 0000000..3622516
--- /dev/null
+++ b/pages/login.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
diff --git a/stores/auth.ts b/stores/auth.ts
new file mode 100644
index 0000000..4807398
--- /dev/null
+++ b/stores/auth.ts
@@ -0,0 +1,31 @@
+import { defineStore } from 'pinia';
+
+interface AuthUser {
+ id: string;
+ email: string;
+ username: string;
+ role: 'ADMIN' | 'DEV' | 'MEMBER';
+}
+
+export const useAuthStore = defineStore('auth', () => {
+ const user = ref(null);
+ const token = ref(null);
+ const isAuthenticated = computed(() => !!token.value);
+
+ async function login(credentials: { email: string; password: string }) {
+ const config = useRuntimeConfig();
+ const data = await $fetch<{ token: string; user: AuthUser }>(
+ `${config.public.apiBaseUrl}/auth/login`,
+ { method: 'POST', body: credentials },
+ );
+ token.value = data.token;
+ user.value = data.user;
+ }
+
+ function logout() {
+ token.value = null;
+ user.value = null;
+ }
+
+ return { user, token, isAuthenticated, login, logout };
+});
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..4b34df1
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "./.nuxt/tsconfig.json"
+}
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..b519c1f
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineVitestConfig } from '@nuxt/test-utils/config';
+
+export default defineVitestConfig({
+ test: {
+ environment: 'nuxt',
+ },
+});