2026-03-19 18:43:08 +08:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
2026-03-27 14:05:03 +08:00
|
|
|
import '../../core/l10n/l10n.dart';
|
2026-03-19 18:43:08 +08:00
|
|
|
import '../../core/theme/design_tokens.dart';
|
|
|
|
|
import 'app_button.dart';
|
|
|
|
|
|
|
|
|
|
Future<bool> showConfirmSheet(
|
|
|
|
|
BuildContext context, {
|
|
|
|
|
required String title,
|
|
|
|
|
required String message,
|
2026-03-27 14:05:03 +08:00
|
|
|
String? confirmText,
|
|
|
|
|
String? cancelText,
|
2026-03-19 18:43:08 +08:00
|
|
|
bool isDestructive = false,
|
|
|
|
|
}) async {
|
2026-03-27 14:05:03 +08:00
|
|
|
final l10n = context.l10n;
|
|
|
|
|
final resolvedConfirmText = confirmText ?? l10n.commonConfirm;
|
|
|
|
|
final resolvedCancelText = cancelText ?? l10n.commonCancel;
|
2026-03-19 18:43:08 +08:00
|
|
|
final result = await showModalBottomSheet<bool>(
|
|
|
|
|
context: context,
|
|
|
|
|
isScrollControlled: true,
|
2026-03-27 19:07:39 +08:00
|
|
|
backgroundColor: Theme.of(context).colorScheme.surface.withValues(alpha: 0),
|
2026-03-19 18:43:08 +08:00
|
|
|
builder: (sheetContext) {
|
2026-03-27 19:07:39 +08:00
|
|
|
final colorScheme = Theme.of(sheetContext).colorScheme;
|
|
|
|
|
|
2026-03-19 18:43:08 +08:00
|
|
|
return SafeArea(
|
|
|
|
|
top: false,
|
|
|
|
|
child: Container(
|
|
|
|
|
margin: const EdgeInsets.fromLTRB(
|
|
|
|
|
AppSpacing.md,
|
|
|
|
|
AppSpacing.none,
|
|
|
|
|
AppSpacing.md,
|
|
|
|
|
AppSpacing.md,
|
|
|
|
|
),
|
|
|
|
|
padding: const EdgeInsets.all(AppSpacing.lg),
|
|
|
|
|
decoration: BoxDecoration(
|
2026-03-27 19:07:39 +08:00
|
|
|
color: colorScheme.surface,
|
2026-03-19 18:43:08 +08:00
|
|
|
borderRadius: BorderRadius.circular(AppRadius.xl),
|
2026-03-27 19:07:39 +08:00
|
|
|
border: Border.all(color: colorScheme.outlineVariant),
|
2026-03-19 18:43:08 +08:00
|
|
|
),
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
title,
|
|
|
|
|
textAlign: TextAlign.center,
|
2026-03-27 19:07:39 +08:00
|
|
|
style: TextStyle(
|
2026-03-19 18:43:08 +08:00
|
|
|
fontSize: 18,
|
|
|
|
|
fontWeight: FontWeight.w700,
|
2026-03-27 19:07:39 +08:00
|
|
|
color: colorScheme.onSurface,
|
2026-03-19 18:43:08 +08:00
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: AppSpacing.xs),
|
|
|
|
|
Text(
|
|
|
|
|
message,
|
|
|
|
|
textAlign: TextAlign.center,
|
2026-03-27 19:07:39 +08:00
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
color: colorScheme.onSurfaceVariant,
|
|
|
|
|
),
|
2026-03-19 18:43:08 +08:00
|
|
|
),
|
|
|
|
|
const SizedBox(height: AppSpacing.lg),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 52,
|
|
|
|
|
child: GestureDetector(
|
|
|
|
|
onTap: () => Navigator.of(sheetContext).pop(true),
|
|
|
|
|
child: Container(
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: isDestructive
|
2026-03-27 19:07:39 +08:00
|
|
|
? colorScheme.error
|
|
|
|
|
: colorScheme.primary,
|
2026-03-19 18:43:08 +08:00
|
|
|
borderRadius: BorderRadius.circular(AppRadius.full),
|
|
|
|
|
),
|
|
|
|
|
child: Text(
|
2026-03-27 14:05:03 +08:00
|
|
|
resolvedConfirmText,
|
2026-03-27 19:07:39 +08:00
|
|
|
style: TextStyle(
|
2026-03-19 18:43:08 +08:00
|
|
|
fontSize: 15,
|
|
|
|
|
fontWeight: FontWeight.w700,
|
2026-03-27 19:07:39 +08:00
|
|
|
color: isDestructive
|
|
|
|
|
? colorScheme.onError
|
|
|
|
|
: colorScheme.onPrimary,
|
2026-03-19 18:43:08 +08:00
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: AppSpacing.sm),
|
|
|
|
|
SizedBox(
|
|
|
|
|
height: 52,
|
|
|
|
|
child: AppButton(
|
2026-03-27 14:05:03 +08:00
|
|
|
text: resolvedCancelText,
|
2026-03-19 18:43:08 +08:00
|
|
|
isOutlined: true,
|
|
|
|
|
onPressed: () => Navigator.of(sheetContext).pop(false),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
return result == true;
|
|
|
|
|
}
|