Successfully integrated login api with userbloc

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
rodolfobacuinjr 2023-01-19 13:21:12 +08:00
parent 224b5ce7ac
commit 0c0c6c1c90
15 changed files with 256 additions and 66 deletions

View File

@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:unit2/model/login_data/user_info/user_data.dart';
import 'package:unit2/model/login_data/version_info.dart';
import 'package:unit2/sevices/login_service/auth_service.dart';
import 'package:unit2/widgets/error_state.dart';
@ -10,6 +11,8 @@ part 'user_state.dart';
class UserBloc extends Bloc<UserEvent, UserState> {
UserBloc() : super(UserInitial()) {
// this event is called when opening the app to check if
// there is new app version
on<GetApkVersion>((event, emit) async {
debugPrint("getApkEvent is called");
try {
@ -21,6 +24,14 @@ class UserBloc extends Bloc<UserEvent, UserState> {
message: e.toString(),
));
}
on<UserLogin>((event, emit) async{
try{
UserData? userData = await AuthService.instance.webLogin(username: event.username,password: event.password);
emit(UserLoggedIn(userData: userData));
}catch(e){
emit(UserError(message: e.toString()));
}
});
});
}
}

View File

@ -11,3 +11,9 @@ class GetApkVersion extends UserEvent{
@override
List<Object> get props => [];
}
class UserLogin extends UserEvent{
final String? username;
final String? password;
const UserLogin({this.username,this.password});
}

View File

@ -27,6 +27,10 @@ class UserError extends UserState {
@override
List<Object> get props => [];
}
class UserLoggedIn extends UserState{
final UserData? userData;
const UserLoggedIn({this.userData});
}
class VersionLoaded extends UserState {
final VersionInfo? versionInfo;

View File

@ -22,7 +22,7 @@ class Department {
factory Department.fromJson(Map<String, dynamic> json) => Department(
id: json["id"],
code: json["code"],
head: json["head"],
head:json["head"]==null?null:Head.fromJson(json["head"]),
name: json["name"],
acronym: json["acronym"],
parentStationId: json["parent_station_id"],

View File

@ -22,8 +22,8 @@ class EmployeeInfo {
empid: json["empid"],
classid: json["classid"],
uuid: json["uuid"],
office: Office.fromJson(json["office"]),
profile: Profile.fromJson(json["profile"]),
office: json["office"]==null?null:Office.fromJson(json["office"]),
profile: json["profile"]==null?null:Profile.fromJson(json["profile"]),
);
Map<String, dynamic> toJson() => {
@ -63,7 +63,7 @@ class Profile {
int? id;
String? sex;
dynamic gender;
String? gender;
bool? deceased;
double? heightM;
DateTime? birthdate;

View File

@ -23,14 +23,14 @@ class Office {
PositionSpecificrole? positionSpecificrole;
factory Office.fromJson(Map<String, dynamic> json) => Office(
unit: Department.fromJson(json["unit"]),
section: Department.fromJson(json["section"]),
division: Department.fromJson(json["division"]),
unit: json["unit"]==null?null:Department.fromJson(json["unit"]),
section: json["section"]==null?null:Department.fromJson(json["section"]),
division: json["division"] ==null? null:Department.fromJson(json["division"]),
posstatid: json["posstatid"],
department: Department.fromJson(json["department"]),
department: json["department"]==null?null:Department.fromJson(json["department"]),
stationId: json["station_id"],
positionClass: PositionClass.fromJson(json["position_class"]),
positionSpecificrole:
positionClass: json["position_class"]==null?null:PositionClass.fromJson(json["position_class"]),
positionSpecificrole:json["position_specificrole"]==null?null:
PositionSpecificrole.fromJson(json["position_specificrole"]),
);

View File

@ -25,7 +25,7 @@ class PositionClass {
groupcode: json["groupcode"],
salarygrade: json["salarygrade"],
classSuffix: json["class_suffix"],
classTitleid: PositionSpecificrole.fromJson(json["class_titleid"]),
classTitleid:json["class_titleid"]==null?null: PositionSpecificrole.fromJson(json["class_titleid"]),
qualificationid: json["qualificationid"],
competencyModelId: json["competency_model_id"],
);

View File

@ -1,5 +1,5 @@
import 'assigned_area.dart';
import 'modue.dart';
import 'module.dart';
class Role {
Role({

View File

@ -0,0 +1,98 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_svg/svg.dart';
import 'package:unit2/theme-data.dart/btn-style.dart';
import '../../../../theme-data.dart/colors.dart';
class Update extends StatefulWidget {
const Update({super.key});
@override
State<Update> createState() => _UpdateState();
}
class _UpdateState extends State<Update> {
@override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 25),
height: MediaQuery.of(context).size.height,
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/svgs/download.svg',
height: 200.0,
width: 200.0,
allowDrawingOutsideViewBox: true,
),
const SizedBox(
height: 5,
),
Text("UPDATE REQUIRED!",
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.displaySmall!
.copyWith(color: primary, fontSize: 28)),
],
),
const SizedBox(
height: 10,
),
RichText(
textAlign: TextAlign.justify,
text: TextSpan(
text: 'Your app version ',
style: const TextStyle(
fontSize: 16,
color: Colors.black,
),
children: <TextSpan>[
TextSpan(
text: "mobileVersion",
style: const TextStyle(
color: primary, fontWeight: FontWeight.bold)),
const TextSpan(
text: " did not match with the latest version ",
style: TextStyle(color: Colors.black)),
TextSpan(
text:
"widget.currentVersion.data.version".toString(),
style: const TextStyle(
color: primary, fontWeight: FontWeight.bold)),
const TextSpan(
text:
". Download the app latest version to procceed using the uniT-App.",
style: TextStyle(color: Colors.black)),
])),
const SizedBox(
height: 12.0,
),
SizedBox(
height: 60,
width: MediaQuery.of(context).size.width,
child: ElevatedButton.icon(
icon: const Icon(Icons.download),
style: mainBtnStyle(primary, Colors.transparent, second),
onPressed: () async {},
label: const Text("Download Latest App Version.")),
),
],
),
),
),
);
}
}

