language change screen ui

This commit is contained in:
jayesh
2024-06-06 14:51:31 +05:30
parent 1f7f5755a0
commit 70ede0ce67
26 changed files with 501 additions and 11 deletions

View File

@@ -0,0 +1,7 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="path-1-inside-1_2028_2122" fill="white">
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 8.08789L13.4757 13.3593C12.6195 14.3307 11.4193 14.3307 10.5631 13.3593L6 8.08789"/>
</mask>
<path d="M19.1383 9.06481C19.6778 8.43617 19.6056 7.48917 18.9769 6.94964C18.3483 6.4101 17.4013 6.48233 16.8617 7.11097L19.1383 9.06481ZM13.4757 13.3593L14.601 14.3511C14.6054 14.3462 14.6097 14.3412 14.614 14.3362L13.4757 13.3593ZM10.5631 13.3593L9.42895 14.3411L9.43781 14.3511L10.5631 13.3593ZM7.13412 7.10617C6.59192 6.47981 5.64463 6.41158 5.01828 6.95378C4.39192 7.49597 4.32369 8.44326 4.86588 9.06961L7.13412 7.10617ZM16.8617 7.11097L12.3375 12.3824L14.614 14.3362L19.1383 9.06481L16.8617 7.11097ZM12.3504 12.3675C12.1561 12.5879 12.0314 12.5879 12.0194 12.5879C12.0075 12.5879 11.8827 12.5879 11.6884 12.3675L9.43781 14.3511C10.0997 15.1021 11.0032 15.5879 12.0194 15.5879C13.0357 15.5879 13.9391 15.1021 14.601 14.3511L12.3504 12.3675ZM11.6972 12.3776L7.13412 7.10617L4.86588 9.06961L9.42899 14.341L11.6972 12.3776Z" fill="#05391B" mask="url(#path-1-inside-1_2028_2122)"/>
<path d="M22.2416 8.60756C22.2406 8.62349 22.2401 8.63944 22.2401 8.6554V15.5204C22.2401 15.5363 22.2406 15.5523 22.2416 15.5682C22.319 16.7783 21.8584 17.977 20.945 18.8831C20.0301 19.7906 18.7409 20.3228 17.3734 20.3379H6.59176C3.68522 20.3379 1.75 18.1955 1.75 15.5204V8.6554C1.75 5.98031 3.68522 3.83789 6.59176 3.83789H17.3734C18.7409 3.85294 20.0301 4.3852 20.945 5.29268C21.8584 6.19874 22.319 7.39744 22.2416 8.60756Z" stroke="#05391B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.99033 4.87254C3.30665 4.34878 5.0495 2.44376 6.29322 2.50127C6.665 2.53208 6.99364 2.75699 7.26067 3.01784C7.87379 3.61656 9.62897 5.88101 9.72859 6.35753C9.97096 7.52621 8.57833 8.1999 9.00454 9.37783C10.0911 12.0366 11.9634 13.9088 14.6233 14.9943C15.8003 15.4205 16.474 14.0279 17.6428 14.2713C18.1183 14.3709 20.3839 16.126 20.9826 16.7391C21.2425 17.0051 21.4684 17.3347 21.4992 17.7065C21.5454 19.0159 19.5222 20.7833 19.1278 21.0092C18.1974 21.6747 16.9834 21.6634 15.5035 20.9753C11.3739 19.2572 4.77426 12.7822 3.02422 8.49669C2.35461 7.02505 2.30839 5.80297 2.99033 4.87254Z" stroke="#05391B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g opacity="0.6">
<rect x="7.5" y="4.5" width="7.5" height="13.5" fill="white"/>
<mask id="mask0_2028_5820" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="2" width="20" height="20">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 13C11.45 13 11 12.55 11 12V8C11 7.45 11.45 7 12 7C12.55 7 13 7.45 13 8V12C13 12.55 12.55 13 12 13ZM11 15V17H13V15H11Z" fill="black"/>
</mask>
<g mask="url(#mask0_2028_5820)">
<rect width="24" height="24" fill="#0172CB"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 674 B

View File

@@ -43,8 +43,13 @@ class RouteName {
static const String confirmPinScreen = 'confirmPinScreen';
//Forgot Password
static const String forgotPasswordPhoneVerificationScreen =
'forgotPasswordPhoneVerificationScreen';
static const String forgotPasswordScreen = 'forgotPasswordScreen';
//contact Admin
static const String contactAdminScreen = 'contactAdminScreen';
//language change
static const String languageChangeScreen = 'languageChangeScreen';
}

View File

