|
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/classes/colors.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
|
|
|
|
|
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
|
|
|
|
|
|
|
|
|
|
/// Generic, fully customizable confirmation bottom sheet matching the app's visual theme
|
|
|
|
|
/// (same handle bar / rounded-top-sheet / gradient button look used across other sheets).
|
|
|
|
|
/// Everything is driven by the caller - title/message/button text/colors/icon/callbacks -
|
|
|
|
|
/// with sensible defaults so a minimal call still looks consistent with the rest of the app.
|
|
|
|
|
class ConfirmBottomSheet extends StatelessWidget {
|
|
|
|
|
final String? title;
|
|
|
|
|
final String message;
|
|
|
|
|
final String? confirmText;
|
|
|
|
|
final String? cancelText;
|
|
|
|
|
final VoidCallback onConfirm;
|
|
|
|
|
final VoidCallback? onCancel;
|
|
|
|
|
final bool isDestructive;
|
|
|
|
|
final bool showCancelButton;
|
|
|
|
|
final IconData? icon;
|
|
|
|
|
final Color? iconColor;
|
|
|
|
|
final Color? iconBackgroundColor;
|
|
|
|
|
final List<Color>? confirmButtonColors;
|
|
|
|
|
final Color? confirmButtonTextColor;
|
|
|
|
|
final Color? cancelButtonColor;
|
|
|
|
|
final Color? cancelButtonTextColor;
|
|
|
|
|
|
|
|
|
|
const ConfirmBottomSheet({
|
|
|
|
|
Key? key,
|
|
|
|
|
this.title,
|
|
|
|
|
required this.message,
|
|
|
|
|
this.confirmText,
|
|
|
|
|
this.cancelText,
|
|
|
|
|
required this.onConfirm,
|
|
|
|
|
this.onCancel,
|
|
|
|
|
this.isDestructive = false,
|
|
|
|
|
this.showCancelButton = true,
|
|
|
|
|
this.icon,
|
|
|
|
|
this.iconColor,
|
|
|
|
|
this.iconBackgroundColor,
|
|
|
|
|
this.confirmButtonColors,
|
|
|
|
|
this.confirmButtonTextColor,
|
|
|
|
|
this.cancelButtonColor,
|
|
|
|
|
this.cancelButtonTextColor,
|
|
|
|
|
}) : super(key: key);
|
|
|
|
|
|
|
|
|
|
/// Convenience launcher - mirrors Utils.confirmDialog's call shape but as a bottom sheet.
|
|
|
|
|
static Future<void> show(
|
|
|
|
|
BuildContext context, {
|
|
|
|
|
String? title,
|
|
|
|
|
required String message,
|
|
|
|
|
String? confirmText,
|
|
|
|
|
String? cancelText,
|
|
|
|
|
required VoidCallback onConfirm,
|
|
|
|
|
VoidCallback? onCancel,
|
|
|
|
|
bool isDestructive = false,
|
|
|
|
|
bool showCancelButton = true,
|
|
|
|
|
IconData? icon,
|
|
|
|
|
Color? iconColor,
|
|
|
|
|
Color? iconBackgroundColor,
|
|
|
|
|
List<Color>? confirmButtonColors,
|
|
|
|
|
Color? confirmButtonTextColor,
|
|
|
|
|
Color? cancelButtonColor,
|
|
|
|
|
Color? cancelButtonTextColor,
|
|
|
|
|
}) {
|
|
|
|
|
return showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
isScrollControlled: true,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
builder: (BuildContext sheetContext) {
|
|
|
|
|
return ConfirmBottomSheet(
|
|
|
|
|
title: title,
|
|
|
|
|
message: message,
|
|
|
|
|
confirmText: confirmText,
|
|
|
|
|
cancelText: cancelText,
|
|
|
|
|
onConfirm: onConfirm,
|
|
|
|
|
onCancel: onCancel,
|
|
|
|
|
isDestructive: isDestructive,
|
|
|
|
|
showCancelButton: showCancelButton,
|
|
|
|
|
icon: icon,
|
|
|
|
|
iconColor: iconColor,
|
|
|
|
|
iconBackgroundColor: iconBackgroundColor,
|
|
|
|
|
confirmButtonColors: confirmButtonColors,
|
|
|
|
|
confirmButtonTextColor: confirmButtonTextColor,
|
|
|
|
|
cancelButtonColor: cancelButtonColor,
|
|
|
|
|
cancelButtonTextColor: cancelButtonTextColor,
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
Color effectiveIconColor = iconColor ?? (isDestructive ? MyColors.redColor : MyColors.textMixColor);
|
|
|
|
|
Color effectiveIconBg = iconBackgroundColor ?? effectiveIconColor.withOpacity(0.1);
|
|
|
|
|
List<Color> effectiveConfirmColors = confirmButtonColors ?? (isDestructive ? const [MyColors.redA3Color, MyColors.redColor] : const [MyColors.gradiantEndColor, MyColors.gradiantStartColor]);
|
|
|
|
|
|
|
|
|
|
return SafeArea(
|
|
|
|
|
top: false,
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: const EdgeInsets.fromLTRB(20, 12, 20, 20),
|
|
|
|
|
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24))),
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
|
children: [
|
|
|
|
|
// Drag handle
|
|
|
|
|
Center(
|
|
|
|
|
child: Container(width: 44, height: 4.5, margin: const EdgeInsets.only(bottom: 18), decoration: BoxDecoration(color: const Color(0xFFCBD5E1), borderRadius: BorderRadius.circular(2.5))),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
if (icon != null) ...[
|
|
|
|
|
Center(
|
|
|
|
|
child: Container(
|
|
|
|
|
width: 56,
|
|
|
|
|
height: 56,
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(color: effectiveIconBg, shape: BoxShape.circle),
|
|
|
|
|
child: Icon(icon, color: effectiveIconColor, size: 28),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
16.height,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
(title ?? LocaleKeys.confirm.tr()).toText18(isBold: true, isCentered: true, color: MyColors.darkTextColor),
|
|
|
|
|
8.height,
|
|
|
|
|
message.toText14(color: MyColors.grey70Color, textAlign: TextAlign.center),
|
|
|
|
|
24.height,
|
|
|
|
|
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
if (showCancelButton) ...[
|
|
|
|
|
Expanded(
|
|
|
|
|
child: DefaultButton(
|
|
|
|
|
cancelText ?? LocaleKeys.cancel.tr(),
|
|
|
|
|
() {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
onCancel?.call();
|
|
|
|
|
},
|
|
|
|
|
colors: [cancelButtonColor ?? MyColors.lightGreyEAColor, cancelButtonColor ?? MyColors.lightGreyEAColor],
|
|
|
|
|
textColor: cancelButtonTextColor ?? MyColors.darkTextColor,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
12.width,
|
|
|
|
|
],
|
|
|
|
|
Expanded(
|
|
|
|
|
child: DefaultButton(
|
|
|
|
|
confirmText ?? LocaleKeys.ok.tr(),
|
|
|
|
|
() {
|
|
|
|
|
Navigator.pop(context);
|
|
|
|
|
onConfirm();
|
|
|
|
|
},
|
|
|
|
|
colors: effectiveConfirmColors,
|
|
|
|
|
textColor: confirmButtonTextColor ?? Colors.white,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|