Files
submanager/lib/widgets/common/dialogs/confirmation_dialog.dart
JiWoong Sul 2f60ef585a feat: 글래스모피즘 디자인 시스템 및 색상 가이드 전면 적용
- @doc/color.md 가이드라인에 따른 색상 시스템 전면 개편
- 딥 블루(#2563EB), 스카이 블루(#60A5FA) 메인 컬러로 변경
- 모든 화면과 위젯에 글래스모피즘 효과 일관성 있게 적용
- darkNavy, navyGray 등 새로운 텍스트 색상 체계 도입
- 공통 스낵바 및 다이얼로그 컴포넌트 추가
- Claude AI 프로젝트 컨텍스트 파일(CLAUDE.md) 추가

영향받은 컴포넌트:
- 10개 스크린 (main, settings, detail, splash 등)
- 30개 이상 위젯 (buttons, cards, forms 등)
- 테마 시스템 (AppColors, AppTheme)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-11 18:41:05 +09:00

353 lines
8.9 KiB
Dart

import 'package:flutter/material.dart';
/// 확인 다이얼로그 위젯
/// 사용자에게 중요한 작업을 확인받을 때 사용합니다.
class ConfirmationDialog extends StatelessWidget {
final String title;
final String? message;
final Widget? content;
final String confirmText;
final String cancelText;
final VoidCallback? onConfirm;
final VoidCallback? onCancel;
final Color? confirmColor;
final IconData? icon;
final Color? iconColor;
final double iconSize;
const ConfirmationDialog({
super.key,
required this.title,
this.message,
this.content,
this.confirmText = '확인',
this.cancelText = '취소',
this.onConfirm,
this.onCancel,
this.confirmColor,
this.icon,
this.iconColor,
this.iconSize = 48,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final effectiveConfirmColor = confirmColor ?? theme.primaryColor;
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) ...[
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: (iconColor ?? effectiveConfirmColor).withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
),
child: Icon(
icon,
color: iconColor ?? effectiveConfirmColor,
size: iconSize,
),
),
const SizedBox(height: 16),
],
if (content != null)
content!
else if (message != null)
Text(
message!,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 16,
height: 1.5,
),
),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
onCancel?.call();
},
child: Text(cancelText),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(true);
onConfirm?.call();
},
style: ElevatedButton.styleFrom(
backgroundColor: effectiveConfirmColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
confirmText,
style: const TextStyle(color: Colors.white),
),
),
],
);
}
/// 다이얼로그를 표시하고 결과를 반환하는 정적 메서드
static Future<bool?> show({
required BuildContext context,
required String title,
String? message,
Widget? content,
String confirmText = '확인',
String cancelText = '취소',
Color? confirmColor,
IconData? icon,
Color? iconColor,
double iconSize = 48,
}) {
return showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (context) => ConfirmationDialog(
title: title,
message: message,
content: content,
confirmText: confirmText,
cancelText: cancelText,
confirmColor: confirmColor,
icon: icon,
iconColor: iconColor,
iconSize: iconSize,
),
);
}
}
/// 성공 다이얼로그
class SuccessDialog extends StatelessWidget {
final String title;
final String? message;
final String buttonText;
final VoidCallback? onPressed;
const SuccessDialog({
super.key,
required this.title,
this.message,
this.buttonText = '확인',
this.onPressed,
});
@override
Widget build(BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: const Icon(
Icons.check_circle,
color: Colors.green,
size: 64,
),
),
const SizedBox(height: 24),
Text(
title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
if (message != null) ...[
const SizedBox(height: 12),
Text(
message!,
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
),
textAlign: TextAlign.center,
),
],
],
),
actions: [
Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
onPressed?.call();
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 12,
),
),
child: Text(
buttonText,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
),
],
);
}
static Future<void> show({
required BuildContext context,
required String title,
String? message,
String buttonText = '확인',
VoidCallback? onPressed,
}) {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (context) => SuccessDialog(
title: title,
message: message,
buttonText: buttonText,
onPressed: onPressed,
),
);
}
}
/// 에러 다이얼로그
class ErrorDialog extends StatelessWidget {
final String title;
final String? message;
final String buttonText;
final VoidCallback? onPressed;
const ErrorDialog({
super.key,
required this.title,
this.message,
this.buttonText = '확인',
this.onPressed,
});
@override
Widget build(BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: const Icon(
Icons.error_outline,
color: Colors.red,
size: 64,
),
),
const SizedBox(height: 24),
Text(
title,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
if (message != null) ...[
const SizedBox(height: 12),
Text(
message!,
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
),
textAlign: TextAlign.center,
),
],
],
),
actions: [
Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
onPressed?.call();
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 12,
),
),
child: Text(
buttonText,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
),
],
);
}
static Future<void> show({
required BuildContext context,
required String title,
String? message,
String buttonText = '확인',
VoidCallback? onPressed,
}) {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (context) => ErrorDialog(
title: title,
message: message,
buttonText: buttonText,
onPressed: onPressed,
),
);
}
}