Complete refactoring SFM App Source Code
This commit is contained in:
234
lib/feature/auth/login/screen/login_screen.dart
Normal file
234
lib/feature/auth/login/screen/login_screen.dart
Normal file
@@ -0,0 +1,234 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../../../product/constant/app/api_path_constant.dart';
|
||||
import '../../../../product/constant/enums/app_route_enums.dart';
|
||||
import '../model/login_model.dart';
|
||||
import '../../../../product/cache/local_manager.dart';
|
||||
import '../../../../product/constant/enums/local_keys_enums.dart';
|
||||
import '../../../../product/services/api_services.dart';
|
||||
import '../../../../product/shared/shared_snack_bar.dart';
|
||||
import '../../../../product/constant/icon/icon_constants.dart';
|
||||
import '../../../../product/extention/context_extention.dart';
|
||||
import '../../../../product/constant/image/image_constants.dart';
|
||||
import '../../../../product/services/language_services.dart';
|
||||
import '../bloc/login_bloc.dart';
|
||||
import '../../../../product/base/bloc/base_bloc.dart';
|
||||
import '../../../../product/shared/shared_background.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
|
||||
@override
|
||||
State<LoginScreen> createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
late LoginBloc loginBloc;
|
||||
Map<String, dynamic> loginRequest = {"username": "", "password": ""};
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
bool isShowPassword = true;
|
||||
APIServices apiServices = APIServices();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loginBloc = BlocProvider.of(context);
|
||||
checkLogin(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SharedBackground(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Image.asset(
|
||||
ImageConstants.instance.getImage("logo"),
|
||||
height: context.dynamicHeight(0.2),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: context.mediumValue,
|
||||
),
|
||||
StreamBuilder<Map<String, dynamic>>(
|
||||
stream: loginBloc.streamLoginRequest,
|
||||
builder: (context, loginResquestSnapshot) {
|
||||
return Padding(
|
||||
padding: context.paddingLow,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
textInputAction: TextInputAction.next,
|
||||
validator: (value) {
|
||||
if (value == "null" || value!.isEmpty) {
|
||||
return appLocalization(context)
|
||||
.login_account_not_empty;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onSaved: (username) {
|
||||
loginRequest["username"] = username!;
|
||||
loginBloc.sinkLoginRequest.add(loginRequest);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
appLocalization(context).login_account_hint,
|
||||
prefixIcon: Padding(
|
||||
padding: context.dynamicPadding(16),
|
||||
child: IconConstants.instance
|
||||
.getMaterialIcon(Icons.person),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: context.lowValue),
|
||||
StreamBuilder<bool>(
|
||||
stream: loginBloc.streamIsShowPassword,
|
||||
builder: (context, isShowPassSnapshot) {
|
||||
return TextFormField(
|
||||
textInputAction: TextInputAction.done,
|
||||
obscureText:
|
||||
isShowPassSnapshot.data ?? isShowPassword,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return appLocalization(context)
|
||||
.login_password_not_empty;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onSaved: (password) {
|
||||
loginRequest["password"] = password!;
|
||||
loginBloc.sinkLoginRequest.add(loginRequest);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: appLocalization(context)
|
||||
.login_password_hint,
|
||||
prefixIcon: Padding(
|
||||
padding: context.dynamicPadding(16),
|
||||
child: IconConstants.instance
|
||||
.getMaterialIcon(Icons.lock),
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () {
|
||||
isShowPassword = !isShowPassword;
|
||||
loginBloc.sinkIsShowPassword
|
||||
.add(isShowPassword);
|
||||
},
|
||||
icon: isShowPassword
|
||||
? IconConstants.instance
|
||||
.getMaterialIcon(
|
||||
Icons.visibility,
|
||||
)
|
||||
: IconConstants.instance
|
||||
.getMaterialIcon(
|
||||
Icons.visibility_off,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: context.lowValue,
|
||||
),
|
||||
ElevatedButton(
|
||||
style: const ButtonStyle(
|
||||
backgroundColor:
|
||||
MaterialStatePropertyAll(Colors.blue),
|
||||
foregroundColor:
|
||||
MaterialStatePropertyAll(Colors.white),
|
||||
),
|
||||
onPressed: () {
|
||||
validate();
|
||||
},
|
||||
child: Text(
|
||||
appLocalization(context).login_button_content),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void validate() async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
_formKey.currentState!.save();
|
||||
var data =
|
||||
await apiServices.login(APIPathConstants.LOGIN_PATH, loginRequest);
|
||||
if (data != "") {
|
||||
Map<String, dynamic> tokenData = jsonDecode(data);
|
||||
String token = tokenData['token'];
|
||||
LocaleManager.instance.setString(PreferencesKeys.TOKEN, token);
|
||||
String userToken = getBaseToken(token);
|
||||
var decode = decodeBase64Token(userToken);
|
||||
LoginModel loginModel =
|
||||
LoginModel.fromJson(jsonDecode(decode) as Map<String, dynamic>);
|
||||
LocaleManager.instance.setString(PreferencesKeys.UID, loginModel.id!);
|
||||
LocaleManager.instance.setInt(PreferencesKeys.EXP, loginModel.exp!);
|
||||
LocaleManager.instance
|
||||
.setString(PreferencesKeys.ROLE, loginModel.role!);
|
||||
context.goNamed(AppRoutes.HOME.name);
|
||||
} else {
|
||||
showErrorTopSnackBarCustom(
|
||||
context, appLocalization(context).login_incorrect_usernameOrPass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkLogin(BuildContext context) async {
|
||||
// ThemeNotifier themeNotifier = context.watch<ThemeNotifier>();
|
||||
await LocaleManager.prefrencesInit();
|
||||
// String theme = LocaleManager.instance.getStringValue(PreferencesKeys.THEME);
|
||||
String token = LocaleManager.instance.getStringValue(PreferencesKeys.TOKEN);
|
||||
int exp = LocaleManager.instance.getIntValue(PreferencesKeys.EXP);
|
||||
log("Token cu: ${LocaleManager.instance.getStringValue(PreferencesKeys.TOKEN)}");
|
||||
log("UID: ${LocaleManager.instance.getStringValue(PreferencesKeys.UID)}");
|
||||
log("EXP: ${LocaleManager.instance.getIntValue(PreferencesKeys.EXP)}");
|
||||
log("Role: ${LocaleManager.instance.getStringValue(PreferencesKeys.ROLE)}");
|
||||
log("Theme: ${LocaleManager.instance.getStringValue(PreferencesKeys.THEME)}");
|
||||
log("Lang: ${LocaleManager.instance.getStringValue(PreferencesKeys.LANGUAGE_CODE)}");
|
||||
// log("Theme: $theme");
|
||||
// if (theme == AppThemes.DARK.name) {
|
||||
// themeNotifier.changeValue(AppThemes.DARK);
|
||||
// } else {
|
||||
// themeNotifier.changeValue(AppThemes.LIGHT);
|
||||
// }
|
||||
int timeNow = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
if (token != "" && (exp - timeNow) > 7200) {
|
||||
context.goNamed(AppRoutes.HOME.name);
|
||||
}
|
||||
}
|
||||
|
||||
getBaseToken(String token) {
|
||||
List<String> parts = token.split('.');
|
||||
String userToken = parts[1];
|
||||
return userToken;
|
||||
}
|
||||
|
||||
decodeBase64Token(String value) {
|
||||
List<int> res = base64.decode(base64.normalize(value));
|
||||
return utf8.decode(res);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user