km away fixed.
parent
51ac2d8051
commit
a94613f693
@ -0,0 +1,171 @@
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue