Modif de l'affichage des données d'un événement et de l'afichage de la création/édition

Options sont maintenant géres dans firebase
This commit is contained in:
ElPoyo
2025-10-10 19:20:38 +02:00
parent aae68f8ab7
commit 4128ddc34a
13 changed files with 850 additions and 299 deletions

View File

@@ -13,6 +13,7 @@ import 'package:em2rp/views/widgets/user_management/user_card.dart';
import 'package:em2rp/models/user_model.dart';
import 'package:em2rp/views/widgets/user_management/user_multi_select_widget.dart';
import 'package:em2rp/views/event_add_page.dart';
import 'package:em2rp/views/widgets/event_form/event_options_display_widget.dart';
class EventDetails extends StatelessWidget {
final EventModel event;
@@ -87,23 +88,29 @@ class EventDetails extends StatelessWidget {
),
const SizedBox(height: 16),
Row(
crossAxisAlignment: CrossAxisAlignment.start, // Optionnel mais recommandé pour bien aligner
//Titre de l'événement
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// On remplace le SelectableText par une Column
Expanded( // Utiliser Expanded pour que le texte ne déborde pas
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // Aligne les textes à gauche
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 1. Votre titre original
SelectableText(
event.name,
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
color: AppColors.noir,
fontWeight: FontWeight.bold,
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(
event.name,
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
color: AppColors.noir,
fontWeight: FontWeight.bold,
),
),
const SizedBox(width: 12),
_buildStatusIcon(event.status),
],
),
),
const SizedBox(height: 4),
//Type d'événement
Text(
event.eventTypeId,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
@@ -113,8 +120,8 @@ class EventDetails extends StatelessWidget {
],
),
),
const SizedBox(width: 12),
_buildStatusIcon(event.status),
// Statut de l'événement
const SizedBox(width: 8),
Spacer(),
if (Provider.of<LocalUserProvider>(context, listen: false)
@@ -168,13 +175,13 @@ class EventDetails extends StatelessWidget {
_buildInfoRow(
context,
Icons.calendar_today,
'Date de début',
'Horaire de début',
dateFormat.format(event.startDateTime),
),
_buildInfoRow(
context,
Icons.calendar_today,
'Date de fin',
'Horaire de fin',
dateFormat.format(event.endDateTime),
),
if (canViewPrices)
@@ -185,82 +192,50 @@ class EventDetails extends StatelessWidget {
currencyFormat.format(event.basePrice),
),
if (event.options.isNotEmpty) ...[
const SizedBox(height: 8),
Text('Options sélectionnées',
style:
Theme.of(context).textTheme.titleLarge?.copyWith(
color: AppColors.noir,
fontWeight: FontWeight.bold,
)),
const SizedBox(height: 4),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: event.options.map((opt) {
final price = (opt['price'] ?? 0.0) as num;
final isNegative = price < 0;
return ListTile(
leading: Icon(Icons.tune,
color:
isNegative ? Colors.red : AppColors.rouge),
title: Text(opt['name'] ?? '',
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text(opt['details'] ?? ''),
trailing: canViewPrices
? Text(
(isNegative ? '- ' : '+ ') +
currencyFormat.format(price.abs()),
style: TextStyle(
color: isNegative
? Colors.red
: AppColors.noir,
fontWeight: FontWeight.bold,
),
)
: null,
contentPadding: EdgeInsets.zero,
dense: true,
);
}).toList(),
EventOptionsDisplayWidget(
optionsData: event.options,
canViewPrices: canViewPrices,
showPriceCalculation: false, // On affiche le total séparément
),
if (canViewPrices) ...[
const SizedBox(height: 4),
Builder(
builder: (context) {
final total = event.basePrice +
event.options.fold<num>(0,
(sum, opt) => sum + (opt['price'] ?? 0.0));
return Padding(
padding:
const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Row(
children: [
const Icon(Icons.attach_money,
color: AppColors.rouge),
const SizedBox(width: 8),
Text('Prix total : ',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
color: AppColors.noir,
fontWeight: FontWeight.bold,
)),
Text(
currencyFormat.format(total),
],
if (canViewPrices) ...[
const SizedBox(height: 4),
Builder(
builder: (context) {
final total = event.basePrice +
event.options.fold<num>(0,
(sum, opt) => sum + (opt['price'] ?? 0.0));
return Padding(
padding:
const EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Row(
children: [
const Icon(Icons.attach_money,
color: AppColors.rouge),
const SizedBox(width: 8),
Text('Prix total : ',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
color: AppColors.rouge,
color: AppColors.noir,
fontWeight: FontWeight.bold,
),
),
],
),
);
},
),
],
)),
Text(
currencyFormat.format(total),
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(
color: AppColors.rouge,
fontWeight: FontWeight.bold,
),
),
],
),
);
},
),
],
_buildInfoRow(
context,
@@ -268,12 +243,39 @@ class EventDetails extends StatelessWidget {
'Temps d\'installation',
'${event.installationTime} heures',
),
// Sous-titre: Horaire d'arrivée prévisionnelle (début - installation)
Builder(
builder: (context) {
final arrival = event.startDateTime.subtract(Duration(hours: event.installationTime));
return Padding(
padding: const EdgeInsets.only(left: 36.0, bottom: 4.0),
child: Text(
'Horaire d\'arrivée prévisionnel : ${DateFormat('dd/MM/yyyy HH:mm').format(arrival)}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.grey[700]),
),
);
},
),
_buildInfoRow(
context,
Icons.construction,
'Temps de démontage',
'${event.disassemblyTime} heures',
),
// Sous-titre: Horaire de départ prévu (fin + démontage)
Builder(
builder: (context) {
final departure = event.endDateTime.add(Duration(hours: event.disassemblyTime));
return Padding(
padding: const EdgeInsets.only(left: 36.0, bottom: 4.0),
child: Text(
'Horaire de départ prévu : ${DateFormat('dd/MM/yyyy HH:mm').format(departure)}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.grey[700]),
),
);
},
),
const SizedBox(height: 16),
Text(
'Description',