feat: add event details description component and environment configuration file

This commit is contained in:
ElPoyo
2026-05-28 00:04:48 +02:00
parent d9cd251bb7
commit 4d18956abe
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'package:em2rp/models/event_model.dart'; import 'package:em2rp/models/event_model.dart';
import 'package:em2rp/utils/colors.dart'; import 'package:em2rp/utils/colors.dart';
import 'package:url_launcher/url_launcher.dart';
class EventDetailsDescription extends StatelessWidget { class EventDetailsDescription extends StatelessWidget {
final EventModel event; final EventModel event;
@@ -45,6 +47,13 @@ class EventDetailsDescription extends StatelessWidget {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText( SelectableText(
event.address, event.address,
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
@@ -57,6 +66,30 @@ class EventDetailsDescription extends StatelessWidget {
), ),
], ],
], ],
),
),
IconButton(
icon: const Icon(Icons.map, color: AppColors.rouge),
tooltip: 'Ouvrir dans Maps',
onPressed: () async {
final query = event.address;
if (query.isEmpty) return;
final url = Uri.parse('https://www.google.com/maps/search/?api=1&query=${Uri.encodeComponent(query)}');
if (await canLaunchUrl(url)) {
await launchUrl(url, mode: LaunchMode.externalApplication);
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Impossible d\'ouvrir l\'application de carte')),
);
}
}
},
),
],
),
],
); );
} }
@@ -68,12 +101,22 @@ class EventDetailsDescription extends StatelessWidget {
_buildInfoRow(context, Icons.people, 'Jauge', '${event.jauge} personnes'), _buildInfoRow(context, Icons.people, 'Jauge', '${event.jauge} personnes'),
const SizedBox(height: 8), const SizedBox(height: 8),
], ],
if (event.contactEmail != null) ...[ if (event.contactEmail != null && event.contactEmail!.isNotEmpty) ...[
_buildInfoRow(context, Icons.email, 'Email', event.contactEmail!), _buildInfoRow(context, Icons.email, 'Email', event.contactEmail!, onTap: () async {
final url = Uri.parse('mailto:${event.contactEmail!}');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
}),
const SizedBox(height: 8), const SizedBox(height: 8),
], ],
if (event.contactPhone != null) ...[ if (event.contactPhone != null && event.contactPhone!.isNotEmpty) ...[
_buildInfoRow(context, Icons.phone, 'Téléphone', event.contactPhone!), _buildInfoRow(context, Icons.phone, 'Téléphone', event.contactPhone!, onTap: () async {
final url = Uri.parse('tel:${event.contactPhone!}');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
}),
], ],
], ],
); );
@@ -86,15 +129,25 @@ class EventDetailsDescription extends StatelessWidget {
children: [ children: [
if (event.jauge != null) if (event.jauge != null)
_buildInfoChip(context, Icons.people, 'Jauge', '${event.jauge} personnes'), _buildInfoChip(context, Icons.people, 'Jauge', '${event.jauge} personnes'),
if (event.contactEmail != null) if (event.contactEmail != null && event.contactEmail!.isNotEmpty)
_buildInfoChip(context, Icons.email, 'Email', event.contactEmail!), _buildInfoChip(context, Icons.email, 'Email', event.contactEmail!, onTap: () async {
if (event.contactPhone != null) final url = Uri.parse('mailto:${event.contactEmail!}');
_buildInfoChip(context, Icons.phone, 'Téléphone', event.contactPhone!), if (await canLaunchUrl(url)) {
await launchUrl(url);
}
}),
if (event.contactPhone != null && event.contactPhone!.isNotEmpty)
_buildInfoChip(context, Icons.phone, 'Téléphone', event.contactPhone!, onTap: () async {
final url = Uri.parse('tel:${event.contactPhone!}');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
}),
], ],
); );
} }
Widget _buildInfoRow(BuildContext context, IconData icon, String label, String value) { Widget _buildInfoRow(BuildContext context, IconData icon, String label, String value, {VoidCallback? onTap}) {
return Row( return Row(
children: [ children: [
Icon(icon, size: 20, color: Theme.of(context).primaryColor), Icon(icon, size: 20, color: Theme.of(context).primaryColor),
@@ -109,11 +162,23 @@ class EventDetailsDescription extends StatelessWidget {
color: Colors.grey[600], color: Colors.grey[600],
), ),
), ),
SelectableText( onTap == null
? SelectableText(
value, value,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
)
: SelectableText.rich(
TextSpan(
text: value,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w500,
color: AppColors.rouge,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()..onTap = onTap,
),
), ),
], ],
), ),
@@ -122,7 +187,7 @@ class EventDetailsDescription extends StatelessWidget {
); );
} }
Widget _buildInfoChip(BuildContext context, IconData icon, String label, String value) { Widget _buildInfoChip(BuildContext context, IconData icon, String label, String value, {VoidCallback? onTap}) {
final primaryColor = Theme.of(context).primaryColor; final primaryColor = Theme.of(context).primaryColor;
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
@@ -146,11 +211,23 @@ class EventDetailsDescription extends StatelessWidget {
color: Colors.grey[600], color: Colors.grey[600],
), ),
), ),
SelectableText( onTap == null
? SelectableText(
value, value,
style: Theme.of(context).textTheme.bodySmall?.copyWith( style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
)
: SelectableText.rich(
TextSpan(
text: value,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w500,
color: AppColors.rouge,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()..onTap = onTap,
),
), ),
], ],
), ),