login screen, choose country screen
This commit is contained in:
BIN
assets/images/country_flag/png/bahrain_flag.png
Normal file
BIN
assets/images/country_flag/png/bahrain_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/country_flag/png/kuwait_flag.png
Normal file
BIN
assets/images/country_flag/png/kuwait_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 854 B |
BIN
assets/images/country_flag/png/oman_flag.png
Normal file
BIN
assets/images/country_flag/png/oman_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 959 B |
BIN
assets/images/country_flag/png/qatar_flag.png
Normal file
BIN
assets/images/country_flag/png/qatar_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/country_flag/png/saudi_arabia_flag.png
Normal file
BIN
assets/images/country_flag/png/saudi_arabia_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/country_flag/png/uae_flag.png
Normal file
BIN
assets/images/country_flag/png/uae_flag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 678 B |
@@ -14,4 +14,7 @@ class RouteName {
|
||||
|
||||
//Welcome
|
||||
static const String welcomeScreen = 'welcome';
|
||||
|
||||
//choose country
|
||||
static const String chooseCountryScreen = 'chooseCountryScreen';
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:tanami_app/core/routes/route_name.dart';
|
||||
import 'package:tanami_app/features/countrySelection/presentation/pages/choose_country_screen.dart';
|
||||
import 'package:tanami_app/features/welcome/presentation/pages/weclome_screen.dart';
|
||||
|
||||
import '../../features/login/presentation/pages/login_screen.dart';
|
||||
@@ -43,6 +44,13 @@ final goRouter = GoRouter(
|
||||
return const WelcomeScreen();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: RouteName.chooseCountryScreen,
|
||||
path: RouteName.chooseCountryScreen,
|
||||
builder: (context, state) {
|
||||
return const ChooseCountryScreen();
|
||||
},
|
||||
),
|
||||
]),
|
||||
|
||||
// GoRoute(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
class AppColor {
|
||||
//Primary Color
|
||||
static const Color primaryColor = Color(0xFF002F0F);
|
||||
static const Color primaryColor2 = Color(0xFF004717);
|
||||
|
||||
//Welcome Color
|
||||
static const Color indicatorActiveColor = Color(0xFF002F0F);
|
||||
@@ -11,6 +12,7 @@ class AppColor {
|
||||
//Common Color
|
||||
static const Color plainWhite = Color(0xFFFFFFFF);
|
||||
static const Color darkGreyColor = Color(0xFF343434);
|
||||
static const Color plainBlack = Color(0xFF000000);
|
||||
|
||||
//Auth Color
|
||||
static const Color charcoalColor = Color(0xFF272727);
|
||||
@@ -28,4 +30,10 @@ class AppColor {
|
||||
//Button Color
|
||||
static const Color inactiveBtnColor = Color(0xFFD8D8D8);
|
||||
static const Color inactiveBtnTxtColor = Color(0xFF8D8D8D);
|
||||
|
||||
//AppBar Color
|
||||
static const Color appBarIconColor = Color(0xFF363636);
|
||||
|
||||
//Radio Color
|
||||
static const Color radioActiveColor = Color(0xFF0B8933);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ class AppImages {
|
||||
|
||||
//Country Flag
|
||||
static const String bahrainFlag =
|
||||
"assets/images/country_flag/svg/bahrain_flag.svg";
|
||||
"assets/images/country_flag/png/bahrain_flag.png";
|
||||
static const String kuwaitFlag =
|
||||
"assets/images/auth_screen/svg/kuwait_flag.svg";
|
||||
static const String omanFlag = "assets/images/auth_screen/svg/oman_flag.svg";
|
||||
"assets/images/country_flag/png/kuwait_flag.png";
|
||||
static const String omanFlag = "assets/images/country_flag/png/oman_flag.png";
|
||||
static const String qatarFlag =
|
||||
"assets/images/country_flag/svg/qatar_flag.svg";
|
||||
"assets/images/country_flag/png/qatar_flag.png";
|
||||
static const String saudiArabiaflag =
|
||||
"assets/images/auth_screen/svg/saudi_arabia_flag.svg";
|
||||
"assets/images/country_flag/png/saudi_arabia_flag.png";
|
||||
static const String unitedArabEmiratesFlag =
|
||||
"assets/images/auth_screen/svg/united_arab_emirates_flag.svg";
|
||||
"assets/images/country_flag/png/uae_flag.png";
|
||||
}
|
||||
|
||||
@@ -28,4 +28,14 @@ class AppText {
|
||||
static const String enterPhoneNo = "Enter phone number";
|
||||
static const String invalidPassword = "Invalid Password";
|
||||
static const String forgorPassword = "Forgot Password";
|
||||
|
||||
//Country Name
|
||||
static const String bahrainCountryText = "Bahrain";
|
||||
static const String kuwaitCountryText = "Kuwait";
|
||||
static const String omanCountryText = "Oman";
|
||||
static const String qatarCountryText = "Qatar";
|
||||
static const String saudiArabiaCountryText = "Saudi Arabia";
|
||||
static const String uaeCountryText = "United Arab Emirates";
|
||||
|
||||
static const String confirmSelectionText = "Confirm selection";
|
||||
}
|
||||
|
||||
20
lib/core/utils/constant/country_flag_data.dart
Normal file
20
lib/core/utils/constant/country_flag_data.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:tanami_app/core/styles/app_images.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
|
||||
List<String> countryName = [
|
||||
AppText.bahrainCountryText,
|
||||
AppText.kuwaitCountryText,
|
||||
AppText.omanCountryText,
|
||||
AppText.qatarCountryText,
|
||||
AppText.saudiArabiaCountryText,
|
||||
AppText.uaeCountryText,
|
||||
];
|
||||
|
||||
List<String> countryFlag = [
|
||||
AppImages.bahrainFlag,
|
||||
AppImages.kuwaitFlag,
|
||||
AppImages.omanFlag,
|
||||
AppImages.qatarFlag,
|
||||
AppImages.saudiArabiaflag,
|
||||
AppImages.unitedArabEmiratesFlag,
|
||||
];
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import 'choose_country_event.dart';
|
||||
import 'choose_country_state.dart';
|
||||
|
||||
class RadioBloc extends Bloc<RadioEvent, RadioState> {
|
||||
RadioBloc() : super(RadioInitial()) {
|
||||
on<RadioSelected>(_onRadioSelected);
|
||||
}
|
||||
|
||||
void _onRadioSelected(RadioSelected event, Emitter<RadioState> emit) {
|
||||
emit(RadioSelectionChanged(event.selectedIndex));
|
||||
}
|
||||
|
||||
int get selectedCountry {
|
||||
if (state is RadioSelectionChanged) {
|
||||
return (state as RadioSelectionChanged).selectedIndex;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class RadioEvent extends Equatable {
|
||||
const RadioEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RadioSelected extends RadioEvent {
|
||||
final int selectedIndex;
|
||||
|
||||
const RadioSelected(this.selectedIndex);
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedIndex];
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
abstract class RadioState extends Equatable {
|
||||
const RadioState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class RadioInitial extends RadioState {}
|
||||
|
||||
class RadioSelectionChanged extends RadioState {
|
||||
final int selectedIndex;
|
||||
|
||||
const RadioSelectionChanged(this.selectedIndex);
|
||||
|
||||
@override
|
||||
List<Object> get props => [selectedIndex];
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:tanami_app/core/routes/routes.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
import 'package:tanami_app/shared/components/appbar_widget.dart';
|
||||
|
||||
import '../../../../core/styles/app_color.dart';
|
||||
import '../../../../shared/components/button_widget.dart';
|
||||
import '../widgets/country_selection_list.dart';
|
||||
|
||||
class ChooseCountryLayout extends StatelessWidget {
|
||||
const ChooseCountryLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
bottomNavigationBar: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 35,
|
||||
),
|
||||
width: 1.sw,
|
||||
height: 56.h,
|
||||
child: ButtonWidget().elevatedBtn(
|
||||
txtClr: AppColor.plainWhite,
|
||||
function: () {
|
||||
// radioBloc.add(const BackPressed(true));
|
||||
goRouter.pop();
|
||||
},
|
||||
text: AppText.confirmSelectionText,
|
||||
clr: AppColor.primaryColor2,
|
||||
),
|
||||
),
|
||||
appBar: const AppBarWidget(
|
||||
height: 75,
|
||||
titleTxt: AppText.chooseCountry,
|
||||
),
|
||||
body: const CountrySelectionList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'choose_country_layout.dart';
|
||||
|
||||
class ChooseCountryScreen extends StatelessWidget {
|
||||
const ChooseCountryScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: ChooseCountryLayout(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
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/utils/constant/country_flag_data.dart';
|
||||
import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
|
||||
import '../bloc/choose_country_bloc.dart';
|
||||
import '../bloc/choose_country_event.dart';
|
||||
import '../bloc/choose_country_state.dart';
|
||||
|
||||
class CountrySelectionList extends StatelessWidget {
|
||||
const CountrySelectionList({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final radioBloc = context.read<RadioBloc>();
|
||||
return BlocBuilder<RadioBloc, RadioState>(
|
||||
builder: (context, state) {
|
||||
int selectedIndex = 0;
|
||||
if (state is RadioSelectionChanged) {
|
||||
selectedIndex = state.selectedIndex;
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: List<Widget>.generate(countryFlag.length, (int index) {
|
||||
return ListTile(
|
||||
title: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
countryFlag[index],
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
const Gap(10),
|
||||
TextWidget().tex14W500(countryName[index],
|
||||
clr: AppColor.charcoalColor),
|
||||
],
|
||||
),
|
||||
leading: Radio<int>(
|
||||
activeColor: AppColor.radioActiveColor,
|
||||
value: index,
|
||||
groupValue: selectedIndex,
|
||||
onChanged: (int? value) {
|
||||
if (value != null) {
|
||||
radioBloc.add(RadioSelected(value));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'login_event.dart';
|
||||
@@ -20,6 +18,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||
phoneNumberTextField.addListener(_onFormFieldChanged);
|
||||
passwordTextField.addListener(_onFormFieldChanged);
|
||||
countrySelectionTextField.addListener(_onFormFieldChanged);
|
||||
on<LoginFormChanged>(_onLoginFormChanged);
|
||||
on<LoginSubmitted>((event, emit) async {
|
||||
if (!formKey.currentState!.validate()) {
|
||||
return;
|
||||
@@ -43,19 +42,18 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||
});
|
||||
}
|
||||
void _onFormFieldChanged() {
|
||||
add(LoginFormChanged());
|
||||
add(LoginFormChanged(
|
||||
phoneNumberTextField.text,
|
||||
passwordTextField.text,
|
||||
countrySelectionTextField.text,
|
||||
));
|
||||
}
|
||||
|
||||
bool areFieldsFilled() {
|
||||
return phoneNumberTextField.text.isNotEmpty &&
|
||||
passwordTextField.text.isNotEmpty &&
|
||||
countrySelectionTextField.text.isNotEmpty;
|
||||
}
|
||||
|
||||
Stream<LoginState> mapEventToState(LoginEvent event) async* {
|
||||
if (event is LoginFormChanged) {
|
||||
yield LoginFieldsState(areFieldsFilled());
|
||||
}
|
||||
void _onLoginFormChanged(LoginFormChanged event, Emitter<LoginState> emit) {
|
||||
final areFieldsFilled = event.phoneNumber.isNotEmpty &&
|
||||
event.password.isNotEmpty &&
|
||||
event.country.isNotEmpty;
|
||||
emit(LoginFieldsState(areFieldsFilled));
|
||||
}
|
||||
|
||||
// Mock API function, replace with actual API call
|
||||
@@ -71,6 +69,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> {
|
||||
Future<void> close() {
|
||||
phoneNumberTextField.dispose();
|
||||
passwordTextField.dispose();
|
||||
countrySelectionTextField.dispose();
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,13 @@ class LoginSubmitted extends LoginEvent {
|
||||
List<Object> get props => [phoneNumber, password, countryResidence];
|
||||
}
|
||||
|
||||
class LoginFormChanged extends LoginEvent {}
|
||||
class LoginFormChanged extends LoginEvent {
|
||||
final String phoneNumber;
|
||||
final String password;
|
||||
final String country;
|
||||
|
||||
const LoginFormChanged(this.phoneNumber, this.password, this.country);
|
||||
|
||||
@override
|
||||
List<Object> get props => [phoneNumber, password, country];
|
||||
}
|
||||
|
||||
@@ -26,4 +26,7 @@ class LoginFieldsState extends LoginState {
|
||||
final bool areFieldsFilled;
|
||||
|
||||
const LoginFieldsState(this.areFieldsFilled);
|
||||
|
||||
@override
|
||||
List<Object> get props => [areFieldsFilled];
|
||||
}
|
||||
|
||||
@@ -5,17 +5,17 @@ import '../widgets/bottom_section.dart';
|
||||
import '../widgets/top_section.dart';
|
||||
|
||||
class LoginLayout extends StatelessWidget {
|
||||
LoginLayout({super.key});
|
||||
const LoginLayout({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ListView(
|
||||
//
|
||||
children: [
|
||||
const TopSection(),
|
||||
children: const [
|
||||
TopSection(),
|
||||
LoginForm(),
|
||||
const BottomSection(),
|
||||
BottomSection(),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ class LoginScreen extends StatelessWidget {
|
||||
),
|
||||
BlocProvider(
|
||||
create: (context) => PasswordVisibilityBloc(),
|
||||
)
|
||||
),
|
||||
],
|
||||
child: LoginLayout(),
|
||||
child: const LoginLayout(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ class BottomSection extends StatelessWidget {
|
||||
bool isButtonEnabled = false;
|
||||
if (state is LoginFieldsState) {
|
||||
isButtonEnabled = state.areFieldsFilled;
|
||||
} else if (state is LoginSuccess || state is LoginFailure) {
|
||||
isButtonEnabled = true;
|
||||
}
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
@@ -61,7 +63,9 @@ class BottomSection extends StatelessWidget {
|
||||
width: 1.sw,
|
||||
height: 56.h,
|
||||
child: ButtonWidget().elevatedBtn(
|
||||
txtClr: AppColor.inactiveBtnTxtColor,
|
||||
txtClr: isButtonEnabled
|
||||
? AppColor.plainWhite
|
||||
: AppColor.inactiveBtnTxtColor,
|
||||
function: () {
|
||||
isButtonEnabled
|
||||
? context.read<LoginBloc>().add(
|
||||
@@ -80,7 +84,7 @@ class BottomSection extends StatelessWidget {
|
||||
},
|
||||
text: AppText.loginText,
|
||||
clr: isButtonEnabled
|
||||
? AppColor.primaryColor
|
||||
? AppColor.primaryColor2
|
||||
: AppColor.inactiveBtnColor,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -2,52 +2,82 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:tanami_app/core/styles/app_text.dart';
|
||||
import 'package:tanami_app/core/utils/constant/country_flag_data.dart';
|
||||
|
||||
import '../../../../shared/components/form_label_textfield.dart';
|
||||
import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart';
|
||||
import '../../../countrySelection/presentation/bloc/choose_country_state.dart';
|
||||
import '../bloc/login_bloc.dart';
|
||||
|
||||
class LoginForm extends StatelessWidget {
|
||||
LoginForm({super.key});
|
||||
const LoginForm({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final loginBloc = context.read<LoginBloc>();
|
||||
return Form(
|
||||
key: loginBloc.formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 14,
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(50),
|
||||
FormLabelTextField(
|
||||
hintText: AppText.chooseCountry,
|
||||
title: AppText.countryOfResidence,
|
||||
type: "country selection",
|
||||
textEditingController: loginBloc.countrySelectionTextField,
|
||||
),
|
||||
const Gap(20),
|
||||
FormLabelTextField(
|
||||
hintText: "+0 (000) 000 00 00",
|
||||
title: AppText.phoneNumber,
|
||||
type: "phone number",
|
||||
textEditingController: loginBloc.phoneNumberTextField,
|
||||
),
|
||||
const Gap(20),
|
||||
FormLabelTextField(
|
||||
hintText: AppText.enterPassword,
|
||||
title: AppText.password,
|
||||
type: "password",
|
||||
textEditingController: loginBloc.passwordTextField,
|
||||
),
|
||||
],
|
||||
|
||||
return BlocConsumer<RadioBloc, RadioState>(listener: (context, state) {
|
||||
int selectedCountry = -1;
|
||||
if (state is RadioSelectionChanged) {
|
||||
selectedCountry = state.selectedIndex;
|
||||
loginBloc.countrySelectionTextField.text = countryName[selectedCountry];
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
int selectedCountry = -1;
|
||||
if (state is RadioSelectionChanged) {
|
||||
selectedCountry = state.selectedIndex;
|
||||
}
|
||||
return Form(
|
||||
key: loginBloc.formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 14,
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Gap(50),
|
||||
FormLabelTextField(
|
||||
prefixWidget: selectedCountry == -1
|
||||
? null
|
||||
: Image.asset(
|
||||
countryFlag[selectedCountry],
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
hintText: AppText.chooseCountry,
|
||||
title: AppText.countryOfResidence,
|
||||
type: "country selection",
|
||||
textEditingController: loginBloc.countrySelectionTextField,
|
||||
),
|
||||
const Gap(20),
|
||||
FormLabelTextField(
|
||||
prefixWidget: selectedCountry == -1
|
||||
? null
|
||||
: Image.asset(
|
||||
countryFlag[selectedCountry],
|
||||
width: 20,
|
||||
height: 20,
|
||||
),
|
||||
hintText: "+0 (000) 000 00 00",
|
||||
title: AppText.phoneNumber,
|
||||
type: "phone number",
|
||||
textEditingController: loginBloc.phoneNumberTextField,
|
||||
),
|
||||
const Gap(20),
|
||||
FormLabelTextField(
|
||||
hintText: AppText.enterPassword,
|
||||
title: AppText.password,
|
||||
type: "password",
|
||||
textEditingController: loginBloc.passwordTextField,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
import 'core/routes/routes.dart';
|
||||
import 'core/utils/connectivity/network_connectivity.dart';
|
||||
import 'features/countrySelection/presentation/bloc/choose_country_bloc.dart';
|
||||
|
||||
/* CREATED BY - JAYESH JAIN
|
||||
DATE - 24-05-2024
|
||||
@@ -47,16 +49,23 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenUtilInit(
|
||||
builder: (BuildContext context, Widget? child) => MaterialApp.router(
|
||||
title: 'Tanami Capital',
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(
|
||||
create: (context) => RadioBloc(),
|
||||
)
|
||||
],
|
||||
child: ScreenUtilInit(
|
||||
builder: (BuildContext context, Widget? child) => MaterialApp.router(
|
||||
title: 'Tanami Capital',
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
routerConfig: goRouter,
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
routerConfig: goRouter,
|
||||
designSize: const Size(390, 844),
|
||||
),
|
||||
designSize: const Size(390, 844),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
73
lib/shared/components/appbar_widget.dart
Normal file
73
lib/shared/components/appbar_widget.dart
Normal file
@@ -0,0 +1,73 @@
|
||||
// ignore_for_file: non_constant_identifier_names, file_names, prefer_const_constructors
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:tanami_app/core/routes/routes.dart';
|
||||
import 'package:tanami_app/core/styles/app_color.dart';
|
||||
import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
|
||||
class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(height!);
|
||||
const AppBarWidget(
|
||||
{super.key,
|
||||
required this.titleTxt,
|
||||
this.suffixIcon,
|
||||
this.showLeading = true,
|
||||
this.customBack,
|
||||
this.backPageName = '',
|
||||
this.customActionWidget,
|
||||
this.onCustomActionPressed,
|
||||
this.height = 105});
|
||||
|
||||
final String titleTxt;
|
||||
final String? suffixIcon;
|
||||
final bool? showLeading;
|
||||
final bool? customBack;
|
||||
final String? backPageName;
|
||||
final Widget? customActionWidget;
|
||||
final VoidCallback? onCustomActionPressed;
|
||||
final double? height;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PreferredSize(
|
||||
preferredSize: Size.fromHeight(height ?? 130),
|
||||
child: AppBar(
|
||||
scrolledUnderElevation: 0.0,
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
title: TextWidget().tex20W700(titleTxt, clr: AppColor.charcoalColor),
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 16.w,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
customBack ?? false
|
||||
? goRouter.goNamed(backPageName!)
|
||||
: goRouter.pop();
|
||||
},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 8.w),
|
||||
child: Icon(
|
||||
Icons.arrow_back_rounded,
|
||||
color: AppColor.appBarIconColor,
|
||||
size: 25.r,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
if (customActionWidget != null)
|
||||
InkWell(
|
||||
onTap: onCustomActionPressed,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 14.w),
|
||||
child: customActionWidget,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import 'package:tanami_app/core/styles/app_text.dart';
|
||||
import 'package:tanami_app/shared/components/password_text_form_field.dart';
|
||||
import 'package:tanami_app/shared/components/text_widget.dart';
|
||||
|
||||
import '../../core/routes/route_name.dart';
|
||||
import '../../core/routes/routes.dart';
|
||||
import 'text_from_field_widget.dart';
|
||||
|
||||
class FormLabelTextField extends StatelessWidget {
|
||||
@@ -14,11 +16,13 @@ class FormLabelTextField extends StatelessWidget {
|
||||
required this.type,
|
||||
required this.textEditingController,
|
||||
required this.hintText,
|
||||
this.prefixWidget,
|
||||
});
|
||||
final String title;
|
||||
final String type;
|
||||
final String hintText;
|
||||
final TextEditingController textEditingController;
|
||||
final Widget? prefixWidget;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -56,12 +60,18 @@ class FormLabelTextField extends StatelessWidget {
|
||||
textEditingController: textEditingController,
|
||||
readonly: type == "country selection" ? true : false,
|
||||
hintText: hintText,
|
||||
leadingIcon: prefixWidget,
|
||||
suffixIcon: type == "country selection"
|
||||
? const Icon(
|
||||
Icons.arrow_forward_ios_rounded,
|
||||
color: Color(0xFFB4B4B4),
|
||||
)
|
||||
: const SizedBox())
|
||||
: const SizedBox(),
|
||||
onTap: () {
|
||||
if (type == "country selection") {
|
||||
goRouter.pushNamed(RouteName.chooseCountryScreen);
|
||||
}
|
||||
})
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,3 +93,4 @@ flutter:
|
||||
- assets/images/auth_screen/png/
|
||||
- assets/images/country_flag/
|
||||
- assets/images/country_flag/svg/
|
||||
- assets/images/country_flag/png/
|
||||
|
||||
Reference in New Issue
Block a user