Refactoring
This commit is contained in:
68
lib/assets/json/event_categories.json
Normal file
68
lib/assets/json/event_categories.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"categories": {
|
||||
"Événements Professionnels": [
|
||||
"Conférence",
|
||||
"Séminaire",
|
||||
"Webinar",
|
||||
"Atelier",
|
||||
"Networking",
|
||||
"Réunion d'affaires",
|
||||
"Salon",
|
||||
"Forum",
|
||||
"Rencontre professionnelle",
|
||||
"Conférence académique",
|
||||
"Conférence TEDx",
|
||||
"Lancement de produit",
|
||||
"Assemblée générale",
|
||||
"Réunion de crise",
|
||||
"Lancement de startup"
|
||||
],
|
||||
"Événements Culturels": [
|
||||
"Concert",
|
||||
"Festival",
|
||||
"Exposition",
|
||||
"Projection de film",
|
||||
"Rencontre littéraire",
|
||||
"Spectacle de théâtre",
|
||||
"Spectacle de danse",
|
||||
"Festival de cinéma",
|
||||
"Exposition d'art",
|
||||
"Projection en avant-première",
|
||||
"Festival de bande dessinée",
|
||||
"Projection de documentaire",
|
||||
"Festival de rue"
|
||||
],
|
||||
"Événements Sportifs": [
|
||||
"Compétition sportive",
|
||||
"Marathon",
|
||||
"Tournoi de jeux vidéo",
|
||||
"Hackathon",
|
||||
"Compétition de sport électronique",
|
||||
"Tournoi sportif"
|
||||
],
|
||||
"Événements Caritatifs": [
|
||||
"Dîner caritatif",
|
||||
"Collecte de fonds",
|
||||
"Vente aux enchères",
|
||||
"Vente de charité"
|
||||
],
|
||||
"Événements Sociaux": [
|
||||
"Fête nationale",
|
||||
"Fête de mariage",
|
||||
"Anniversaire",
|
||||
"Réveillon du nouvel an",
|
||||
"Fête de Noël",
|
||||
"Soirée de gala",
|
||||
"Fête de fin d'année"
|
||||
],
|
||||
"Ateliers et Formations": [
|
||||
"Atelier culinaire",
|
||||
"Cours de yoga",
|
||||
"Session de formation",
|
||||
"Atelier de design",
|
||||
"Atelier d'écriture",
|
||||
"Atelier de peinture",
|
||||
"Atelier de bricolage"
|
||||
]
|
||||
}
|
||||
}
|
||||
32
lib/data/services/category_service.dart
Normal file
32
lib/data/services/category_service.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
/// Service pour gérer le chargement des catégories depuis un fichier JSON.
|
||||
class CategoryService {
|
||||
/// Méthode pour charger les catégories depuis un fichier JSON.
|
||||
/// Cette méthode retourne un Map où chaque clé représente un type de catégorie
|
||||
/// et chaque valeur est une liste de catégories associées à ce type.
|
||||
Future<Map<String, List<String>>> loadCategories() async {
|
||||
try {
|
||||
// Charger le fichier JSON à partir des assets
|
||||
print('Chargement du fichier JSON des catégories...');
|
||||
final String response = await rootBundle.loadString('lib/assets/json/event_categories.json');
|
||||
|
||||
// Décoder le contenu du fichier JSON
|
||||
final Map<String, dynamic> data = json.decode(response);
|
||||
print('Données JSON décodées avec succès.');
|
||||
|
||||
// Transformer les données en un Map de catégories par type
|
||||
final Map<String, List<String>> categoriesByType = (data['categories'] as Map<String, dynamic>).map(
|
||||
(key, value) => MapEntry(key, List<String>.from(value)),
|
||||
);
|
||||
|
||||
print('Catégories chargées: $categoriesByType');
|
||||
return categoriesByType;
|
||||
} catch (e) {
|
||||
// Gérer les erreurs de chargement ou de décodage
|
||||
print('Erreur lors du chargement des catégories: $e');
|
||||
throw Exception('Impossible de charger les catégories.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'package:afterwork/data/models/event_model.dart';
|
||||
import 'package:afterwork/data/models/user_model.dart';
|
||||
import 'package:afterwork/core/constants/urls.dart';
|
||||
import 'package:afterwork/data/services/category_service.dart';
|
||||
import '../location/location_picker_screen.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
/// Classe représentant la boîte de dialogue pour ajouter un nouvel événement.
|
||||
/// Cette boîte de dialogue permet à l'utilisateur de remplir les détails d'un nouvel événement.
|
||||
class AddEventDialog extends StatefulWidget {
|
||||
final String userId;
|
||||
final String userName;
|
||||
@@ -27,15 +27,36 @@ class AddEventDialog extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AddEventDialogState extends State<AddEventDialog> {
|
||||
final _formKey = GlobalKey<FormState>(); // Clé globale pour valider le formulaire
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
// Variables pour stocker les données de l'événement
|
||||
String _title = '';
|
||||
String _description = '';
|
||||
DateTime? _selectedDate;
|
||||
String? _imagePath;
|
||||
String _location = 'Abidjan'; // Par défaut à Cocody, Abidjan
|
||||
String _location = 'Abidjan';
|
||||
String _category = '';
|
||||
String _link = '';
|
||||
LatLng? _selectedLatLng = const LatLng(5.348722, -3.985038); // Par défaut à Cocody, Abidjan
|
||||
LatLng? _selectedLatLng = const LatLng(5.348722, -3.985038);
|
||||
Map<String, List<String>> _categories = {};
|
||||
List<String> _currentCategories = [];
|
||||
String? _selectedCategoryType;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadCategories();
|
||||
}
|
||||
|
||||
void _loadCategories() async {
|
||||
final CategoryService categoryService = CategoryService();
|
||||
final categories = await categoryService.loadCategories();
|
||||
setState(() {
|
||||
_categories = categories;
|
||||
_selectedCategoryType = categories.keys.first;
|
||||
_currentCategories = categories[_selectedCategoryType] ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -48,7 +69,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Form(
|
||||
key: _formKey, // Formulaire clé pour valider l'entrée des utilisateurs
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
@@ -75,7 +96,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de saisie du titre de l'événement.
|
||||
Widget _buildTitleField() {
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
@@ -104,7 +124,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de saisie de la description de l'événement.
|
||||
Widget _buildDescriptionField() {
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
@@ -134,7 +153,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Widget pour le sélecteur de date pour l'événement.
|
||||
Widget _buildDatePicker() {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
@@ -175,7 +193,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de localisation pour l'événement.
|
||||
Widget _buildLocationField(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
@@ -217,29 +234,76 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de saisie de la catégorie de l'événement.
|
||||
/// Construction du champ de catégorie avec sélection du type et de la catégorie.
|
||||
Widget _buildCategoryField() {
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Catégorie',
|
||||
labelStyle: const TextStyle(color: Colors.white70),
|
||||
filled: true,
|
||||
fillColor: Colors.white.withOpacity(0.1),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
borderSide: BorderSide.none,
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DropdownButtonFormField<String>(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Type de catégorie',
|
||||
labelStyle: const TextStyle(color: Colors.white70),
|
||||
filled: true,
|
||||
fillColor: Colors.white.withOpacity(0.1),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
value: _selectedCategoryType,
|
||||
items: _categories.keys.map((String type) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: type,
|
||||
child: Text(type, style: const TextStyle(color: Colors.black)),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
_selectedCategoryType = newValue;
|
||||
_currentCategories = _categories[newValue] ?? [];
|
||||
_category = ''; // Réinitialiser la catégorie sélectionnée
|
||||
print('Type de catégorie sélectionné : $_selectedCategoryType');
|
||||
print('Catégories disponibles pour ce type : $_currentCategories');
|
||||
});
|
||||
},
|
||||
),
|
||||
prefixIcon: const Icon(Icons.category, color: Colors.white70),
|
||||
),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
onSaved: (value) {
|
||||
_category = value ?? '';
|
||||
print('Catégorie sauvegardée: $_category');
|
||||
},
|
||||
const SizedBox(height: 10),
|
||||
DropdownButtonFormField<String>(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Catégorie',
|
||||
labelStyle: const TextStyle(color: Colors.white70),
|
||||
filled: true,
|
||||
fillColor: Colors.white.withOpacity(0.1),
|
||||
border: const OutlineInputBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
value: _category.isNotEmpty ? _category : null,
|
||||
items: _currentCategories.map((String category) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: category,
|
||||
child: Text(category, style: const TextStyle(color: Colors.black)),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
_category = newValue ?? '';
|
||||
print('Catégorie sélectionnée : $_category');
|
||||
});
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
print('Erreur: Catégorie non sélectionnée');
|
||||
return 'Veuillez sélectionner une catégorie';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de sélection d'image pour l'événement.
|
||||
Widget _buildImagePicker() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
@@ -268,7 +332,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du champ de saisie du lien associé à l'événement.
|
||||
Widget _buildLinkField() {
|
||||
return TextFormField(
|
||||
decoration: InputDecoration(
|
||||
@@ -290,7 +353,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construction du bouton de soumission pour ajouter l'événement.
|
||||
Widget _buildSubmitButton() {
|
||||
return ElevatedButton(
|
||||
onPressed: () async {
|
||||
@@ -298,7 +360,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
_formKey.currentState!.save();
|
||||
print('Formulaire validé');
|
||||
|
||||
// Créer l'événement en utilisant l'ID réel de l'utilisateur pour le créateur et les participants
|
||||
EventModel newEvent = EventModel(
|
||||
id: '',
|
||||
title: _title,
|
||||
@@ -308,7 +369,7 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
category: _category,
|
||||
link: _link,
|
||||
imageUrl: _imagePath ?? '',
|
||||
status: '',
|
||||
status: 'OPEN',
|
||||
creator: UserModel(
|
||||
userId: widget.userId,
|
||||
nom: widget.userName,
|
||||
@@ -327,11 +388,9 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
],
|
||||
);
|
||||
|
||||
// Convertir l'événement en JSON
|
||||
Map<String, dynamic> eventData = newEvent.toJson();
|
||||
print('Données JSON de l\'événement: $eventData');
|
||||
|
||||
// Envoyer la requête POST à l'API
|
||||
final response = await http.post(
|
||||
Uri.parse('${Urls.baseUrl}/events'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
@@ -342,7 +401,6 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
print('Réponse brute: ${response.body}');
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
// Création réussie
|
||||
print('Événement créé avec succès');
|
||||
Fluttertoast.showToast(
|
||||
msg: "Événement créé avec succès!",
|
||||
@@ -352,9 +410,8 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
textColor: Colors.white,
|
||||
fontSize: 16.0,
|
||||
);
|
||||
Navigator.of(context).pop(); // Ne passez pas de valeur ici
|
||||
Navigator.of(context).pop(); // Fermer la boîte de dialogue
|
||||
} else {
|
||||
// Gérer l'erreur
|
||||
print('Erreur lors de la création de l\'événement: ${response.reasonPhrase}');
|
||||
Fluttertoast.showToast(
|
||||
msg: "Erreur lors de la création de l'événement",
|
||||
@@ -383,5 +440,4 @@ class _AddEventDialogState extends State<AddEventDialog> {
|
||||
child: const Text('Ajouter l\'événement', style: TextStyle(color: Colors.white)),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,27 +2,53 @@ import 'package:flutter/material.dart';
|
||||
import 'package:afterwork/data/datasources/event_remote_data_source.dart';
|
||||
|
||||
/// Widget pour afficher une carte d'événement.
|
||||
/// Cette classe est utilisée pour afficher les détails d'un événement,
|
||||
/// incluant son titre, sa description, son image, et des actions possibles
|
||||
/// telles que réagir, commenter, partager, participer, et fermer l'événement.
|
||||
class EventCard extends StatelessWidget {
|
||||
// Identifiant unique de l'événement
|
||||
final String eventId;
|
||||
// Source de données distante pour les opérations sur l'événement
|
||||
final EventRemoteDataSource eventRemoteDataSource;
|
||||
// Identifiant de l'utilisateur
|
||||
final String userId;
|
||||
// Nom de l'utilisateur
|
||||
final String userName;
|
||||
// Prénom de l'utilisateur
|
||||
final String userLastName;
|
||||
// URL de l'image de profil de l'utilisateur
|
||||
final String profileImage;
|
||||
// Nom complet de l'utilisateur (nom + prénom)
|
||||
final String name;
|
||||
// Date de publication de l'événement
|
||||
final String datePosted;
|
||||
// Titre de l'événement
|
||||
final String eventTitle;
|
||||
// Description de l'événement
|
||||
final String eventDescription;
|
||||
// URL de l'image de l'événement
|
||||
final String eventImageUrl;
|
||||
final String eventStatus; // Ajout du statut de l'événement
|
||||
// Statut de l'événement (e.g., "OPEN", "CLOSED")
|
||||
final String eventStatus;
|
||||
// Catégorie de l'événement
|
||||
final String eventCategory;
|
||||
// Nombre de réactions à l'événement
|
||||
final int reactionsCount;
|
||||
// Nombre de commentaires sur l'événement
|
||||
final int commentsCount;
|
||||
// Nombre de partages de l'événement
|
||||
final int sharesCount;
|
||||
// Callback pour l'action "Réagir"
|
||||
final VoidCallback onReact;
|
||||
// Callback pour l'action "Commenter"
|
||||
final VoidCallback onComment;
|
||||
// Callback pour l'action "Partager"
|
||||
final VoidCallback onShare;
|
||||
// Callback pour l'action "Participer"
|
||||
final VoidCallback onParticipate;
|
||||
// Callback pour afficher plus d'options
|
||||
final VoidCallback onMoreOptions;
|
||||
// Callback pour fermer l'événement
|
||||
final VoidCallback onCloseEvent;
|
||||
|
||||
const EventCard({
|
||||
@@ -38,7 +64,8 @@ class EventCard extends StatelessWidget {
|
||||
required this.eventTitle,
|
||||
required this.eventDescription,
|
||||
required this.eventImageUrl,
|
||||
required this.eventStatus, // Initialisation du statut de l'événement
|
||||
required this.eventStatus,
|
||||
required this.eventCategory,
|
||||
required this.reactionsCount,
|
||||
required this.commentsCount,
|
||||
required this.sharesCount,
|
||||
@@ -52,13 +79,20 @@ class EventCard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Log du rendu de la carte d'événement
|
||||
print('Rendu de l\'EventCard pour l\'événement $eventId avec statut $eventStatus');
|
||||
|
||||
return AnimatedOpacity(
|
||||
opacity: 1.0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Dismissible(
|
||||
key: ValueKey(eventId),
|
||||
direction: DismissDirection.startToEnd,
|
||||
onDismissed: (direction) => onCloseEvent(),
|
||||
onDismissed: (direction) {
|
||||
// Log du déclenchement de la fermeture de l'événement
|
||||
print('Tentative de fermeture de l\'événement $eventId');
|
||||
onCloseEvent();
|
||||
},
|
||||
background: Container(
|
||||
color: Colors.red,
|
||||
alignment: Alignment.centerLeft,
|
||||
@@ -80,13 +114,15 @@ class EventCard extends StatelessWidget {
|
||||
children: [
|
||||
_buildHeader(context),
|
||||
const SizedBox(height: 10),
|
||||
_buildEventCategory(), // Affichage de la catégorie de l'événement
|
||||
const SizedBox(height: 5),
|
||||
_buildEventDetails(),
|
||||
const SizedBox(height: 10),
|
||||
_buildEventImage(),
|
||||
const SizedBox(height: 10),
|
||||
Divider(color: Colors.white.withOpacity(0.2)),
|
||||
_buildInteractionRow(),
|
||||
const SizedBox(height: 10),
|
||||
const SizedBox(height: 5),
|
||||
_buildParticipateButton(),
|
||||
],
|
||||
),
|
||||
@@ -99,7 +135,12 @@ class EventCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Construire l'en-tête de la carte avec les informations de l'utilisateur.
|
||||
/// Cette méthode affiche l'image de profil, le nom de l'utilisateur, la date
|
||||
/// de publication de l'événement, et le statut de l'événement.
|
||||
Widget _buildHeader(BuildContext context) {
|
||||
// Log du rendu de l'en-tête de la carte
|
||||
print('Rendu de l\'en-tête pour l\'événement $eventId');
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
CircleAvatar(
|
||||
@@ -134,19 +175,48 @@ class EventCard extends StatelessWidget {
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.more_vert, color: Colors.white),
|
||||
onPressed: onMoreOptions,
|
||||
onPressed: () {
|
||||
// Log du déclenchement du bouton "Plus d'options"
|
||||
print('Plus d\'options déclenché pour l\'événement $eventId');
|
||||
onMoreOptions();
|
||||
},
|
||||
),
|
||||
if (eventStatus != 'CLOSED') // Masquer le bouton de fermeture si l'événement est fermé
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close, color: Colors.white),
|
||||
onPressed: onCloseEvent,
|
||||
onPressed: () {
|
||||
// Log du déclenchement du bouton de fermeture de l'événement
|
||||
print('Tentative de fermeture de l\'événement $eventId');
|
||||
onCloseEvent();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Afficher la catégorie de l'événement au-dessus du titre.
|
||||
/// Cette méthode affiche la catégorie en italique pour distinguer le type d'événement.
|
||||
Widget _buildEventCategory() {
|
||||
// Log du rendu de la catégorie de l'événement
|
||||
print('Affichage de la catégorie pour l\'événement $eventId: $eventCategory');
|
||||
|
||||
return Text(
|
||||
eventCategory,
|
||||
style: const TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontSize: 14,
|
||||
fontStyle: FontStyle.italic, // Style en italique
|
||||
fontWeight: FontWeight.w400, // Titre fin
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Afficher les détails de l'événement.
|
||||
/// Cette méthode affiche le titre et la description de l'événement.
|
||||
Widget _buildEventDetails() {
|
||||
// Log du rendu des détails de l'événement
|
||||
print('Affichage des détails pour l\'événement $eventId');
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -168,7 +238,11 @@ class EventCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Afficher l'image de l'événement.
|
||||
/// Cette méthode affiche l'image associée à l'événement.
|
||||
Widget _buildEventImage() {
|
||||
// Log du rendu de l'image de l'événement
|
||||
print('Affichage de l\'image pour l\'événement $eventId');
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
child: Image.network(
|
||||
@@ -177,7 +251,8 @@ class EventCard extends StatelessWidget {
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
print('Erreur de chargement de l\'image: $error');
|
||||
// Log de l'erreur lors du chargement de l'image
|
||||
print('Erreur de chargement de l\'image pour l\'événement $eventId: $error');
|
||||
return Image.asset(
|
||||
'lib/assets/images/placeholder.png',
|
||||
height: 180,
|
||||
@@ -190,29 +265,51 @@ class EventCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Afficher les icônes d'interaction (réagir, commenter, partager).
|
||||
/// Cette méthode affiche les boutons pour réagir, commenter, et partager l'événement.
|
||||
Widget _buildInteractionRow() {
|
||||
// Log du rendu de la ligne d'interaction de l'événement
|
||||
print('Affichage des interactions pour l\'événement $eventId');
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0.0), // Réduire le padding vertical
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround, // Utiliser spaceAround pour réduire l'espace
|
||||
children: [
|
||||
_buildIconButton(
|
||||
icon: Icons.thumb_up_alt_outlined,
|
||||
label: 'Réagir',
|
||||
count: reactionsCount,
|
||||
onPressed: onReact,
|
||||
Flexible(
|
||||
child: _buildIconButton(
|
||||
icon: Icons.thumb_up_alt_outlined,
|
||||
label: 'Réagir',
|
||||
count: reactionsCount,
|
||||
onPressed: () {
|
||||
// Log de l'action "Réagir"
|
||||
print('Réaction à l\'événement $eventId');
|
||||
onReact();
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildIconButton(
|
||||
icon: Icons.comment_outlined,
|
||||
label: 'Commenter',
|
||||
count: commentsCount,
|
||||
onPressed: onComment,
|
||||
Flexible(
|
||||
child: _buildIconButton(
|
||||
icon: Icons.comment_outlined,
|
||||
label: 'Commenter',
|
||||
count: commentsCount,
|
||||
onPressed: () {
|
||||
// Log de l'action "Commenter"
|
||||
print('Commentaire sur l\'événement $eventId');
|
||||
onComment();
|
||||
},
|
||||
),
|
||||
),
|
||||
_buildIconButton(
|
||||
icon: Icons.share_outlined,
|
||||
label: 'Partager',
|
||||
count: sharesCount,
|
||||
onPressed: onShare,
|
||||
Flexible(
|
||||
child: _buildIconButton(
|
||||
icon: Icons.share_outlined,
|
||||
label: 'Partager',
|
||||
count: sharesCount,
|
||||
onPressed: () {
|
||||
// Log de l'action "Partager"
|
||||
print('Partage de l\'événement $eventId');
|
||||
onShare();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -220,12 +317,16 @@ class EventCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Bouton d'interaction personnalisé.
|
||||
/// Cette méthode construit un bouton avec une icône et un label pour l'interaction.
|
||||
Widget _buildIconButton({
|
||||
required IconData icon,
|
||||
required String label,
|
||||
required int count,
|
||||
required VoidCallback onPressed,
|
||||
}) {
|
||||
// Log de la construction du bouton d'interaction
|
||||
print('Construction du bouton $label pour l\'événement $eventId');
|
||||
|
||||
return Expanded(
|
||||
child: TextButton.icon(
|
||||
onPressed: onPressed,
|
||||
@@ -233,13 +334,19 @@ class EventCard extends StatelessWidget {
|
||||
label: Text(
|
||||
'$label ($count)',
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 12),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Bouton pour participer à l'événement.
|
||||
/// Cette méthode construit un bouton qui permet de participer à l'événement.
|
||||
/// Si l'événement est fermé, le bouton est désactivé.
|
||||
Widget _buildParticipateButton() {
|
||||
// Log de la construction du bouton "Participer"
|
||||
print('Construction du bouton "Participer" pour l\'événement $eventId avec statut $eventStatus');
|
||||
|
||||
return ElevatedButton(
|
||||
onPressed: eventStatus == 'CLOSED' ? null : onParticipate, // Désactiver si l'événement est fermé
|
||||
style: ElevatedButton.styleFrom(
|
||||
@@ -258,7 +365,11 @@ class EventCard extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Construire un badge pour afficher le statut de l'événement.
|
||||
/// Cette méthode affiche un badge avec le statut de l'événement ("OPEN" ou "CLOSED").
|
||||
Widget _buildStatusBadge() {
|
||||
// Log de la construction du badge de statut
|
||||
print('Construction du badge de statut pour l\'événement $eventId: $eventStatus');
|
||||
|
||||
Color badgeColor;
|
||||
switch (eventStatus) {
|
||||
case 'CLOSED':
|
||||
|
||||
@@ -112,7 +112,8 @@ class _EventScreenState extends State<EventScreen> {
|
||||
userLastName: widget.userLastName,
|
||||
profileImage: 'lib/assets/images/profile_picture.png',
|
||||
name: '${widget.userName} ${widget.userLastName}',
|
||||
datePosted: 'Posté le 24/08/2024',
|
||||
eventCategory: event.category,
|
||||
datePosted: event.date,
|
||||
eventTitle: event.title,
|
||||
eventDescription: event.description,
|
||||
eventImageUrl: event.imageUrl ?? 'lib/assets/images/placeholder.png',
|
||||
|
||||
@@ -47,7 +47,7 @@ flutter:
|
||||
- lib/assets/images/background.webp
|
||||
- lib/assets/images/profile_picture.png
|
||||
- lib/assets/images/placeholder.png
|
||||
|
||||
- lib/assets/json/event_categories.json
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
|
||||
Reference in New Issue
Block a user