Files
unionflow-mobile-apps/lib/shared/widgets/confirmation_dialog.dart
dahoud 0abcdcc478 feat(design-system): dark mode adaptatif sur widgets partagés
Pattern AppColors pair (isDark ? AppColors.surfaceDark : AppColors.surface)
appliqué sur :
- UnionStatWidget, UnionBalanceCard, UnionActionButton, UFSectionHeader
- DashboardEventRow, DashboardActivityRow, UnionExportButton
- MiniAvatar (border adaptatif)
- ConfirmationDialog (cancel colors adaptés)
- FileUploadWidget (textSecondary adaptatif)

Les couleurs surface/border/textPrimary/textSecondary hardcodées (light-only)
sont remplacées par les paires *Dark conditionnelles.
Les couleurs sémantiques (error, success, warning, primary) restent inchangées.
2026-04-15 20:13:22 +00:00

295 lines
7.8 KiB
Dart

/// Dialogue de confirmation réutilisable
/// Utilisé pour confirmer les actions critiques (suppression, etc.)
library confirmation_dialog;
import 'package:flutter/material.dart';
import '../design_system/tokens/app_colors.dart';
/// Type d'action pour personnaliser l'apparence du dialogue
enum ConfirmationAction {
delete,
deactivate,
activate,
cancel,
warning,
info,
}
/// Dialogue de confirmation générique
class ConfirmationDialog extends StatelessWidget {
final String title;
final String message;
final String confirmText;
final String cancelText;
final ConfirmationAction action;
final VoidCallback? onConfirm;
final VoidCallback? onCancel;
const ConfirmationDialog({
super.key,
required this.title,
required this.message,
this.confirmText = 'Confirmer',
this.cancelText = 'Annuler',
this.action = ConfirmationAction.warning,
this.onConfirm,
this.onCancel,
});
/// Constructeur pour suppression
const ConfirmationDialog.delete({
super.key,
required this.title,
required this.message,
this.confirmText = 'Supprimer',
this.cancelText = 'Annuler',
this.onConfirm,
this.onCancel,
}) : action = ConfirmationAction.delete;
/// Constructeur pour désactivation
const ConfirmationDialog.deactivate({
super.key,
required this.title,
required this.message,
this.confirmText = 'Désactiver',
this.cancelText = 'Annuler',
this.onConfirm,
this.onCancel,
}) : action = ConfirmationAction.deactivate;
/// Constructeur pour activation
const ConfirmationDialog.activate({
super.key,
required this.title,
required this.message,
this.confirmText = 'Activer',
this.cancelText = 'Annuler',
this.onConfirm,
this.onCancel,
}) : action = ConfirmationAction.activate;
@override
Widget build(BuildContext context) {
final colors = _getColors(context);
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
title: Row(
children: [
Icon(
_getIcon(),
color: colors['icon'],
size: 28,
),
const SizedBox(width: 12),
Expanded(
child: Text(
title,
style: TextStyle(
color: colors['title'],
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
],
),
content: Text(
message,
style: const TextStyle(
fontSize: 16,
height: 1.5,
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context, false);
onCancel?.call();
},
child: Text(
cancelText,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
ElevatedButton(
onPressed: () {
Navigator.pop(context, true);
onConfirm?.call();
},
style: ElevatedButton.styleFrom(
backgroundColor: colors['button'],
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
child: Text(
confirmText,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
],
);
}
IconData _getIcon() {
switch (action) {
case ConfirmationAction.delete:
return Icons.delete_forever;
case ConfirmationAction.deactivate:
return Icons.block;
case ConfirmationAction.activate:
return Icons.check_circle;
case ConfirmationAction.cancel:
return Icons.cancel;
case ConfirmationAction.warning:
return Icons.warning;
case ConfirmationAction.info:
return Icons.info;
}
}
Map<String, Color> _getColors(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
switch (action) {
case ConfirmationAction.delete:
return {
'icon': AppColors.error,
'title': AppColors.error,
'button': AppColors.error,
};
case ConfirmationAction.deactivate:
return {
'icon': AppColors.warning,
'title': AppColors.warning,
'button': AppColors.warning,
};
case ConfirmationAction.activate:
return {
'icon': AppColors.success,
'title': AppColors.success,
'button': AppColors.success,
};
case ConfirmationAction.cancel:
return {
'icon': isDark ? AppColors.textSecondaryDark : AppColors.textTertiary,
'title': isDark ? AppColors.textSecondaryDark : AppColors.textSecondary,
'button': isDark ? AppColors.textSecondaryDark : AppColors.textTertiary,
};
case ConfirmationAction.warning:
return {
'icon': AppColors.warningUI,
'title': AppColors.warning,
'button': AppColors.warningUI,
};
case ConfirmationAction.info:
return {
'icon': AppColors.info,
'title': AppColors.primary,
'button': AppColors.info,
};
}
}
}
/// Fonction utilitaire pour afficher un dialogue de confirmation
Future<bool> showConfirmationDialog({
required BuildContext context,
required String title,
required String message,
String confirmText = 'Confirmer',
String cancelText = 'Annuler',
ConfirmationAction action = ConfirmationAction.warning,
}) async {
final result = await showDialog<bool>(
context: context,
builder: (context) => ConfirmationDialog(
title: title,
message: message,
confirmText: confirmText,
cancelText: cancelText,
action: action,
onConfirm: () {},
onCancel: () {},
),
);
return result ?? false;
}
/// Fonction utilitaire pour dialogue de suppression
Future<bool> showDeleteConfirmation({
required BuildContext context,
required String itemName,
String? additionalMessage,
}) async {
final message = additionalMessage != null
? 'Êtes-vous sûr de vouloir supprimer "$itemName" ?\n\n$additionalMessage\n\nCette action est irréversible.'
: 'Êtes-vous sûr de vouloir supprimer "$itemName" ?\n\nCette action est irréversible.';
final result = await showDialog<bool>(
context: context,
builder: (context) => ConfirmationDialog.delete(
title: 'Confirmer la suppression',
message: message,
onConfirm: () {},
onCancel: () {},
),
);
return result ?? false;
}
/// Fonction utilitaire pour dialogue de désactivation
Future<bool> showDeactivateConfirmation({
required BuildContext context,
required String itemName,
String? reason,
}) async {
final message = reason != null
? 'Êtes-vous sûr de vouloir désactiver "$itemName" ?\n\n$reason'
: 'Êtes-vous sûr de vouloir désactiver "$itemName" ?';
final result = await showDialog<bool>(
context: context,
builder: (context) => ConfirmationDialog.deactivate(
title: 'Confirmer la désactivation',
message: message,
onConfirm: () {},
onCancel: () {},
),
);
return result ?? false;
}
/// Fonction utilitaire pour dialogue d'activation
Future<bool> showActivateConfirmation({
required BuildContext context,
required String itemName,
}) async {
final result = await showDialog<bool>(
context: context,
builder: (context) => ConfirmationDialog.activate(
title: 'Confirmer l\'activation',
message: 'Êtes-vous sûr de vouloir activer "$itemName" ?',
onConfirm: () {},
onCancel: () {},
),
);
return result ?? false;
}