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:
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user