693 lines
22 KiB
Dart
693 lines
22 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
import '../../../../shared/design_system/tokens/app_colors.dart';
|
|
import '../../../../shared/design_system/unionflow_design_system.dart';
|
|
import '../../../../shared/widgets/core_card.dart';
|
|
|
|
/// Page Aide & Support - UnionFlow Mobile
|
|
///
|
|
/// Page complète d'aide avec FAQ, guides, support technique,
|
|
/// et ressources pour les utilisateurs.
|
|
class HelpSupportPage extends StatefulWidget {
|
|
const HelpSupportPage({super.key});
|
|
|
|
@override
|
|
State<HelpSupportPage> createState() => _HelpSupportPageState();
|
|
}
|
|
|
|
class _HelpSupportPageState extends State<HelpSupportPage> {
|
|
final TextEditingController _searchController = TextEditingController();
|
|
String _searchQuery = '';
|
|
int _selectedCategoryIndex = 0;
|
|
|
|
final List<String> _categories = [
|
|
'Tout',
|
|
'Connexion',
|
|
'Membres',
|
|
'Organisations',
|
|
'Événements',
|
|
'Technique',
|
|
];
|
|
|
|
@override
|
|
void dispose() {
|
|
_searchController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
|
appBar: const UFAppBar(title: 'AIDE & SUPPORT'),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(12),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Header harmonisé
|
|
_buildHeader(),
|
|
const SizedBox(height: 8),
|
|
|
|
// Barre de recherche
|
|
_buildSearchSection(),
|
|
const SizedBox(height: 8),
|
|
|
|
// Actions rapides
|
|
_buildQuickActionsSection(),
|
|
const SizedBox(height: 8),
|
|
|
|
// Catégories FAQ
|
|
_buildCategoriesSection(),
|
|
const SizedBox(height: 8),
|
|
|
|
// FAQ
|
|
_buildFAQSection(),
|
|
const SizedBox(height: 8),
|
|
|
|
// Guides et tutoriels
|
|
_buildGuidesSection(),
|
|
const SizedBox(height: 8),
|
|
|
|
// Contact support
|
|
_buildContactSection(),
|
|
const SizedBox(height: 80),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Header épuré
|
|
Widget _buildHeader() {
|
|
return Center(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(10),
|
|
decoration: BoxDecoration(
|
|
color: AppColors.primaryGreen.withOpacity(0.1),
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: const Icon(
|
|
Icons.help_outline,
|
|
color: AppColors.primaryGreen,
|
|
size: 32,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'COMMENT POUVONS-NOUS VOUS AIDER ?',
|
|
style: AppTypography.headerSmall.copyWith(fontWeight: FontWeight.bold),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'Documentation, FAQ et support technique',
|
|
style: AppTypography.subtitleSmall,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section de recherche
|
|
Widget _buildSearchSection() {
|
|
return CoreCard(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
const Icon(Icons.search, color: AppColors.primaryGreen, size: 18),
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'RECHERCHER DANS L\'AIDE',
|
|
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 12),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: AppColors.lightSurface,
|
|
borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(color: AppColors.lightBorder),
|
|
),
|
|
child: TextField(
|
|
controller: _searchController,
|
|
onChanged: (value) => setState(() => _searchQuery = value),
|
|
style: AppTypography.bodyTextSmall,
|
|
decoration: InputDecoration(
|
|
hintText: 'Une question, un mot-clé...',
|
|
hintStyle: AppTypography.subtitleSmall,
|
|
prefixIcon: const Icon(Icons.search, color: AppColors.textSecondaryLight, size: 18),
|
|
suffixIcon: _searchQuery.isNotEmpty
|
|
? IconButton(
|
|
onPressed: () {
|
|
_searchController.clear();
|
|
setState(() => _searchQuery = '');
|
|
},
|
|
icon: const Icon(Icons.clear, color: AppColors.textSecondaryLight, size: 18),
|
|
)
|
|
: null,
|
|
border: InputBorder.none,
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section actions rapides
|
|
Widget _buildQuickActionsSection() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 4, bottom: 12),
|
|
child: Text(
|
|
'ACTIONS RAPIDES',
|
|
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
|
|
),
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: _buildQuickActionCard(
|
|
'CHAT',
|
|
'Support Direct',
|
|
Icons.chat_bubble_outline,
|
|
AppColors.primaryGreen,
|
|
() => _startLiveChat(),
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: _buildQuickActionCard(
|
|
'BUG',
|
|
'Signaler',
|
|
Icons.bug_report_outlined,
|
|
AppColors.error,
|
|
() => _reportBug(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 12),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: _buildQuickActionCard(
|
|
'IDÉE',
|
|
'Suggérer',
|
|
Icons.lightbulb_outline,
|
|
AppColors.warning,
|
|
() => _requestFeature(),
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: _buildQuickActionCard(
|
|
'EMAIL',
|
|
'Support Tech',
|
|
Icons.mark_email_read_outlined,
|
|
AppColors.info,
|
|
() => _contactByEmail(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// Carte d'action rapide
|
|
Widget _buildQuickActionCard(String title, String subtitle, IconData icon, Color color, VoidCallback onTap) {
|
|
return CoreCard(
|
|
padding: const EdgeInsets.all(12),
|
|
onTap: onTap,
|
|
child: Column(
|
|
children: [
|
|
Icon(icon, color: color, size: 24),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
title,
|
|
style: AppTypography.actionText.copyWith(fontSize: 11),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
Text(
|
|
subtitle,
|
|
style: AppTypography.subtitleSmall.copyWith(fontSize: 9),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section catégories
|
|
Widget _buildCategoriesSection() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 4, bottom: 8),
|
|
child: Text(
|
|
'PAR CATÉGORIE',
|
|
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
|
|
),
|
|
),
|
|
SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: Row(
|
|
children: _categories.asMap().entries.map((entry) {
|
|
final isSelected = _selectedCategoryIndex == entry.key;
|
|
return Padding(
|
|
padding: const EdgeInsets.only(right: 8),
|
|
child: _buildCategoryChip(entry.value, isSelected, () {
|
|
setState(() => _selectedCategoryIndex = entry.key);
|
|
}),
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// Chip de catégorie
|
|
Widget _buildCategoryChip(String label, bool isSelected, VoidCallback onTap) {
|
|
return InkWell(
|
|
onTap: onTap,
|
|
borderRadius: BorderRadius.circular(4),
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
|
decoration: BoxDecoration(
|
|
color: isSelected ? AppColors.primaryGreen.withOpacity(0.1) : Colors.transparent,
|
|
borderRadius: BorderRadius.circular(4),
|
|
border: Border.all(
|
|
color: isSelected ? AppColors.primaryGreen : AppColors.lightBorder,
|
|
),
|
|
),
|
|
child: Text(
|
|
label.toUpperCase(),
|
|
style: AppTypography.badgeText.copyWith(
|
|
color: isSelected ? AppColors.primaryGreen : AppColors.textSecondaryLight,
|
|
fontSize: 9,
|
|
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section FAQ
|
|
Widget _buildFAQSection() {
|
|
final faqs = _getFilteredFAQs();
|
|
if (faqs.isEmpty) return const SizedBox.shrink();
|
|
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 4, bottom: 12),
|
|
child: Text(
|
|
'QUESTIONS FRÉQUENTES',
|
|
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
|
|
),
|
|
),
|
|
...faqs.map((faq) => Padding(
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
child: _buildFAQItem(faq),
|
|
)),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// Élément FAQ
|
|
Widget _buildFAQItem(Map<String, dynamic> faq) {
|
|
return CoreCard(
|
|
padding: EdgeInsets.zero,
|
|
child: ExpansionTile(
|
|
title: Text(
|
|
faq['question'],
|
|
style: AppTypography.actionText.copyWith(fontSize: 12),
|
|
),
|
|
leading: Icon(
|
|
faq['icon'] as IconData,
|
|
color: AppColors.primaryGreen,
|
|
size: 18,
|
|
),
|
|
iconColor: AppColors.primaryGreen,
|
|
collapsedIconColor: AppColors.textSecondaryLight,
|
|
shape: const RoundedRectangleBorder(side: BorderSide.none),
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
child: Text(
|
|
faq['answer'],
|
|
style: AppTypography.subtitleSmall.copyWith(fontSize: 11, height: 1.4),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section guides
|
|
Widget _buildGuidesSection() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 4, bottom: 12),
|
|
child: Text(
|
|
'GUIDES & TUTORIELS',
|
|
style: AppTypography.subtitleSmall.copyWith(fontWeight: FontWeight.bold, letterSpacing: 1.1),
|
|
),
|
|
),
|
|
_buildGuideItem('Introduction', 'Démarrer avec UnionFlow', Icons.play_circle_outline, AppColors.success, () => _openGuide('getting-started')),
|
|
_buildGuideItem('Membres', 'Gérer vos adhérents', Icons.people_outline, AppColors.primaryGreen, () => _openGuide('members')),
|
|
_buildGuideItem('Organisations', 'Structures & Syndicats', Icons.business_outlined, AppColors.info, () => _openGuide('organizations')),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// Élément de guide
|
|
Widget _buildGuideItem(String title, String description, IconData icon, Color color, VoidCallback onTap) {
|
|
return CoreCard(
|
|
margin: const EdgeInsets.only(bottom: 8),
|
|
onTap: onTap,
|
|
child: Row(
|
|
children: [
|
|
Icon(icon, color: color, size: 20),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(title, style: AppTypography.actionText.copyWith(fontSize: 12)),
|
|
Text(description, style: AppTypography.subtitleSmall.copyWith(fontSize: 10)),
|
|
],
|
|
),
|
|
),
|
|
const Icon(Icons.chevron_right, color: AppColors.textSecondaryLight, size: 16),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Section contact
|
|
Widget _buildContactSection() {
|
|
return CoreCard(
|
|
backgroundColor: AppColors.primaryGreen, // Correction: color -> backgroundColor
|
|
child: Column(
|
|
children: [
|
|
const Icon(Icons.headset_mic_outlined, color: Colors.white, size: 32),
|
|
const SizedBox(height: 12),
|
|
Text(
|
|
'BESOIN D\'AIDE SUPPLÉMENTAIRE ?',
|
|
style: AppTypography.headerSmall.copyWith(color: Colors.white, fontSize: 14),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'Disponible lun-ven, 9h-18h',
|
|
style: AppTypography.subtitleSmall.copyWith(color: Colors.white.withOpacity(0.8)),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 20),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: UFPrimaryButton(
|
|
label: 'EMAIL', // Correction: text -> label
|
|
onPressed: () => _contactByEmail(),
|
|
backgroundColor: Colors.white,
|
|
textColor: AppColors.primaryGreen,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: UFPrimaryButton(
|
|
label: 'CHAT', // Correction: text -> label
|
|
onPressed: () => _startLiveChat(),
|
|
backgroundColor: Colors.white.withOpacity(0.2),
|
|
textColor: Colors.white,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Obtenir les FAQs filtrées
|
|
List<Map<String, dynamic>> _getFilteredFAQs() {
|
|
final allFAQs = [
|
|
{
|
|
'question': 'Comment me connecter à UnionFlow ?',
|
|
'answer': 'Utilisez vos identifiants fournis par votre organisation. La connexion se fait via Keycloak pour une sécurité optimale.',
|
|
'category': 'Connexion',
|
|
'icon': Icons.login,
|
|
},
|
|
{
|
|
'question': 'Comment ajouter un nouveau membre ?',
|
|
'answer': 'Allez dans la section Membres, cliquez sur le bouton + et remplissez les informations requises. Vous devez avoir les permissions appropriées.',
|
|
'category': 'Membres',
|
|
'icon': Icons.person_add,
|
|
},
|
|
{
|
|
'question': 'Comment créer une nouvelle organisation ?',
|
|
'answer': 'Dans la section Organisations, utilisez le bouton "Nouvelle organisation" et suivez les étapes du formulaire.',
|
|
'category': 'Organisations',
|
|
'icon': Icons.business,
|
|
},
|
|
{
|
|
'question': 'Comment planifier un événement ?',
|
|
'answer': 'Accédez à la section Événements, cliquez sur "Nouvel événement" et configurez les détails, date, lieu et participants.',
|
|
'category': 'Événements',
|
|
'icon': Icons.event,
|
|
},
|
|
{
|
|
'question': 'L\'application ne se synchronise pas',
|
|
'answer': 'Vérifiez votre connexion internet. Si le problème persiste, déconnectez-vous et reconnectez-vous.',
|
|
'category': 'Technique',
|
|
'icon': Icons.sync_problem,
|
|
},
|
|
{
|
|
'question': 'Comment modifier mes informations personnelles ?',
|
|
'answer': 'Allez dans Plus > Profil pour modifier vos informations personnelles et préférences.',
|
|
'category': 'Tout',
|
|
'icon': Icons.edit,
|
|
},
|
|
];
|
|
|
|
if (_selectedCategoryIndex == 0) return allFAQs; // Tout
|
|
|
|
final selectedCategory = _categories[_selectedCategoryIndex];
|
|
return allFAQs.where((faq) => faq['category'] == selectedCategory).toList();
|
|
}
|
|
|
|
// ==================== MÉTHODES D'ACTION ====================
|
|
|
|
/// Démarrer un chat en direct
|
|
void _startLiveChat() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Chat en direct'),
|
|
content: const Text(
|
|
'Contacter le support par email pour toute question. '
|
|
'Notre équipe vous répondra dans les meilleurs délais.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Fermer'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
_contactByEmail();
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.primaryGreen,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: const Text('Envoyer un email'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Signaler un bug
|
|
void _reportBug() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Signaler un bug'),
|
|
content: const Text(
|
|
'Décrivez le problème rencontré et les étapes pour le reproduire. '
|
|
'Notre équipe technique vous répondra rapidement.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Annuler'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
_launchUrl('mailto:support@unionflow.com?subject=Rapport de bug - UnionFlow Mobile');
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.error,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: const Text('Signaler'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Demander une fonctionnalité
|
|
void _requestFeature() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Demander une fonctionnalité'),
|
|
content: const Text(
|
|
'Partagez vos idées d\'amélioration ! '
|
|
'Nous étudions toutes les suggestions pour améliorer UnionFlow.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Annuler'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
_launchUrl('mailto:support@unionflow.com?subject=Demande de fonctionnalité - UnionFlow Mobile');
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.primaryGreen,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: const Text('Envoyer'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Contacter par email
|
|
void _contactByEmail() {
|
|
_launchUrl('mailto:support@unionflow.com?subject=Support UnionFlow Mobile');
|
|
}
|
|
|
|
/// Ouvrir un guide
|
|
void _openGuide(String guideId) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Guide'),
|
|
content: Text(
|
|
'Consultez notre documentation en ligne pour le guide "$guideId".',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Fermer'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
_launchUrl('https://docs.unionflow.com/$guideId');
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.primaryGreen,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: const Text('Voir en ligne'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Afficher la visite guidée
|
|
void _showHelpTour() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: const Text('Visite guidée'),
|
|
content: const Text(
|
|
'Parcourez les onglets de l\'application pour découvrir les fonctionnalités. '
|
|
'En cas de question, contactez le support par email.',
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: const Text('Fermer'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
_contactByEmail();
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: AppColors.primaryGreen,
|
|
foregroundColor: Colors.white,
|
|
),
|
|
child: const Text('Contacter le support'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Lancer une URL
|
|
Future<void> _launchUrl(String url) async {
|
|
try {
|
|
final uri = Uri.parse(url);
|
|
if (await canLaunchUrl(uri)) {
|
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
|
} else {
|
|
_showErrorSnackBar('Impossible d\'ouvrir le lien');
|
|
}
|
|
} catch (e) {
|
|
_showErrorSnackBar('Erreur lors de l\'ouverture du lien');
|
|
}
|
|
}
|
|
|
|
/// Afficher un message d'erreur
|
|
void _showErrorSnackBar(String message) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text(message),
|
|
backgroundColor: AppColors.error,
|
|
behavior: SnackBarBehavior.floating,
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Afficher un message de succès
|
|
void _showSuccessSnackBar(String message) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text(message),
|
|
backgroundColor: AppColors.success,
|
|
behavior: SnackBarBehavior.floating,
|
|
),
|
|
);
|
|
}
|
|
}
|