elCaribe app - customization and branding
This commit is contained in:
455
news-app/lib/ui/screens/auth/loginScreen.dart
Normal file
455
news-app/lib/ui/screens/auth/loginScreen.dart
Normal file
@@ -0,0 +1,455 @@
|
||||
import 'dart:io';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:news/cubits/Auth/authCubit.dart';
|
||||
import 'package:news/cubits/Auth/registerTokenCubit.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
import 'package:news/cubits/privacyTermsCubit.dart';
|
||||
import 'package:news/cubits/settingCubit.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/bottomComBtn.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/fieldFocusChange.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setConfimPass.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setDivider.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setEmail.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setForgotPass.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setLoginAndSignUpBtn.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setName.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setPassword.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/setTermPolicy.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/SnackBarWidget.dart';
|
||||
|
||||
import 'package:news/ui/widgets/customTextBtn.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/internetConnectivity.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/Auth/socialSignUpCubit.dart';
|
||||
import 'package:news/utils/validators.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
final bool? isFromApp;
|
||||
const LoginScreen({super.key, this.isFromApp});
|
||||
|
||||
@override
|
||||
LoginScreenState createState() => LoginScreenState();
|
||||
|
||||
static Route route(RouteSettings routeSettings) {
|
||||
if (routeSettings.arguments == null) {
|
||||
return CupertinoPageRoute(builder: (_) => const LoginScreen());
|
||||
} else {
|
||||
final arguments = routeSettings.arguments as Map<String, dynamic>;
|
||||
return CupertinoPageRoute(builder: (_) => LoginScreen(isFromApp: arguments['isFromApp'] ?? false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoginScreenState extends State<LoginScreen> with TickerProviderStateMixin {
|
||||
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
|
||||
TabController? _tabController;
|
||||
FocusNode emailFocus = FocusNode();
|
||||
FocusNode passFocus = FocusNode();
|
||||
FocusNode nameFocus = FocusNode();
|
||||
FocusNode emailSFocus = FocusNode();
|
||||
FocusNode passSFocus = FocusNode();
|
||||
FocusNode confPassFocus = FocusNode();
|
||||
TextEditingController? emailC, passC, sEmailC, sPassC, sNameC, sConfPassC;
|
||||
String? name, email, pass, mobile, profile, confPass;
|
||||
bool isPolicyAvailable = false;
|
||||
bool isObscure = true; //setPassword widget
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<PrivacyTermsCubit>().getPrivacyTerms(langId: context.read<AppLocalizationCubit>().state.id);
|
||||
});
|
||||
|
||||
_tabController = TabController(length: 2, vsync: this, initialIndex: 0);
|
||||
assignAllTextController();
|
||||
_tabController!.addListener(() {
|
||||
FocusScope.of(context).unfocus(); //dismiss keyboard
|
||||
clearLoginTextFields();
|
||||
clearSignUpTextFields();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
assignAllTextController() {
|
||||
emailC = TextEditingController();
|
||||
passC = TextEditingController();
|
||||
sEmailC = TextEditingController();
|
||||
sPassC = TextEditingController();
|
||||
sNameC = TextEditingController();
|
||||
sConfPassC = TextEditingController();
|
||||
}
|
||||
|
||||
clearSignUpTextFields() {
|
||||
setState(() {
|
||||
sNameC!.clear();
|
||||
sEmailC!.clear();
|
||||
sPassC!.clear();
|
||||
sConfPassC!.clear();
|
||||
});
|
||||
}
|
||||
|
||||
clearLoginTextFields() {
|
||||
setState(() {
|
||||
emailC!.clear();
|
||||
passC!.clear();
|
||||
});
|
||||
}
|
||||
|
||||
disposeAllTextController() {
|
||||
emailC!.dispose();
|
||||
passC!.dispose();
|
||||
sEmailC!.dispose();
|
||||
sPassC!.dispose();
|
||||
sNameC!.dispose();
|
||||
sConfPassC!.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController?.dispose();
|
||||
disposeAllTextController();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
showContent() {
|
||||
return BlocConsumer<SocialSignUpCubit, SocialSignUpState>(
|
||||
bloc: context.read<SocialSignUpCubit>(),
|
||||
listener: (context, state) async {
|
||||
if (state is SocialSignUpFailure) {
|
||||
showSnackBar(state.errorMessage, context);
|
||||
}
|
||||
if (state is SocialSignUpSuccess) {
|
||||
context.read<AuthCubit>().checkAuthStatus();
|
||||
if (state.authModel.status == "0") {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'deactiveMsg'), context);
|
||||
} else {
|
||||
FirebaseMessaging.instance.getToken().then((token) async {
|
||||
if (token != null) {
|
||||
context.read<RegisterTokenCubit>().registerToken(fcmId: token, context: context);
|
||||
if (token != context.read<SettingsCubit>().getSettings().token) {
|
||||
context.read<SettingsCubit>().changeFcmToken(token);
|
||||
}
|
||||
if (state.authModel.isFirstLogin != null && state.authModel.isFirstLogin!.isNotEmpty && state.authModel.isFirstLogin == "0" && state.authModel.type != loginApple) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.editUserProfile, (route) => false, arguments: {"from": "login"});
|
||||
} else if (widget.isFromApp == true) {
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
Navigator.pushNamedAndRemoveUntil(context, Routes.home, (route) => false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return Form(
|
||||
key: _formkey,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsetsDirectional.only(top: 30.0, bottom: 5.0, start: 20.0, end: 20.0),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[skipBtn(), showTabs(), showTabBarView()]),
|
||||
),
|
||||
if (state is SocialSignUpProgress) UiUtils.showCircularProgress(true, Theme.of(context).primaryColor),
|
||||
],
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
skipBtn() {
|
||||
return Align(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
child: CustomTextButton(
|
||||
onTap: () {
|
||||
Navigator.of(context).pushReplacementNamed(Routes.home, arguments: false);
|
||||
},
|
||||
text: UiUtils.getTranslatedLabel(context, 'skip'),
|
||||
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7),
|
||||
));
|
||||
}
|
||||
|
||||
showTabs() {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: Container(
|
||||
padding: const EdgeInsetsDirectional.only(start: 10.0),
|
||||
child: TabBar(
|
||||
overlayColor: WidgetStateProperty.all(Colors.transparent),
|
||||
controller: _tabController,
|
||||
labelStyle: Theme.of(context).textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600, letterSpacing: 0.5),
|
||||
labelPadding: EdgeInsets.zero,
|
||||
labelColor: backgroundColor,
|
||||
unselectedLabelColor: UiUtils.getColorScheme(context).primaryContainer,
|
||||
indicator: BoxDecoration(borderRadius: BorderRadius.circular(50), color: UiUtils.getColorScheme(context).secondaryContainer),
|
||||
tabs: [Tab(text: UiUtils.getTranslatedLabel(context, 'signInTab')), Tab(text: UiUtils.getTranslatedLabel(context, 'signupBtn'))])),
|
||||
));
|
||||
}
|
||||
|
||||
bool validateAndSave() {
|
||||
final form = _formkey.currentState;
|
||||
form!.save();
|
||||
|
||||
if (!isPolicyAvailable) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'addTCFirst'), context);
|
||||
return false;
|
||||
}
|
||||
|
||||
return form.validate();
|
||||
}
|
||||
|
||||
Widget setPassword({required FocusNode currFocus, FocusNode? nextFocus, required TextEditingController passC, required String pass, required double topPad, required bool isLogin}) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: topPad),
|
||||
child: TextFormField(
|
||||
focusNode: currFocus,
|
||||
textInputAction: isLogin ? TextInputAction.done : TextInputAction.next,
|
||||
controller: passC,
|
||||
obscureText: isObscure,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: UiUtils.getColorScheme(context).primaryContainer,
|
||||
),
|
||||
validator: (val) => Validators.passValidation(val!, context),
|
||||
onFieldSubmitted: (v) {
|
||||
if (!isLogin) {
|
||||
fieldFocusChange(context, currFocus, nextFocus!);
|
||||
}
|
||||
},
|
||||
onChanged: (String value) {
|
||||
pass = value;
|
||||
setState(() {});
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: UiUtils.getTranslatedLabel(context, 'passLbl'),
|
||||
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.5),
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(end: 12.0),
|
||||
child: IconButton(
|
||||
icon: isObscure
|
||||
? Icon(Icons.visibility_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6))
|
||||
: Icon(Icons.visibility_off_rounded, size: 20, color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.6)),
|
||||
splashColor: Colors.transparent,
|
||||
onPressed: () {
|
||||
setState(() => isObscure = !isObscure);
|
||||
},
|
||||
)),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).colorScheme.surface,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 25, vertical: 17),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
showTabBarView() {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: MediaQuery.of(context).size.height * 1.0,
|
||||
child: TabBarView(
|
||||
controller: _tabController,
|
||||
dragStartBehavior: DragStartBehavior.start,
|
||||
children: [
|
||||
//Login
|
||||
SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
child: Column(children: [
|
||||
loginTxt(),
|
||||
SetEmail(currFocus: emailFocus, nextFocus: passFocus, emailC: emailC!, email: email ?? '', topPad: 20),
|
||||
SetPassword(currFocus: passFocus, passC: passC!, pass: pass ?? '', topPad: 20, isLogin: true),
|
||||
setForgotPass(context),
|
||||
SetLoginAndSignUpBtn(
|
||||
onTap: () async {
|
||||
FocusScope.of(context).unfocus(); //dismiss keyboard
|
||||
if (validateAndSave()) {
|
||||
if (await InternetConnectivity.isNetworkAvailable()) {
|
||||
context.read<SocialSignUpCubit>().socialSignUpUser(email: emailC!.text.trim(), password: passC!.text, authProvider: AuthProviders.email, context: context);
|
||||
} else {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'internetmsg'), context);
|
||||
}
|
||||
}
|
||||
},
|
||||
text: 'loginTxt',
|
||||
topPad: 20),
|
||||
SetDividerOR(),
|
||||
bottomBtn(),
|
||||
BlocConsumer<PrivacyTermsCubit, PrivacyTermsState>(listener: (context, state) {
|
||||
if (state is PrivacyTermsFetchSuccess) {
|
||||
isPolicyAvailable = true;
|
||||
}
|
||||
if (state is PrivacyTermsFetchFailure) {
|
||||
isPolicyAvailable = false;
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
return (state is PrivacyTermsFetchSuccess) ? setTermPolicyTxt(context, state) : const SizedBox.shrink();
|
||||
})
|
||||
]),
|
||||
)),
|
||||
//SignUp
|
||||
SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
child: Column(
|
||||
children: [
|
||||
signUpTxt(),
|
||||
SetName(currFocus: nameFocus, nextFocus: emailSFocus, nameC: sNameC!, name: sNameC!.text),
|
||||
SetEmail(currFocus: emailSFocus, nextFocus: passSFocus, emailC: sEmailC!, email: sEmailC!.text, topPad: 20),
|
||||
setPassword(currFocus: passSFocus, nextFocus: confPassFocus, passC: sPassC!, pass: sPassC!.text, topPad: 20, isLogin: false),
|
||||
SetConfirmPass(currFocus: confPassFocus, confPassC: sConfPassC!, confPass: sConfPassC!.text, pass: sPassC!.text),
|
||||
SetLoginAndSignUpBtn(
|
||||
onTap: () async {
|
||||
FocusScope.of(context).unfocus(); //dismiss keyboard
|
||||
final form = _formkey.currentState;
|
||||
if (form!.validate()) {
|
||||
form.save();
|
||||
if (await InternetConnectivity.isNetworkAvailable()) {
|
||||
registerWithEmailPassword(sEmailC!.text.trim(), sPassC!.text.trim());
|
||||
} else {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'internetmsg'), context);
|
||||
}
|
||||
}
|
||||
},
|
||||
text: 'signupBtn',
|
||||
topPad: 25)
|
||||
],
|
||||
),
|
||||
))
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
registerWithEmailPassword(String email, String password) async {
|
||||
try {
|
||||
final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password);
|
||||
User? user = credential.user;
|
||||
user!.updateDisplayName(sNameC!.text.trim()).then((value) => debugPrint("updated name is - ${user.displayName}"));
|
||||
user.reload();
|
||||
|
||||
user.sendEmailVerification().then((value) => showSnackBar('${UiUtils.getTranslatedLabel(context, 'verifSentMail')} $email', context));
|
||||
clearSignUpTextFields();
|
||||
_tabController!.animateTo(0);
|
||||
FocusScope.of(context).requestFocus(emailFocus);
|
||||
} on FirebaseAuthException catch (e) {
|
||||
if (e.code == 'weakPassword') {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'weakPassword'), context);
|
||||
}
|
||||
if (e.code == 'email-already-in-use') {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'emailAlreadyInUse'), context);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
loginTxt() {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 20.0, start: 10.0),
|
||||
child: CustomTextLabel(
|
||||
text: 'loginDescr',
|
||||
textStyle: Theme.of(context).textTheme.headlineSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w800, letterSpacing: 0.5),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
signUpTxt() {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(top: 35.0, start: 10.0),
|
||||
child: CustomTextLabel(
|
||||
text: 'signupDescr',
|
||||
textStyle: Theme.of(context).textTheme.headlineSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w800, letterSpacing: 0.5),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
bottomBtn() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 20.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: (fblogInEnabled) ? MainAxisAlignment.spaceBetween : MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
BottomCommButton(
|
||||
btnCaption: 'google',
|
||||
onTap: () {
|
||||
if (!isPolicyAvailable) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'addTCFirst'), context);
|
||||
} else {
|
||||
context.read<SocialSignUpCubit>().socialSignUpUser(authProvider: AuthProviders.gmail, context: context);
|
||||
}
|
||||
},
|
||||
img: 'google_button'),
|
||||
if (fblogInEnabled)
|
||||
BottomCommButton(
|
||||
onTap: () {
|
||||
if (!isPolicyAvailable) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'addTCFirst'), context);
|
||||
} else {
|
||||
context.read<SocialSignUpCubit>().socialSignUpUser(authProvider: AuthProviders.fb, context: context);
|
||||
}
|
||||
},
|
||||
img: 'facebook_button',
|
||||
btnCaption: 'fb'),
|
||||
if (Platform.isIOS)
|
||||
BottomCommButton(
|
||||
onTap: () {
|
||||
if (!isPolicyAvailable) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'addTCFirst'), context);
|
||||
} else {
|
||||
context.read<SocialSignUpCubit>().socialSignUpUser(authProvider: AuthProviders.apple, context: context);
|
||||
}
|
||||
},
|
||||
img: 'apple_logo',
|
||||
btnCaption: 'apple',
|
||||
btnColor: UiUtils.getColorScheme(context).primaryContainer),
|
||||
if (context.read<AppConfigurationCubit>().getMobileLoginMode() != "" && context.read<AppConfigurationCubit>().getMobileLoginMode() != "0")
|
||||
BottomCommButton(
|
||||
onTap: () {
|
||||
if (!isPolicyAvailable) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'addTCFirst'), context);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.requestOtp);
|
||||
}
|
||||
},
|
||||
img: 'phone_button',
|
||||
btnCaption: 'mobileLbl',
|
||||
btnColor: UiUtils.getColorScheme(context).primaryContainer)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: showContent(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user