feat: Initialize project with configuration files and basic structure

This commit is contained in:
Thibault Pouch
2026-05-01 10:57:26 +02:00
parent 268f7949dc
commit c2920dbbdc
11 changed files with 151 additions and 0 deletions

1
.env.example Normal file
View File

@@ -0,0 +1 @@
NUXT_PUBLIC_API_BASE_URL=http://localhost:3000

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
node_modules/
.nuxt/
.output/
.env
dist/
coverage/

6
app.vue Normal file
View File

@@ -0,0 +1,6 @@
<template>
<NuxtRouteAnnouncer />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

6
middleware/auth.ts Normal file
View File

@@ -0,0 +1,6 @@
import { useAuthStore } from '~/stores/auth';
export default defineNuxtRouteMiddleware(() => {
const auth = useAuthStore();
if (!auth.isAuthenticated) return navigateTo('/login');
});

9
nuxt.config.ts Normal file
View File

@@ -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
},
},
})

27
package.json Normal file
View File

@@ -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"
}
}

9
pages/dashboard.vue Normal file
View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
definePageMeta({ middleware: 'auth' });
</script>
<template>
<div class="p-8">
<h1 class="text-2xl font-bold">Dashboard</h1>
</div>
</template>

46
pages/login.vue Normal file
View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
import { useAuthStore } from '~/stores/auth';
definePageMeta({ layout: false });
const auth = useAuthStore();
const email = ref('');
const password = ref('');
const error = ref('');
async function submit() {
error.value = '';
try {
await auth.login({ email: email.value, password: password.value });
await navigateTo('/dashboard');
} catch {
error.value = 'Invalid credentials.';
}
}
</script>
<template>
<div class="min-h-screen flex items-center justify-center bg-gray-50">
<form class="w-full max-w-sm space-y-4" @submit.prevent="submit">
<h1 class="text-2xl font-bold text-center">CrowMate Intranet</h1>
<p v-if="error" class="text-red-500 text-sm text-center">{{ error }}</p>
<input
v-model="email"
type="email"
placeholder="Email"
required
class="w-full border rounded px-3 py-2 text-sm"
/>
<input
v-model="password"
type="password"
placeholder="Password"
required
class="w-full border rounded px-3 py-2 text-sm"
/>
<button type="submit" class="w-full bg-black text-white rounded py-2 text-sm font-medium">
Sign in
</button>
</form>
</div>
</template>

31
stores/auth.ts Normal file
View File

@@ -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<AuthUser | null>(null);
const token = ref<string | null>(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 };
});

3
tsconfig.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "./.nuxt/tsconfig.json"
}

7
vitest.config.ts Normal file
View File

@@ -0,0 +1,7 @@
import { defineVitestConfig } from '@nuxt/test-utils/config';
export default defineVitestConfig({
test: {
environment: 'nuxt',
},
});