View File

@ -9,8 +9,6 @@ import 'package:go_router/go_router.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:unit2/bloc/bloc/user_bloc.dart';
import 'package:unit2/utils/alerts.dart';
import 'package:unit2/utils/scanner.dart';
import 'package:unit2/utils/text_container.dart';
import 'package:unit2/widgets/error_state.dart';
@ -41,11 +39,10 @@ class _UniT2LoginState extends State<UniT2Login> {
child: Scaffold(
body: ProgressHUD(
child: BlocConsumer<UserBloc, UserState>(listener: (context, state) {
if (state is UserLoading) {
if (state is UserLoggedIn) {
final progress = ProgressHUD.of(context);
progress?.showWithText(
'Logging in...',
);
progress!.dismiss();
debugPrint(state.userData!.user!.login!.user!.firstName);
}
}, builder: (context, state) {
if (state is VersionLoaded) {
@ -188,17 +185,32 @@ class _UniT2LoginState extends State<UniT2Login> {
style: TextStyle(color: Colors.white),
),
onPressed: () {
FocusScope.of(context).unfocus();
// Future.delayed(
// const Duration(seconds: 5), () {
// progress!.dismiss();
final progress =
ProgressHUD.of(context);
// context.goNamed("home");
// });
// if (_formKey.currentState!
// .saveAndValidate()) {
// context.go(context.namedLocation('home'));
// }
FocusScope.of(context).unfocus();
if (_formKey.currentState!
.saveAndValidate()) {
progress?.showWithText(
'Logging in...',
);
BlocProvider.of<UserBloc>(context)
.add(UserLogin(
username:
"rjvincentlopeplopez",
password: "shesthequ33n"
// username: _formKey
// .currentState!
// .value['username'],
// password: _formKey
// .currentState!
// .value[
// 'password']
));
}
// if (_formKey.currentState.validate()) {
// _formKey.currentState.save();
@ -290,7 +302,7 @@ class _UniT2LoginState extends State<UniT2Login> {
if (state is SplashScreen) {
return const UniTSplashScreen();
}
return Center(
return const Center(
child: Text("Default"),
);
}),

View File

@ -2,8 +2,11 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:unit2/model/login_data/user_info/user_data.dart';
import 'package:unit2/model/login_data/version_info.dart';
import 'package:http/http.dart' as http;
import 'package:unit2/utils/request.dart';
import '../../utils/text_container.dart';
import '../../utils/urls.dart';
@ -27,13 +30,32 @@ class AuthService {
Map data = jsonDecode(response.body);
versionInfo = VersionInfo.fromJson(data['data']);
}
} on TimeoutException catch (e) {
} on TimeoutException catch (_) {
throw (timeoutError);
} on SocketException catch (e) {
} on SocketException catch (_) {
throw (timeoutError);
} catch (e) {
throw (e.toString());
}
return versionInfo;
}
Future<UserData> webLogin({String? username, String? password})async{
Map <String,String> body ={'username':username!,'password':password!};
Map<String, String> baseHeaders = {
'Content-Type': 'application/json'
};
String path = Url.instance.authentication();
UserData? userData;
try{
http.Response response = await Request.instance.postRequest(path: path,param: {},headers: baseHeaders,body: body);
if(response.statusCode == 200){
Map data = jsonDecode(response.body);
userData = UserData.fromJson(data['data']);
}
}catch(e){
throw (e.toString());
}
return userData!;
}
}

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
@ -59,39 +60,39 @@ class Request {
Map? body,
Map<String, String>? param}) async {
Response response;
try {
response = await post(Uri.http(host, path!, param), headers: headers)
// try {
response = await post(Uri.http(host, path!, param), headers: headers,body: jsonEncode(body))
.timeout(Duration(seconds: requestTimeout));
} on TimeoutException catch (_) {
Fluttertoast.showToast(
msg: timeoutError,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.black,
);
throw (timeoutError);
} on SocketException catch (_) {
Fluttertoast.showToast(
msg: timeoutError,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.black,
);
throw (timeoutError);
} on FormatException catch (_) {
throw const FormatException(formatError);
} on HttpException catch (_) {
throw const HttpException(httpError);
} on Error catch (e) {
debugPrint("post request error: $e");
Fluttertoast.showToast(
msg: onError,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
backgroundColor: Colors.black,
);
throw (onError);
}
// } on TimeoutException catch (_) {
// Fluttertoast.showToast(
// msg: timeoutError,
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.BOTTOM,
// backgroundColor: Colors.black,
// );
// throw (timeoutError);
// } on SocketException catch (_) {
// Fluttertoast.showToast(
// msg: timeoutError,
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.BOTTOM,
// backgroundColor: Colors.black,
// );
// throw (timeoutError);
// } on FormatException catch (_) {
// throw const FormatException(formatError);
// } on HttpException catch (_) {
// throw const HttpException(httpError);
// } on Error catch (e) {
// debugPrint("post request error: $e");
// Fluttertoast.showToast(
// msg: onError,
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.BOTTOM,
// backgroundColor: Colors.black,
// );
// throw (e.toString());
// }
return response;
}
}

View File

@ -7,7 +7,7 @@ class Url{
}
String authentication(){
return '/api/account/auth/login';
return '/api/account/auth/login/';
}
String apkUrl(){

View File

@ -1,12 +1,48 @@
import 'package:animate_do/animate_do.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/utils/global.dart';
class UniTSplashScreen extends StatelessWidget {
const UniTSplashScreen({super.key});
@override
Widget build(BuildContext context) {
return const Center(child: Text("Splash Screen"),);
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SlideInUp(
from: 50,
duration: const Duration(milliseconds: 300),
child: SvgPicture.asset(
'assets/svgs/logo.svg',
height: blockSizeVertical * 15.0,
allowDrawingOutsideViewBox: true,
color: primary,
),
),
const SizedBox(
height: 24,
),
SlideInDown(
from: 100,
duration: const Duration(milliseconds: 200),
child: Text("uniT-App",
style: TextStyle(
fontSize: blockSizeVertical * 5,
fontWeight: FontWeight.w800,
letterSpacing: .2,
height: 1,
color: Colors.black)),
),
],
),
);
}
}