From 1f7f5755a0dc6e469e578b2003a07851c3e95ad5 Mon Sep 17 00:00:00 2001 From: jayesh Date: Thu, 6 Jun 2024 12:30:53 +0530 Subject: [PATCH] settings screen ui --- .../settings_screen/svg/dragger_icon.svg | 18 ++++ lib/core/styles/app_color.dart | 1 + lib/core/styles/app_images.dart | 12 ++- lib/core/styles/app_text.dart | 1 + .../presentation/pages/settings_layout.dart | 24 ++++- .../widgets/general_settings_section.dart | 52 +++++++++ .../widgets/privacy_settings_section.dart | 58 ++++++++++ .../widgets/settings_bottom_section.dart | 43 ++++++++ .../widgets/settings_list_tile_item.dart | 51 +++++++++ .../widgets/support_settings_section.dart | 53 ++++++++++ .../components/bloc/toggle/toggle_bloc.dart | 16 +-- .../components/bloc/toggle/toggle_event.dart | 2 + .../components/bloc/toggle/toggle_state.dart | 5 - lib/shared/components/toggle_widget.dart | 100 +++++++++++++----- 14 files changed, 384 insertions(+), 52 deletions(-) create mode 100644 assets/images/settings_screen/svg/dragger_icon.svg create mode 100644 lib/features/MainScreens/Settings/presentation/widgets/general_settings_section.dart create mode 100644 lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart create mode 100644 lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart create mode 100644 lib/features/MainScreens/Settings/presentation/widgets/settings_list_tile_item.dart create mode 100644 lib/features/MainScreens/Settings/presentation/widgets/support_settings_section.dart diff --git a/assets/images/settings_screen/svg/dragger_icon.svg b/assets/images/settings_screen/svg/dragger_icon.svg new file mode 100644 index 0000000..a05bb9d --- /dev/null +++ b/assets/images/settings_screen/svg/dragger_icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/lib/core/styles/app_color.dart b/lib/core/styles/app_color.dart index 77111b6..b0f4a31 100644 --- a/lib/core/styles/app_color.dart +++ b/lib/core/styles/app_color.dart @@ -36,6 +36,7 @@ class AppColor { //Radio Color static const Color radioActiveColor = Color(0xFF0B8933); + static const Color shadowColor = Colors.black26; //Otp Color static const Color strokeColor = Color(0xFFB4B4B4); diff --git a/lib/core/styles/app_images.dart b/lib/core/styles/app_images.dart index eb94337..51f1f1e 100644 --- a/lib/core/styles/app_images.dart +++ b/lib/core/styles/app_images.dart @@ -81,13 +81,15 @@ class AppImages { static const String upgradeIcon = 'assets/images/settings_screen/svg/upgrade_icon.svg'; static const String faqIcon = - 'assets/images/settings_screen/svg/upgrade_icon.svg'; + 'assets/images/settings_screen/svg/faq_icon.svg'; static const String languageIcon = - 'assets/images/settings_screen/svg/upgrade_icon.svg'; + 'assets/images/settings_screen/svg/language_icon.svg'; static const String privacyIcon = - 'assets/images/settings_screen/svg/upgrade_icon.svg'; + 'assets/images/settings_screen/svg/privacy_icon.svg'; static const String resetPasswordIcon = - 'assets/images/settings_screen/svg/upgrade_icon.svg'; + 'assets/images/settings_screen/svg/reset_password_icon.svg'; static const String resetPinIcon = - 'assets/images/settings_screen/svg/upgrade_icon.svg'; + 'assets/images/settings_screen/svg/reset_pin_icon.svg'; + static const String contactIcon = + 'assets/images/settings_screen/svg/contact_icon.svg'; } diff --git a/lib/core/styles/app_text.dart b/lib/core/styles/app_text.dart index 7702c29..da589a1 100644 --- a/lib/core/styles/app_text.dart +++ b/lib/core/styles/app_text.dart @@ -144,6 +144,7 @@ class AppText { static const String biometricText = "Biometric ID"; static const String resetPasswordText = "Reset Password"; static const String resetPinCodeText = "Reset PIN-code"; + static const String supportText = "Support"; static const String contactAdminText = "Contact Admin"; static const String privacyPolicyText = "Privacy Policy"; static const String termsAndConditionText = "Terms & Conditions"; diff --git a/lib/features/MainScreens/Settings/presentation/pages/settings_layout.dart b/lib/features/MainScreens/Settings/presentation/pages/settings_layout.dart index 9f4f429..e2015b6 100644 --- a/lib/features/MainScreens/Settings/presentation/pages/settings_layout.dart +++ b/lib/features/MainScreens/Settings/presentation/pages/settings_layout.dart @@ -1,7 +1,11 @@ import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; +import 'package:tanami_app/features/MainScreens/Settings/presentation/widgets/support_settings_section.dart'; +import '../widgets/general_settings_section.dart'; import '../widgets/kyc_card.dart'; +import '../widgets/privacy_settings_section.dart'; +import '../widgets/settings_bottom_section.dart'; class SettingsLayout extends StatelessWidget { const SettingsLayout({super.key}); @@ -12,12 +16,22 @@ class SettingsLayout extends StatelessWidget { body: Padding( padding: const EdgeInsets.symmetric( horizontal: 16, + vertical: 10, ), - child: ListView( - children: [ - const Gap(10), - kycCard(), - ], + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + kycCard(), + const Gap(15), + const GeneralSettingsSection(), + const Gap(15), + const PrivacySettingsSection(), + const Gap(15), + const SupportSettingsSection(), + const SettingsBottomSection(), + ], + ), ), ), ); diff --git a/lib/features/MainScreens/Settings/presentation/widgets/general_settings_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/general_settings_section.dart new file mode 100644 index 0000000..5c6bb61 --- /dev/null +++ b/lib/features/MainScreens/Settings/presentation/widgets/general_settings_section.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_images.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; +import 'package:tanami_app/shared/components/bloc/toggle/toggle_bloc.dart'; +import 'package:tanami_app/shared/components/text_widget.dart'; + +import '../../../../../shared/components/toggle_widget.dart'; +import 'settings_list_tile_item.dart'; + +class GeneralSettingsSection extends StatelessWidget { + const GeneralSettingsSection({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextWidget().text14W600( + AppText.generalText, + clr: AppColor.hintTextColor, + ), + const Gap(5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextWidget().text14W600( + AppText.notificationText, + clr: AppColor.textLabelColor, + ), + BlocProvider( + create: (_) => ToggleBloc(), + child: const CustomToggle(), + ) + ], + ), + const Gap(12), + const SettingsListItem( + icon: AppImages.languageIcon, + title: AppText.languageText, + trailing: AppText.englishText, + ), + const Gap(10), + const Divider( + color: AppColor.academyCardTextColor, + ), + ], + ); + } +} diff --git a/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart new file mode 100644 index 0000000..91a64bf --- /dev/null +++ b/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_images.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; +import 'package:tanami_app/shared/components/bloc/toggle/toggle_bloc.dart'; +import 'package:tanami_app/shared/components/text_widget.dart'; + +import '../../../../../shared/components/toggle_widget.dart'; +import 'settings_list_tile_item.dart'; + +class PrivacySettingsSection extends StatelessWidget { + const PrivacySettingsSection({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextWidget().text14W600( + AppText.privacySettingsText, + clr: AppColor.hintTextColor, + ), + const Gap(5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextWidget().text14W600( + AppText.biometricText, + clr: AppColor.textLabelColor, + ), + BlocProvider( + create: (_) => ToggleBloc(), + child: const CustomToggle(), + ) + ], + ), + const Gap(12), + const SettingsListItem( + icon: AppImages.resetPasswordIcon, + title: AppText.resetPasswordText, + trailing: "", + ), + const Gap(8), + const SettingsListItem( + icon: AppImages.resetPinIcon, + title: AppText.resetPinCodeText, + trailing: "", + ), + const Gap(10), + const Divider( + color: AppColor.academyCardTextColor, + ), + ], + ); + } +} diff --git a/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart new file mode 100644 index 0000000..869f8e0 --- /dev/null +++ b/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gap/gap.dart'; + +import '../../../../../core/styles/app_color.dart'; +import '../../../../../core/styles/app_text.dart'; +import '../../../../../shared/components/button_widget.dart'; +import '../../../../../shared/components/text_widget.dart'; + +class SettingsBottomSection extends StatelessWidget { + const SettingsBottomSection({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + const Gap(36), + Container( + margin: const EdgeInsets.symmetric( + horizontal: 16, + ), + width: 1.sw, + height: 56.h, + child: ButtonWidget().elevatedBtn( + txtClr: AppColor.plainWhite, + function: () {}, + text: AppText.logoutText, + clr: AppColor.primaryColor2, + ), + ), + const Gap(5), + ButtonWidget().textBtn( + function: () {}, + text: TextWidget().text14W700( + AppText.deleteAccountText, + clr: AppColor.hintTextColor, + textDecoration: TextDecoration.underline, + )), + ], + ); + } +} diff --git a/lib/features/MainScreens/Settings/presentation/widgets/settings_list_tile_item.dart b/lib/features/MainScreens/Settings/presentation/widgets/settings_list_tile_item.dart new file mode 100644 index 0000000..78b39e0 --- /dev/null +++ b/lib/features/MainScreens/Settings/presentation/widgets/settings_list_tile_item.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:gap/gap.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; + +class SettingsListItem extends StatelessWidget { + final String icon; + final String title; + final String trailing; + + const SettingsListItem({ + super.key, + required this.icon, + required this.title, + required this.trailing, + }); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric( + vertical: 8.0, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(22.0), + color: AppColor.fillColor, + ), + child: ListTile( + leading: SvgPicture.asset(icon), + title: Text(title, + style: GoogleFonts.dmSans( + fontSize: 14, + fontWeight: FontWeight.w600, + color: AppColor.textLabelColor)), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(trailing, + style: GoogleFonts.dmSans( + fontSize: 15, + fontWeight: FontWeight.w500, + color: AppColor.plainBlack)), + const Gap(10), + const Icon(Icons.arrow_forward_ios, size: 16.0), + ], + ), + ), + ); + } +} diff --git a/lib/features/MainScreens/Settings/presentation/widgets/support_settings_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/support_settings_section.dart new file mode 100644 index 0000000..7e57a50 --- /dev/null +++ b/lib/features/MainScreens/Settings/presentation/widgets/support_settings_section.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_images.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; +import 'package:tanami_app/shared/components/text_widget.dart'; + +import 'settings_list_tile_item.dart'; + +class SupportSettingsSection extends StatelessWidget { + const SupportSettingsSection({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextWidget().text14W600( + AppText.supportText, + clr: AppColor.hintTextColor, + ), + const Gap(8), + const SettingsListItem( + icon: AppImages.contactIcon, + title: AppText.contactAdminText, + trailing: "", + ), + const Gap(8), + const SettingsListItem( + icon: AppImages.privacyIcon, + title: AppText.privacyPolicy, + trailing: "", + ), + const Gap(8), + const SettingsListItem( + icon: AppImages.privacyIcon, + title: AppText.termsAndCondition, + trailing: "", + ), + const Gap(8), + const SettingsListItem( + icon: AppImages.faqIcon, + title: AppText.faqText, + trailing: "", + ), + const Gap(10), + const Divider( + color: AppColor.academyCardTextColor, + ), + ], + ); + } +} diff --git a/lib/shared/components/bloc/toggle/toggle_bloc.dart b/lib/shared/components/bloc/toggle/toggle_bloc.dart index c7b0342..7ee8346 100644 --- a/lib/shared/components/bloc/toggle/toggle_bloc.dart +++ b/lib/shared/components/bloc/toggle/toggle_bloc.dart @@ -5,15 +5,15 @@ import 'toggle_event.dart'; import 'toggle_state.dart'; class ToggleBloc extends Bloc { - ToggleBloc() : super(ToggleInitial()); + ToggleBloc() : super(ToggleInitial()) { + on(_onToggleSwitch); + } - Stream mapEventToState(ToggleEvent event) async* { - if (event is ToggleSwitch) { - if (state is ToggleOn) { - yield ToggleOff(); - } else { - yield ToggleOn(); - } + void _onToggleSwitch(ToggleSwitch event, Emitter emit) { + if (state is ToggleOn) { + emit(ToggleOff()); + } else { + emit(ToggleOn()); } } } diff --git a/lib/shared/components/bloc/toggle/toggle_event.dart b/lib/shared/components/bloc/toggle/toggle_event.dart index 375f8ab..5b4309d 100644 --- a/lib/shared/components/bloc/toggle/toggle_event.dart +++ b/lib/shared/components/bloc/toggle/toggle_event.dart @@ -7,3 +7,5 @@ abstract class ToggleEvent extends Equatable { @override List get props => []; } + +class ToggleSwitch extends ToggleEvent {} diff --git a/lib/shared/components/bloc/toggle/toggle_state.dart b/lib/shared/components/bloc/toggle/toggle_state.dart index 15b5e76..d9d7619 100644 --- a/lib/shared/components/bloc/toggle/toggle_state.dart +++ b/lib/shared/components/bloc/toggle/toggle_state.dart @@ -1,10 +1,5 @@ import 'package:equatable/equatable.dart'; -import 'toggle_event.dart'; - -class ToggleSwitch extends ToggleEvent {} - -// States abstract class ToggleState extends Equatable { const ToggleState(); diff --git a/lib/shared/components/toggle_widget.dart b/lib/shared/components/toggle_widget.dart index 6082f6f..7eeda45 100644 --- a/lib/shared/components/toggle_widget.dart +++ b/lib/shared/components/toggle_widget.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; import 'bloc/toggle/toggle_bloc.dart'; +import 'bloc/toggle/toggle_event.dart'; import 'bloc/toggle/toggle_state.dart'; class CustomToggle extends StatelessWidget { @@ -17,36 +19,76 @@ class CustomToggle extends StatelessWidget { onTap: () { context.read().add(ToggleSwitch()); }, - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - width: 50.0, - height: 30.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15.0), - color: isOn ? Colors.green : Colors.grey, - ), - child: Stack( - children: [ - AnimatedPositioned( - duration: const Duration(milliseconds: 200), - curve: Curves.easeIn, - left: isOn ? 20.0 : 0.0, - right: isOn ? 0.0 : 20.0, - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - transitionBuilder: - (Widget child, Animation animation) { - return ScaleTransition(scale: animation, child: child); - }, - child: isOn - ? Icon(Icons.check_circle, - color: Colors.white, size: 30.0, key: UniqueKey()) - : Icon(Icons.remove_circle_outline, - color: Colors.white, size: 30.0, key: UniqueKey()), - ), + child: Stack( + children: [ + AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 60.0, + height: 30.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15.0), + color: isOn + ? AppColor.selectedItemColor + : AppColor.darkGreyColor, ), - ], - ), + ), + AnimatedPositioned( + duration: const Duration(milliseconds: 200), + curve: Curves.easeIn, + left: isOn ? 30.0 : 0.0, + right: isOn ? 0.0 : 30.0, + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 200), + transitionBuilder: + (Widget child, Animation animation) { + return ScaleTransition(scale: animation, child: child); + }, + child: isOn + ? Container( + decoration: const BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: AppColor.shadowColor, + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: CircleAvatar( + backgroundColor: AppColor.plainWhite, + radius: 15, + child: Icon(Icons.circle, + color: AppColor.radioActiveColor, + size: 12.0, + key: UniqueKey()), + ), + ) + : Container( + decoration: const BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: AppColor.shadowColor, + spreadRadius: 1, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: CircleAvatar( + backgroundColor: AppColor.plainWhite, + radius: 15, + child: Icon(Icons.remove, + color: AppColor.darkGreyColor, + size: 20.0, + key: UniqueKey()), + ), + ), + ), + ), + ], ), ); },