import { defineStore } from 'pinia' import { ref, computed } from 'vue' import axios from '@/utils/axios' import router from '@/router' import { useToast } from 'vue-toastification' export const useAuthStore = defineStore('auth', () => { const user = ref(null) const token = ref(localStorage.getItem('token')) const toast = useToast() const isAuthenticated = computed(() => !!token.value) const isAdmin = computed(() => user.value?.is_admin || false) if (token.value) { axios.defaults.headers.common['Authorization'] = `Bearer ${token.value}` } async function login(email, password) { try { // Pour OAuth2PasswordRequestForm, on doit envoyer en format x-www-form-urlencoded const formData = new URLSearchParams() formData.append('username', email) // OAuth2PasswordRequestForm expects username field formData.append('password', password) const response = await axios.post('/api/auth/login', formData.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }) const { access_token, user: userData } = response.data token.value = access_token user.value = userData localStorage.setItem('token', access_token) axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` toast.success(`Bienvenue ${userData.full_name} !`) router.push('/') return { success: true } } catch (error) { toast.error(error.response?.data?.detail || 'Erreur de connexion') return { success: false, error: error.response?.data?.detail } } } async function register(userData) { try { const response = await axios.post('/api/auth/register', userData) const { access_token, user: newUser } = response.data token.value = access_token user.value = newUser localStorage.setItem('token', access_token) axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` toast.success('Inscription réussie !') router.push('/') return { success: true } } catch (error) { toast.error(error.response?.data?.detail || 'Erreur lors de l\'inscription') return { success: false, error: error.response?.data?.detail } } } async function logout() { token.value = null user.value = null notifications.value = [] unreadCount.value = 0 localStorage.removeItem('token') delete axios.defaults.headers.common['Authorization'] // Arrêter le polling des notifications const notificationService = (await import('@/services/notificationService')).default notificationService.stopPolling() router.push('/login') toast.info('Déconnexion réussie') } async function fetchCurrentUser() { if (!token.value) return try { const response = await axios.get('/api/users/me') user.value = response.data } catch (error) { console.error('Error fetching user:', error) if (error.response?.status === 401) { logout() } } } async function updateProfile(profileData) { try { const response = await axios.put('/api/users/me', profileData) user.value = response.data toast.success('Profil mis à jour') return { success: true, data: response.data } } catch (error) { toast.error('Erreur lors de la mise à jour du profil') return { success: false, error: error.response?.data?.detail } } } async function uploadAvatar(file) { try { const formData = new FormData() formData.append('file', file) const response = await axios.post('/api/users/me/avatar', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) user.value = response.data toast.success('Avatar mis à jour') return { success: true, data: response.data } } catch (error) { console.error('Error uploading avatar:', error) toast.error('Erreur lors de l\'upload de l\'avatar') return { success: false, error: error.response?.data?.detail || 'Erreur inconnue' } } } // Notifications const notifications = ref([]) const unreadCount = ref(0) async function fetchNotifications() { if (!token.value) return try { const response = await axios.get('/api/notifications?limit=50') const newNotifications = response.data // Détecter les nouvelles notifications non lues const previousIds = new Set(notifications.value.map(n => n.id)) const previousUnreadIds = new Set( notifications.value.filter(n => !n.is_read).map(n => n.id) ) // Nouvelles notifications = celles qui n'existaient pas avant const hasNewNotifications = newNotifications.some(n => !previousIds.has(n.id)) // Nouvelles notifications non lues = nouvelles ET non lues const newUnreadNotifications = newNotifications.filter( n => !previousIds.has(n.id) && !n.is_read ) notifications.value = newNotifications const newUnreadCount = notifications.value.filter(n => !n.is_read).length const previousUnreadCount = unreadCount.value unreadCount.value = newUnreadCount // Retourner si de nouvelles notifications non lues ont été détectées return { hasNewNotifications: newUnreadNotifications.length > 0, newCount: newUnreadCount, previousCount: previousUnreadCount } } catch (error) { console.error('Error fetching notifications:', error) return { hasNewNotifications: false, newCount: unreadCount.value, previousCount: unreadCount.value } } } async function markNotificationRead(notificationId) { try { await axios.put(`/api/notifications/${notificationId}/read`) const notification = notifications.value.find(n => n.id === notificationId) if (notification && !notification.is_read) { notification.is_read = true notification.read_at = new Date().toISOString() unreadCount.value = Math.max(0, unreadCount.value - 1) } } catch (error) { console.error('Error marking notification read:', error) } } async function markAllNotificationsRead() { try { await axios.put('/api/notifications/read-all') notifications.value.forEach(n => { n.is_read = true n.read_at = new Date().toISOString() }) unreadCount.value = 0 } catch (error) { console.error('Error marking all notifications read:', error) } } async function fetchUnreadCount() { if (!token.value) return try { const response = await axios.get('/api/notifications/unread-count') unreadCount.value = response.data.unread_count } catch (error) { console.error('Error fetching unread count:', error) } } return { user, token, isAuthenticated, isAdmin, login, register, logout, fetchCurrentUser, updateProfile, uploadAvatar, // Notifications notifications, unreadCount, fetchNotifications, markNotificationRead, markAllNotificationsRead, fetchUnreadCount } })