Files
submanager/lib/widgets/dialogs/delete_confirmation_dialog.dart
2025-11-17 19:26:14 +09:00

189 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
// Material 3 기반 다이얼로그
import '../common/buttons/primary_button.dart';
import '../common/buttons/secondary_button.dart';
import '../../l10n/app_localizations.dart';
/// 삭제 확인 다이얼로그
/// 글래스모피즘 스타일의 삭제 확인 다이얼로그입니다.
class DeleteConfirmationDialog extends StatelessWidget {
final String serviceName;
const DeleteConfirmationDialog({
super.key,
required this.serviceName,
});
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
final textThemeColor = Theme.of(context).colorScheme;
final baseMessageStyle = TextStyle(
fontSize: 16,
color: textThemeColor.onSurfaceVariant,
height: 1.5,
);
final highlightStyle = baseMessageStyle.copyWith(
fontWeight: FontWeight.w600,
color: textThemeColor.onSurface,
);
return Dialog(
backgroundColor: textThemeColor.surface,
elevation: 6,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
child: Container(
constraints: const BoxConstraints(maxWidth: 400),
padding: const EdgeInsets.all(32),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 아이콘
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color:
Theme.of(context).colorScheme.error.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: Icon(
Icons.delete_forever_rounded,
color: Theme.of(context).colorScheme.error,
size: 40,
),
),
const SizedBox(height: 24),
// 타이틀
Text(
loc.deleteSubscriptionTitle,
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w700,
color: textThemeColor.onSurface,
),
),
const SizedBox(height: 12),
// 설명
RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: baseMessageStyle,
children: _buildLocalizedMessageSpans(
loc.deleteSubscriptionMessageTemplate,
serviceName,
highlightStyle,
),
),
),
const SizedBox(height: 8),
// 경고 메시지
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
decoration: BoxDecoration(
color: textThemeColor.error.withValues(alpha: 0.05),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: textThemeColor.error.withValues(alpha: 0.2),
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.warning_amber_rounded,
color: textThemeColor.error.withValues(alpha: 0.8),
size: 20,
),
const SizedBox(width: 8),
Text(
loc.deleteIrreversibleWarning,
style: TextStyle(
fontSize: 14,
color: textThemeColor.error,
fontWeight: FontWeight.w500,
),
),
],
),
),
const SizedBox(height: 32),
// 버튼들
Row(
children: [
Expanded(
child: SecondaryButton(
text: loc.cancel,
onPressed: () {
Navigator.of(context).pop(false);
},
),
),
const SizedBox(width: 12),
Expanded(
child: PrimaryButton(
text: loc.delete,
icon: Icons.delete_rounded,
onPressed: () {
Navigator.of(context).pop(true);
},
backgroundColor: textThemeColor.error,
),
),
],
),
],
),
),
);
}
/// 삭제 확인 다이얼로그를 표시합니다.
static Future<bool> show({
required BuildContext context,
required String serviceName,
}) async {
final result = await showDialog<bool>(
context: context,
barrierDismissible: false,
barrierColor: Theme.of(context).colorScheme.scrim.withValues(alpha: 0.5),
builder: (context) => DeleteConfirmationDialog(
serviceName: serviceName,
),
);
return result ?? false;
}
List<TextSpan> _buildLocalizedMessageSpans(
String template,
String serviceName,
TextStyle highlightStyle,
) {
final parts = template.split('@');
if (parts.length == 1) {
return [TextSpan(text: template)];
}
final spans = <TextSpan>[];
for (int i = 0; i < parts.length; i++) {
final segment = parts[i];
if (segment.isNotEmpty) {
spans.add(TextSpan(text: segment));
}
if (i < parts.length - 1) {
spans.add(TextSpan(text: serviceName, style: highlightStyle));
}
}
return spans;
}
}