HydroNutrify_Ari_e41221567/lib/ui/shared/components/custom_dialog.dart

253 lines
6.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:mobile_monitoring/core/constants/colors.dart';
import 'package:mobile_monitoring/ui/shared/components/custom_button.dart';
/// Custom Dialog - Dialog yang reusable
class CustomDialog {
/// Confirmation Dialog - Dialog untuk konfirmasi aksi
static Future<bool?> showConfirmation({
required BuildContext context,
required String title,
required String message,
String confirmText = 'Ya',
String cancelText = 'Tidak',
bool isDangerous = false,
}) {
return showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(cancelText),
),
CustomButton(
text: confirmText,
type: isDangerous ? ButtonType.danger : ButtonType.primary,
size: ButtonSize.small,
onPressed: () => Navigator.of(context).pop(true),
),
],
),
);
}
/// Info Dialog - Dialog untuk menampilkan informasi
static Future<void> showInfo({
required BuildContext context,
required String title,
required String message,
String buttonText = 'OK',
IconData? icon,
Color? iconColor,
}) {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: Row(
children: [
if (icon != null) ...[
Icon(icon, color: iconColor ?? AppColors.info),
const SizedBox(width: 12),
],
Expanded(child: Text(title)),
],
),
content: Text(message),
actions: [
CustomButton(
text: buttonText,
type: ButtonType.primary,
size: ButtonSize.small,
onPressed: () => Navigator.of(context).pop(),
),
],
),
);
}
/// Error Dialog - Dialog untuk menampilkan error
static Future<void> showError({
required BuildContext context,
required String title,
required String message,
String buttonText = 'OK',
}) {
return showInfo(
context: context,
title: title,
message: message,
buttonText: buttonText,
icon: Icons.error_outline,
iconColor: AppColors.error,
);
}
/// Success Dialog - Dialog untuk menampilkan success
static Future<void> showSuccess({
required BuildContext context,
required String title,
required String message,
String buttonText = 'OK',
}) {
return showInfo(
context: context,
title: title,
message: message,
buttonText: buttonText,
icon: Icons.check_circle_outline,
iconColor: AppColors.success,
);
}
/// Loading Dialog - Dialog untuk menampilkan loading
static void showLoading(BuildContext context, {String? message}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => PopScope(
canPop: false,
child: AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(),
if (message != null) ...[
const SizedBox(height: 16),
Text(message),
],
],
),
),
),
);
}
/// Custom Content Dialog - Dialog dengan custom content
static Future<T?> showCustom<T>({
required BuildContext context,
required String title,
required Widget content,
List<Widget>? actions,
bool barrierDismissible = true,
}) {
return showDialog<T>(
context: context,
barrierDismissible: barrierDismissible,
builder: (context) => AlertDialog(
title: Text(title),
content: content,
actions: actions,
),
);
}
}
/// Bottom Sheet Dialog - Bottom sheet yang reusable
class CustomBottomSheet {
/// Show custom bottom sheet
static Future<T?> show<T>({
required BuildContext context,
required Widget child,
String? title,
bool isDismissible = true,
bool enableDrag = true,
double? height,
}) {
return showModalBottomSheet<T>(
context: context,
isDismissible: isDismissible,
enableDrag: enableDrag,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => Container(
height: height,
decoration: const BoxDecoration(
color: AppColors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (enableDrag) ...[
const SizedBox(height: 8),
Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: AppColors.mediumGray,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 8),
],
if (title != null) ...[
Padding(
padding: const EdgeInsets.all(16),
child: Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: AppColors.textPrimary,
),
),
),
const Divider(height: 1),
],
Flexible(child: child),
],
),
),
);
}
/// Show list bottom sheet
static Future<T?> showList<T>({
required BuildContext context,
required String title,
required List<BottomSheetItem<T>> items,
}) {
return show<T>(
context: context,
title: title,
child: ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
leading: item.icon != null
? Icon(item.icon, color: item.iconColor)
: null,
title: Text(item.title),
subtitle: item.subtitle != null ? Text(item.subtitle!) : null,
onTap: () => Navigator.of(context).pop(item.value),
);
},
),
);
}
}
class BottomSheetItem<T> {
final String title;
final String? subtitle;
final IconData? icon;
final Color? iconColor;
final T value;
BottomSheetItem({
required this.title,
this.subtitle,
this.icon,
this.iconColor,
required this.value,
});
}