Merge pull request #21 from WDI-Ideas/jayeshjain25

settings screen ui
This commit is contained in:
Jayesh jain
2024-06-06 12:31:12 +05:30
committed by GitHub
14 changed files with 384 additions and 52 deletions

View File

@@ -0,0 +1,18 @@
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_2021_3980)">
<circle cx="19" cy="17" r="15" fill="white"/>
<circle cx="19" cy="17" r="15.25" stroke="#07405C" stroke-opacity="0.1" stroke-width="0.5"/>
</g>
<circle cx="19" cy="17" r="5" fill="#0B8933"/>
<defs>
<filter id="filter0_d_2021_3980" x="0.5" y="0.5" width="37" height="37" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.027451 0 0 0 0 0.25098 0 0 0 0 0.360784 0 0 0 0.16 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_2021_3980"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_2021_3980" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1011 B

View File

@@ -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);

View File

@@ -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';
}

View File

@@ -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";

View File

@@ -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(),
],
),
),
),
);

View File

@@ -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,
),
],
);
}
}

View File

@@ -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,
),
],
);
}
}

View File

@@ -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,
)),
],
);
}
}

View File

@@ -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),
],
),
),
);
}
}

View File

@@ -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,
),
],
);
}
}

View File

@@ -5,15 +5,15 @@ import 'toggle_event.dart';
import 'toggle_state.dart';
class ToggleBloc extends Bloc<ToggleEvent, ToggleState> {
ToggleBloc() : super(ToggleInitial());
ToggleBloc() : super(ToggleInitial()) {
on<ToggleSwitch>(_onToggleSwitch);
}
Stream<ToggleState> mapEventToState(ToggleEvent event) async* {
if (event is ToggleSwitch) {
if (state is ToggleOn) {
yield ToggleOff();
} else {
yield ToggleOn();
}
void _onToggleSwitch(ToggleSwitch event, Emitter<ToggleState> emit) {
if (state is ToggleOn) {
emit(ToggleOff());
} else {
emit(ToggleOn());
}
}
}

View File

@@ -7,3 +7,5 @@ abstract class ToggleEvent extends Equatable {
@override
List<Object> get props => [];
}
class ToggleSwitch extends ToggleEvent {}

View File

@@ -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();

View File

@@ -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<ToggleBloc>().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<double> 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<double> 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()),
),
),
),
),
],
),
);
},