@@ -7,9 +7,11 @@ import 'package:tanami_app/features/MainScreens/Academy/presentation/pages/acade
import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/portfolio_details_screen.dart';
import 'package:tanami_app/features/biometric/presentation/pages/biometric_screen.dart';
import 'package:tanami_app/features/contactAdmin/presentation/pages/contact_admin_screen.dart';
import 'package:tanami_app/features/countrySelection/presentation/pages/choose_country_screen.dart';
import 'package:tanami_app/features/forgotPassword/presentation/pages/restore_password_screen.dart';
import 'package:tanami_app/features/languageChange/presentation/pages/language_change_screen.dart';
import 'package:tanami_app/features/otpVerification/presentation/pages/otp_screen.dart';
import 'package:tanami_app/features/register/presentation/pages/register_screen.dart';
import 'package:tanami_app/features/register/presentation/pages/register_step_screen.dart';
@@ -152,6 +154,20 @@ final goRouter = GoRouter(
return const RestorePasswordScreen();
},
),
GoRoute(
name: RouteName.contactAdminScreen,
path: RouteName.contactAdminScreen,
builder: (context, state) {
return const ContactAdminScreen();
},
),
GoRoute(
name: RouteName.languageChangeScreen,
path: RouteName.languageChangeScreen,
builder: (context, state) {
return const LanguageChaneScreen();
},
),
],
),
// GoRoute(

View File

@@ -73,4 +73,11 @@ class AppColor {
//KYC Card Color
static const Color kycCardTextColor = Color(0xFF074A23);
static const Color kycCardBgColor = Color(0x7F074A23);
//Contact Admin Color
static const Color contactAdminIconColor = Color(0xFF05391B);
static const Color contactAdminBgColor = Color(0xFFE2EEE2);
//Language Color
static const Color languageTextColor = Color(0xFF015698);
}

View File

@@ -92,4 +92,14 @@ class AppImages {
'assets/images/settings_screen/svg/reset_pin_icon.svg';
static const String contactIcon =
'assets/images/settings_screen/svg/contact_icon.svg';
//Contact
static const String byPhoneIcon =
'assets/images/contact_admin_screen/svg/phone_icon.svg';
static const String byMailIcon =
'assets/images/contact_admin_screen/svg/mail_icon.svg';
//Language
static const String infoIcon =
'assets/images/language_screen/png/info_icon.png';
}

View File

@@ -151,4 +151,15 @@ class AppText {
static const String faqText = "FAQ";
static const String logoutText = "Log Out";
static const String deleteAccountText = "Delete account";
//Contact Admin
static const String byPhoneText = "By phone";
static const String byEmailText = "By-mail";
static const String weAreHereToHelp = "We are here to help!";
//Language Screen
static const String arabicText = "اللغة العربية";
static const String chooseTheLanguageText = "Choose the language";
static const String changingTheLanguageWillReloadApp =
"Changing the language will reload the application";
}

View File

@@ -0,0 +1,19 @@
import 'package:url_launcher/url_launcher.dart';
void launchPhone(String phoneNumber) async {
final url = 'tel:$phoneNumber';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
}
void launchEmail(String email) async {
final url = 'mailto:$email';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
}

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:gap/gap.dart';
import 'package:tanami_app/core/routes/route_name.dart';
import 'package:tanami_app/core/routes/routes.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';
@@ -37,7 +39,10 @@ class GeneralSettingsSection extends StatelessWidget {
],
),
const Gap(12),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {
goRouter.pushNamed(RouteName.languageChangeScreen);
},
icon: AppImages.languageIcon,
title: AppText.languageText,
trailing: AppText.englishText,

View File

@@ -37,13 +37,15 @@ class PrivacySettingsSection extends StatelessWidget {
],
),
const Gap(12),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {},
icon: AppImages.resetPasswordIcon,
title: AppText.resetPasswordText,
trailing: "",
),
const Gap(8),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {},
icon: AppImages.resetPinIcon,
title: AppText.resetPinCodeText,
trailing: "",

View File

