TF-4004 Add no content rules creation page

This commit is contained in:
dab246
2025-09-05 14:37:31 +07:00
committed by Dat H. Pham
parent 0194594b9f
commit 9ab62f5451
13 changed files with 338 additions and 136 deletions
@@ -75,7 +75,7 @@ class EmailRulesController extends BaseController {
}
}
void goToCreateNewRule(BuildContext context) async {
Future<void> goToCreateNewRule() async {
final accountId = _accountDashBoardController.accountId.value;
final session = _accountDashBoardController.sessionCurrent;
if (accountId != null && session != null) {
@@ -1,55 +1,101 @@
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/base/setting_detail_view_builder.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/email_rules_controller.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/email_rules_header_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/list_email_rules_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/add_rule_button_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/count_name_of_rules_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/no_rules_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/menu/settings_utils.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
class EmailRulesView extends GetWidget<EmailRulesController> with AppLoaderMixin {
EmailRulesView({Key? key}) : super(key: key);
class EmailRulesView extends GetWidget<EmailRulesController> {
const EmailRulesView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final isDesktop = controller.responsiveUtils.isDesktop(context);
return SettingDetailViewBuilder(
responsiveUtils: controller.responsiveUtils,
backgroundColor: Colors.transparent,
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Padding(
padding: SettingsUtils.getSettingContentWithoutHeaderPadding(
context,
controller.responsiveUtils,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
EmailRulesHeaderWidget(
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
createRule: () => controller.goToCreateNewRule(context),
child: Container(
color: SettingsUtils.getContentBackgroundColor(
context,
controller.responsiveUtils,
),
decoration: SettingsUtils.getBoxDecorationForContent(
context,
controller.responsiveUtils,
),
width: double.infinity,
padding: isDesktop
? const EdgeInsetsDirectional.only(
start: 30,
end: 30,
top: 22,
)
: null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isDesktop) ...[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: SettingHeaderWidget(
menuItem: AccountMenuItem.emailRules,
textStyle: ThemeUtils.textStyleInter600().copyWith(
color: Colors.black.withValues(alpha: 0.9),
),
padding: const EdgeInsetsDirectional.only(end: 16),
),
),
AddRuleButtonWidget(
imagePaths: controller.imagePaths,
margin: const EdgeInsetsDirectional.only(
start: 169,
top: 24,
end: 57,
),
onAddRuleAction: controller.goToCreateNewRule,
),
],
),
const SizedBox(height: 14),
] else ...[
const SettingExplanationWidget(
menuItem: AccountMenuItem.emailRules,
padding: EdgeInsetsDirectional.symmetric(horizontal: 16),
isCenter: true,
textAlign: TextAlign.center,
),
Center(
child: AddRuleButtonWidget(
imagePaths: controller.imagePaths,
margin: const EdgeInsetsDirectional.only(top: 24, bottom: 16),
minWidth: 230,
onAddRuleAction: controller.goToCreateNewRule,
),
),
const SizedBox(height: 16),
_buildLoadingView(),
const ListEmailRulesWidget()
],
),
Obx(() => CountNameOfRulesWidget(
countRules: controller.listEmailRule.length,
margin: EdgeInsetsDirectional.only(
start: isDesktop ? 0 : 16,
top: 24,
),
)),
NoRulesWidget(
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
onAddRuleAction: controller.goToCreateNewRule,
),
],
),
),
);
}
Widget _buildLoadingView() {
return Obx(() => controller.viewState.value.fold(
(failure) => const SizedBox.shrink(),
(success) => success is LoadingState
? Padding(
padding: const EdgeInsets.only(bottom: 24),
child: loadingWidget)
: const SizedBox.shrink()
));
}
}
@@ -0,0 +1,49 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
typedef OnAddRuleAction = void Function();
class AddRuleButtonWidget extends StatelessWidget {
final ImagePaths imagePaths;
final OnAddRuleAction onAddRuleAction;
final EdgeInsetsGeometry? margin;
final double minWidth;
const AddRuleButtonWidget({
super.key,
required this.imagePaths,
required this.onAddRuleAction,
this.margin,
this.minWidth = 161,
});
@override
Widget build(BuildContext context) {
return TMailButtonWidget(
text: AppLocalizations.of(context).addARule,
icon: imagePaths.icAddIdentity,
backgroundColor: AppColor.primaryMain,
borderRadius: 100,
height: 48,
maxWidth: 300,
minWidth: minWidth,
margin: margin,
textStyle: ThemeUtils.textStyleM3LabelLarge(color: Colors.white),
padding: const EdgeInsetsDirectional.symmetric(
horizontal: 32,
),
iconSize: 16,
iconColor: Colors.white,
iconSpace: 8,
maxLines: 1,
flexibleText: true,
textOverflow: TextOverflow.ellipsis,
mainAxisSize: MainAxisSize.min,
onTapActionCallback: onAddRuleAction,
);
}
}
@@ -0,0 +1,52 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class CountNameOfRulesWidget extends StatelessWidget {
final int countRules;
final EdgeInsetsGeometry? margin;
const CountNameOfRulesWidget({
super.key,
required this.countRules,
this.margin,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: margin ?? const EdgeInsetsDirectional.only(top: 38),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Text(
AppLocalizations.of(context).nameOfRules,
style: ThemeUtils.textStyleInter600().copyWith(
fontSize: 14,
height: 20 / 14,
letterSpacing: 0.25,
color: AppColor.gray424244,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
),
Text(
' ${countRules > 999 ? '999+' : countRules.toString()}',
style: ThemeUtils.textStyleInter400.copyWith(
fontSize: 14,
height: 20 / 14,
letterSpacing: 0.25,
color: AppColor.gray424244,
),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
],
),
);
}
}
@@ -1,94 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/model/account_menu_item.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_explanation_widget.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/widgets/setting_header_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EmailRulesHeaderWidget extends StatelessWidget {
const EmailRulesHeaderWidget({
Key? key,
required this.createRule,
required this.imagePaths,
required this.responsiveUtils,
}) : super(key: key);
final VoidCallback createRule;
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
decoration: const BoxDecoration(
color: AppColor.colorBackgroundWrapIconStyleCode,
borderRadius: BorderRadius.all(Radius.circular(16)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (responsiveUtils.isWebDesktop(context))
const SettingHeaderWidget(menuItem: AccountMenuItem.emailRules)
else
const SettingExplanationWidget(
menuItem: AccountMenuItem.emailRules,
padding: EdgeInsets.all(16),
),
Padding(
padding: const EdgeInsets.all(16),
child: _buildButtonAddNewRule(context),
),
],
),
);
}
Widget _buildButtonAddNewRule(BuildContext context) {
if (!responsiveUtils.isMobile(context)) {
return Row(
children: [
TMailButtonWidget(
key: const Key('new_rule_button'),
text: AppLocalizations.of(context).addNewRule,
icon: imagePaths.icAddNewRules,
borderRadius: 10,
backgroundColor: AppColor.colorTextButton,
iconColor: Colors.white,
minWidth: 130,
padding: const EdgeInsets.symmetric(vertical: 12,horizontal: 8),
iconSize: 20,
textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500,
),
onTapActionCallback: createRule,
),
const Spacer(),
],
);
} else {
return TMailButtonWidget(
key: const Key('new_rule_button'),
text: AppLocalizations.of(context).addNewRule,
icon: imagePaths.icAddNewRules,
borderRadius: 10,
backgroundColor: AppColor.colorTextButton,
iconColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
iconSize: 20,
textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith(
fontSize: 17,
color: Colors.white,
fontWeight: FontWeight.w500,
),
onTapActionCallback: createRule,
);
}
}
}
@@ -0,0 +1,81 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/manage_account/presentation/email_rules/widgets/add_rule_button_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class NoRulesWidget extends StatelessWidget {
final ImagePaths imagePaths;
final ResponsiveUtils responsiveUtils;
final OnAddRuleAction onAddRuleAction;
const NoRulesWidget({
super.key,
required this.imagePaths,
required this.responsiveUtils,
required this.onAddRuleAction,
});
@override
Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context);
final isMobile = responsiveUtils.isMobile(context);
return Expanded(
child: Container(
padding: EdgeInsetsDirectional.only(top: isMobile ? 48 : 32),
alignment: Alignment.topCenter,
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
imagePaths.icNoRules,
width: 98,
height: 98,
fit: BoxFit.fill,
),
const SizedBox(height: 12),
Text(
appLocalizations.noRulesConfigured,
style: ThemeUtils.textStyleInter600(),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
Text(
appLocalizations.messageExplanationNoRulesConfigured,
style: ThemeUtils.textStyleInter400.copyWith(
fontSize: 16,
height: 21.01 / 16,
letterSpacing: -0.15,
color: AppColor.gray424244.withValues(alpha: 0.64),
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
Container(
constraints: const BoxConstraints(minWidth: 230),
height: 48,
child: ConfirmDialogButton(
label: AppLocalizations.of(context).createMyFirstRule,
backgroundColor: Colors.white,
textColor: AppColor.primaryMain,
borderColor: AppColor.primaryMain,
icon: imagePaths.icAddIdentity,
onTapAction: onAddRuleAction,
),
)
],
),
),
),
);
}
}
@@ -144,7 +144,7 @@ class ManageAccountDashBoardView extends GetWidget<ManageAccountDashBoardControl
}
case AccountMenuItem.emailRules:
if (controller.isRuleFilterCapabilitySupported){
return EmailRulesView();
return const EmailRulesView();
} else {
return const SizedBox.shrink();
}
@@ -106,7 +106,7 @@ class SettingsView extends GetWidget<SettingsController> {
}
case AccountMenuItem.emailRules:
if (controller.manageAccountDashboardController.isRuleFilterCapabilitySupported) {
return EmailRulesView();
return const EmailRulesView();
} else {
return const SizedBox.shrink();
}
@@ -40,8 +40,6 @@ class SettingHeaderWidget extends StatelessWidget {
letterSpacing: -0.15,
color: AppColor.gray424244.withValues(alpha: 0.64),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
];