import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_snackbar.dart'; class ConfirmDialog extends StatelessWidget { final String title; final String message; final String confirmText; final String cancelText; final IconData icon; final Color confirmColor; final Future Function() onConfirm; final RxBool? isProcessing; const ConfirmDialog({ super.key, required this.title, required this.message, required this.onConfirm, this.confirmText = "Delete", this.cancelText = "Cancel", this.icon = Icons.delete, this.confirmColor = Colors.redAccent, this.isProcessing, }); @override Widget build(BuildContext context) { // Use provided RxBool, or create one internally final RxBool loading = isProcessing ?? false.obs; return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28), child: _ContentView( title: title, message: message, icon: icon, confirmColor: confirmColor, confirmText: confirmText, cancelText: cancelText, loading: loading, onConfirm: onConfirm, ), ), ); } } class _ContentView extends StatelessWidget { final String title, message, confirmText, cancelText; final IconData icon; final Color confirmColor; final RxBool loading; final Future Function() onConfirm; const _ContentView({ required this.title, required this.message, required this.icon, required this.confirmColor, required this.confirmText, required this.cancelText, required this.loading, required this.onConfirm, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Column( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 48, color: confirmColor), const SizedBox(height: 16), MyText.titleLarge( title, fontWeight: 600, color: theme.colorScheme.onBackground, ), const SizedBox(height: 12), MyText.bodySmall( message, textAlign: TextAlign.center, color: theme.colorScheme.onSurface.withValues(alpha: 0.7), ), const SizedBox(height: 24), Row( children: [ Expanded( child: Obx(() => _DialogButton( text: cancelText, icon: Icons.close, color: Colors.grey, isLoading: false, onPressed: loading.value ? null // disable while loading : () => Navigator.pop(context, false), )), ), const SizedBox(width: 12), Expanded( child: Obx(() => _DialogButton( text: confirmText, icon: Icons.delete_forever, color: confirmColor, isLoading: loading.value, onPressed: () async { try { loading.value = true; await onConfirm(); // 🔥 call API Navigator.pop(context, true); // close on success } catch (e) { // Show error, dialog stays open showAppSnackbar( title: "Error", message: "Failed to delete. Try again.", type: SnackbarType.error, ); } finally { loading.value = false; } }, )), ), ], ), ], ); } } class _DialogButton extends StatelessWidget { final String text; final IconData icon; final Color color; final VoidCallback? onPressed; final bool isLoading; const _DialogButton({ required this.text, required this.icon, required this.color, required this.onPressed, this.isLoading = false, }); @override Widget build(BuildContext context) { return ElevatedButton.icon( onPressed: isLoading ? null : onPressed, icon: isLoading ? SizedBox( width: 18, height: 18, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : Icon(icon, color: Colors.white), label: MyText.bodyMedium( isLoading ? "Submitting.." : text, color: Colors.white, fontWeight: 600, ), style: ElevatedButton.styleFrom( backgroundColor: color, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric(vertical: 12), ), ); } }