@@ -8,12 +8,14 @@ class SettingsListItem extends StatelessWidget {
final String icon;
final String title;
final String trailing;
final Function() onTapFunc;
const SettingsListItem({
super.key,
required this.icon,
required this.title,
required this.trailing,
required this.onTapFunc,
});
@override
@@ -27,6 +29,7 @@ class SettingsListItem extends StatelessWidget {
color: AppColor.fillColor,
),
child: ListTile(
onTap: onTapFunc,
leading: SvgPicture.asset(icon),
title: Text(title,
style: GoogleFonts.dmSans(

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:tanami_app/core/routes/route_name.dart';
import 'package:tanami_app/core/routes/routes.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';
@@ -20,25 +22,31 @@ class SupportSettingsSection extends StatelessWidget {
clr: AppColor.hintTextColor,
),
const Gap(8),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {
goRouter.pushNamed(RouteName.contactAdminScreen);
},
icon: AppImages.contactIcon,
title: AppText.contactAdminText,
trailing: "",
),
const Gap(8),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {},
icon: AppImages.privacyIcon,
title: AppText.privacyPolicy,
trailing: "",
),
const Gap(8),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {},
icon: AppImages.privacyIcon,
title: AppText.termsAndCondition,
trailing: "",
),
const Gap(8),
const SettingsListItem(
SettingsListItem(
onTapFunc: () {},
icon: AppImages.faqIcon,
title: AppText.faqText,
trailing: "",

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:tanami_app/features/contactAdmin/presentation/widgets/bottom_section.dart';
import '../../../../core/styles/app_text.dart';
import '../../../../shared/components/appbar_widget.dart';
import '../widgets/top_section.dart';
class ContactAdminScreen extends StatelessWidget {
const ContactAdminScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const AppBarWidget(
height: 75,
titleTxt: AppText.contactAdminText,
),
body: ListView(
children: [
topSection(),
bottomSection(),
],
),
);
}
}

View File

@@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/core/utils/url_launcher/url_launcher.dart';
import '../../../../shared/components/text_widget.dart';
Widget bottomSection() {
return Padding(
padding: const EdgeInsets.all(22.0),
child: Column(
children: [
const Gap(50.0),
contactOption(
icon: AppImages.byPhoneIcon,
title: AppText.byPhoneText,
subtitle: '+973 12345678',
onTap: () {
launchPhone('+973 12345678');
},
),
const Gap(16.0),
contactOption(
icon: AppImages.byMailIcon,
title: AppText.byEmailText,
subtitle: 'info@tanamicapital.com',
onTap: () {
launchEmail('info@tanamicapital.com');
},
),
],
),
);
}
Widget contactOption({
required String icon,
required String title,
required String subtitle,
required VoidCallback onTap,
}) {
return GestureDetector(
onTap: onTap,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0),
decoration: BoxDecoration(
color: AppColor.contactAdminBgColor,
borderRadius: BorderRadius.circular(22.0),
),
child: Row(
children: [
SvgPicture.asset(
icon,
),
const Gap(16.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextWidget().text14W600(
title,
clr: AppColor.contactAdminIconColor,
),
TextWidget().text14W400(
subtitle,
clr: AppColor.contactAdminIconColor,
),
],
),
const Spacer(),
const Icon(
Icons.arrow_forward_ios,
color: AppColor.contactAdminIconColor,
),
],
),
),
);
}

View File

@@ -0,0 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:gap/gap.dart';
import '../../../../core/styles/app_color.dart';
import '../../../../core/styles/app_images.dart';
import '../../../../core/styles/app_text.dart';
import '../../../../shared/components/text_widget.dart';
Widget topSection() {
return Column(
children: [
const Gap(85),
Center(
child: SvgPicture.asset(
AppImages.weclomeLogo,
),
),
const Gap(24),
TextWidget().text17W700(
AppText.weAreHereToHelp,
clr: AppColor.textLabelColor,
),
const Gap(10),
],
);
}

View File

@@ -0,0 +1,33 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'choose_language_event.dart';
import 'choose_language_state.dart';
class ChooseLanguageBloc
extends Bloc<ChooseLanguageEvent, ChooseLanguageState> {
ChooseLanguageBloc() : super(ChooseLanguageInitial()) {
on<ChooseLanguageSelected>(_onRadioSelected);
on<ResetRadioSelection>(_onResetRadioSelection);
}
void _onRadioSelected(
ChooseLanguageSelected event, Emitter<ChooseLanguageState> emit) {
emit(ChooseLanguageSelectionChanged(event.selectedIndex));
}
void _onResetRadioSelection(
ResetRadioSelection event, Emitter<ChooseLanguageState> emit) {
emit(ChooseLanguageInitial());
}
void resetSelection() {
add(ResetRadioSelection());
}
int get selectedCountry {
if (state is ChooseLanguageSelectionChanged) {
return (state as ChooseLanguageSelectionChanged).selectedIndex;
}
return 0;
}
}

View File

@@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
abstract class ChooseLanguageEvent extends Equatable {
const ChooseLanguageEvent();
@override
List<Object> get props => [];
}
class ChooseLanguageSelected extends ChooseLanguageEvent {
final int selectedIndex;
const ChooseLanguageSelected([this.selectedIndex = 0]);
@override
List<Object> get props => [selectedIndex];
}
class ResetRadioSelection extends ChooseLanguageEvent {}

