working version
This commit is contained in:
16
frontend/src/views/Admin.vue
Normal file → Executable file
16
frontend/src/views/Admin.vue
Normal file → Executable file
@@ -4,8 +4,7 @@
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement du dashboard...</p>
|
||||
<LoadingLogo size="large" text="Chargement du dashboard..." />
|
||||
</div>
|
||||
|
||||
<!-- Admin content -->
|
||||
@@ -579,16 +578,14 @@
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="ticketsLoading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto mb-4"></div>
|
||||
<p class="text-gray-600">Chargement des tickets...</p>
|
||||
<LoadingLogo size="large" text="Chargement des tickets..." />
|
||||
</div>
|
||||
|
||||
<!-- Tickets Grid -->
|
||||
<div v-else-if="filteredTickets.length > 0" class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-6">
|
||||
<div v-if="!ticketsLoading && filteredTickets.length > 0" class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-6">
|
||||
<div
|
||||
v-for="ticket in filteredTickets"
|
||||
:key="ticket.id"
|
||||
v-if="ticket && ticket.id"
|
||||
class="bg-white border border-gray-200 rounded-xl shadow-sm hover:shadow-lg transition-all duration-200 cursor-pointer group ticket-card"
|
||||
@click="showTicketDetails(ticket)"
|
||||
>
|
||||
@@ -674,7 +671,7 @@
|
||||
</div>
|
||||
|
||||
<!-- No Tickets -->
|
||||
<div v-else class="text-center py-12">
|
||||
<div v-if="!ticketsLoading && filteredTickets.length === 0" class="text-center py-12">
|
||||
<div class="w-24 h-24 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<svg class="w-12 h-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
@@ -1244,6 +1241,7 @@ import {
|
||||
} from 'lucide-vue-next'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import { fr } from 'date-fns/locale'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const toast = useToast()
|
||||
@@ -1852,7 +1850,7 @@ function openImageModal(imageUrl) {
|
||||
|
||||
function getMediaUrl(path) {
|
||||
if (!path) return ''
|
||||
return path.startsWith('http') ? path : `http://localhost:8000${path}`
|
||||
return path.startsWith('http') ? path : `${import.meta.env.VITE_API_URL || 'http://localhost:8002'}${path}`
|
||||
}
|
||||
|
||||
// Nouvelles fonctions pour les filtres et actions rapides
|
||||
@@ -2126,4 +2124,4 @@ watch(showTicketEditModal, (newValue) => {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
12
frontend/src/views/AlbumDetail.vue
Normal file → Executable file
12
frontend/src/views/AlbumDetail.vue
Normal file → Executable file
@@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement de l'album...</p>
|
||||
</div>
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement de l'album..." />
|
||||
</div>
|
||||
|
||||
<!-- Album not found -->
|
||||
<div v-else-if="!album" class="text-center py-12">
|
||||
@@ -586,6 +585,7 @@ import {
|
||||
ChevronLeft,
|
||||
ChevronRight
|
||||
} from 'lucide-vue-next'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -859,4 +859,4 @@ onUnmounted(() => {
|
||||
// Clean up event listeners
|
||||
document.removeEventListener('keydown', handleKeyboardNavigation)
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
2
frontend/src/views/Albums.vue
Normal file → Executable file
2
frontend/src/views/Albums.vue
Normal file → Executable file
@@ -783,4 +783,4 @@ onMounted(() => {
|
||||
fetchUsers()
|
||||
fetchUploadLimits()
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
20
frontend/src/views/EventDetail.vue
Normal file → Executable file
20
frontend/src/views/EventDetail.vue
Normal file → Executable file
@@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement de l'événement...</p>
|
||||
</div>
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement de l'événement..." />
|
||||
</div>
|
||||
|
||||
<!-- Event not found -->
|
||||
<div v-else-if="!event" class="text-center py-12">
|
||||
@@ -46,7 +45,15 @@
|
||||
<div class="flex items-start space-x-6">
|
||||
<!-- Cover Image -->
|
||||
<div class="w-64 h-48 bg-gradient-to-br from-primary-400 to-primary-600 rounded-xl flex items-center justify-center">
|
||||
<Calendar v-if="!event.cover_image" class="w-16 h-16 text-white" />
|
||||
<img
|
||||
v-if="!event.cover_image && event.creator_avatar"
|
||||
:src="getMediaUrl(event.creator_avatar)"
|
||||
:alt="event.creator_name"
|
||||
class="w-16 h-16 rounded-full object-cover"
|
||||
>
|
||||
<div v-else-if="!event.cover_image" class="w-16 h-16 rounded-full bg-primary-100 flex items-center justify-center">
|
||||
<User class="w-8 h-8 text-primary-600" />
|
||||
</div>
|
||||
<img
|
||||
v-else
|
||||
:src="getMediaUrl(event.cover_image)"
|
||||
@@ -366,6 +373,7 @@ import {
|
||||
Trash2,
|
||||
Image
|
||||
} from 'lucide-vue-next'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
16
frontend/src/views/Events.vue
Normal file → Executable file
16
frontend/src/views/Events.vue
Normal file → Executable file
@@ -54,7 +54,15 @@
|
||||
<div class="aspect-video bg-gray-100 relative overflow-hidden">
|
||||
<img v-if="event.cover_image" :src="getMediaUrl(event.cover_image)" :alt="event.title" class="w-full h-full object-cover">
|
||||
<div v-else class="w-full h-full flex items-center justify-center">
|
||||
<Calendar class="w-16 h-16 text-gray-400" />
|
||||
<img
|
||||
v-if="event.creator_avatar"
|
||||
:src="getMediaUrl(event.creator_avatar)"
|
||||
:alt="event.creator_name"
|
||||
class="w-16 h-16 rounded-full object-cover"
|
||||
>
|
||||
<div v-else class="w-16 h-16 rounded-full bg-primary-100 flex items-center justify-center">
|
||||
<User class="w-8 h-8 text-primary-600" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Date Badge -->
|
||||
@@ -480,6 +488,11 @@ async function fetchEvents() {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await axios.get(`/api/events?limit=12&offset=${offset.value}`)
|
||||
console.log('Events response:', response.data)
|
||||
if (response.data && response.data.length > 0) {
|
||||
console.log('First event:', response.data[0])
|
||||
console.log('Creator avatar:', response.data[0].creator_avatar)
|
||||
}
|
||||
if (offset.value === 0) {
|
||||
events.value = response.data
|
||||
} else {
|
||||
@@ -488,6 +501,7 @@ async function fetchEvents() {
|
||||
|
||||
hasMoreEvents.value = response.data.length === 12
|
||||
} catch (error) {
|
||||
console.error('Error fetching events:', error)
|
||||
toast.error('Erreur lors du chargement des événements')
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
0
frontend/src/views/Home.vue
Normal file → Executable file
0
frontend/src/views/Home.vue
Normal file → Executable file
10
frontend/src/views/Information.vue
Normal file → Executable file
10
frontend/src/views/Information.vue
Normal file → Executable file
@@ -34,11 +34,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto mb-4"></div>
|
||||
<p class="text-gray-600">Chargement des informations...</p>
|
||||
</div>
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement des informations..." />
|
||||
</div>
|
||||
|
||||
<!-- No Information -->
|
||||
<div v-else-if="filteredInformations.length === 0" class="text-center py-12">
|
||||
@@ -107,6 +106,7 @@ import { useToast } from 'vue-toastification'
|
||||
import { formatDistanceToNow } from 'date-fns'
|
||||
import { fr } from 'date-fns/locale'
|
||||
import axios from '@/utils/axios'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
|
||||
0
frontend/src/views/Login.vue
Normal file → Executable file
0
frontend/src/views/Login.vue
Normal file → Executable file
10
frontend/src/views/MyTickets.vue
Normal file → Executable file
10
frontend/src/views/MyTickets.vue
Normal file → Executable file
@@ -54,11 +54,10 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto mb-4"></div>
|
||||
<p class="text-gray-600">Chargement de vos tickets...</p>
|
||||
</div>
|
||||
<!-- Loading State -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement de vos tickets..." />
|
||||
</div>
|
||||
|
||||
<!-- No Tickets -->
|
||||
<div v-else-if="filteredTickets.length === 0" class="text-center py-12">
|
||||
@@ -318,6 +317,7 @@ import { fr } from 'date-fns/locale'
|
||||
import { Save } from 'lucide-vue-next'
|
||||
import axios from '@/utils/axios'
|
||||
import { getMediaUrl } from '@/utils/axios'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
|
||||
0
frontend/src/views/Posts.vue
Normal file → Executable file
0
frontend/src/views/Posts.vue
Normal file → Executable file
0
frontend/src/views/Profile.vue
Normal file → Executable file
0
frontend/src/views/Profile.vue
Normal file → Executable file
0
frontend/src/views/Register.vue
Normal file → Executable file
0
frontend/src/views/Register.vue
Normal file → Executable file
10
frontend/src/views/Stats.vue
Normal file → Executable file
10
frontend/src/views/Stats.vue
Normal file → Executable file
@@ -2,11 +2,10 @@
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-8">Statistiques du groupe</h1>
|
||||
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement des statistiques...</p>
|
||||
</div>
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement des statistiques..." />
|
||||
</div>
|
||||
|
||||
<!-- Stats content -->
|
||||
<div v-else>
|
||||
@@ -252,6 +251,7 @@ import {
|
||||
AtSign,
|
||||
Eye
|
||||
} from 'lucide-vue-next'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
|
||||
12
frontend/src/views/UserProfile.vue
Normal file → Executable file
12
frontend/src/views/UserProfile.vue
Normal file → Executable file
@@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement du profil...</p>
|
||||
</div>
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement du profil..." />
|
||||
</div>
|
||||
|
||||
<!-- Profile not found -->
|
||||
<div v-else-if="!profileUser" class="text-center py-12">
|
||||
@@ -118,7 +117,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useToast } from 'vue-toastification'
|
||||
@@ -127,6 +126,7 @@ import { getMediaUrl } from '@/utils/axios'
|
||||
import { format, formatDistanceToNow } from 'date-fns'
|
||||
import { fr } from 'date-fns/locale'
|
||||
import { User, ArrowLeft, ArrowRight, MessageSquare, Video, Image, Calendar, Activity } from 'lucide-vue-next'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
12
frontend/src/views/VlogDetail.vue
Normal file → Executable file
12
frontend/src/views/VlogDetail.vue
Normal file → Executable file
@@ -1,10 +1,9 @@
|
||||
<template>
|
||||
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600 mx-auto"></div>
|
||||
<p class="mt-4 text-gray-600">Chargement du vlog...</p>
|
||||
</div>
|
||||
<!-- Loading state -->
|
||||
<div v-if="loading" class="text-center py-12">
|
||||
<LoadingLogo size="large" text="Chargement du vlog..." />
|
||||
</div>
|
||||
|
||||
<!-- Vlog not found -->
|
||||
<div v-else-if="!vlog" class="text-center py-12">
|
||||
@@ -49,7 +48,7 @@
|
||||
<div class="flex items-center">
|
||||
<img
|
||||
v-if="vlog.author_avatar"
|
||||
:src="vlog.author_avatar"
|
||||
:src="getMediaUrl(vlog.author_avatar)"
|
||||
:alt="vlog.author_name"
|
||||
class="w-8 h-8 rounded-full object-cover mr-3"
|
||||
>
|
||||
@@ -238,6 +237,7 @@ import {
|
||||
} from 'lucide-vue-next'
|
||||
import VideoPlayer from '@/components/VideoPlayer.vue'
|
||||
import VlogComments from '@/components/VlogComments.vue'
|
||||
import LoadingLogo from '@/components/LoadingLogo.vue'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
2
frontend/src/views/Vlogs.vue
Normal file → Executable file
2
frontend/src/views/Vlogs.vue
Normal file → Executable file
@@ -58,7 +58,7 @@
|
||||
<div class="flex items-center space-x-2 text-sm text-gray-600 mb-3">
|
||||
<img
|
||||
v-if="vlog.author_avatar"
|
||||
:src="vlog.author_avatar"
|
||||
:src="getMediaUrl(vlog.author_avatar)"
|
||||
:alt="vlog.author_name"
|
||||
class="w-5 h-5 rounded-full object-cover"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user