diff --git a/resources/js/middleware/auth.ts b/resources/js/middleware/auth.ts
new file mode 100644
index 0000000..db03901
--- /dev/null
+++ b/resources/js/middleware/auth.ts
@@ -0,0 +1,98 @@
+import { useAuthStore } from '@/stores/auth';
+import { router } from '@inertiajs/vue3';
+
+/**
+ * Protected routes that require authentication
+ */
+const protectedRoutes = [
+ '/dashboard',
+ '/profile',
+ '/paiement',
+ '/cards',
+ '/agenda',
+ '/checkout',
+ '/payments',
+];
+
+/**
+ * Guest-only routes (redirect if authenticated)
+ */
+const guestRoutes = [
+ '/login',
+ '/register',
+ '/password/request',
+ '/password/reset',
+];
+
+/**
+ * Check if a URL matches any of the route patterns
+ */
+function matchesRoute(url: string, routes: string[]): boolean {
+ return routes.some(route => url.startsWith(route));
+}
+
+/**
+ * Setup Inertia.js navigation guards
+ * This uses Inertia's event system to intercept navigation
+ */
+export function setupAuthGuards(): void {
+ const authStore = useAuthStore();
+
+ // Initialize auth state on app load
+ authStore.checkAuth().catch(() => {
+ // Silent fail - user is not authenticated
+ });
+
+ // Intercept Inertia navigation before it happens
+ router.on('before', async (event) => {
+ const url = event.detail.visit.url.pathname;
+
+ // Check if trying to access a protected route
+ if (matchesRoute(url, protectedRoutes)) {
+ const isAuthenticated = await authStore.checkAuth();
+
+ if (!isAuthenticated && url !== '/login') {
+ // Prevent the navigation and redirect to login
+ event.preventDefault();
+ router.get('/login', {}, {
+ preserveState: false,
+ replace: true
+ });
+ return;
+ }
+ }
+
+ // Check if trying to access a guest-only route
+ if (matchesRoute(url, guestRoutes)) {
+ const isAuthenticated = await authStore.checkAuth();
+
+ if (isAuthenticated && url !== '/dashboard') {
+ // Prevent the navigation and redirect to dashboard
+ event.preventDefault();
+ router.get('/dashboard', {}, {
+ preserveState: false,
+ replace: true
+ });
+ return;
+ }
+ }
+ });
+}
+
+/**
+ * Add a protected route to the list
+ */
+export function addProtectedRoute(route: string): void {
+ if (!protectedRoutes.includes(route)) {
+ protectedRoutes.push(route);
+ }
+}
+
+/**
+ * Add a guest route to the list
+ */
+export function addGuestRoute(route: string): void {
+ if (!guestRoutes.includes(route)) {
+ guestRoutes.push(route);
+ }
+}
diff --git a/resources/js/services/authService.ts b/resources/js/services/authService.ts
new file mode 100644
index 0000000..ae56c3a
--- /dev/null
+++ b/resources/js/services/authService.ts
@@ -0,0 +1,104 @@
+import http from '@/lib/http';
+
+export interface LoginCredentials {
+ email: string;
+ password: string;
+ remember?: boolean;
+}
+
+export interface User {
+ id: number;
+ name: string;
+ email: string;
+ email_verified_at?: string;
+ created_at: string;
+ updated_at: string;
+}
+
+export interface LoginResponse {
+ user: User;
+ token?: string;
+ message?: string;
+}
+
+export interface ApiError {
+ message: string;
+ errors?: Record;
+}
+
+class AuthService {
+ /**
+ * Login user with email and password
+ */
+ async login(credentials: LoginCredentials): Promise {
+ try {
+ const response = await http.post(
+ 'http://localhost:8000/api/auth/login',
+ credentials
+ );
+ return response.data;
+ } catch (error: any) {
+ throw this.handleError(error);
+ }
+ }
+
+ /**
+ * Logout the current user
+ */
+ async logout(): Promise {
+ try {
+ await http.post('http://localhost:8000/api/auth/logout');
+ } catch (error: any) {
+ throw this.handleError(error);
+ }
+ }
+
+ /**
+ * Get the current authenticated user
+ */
+ async getCurrentUser(): Promise {
+ try {
+ const response = await http.get<{ user: User }>(
+ 'http://localhost:8000/api/auth/user'
+ );
+ return response.data.user;
+ } catch (error: any) {
+ throw this.handleError(error);
+ }
+ }
+
+ /**
+ * Check if user is authenticated
+ */
+ async checkAuth(): Promise {
+ try {
+ await this.getCurrentUser();
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
+ /**
+ * Handle API errors
+ */
+ private handleError(error: any): Error {
+ if (error.response?.data) {
+ const apiError = error.response.data as ApiError;
+ const message = apiError.message || 'An error occurred';
+ const errors = apiError.errors;
+
+ if (errors) {
+ const firstError = Object.values(errors)[0];
+ return new Error(firstError ? firstError[0] : message);
+ }
+
+ return new Error(message);
+ }
+
+ return new Error(error.message || 'Network error occurred');
+ }
+}
+
+export const authService = new AuthService();
+export default authService;
diff --git a/resources/js/stores/auth.ts b/resources/js/stores/auth.ts
new file mode 100644
index 0000000..34823b9
--- /dev/null
+++ b/resources/js/stores/auth.ts
@@ -0,0 +1,125 @@
+import authService, { type LoginCredentials, type User } from '@/services/authService';
+import { defineStore } from 'pinia';
+import { computed, ref } from 'vue';
+
+export const useAuthStore = defineStore(
+ 'auth',
+ () => {
+ // State
+ const user = ref(null);
+ const token = ref(null);
+ const loading = ref(false);
+ const error = ref(null);
+
+ // Getters
+ const isAuthenticated = computed(() => user.value !== null);
+ const currentUser = computed(() => user.value);
+
+ // Actions
+ async function login(credentials: LoginCredentials): Promise {
+ loading.value = true;
+ error.value = null;
+
+ try {
+ const response = await authService.login(credentials);
+ user.value = response.user;
+
+ if (response.token) {
+ token.value = response.token;
+ }
+
+ return true;
+ } catch (err: any) {
+ error.value = err.message || 'Login failed';
+ return false;
+ } finally {
+ loading.value = false;
+ }
+ }
+
+ async function logout(): Promise {
+ loading.value = true;
+
+ try {
+ await authService.logout();
+ } catch (err: any) {
+ console.error('Logout error:', err);
+ } finally {
+ // Clear state regardless of API call result
+ user.value = null;
+ token.value = null;
+ error.value = null;
+ loading.value = false;
+ }
+ }
+
+ async function checkAuth(): Promise {
+ if (user.value) {
+ return true;
+ }
+
+ loading.value = true;
+
+ try {
+ const currentUser = await authService.getCurrentUser();
+ user.value = currentUser;
+ return true;
+ } catch {
+ user.value = null;
+ token.value = null;
+ return false;
+ } finally {
+ loading.value = false;
+ }
+ }
+
+ async function fetchUser(): Promise {
+ loading.value = true;
+ error.value = null;
+
+ try {
+ const currentUser = await authService.getCurrentUser();
+ user.value = currentUser;
+ } catch (err: any) {
+ error.value = err.message || 'Failed to fetch user';
+ user.value = null;
+ token.value = null;
+ } finally {
+ loading.value = false;
+ }
+ }
+
+ function clearError(): void {
+ error.value = null;
+ }
+
+ function setUser(userData: User): void {
+ user.value = userData;
+ }
+
+ return {
+ // State
+ user,
+ token,
+ loading,
+ error,
+ // Getters
+ isAuthenticated,
+ currentUser,
+ // Actions
+ login,
+ logout,
+ checkAuth,
+ fetchUser,
+ clearError,
+ setUser,
+ };
+ },
+ {
+ persist: {
+ key: 'auth-storage',
+ storage: typeof window !== 'undefined' ? localStorage : undefined,
+ paths: ['user', 'token'],
+ },
+ }
+);