View File

@@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
abstract class ChooseLanguageState extends Equatable {
const ChooseLanguageState();
@override
List<Object> get props => [];
}
class ChooseLanguageInitial extends ChooseLanguageState {}
class ChooseLanguageSelectionChanged extends ChooseLanguageState {
final int selectedIndex;
const ChooseLanguageSelectionChanged(this.selectedIndex);
@override
List<Object> get props => [selectedIndex];
}

View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.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/appbar_widget.dart';
import 'package:tanami_app/shared/components/text_widget.dart';
import '../widgets/bottom_section.dart';
import '../widgets/language_change_list.dart';
class LanguageChangeLayout extends StatelessWidget {
const LanguageChangeLayout({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: bottomSection(),
appBar: const AppBarWidget(
height: 75,
titleTxt: AppText.languageText,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
const CountrySelectionList(),
const Gap(24),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
width: 24,
height: 24,
AppImages.infoIcon,
),
const Gap(8),
SizedBox(
width: 0.8.sw,
child: TextWidget().text12W500(
AppText.changingTheLanguageWillReloadApp,
clr: AppColor.languageTextColor,
),
)
],
)
],
),
),
);
}
}

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:tanami_app/features/languageChange/presentation/bloc/choose_language_bloc.dart';
import 'language_change_layout.dart';
class LanguageChaneScreen extends StatelessWidget {
const LanguageChaneScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
body: MultiBlocProvider(
// Define the providers for the OnboardingBloc and other blocs
providers: [
BlocProvider(
// Create an instance of the OnboardingBloc
create: (context) => ChooseLanguageBloc(),
),
],
child: const LanguageChangeLayout(),
),
);
}
}

View File

@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:gap/gap.dart';
import '../../../../core/routes/routes.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';
Widget bottomSection() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
width: 1.sw,
height: 56.h,
child: ButtonWidget().elevatedBtn(
txtClr: AppColor.plainWhite,
function: () {
goRouter.pop();
},
text: AppText.submitText,
clr: AppColor.primaryColor2,
),
),
ButtonWidget().textBtn(
function: () {
goRouter.pop();
},
text: TextWidget().text14W700(AppText.backText,
clr: AppColor.textLabelColor,
textDecoration: TextDecoration.underline)),
const Gap(20),
],
);
}

View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:tanami_app/core/styles/app_color.dart';
import 'package:tanami_app/core/styles/app_text.dart';
import 'package:tanami_app/shared/components/text_widget.dart';
import '../bloc/choose_language_bloc.dart';
import '../bloc/choose_language_event.dart';
import '../bloc/choose_language_state.dart';
class CountrySelectionList extends StatelessWidget {
const CountrySelectionList({super.key});
@override
Widget build(BuildContext context) {
final radioBloc = context.read<ChooseLanguageBloc>();
return BlocBuilder<ChooseLanguageBloc, ChooseLanguageState>(
builder: (context, state) {
int selectedIndex = 0;
if (state is ChooseLanguageSelectionChanged) {
selectedIndex = state.selectedIndex;
}
return Column(
children: List<Widget>.generate(languageList.length, (int index) {
return Row(
children: [
Radio<int>(
activeColor: AppColor.radioActiveColor,
value: index,
groupValue: selectedIndex,
onChanged: (int? value) {
if (value != null) {
radioBloc.add(ChooseLanguageSelected(value));
}
},
),
TextWidget().text14W500(languageList[index],
clr: AppColor.charcoalColor),
],
);
}),
);
},
);
}
}
List<String> languageList = [
AppText.englishText,
AppText.arabicText,
];

View File

@@ -1222,13 +1222,13 @@ packages:
source: hosted
version: "10.3.0"
url_launcher:
dependency: transitive
dependency: "direct main"
description:
name: url_launcher
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted
version: "6.2.6"
version: "6.3.0"
url_launcher_android:
dependency: transitive
description:

View File

@@ -78,6 +78,9 @@ dependencies:
sms_autofill: ^2.3.1
carousel_slider: ^4.2.1
#Url Launcher
url_launcher: ^6.3.0
dev_dependencies:
flutter_test:
sdk: flutter
@@ -109,6 +112,10 @@ flutter:
- assets/images/biometric_screen/svg/
- assets/images/dialog/
- assets/images/dialog/svg/
- assets/images/contact_admin_screen/
- assets/images/contact_admin_screen/svg/
- assets/images/settings_screen/
- assets/images/settings_screen/png/
- assets/images/settings_screen/svg/
- assets/images/language_screen/
- assets/images/language_screen/png/