add userbloc and perform version info check
parent
f973820a3b
commit
224b5ce7ac
|
@ -0,0 +1,26 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.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';
|
||||
|
||||
part 'user_event.dart';
|
||||
part 'user_state.dart';
|
||||
|
||||
class UserBloc extends Bloc<UserEvent, UserState> {
|
||||
UserBloc() : super(UserInitial()) {
|
||||
on<GetApkVersion>((event, emit) async {
|
||||
debugPrint("getApkEvent is called");
|
||||
try {
|
||||
emit(SplashScreen());
|
||||
VersionInfo versionInfo = await AuthService.instance.getVersionInfo();
|
||||
emit(VersionLoaded(versionInfo: versionInfo));
|
||||
} catch (e) {
|
||||
emit(UserError(
|
||||
message: e.toString(),
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
part of 'user_bloc.dart';
|
||||
|
||||
abstract class UserEvent extends Equatable {
|
||||
const UserEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class GetApkVersion extends UserEvent{
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
part of 'user_bloc.dart';
|
||||
|
||||
abstract class UserState extends Equatable {
|
||||
const UserState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UserInitial extends UserState {}
|
||||
|
||||
class UserLoading extends UserState {
|
||||
final String? message;
|
||||
const UserLoading({this.message});
|
||||
@override
|
||||
List<Object> get props => [message!];
|
||||
}
|
||||
|
||||
class SplashScreen extends UserState {
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class UserError extends UserState {
|
||||
final String? message;
|
||||
const UserError({this.message});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class VersionLoaded extends UserState {
|
||||
final VersionInfo? versionInfo;
|
||||
const VersionLoaded({this.versionInfo});
|
||||
@override
|
||||
List<Object> get props => [versionInfo!];
|
||||
}
|
|
@ -2,6 +2,8 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:device_preview/device_preview.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:unit2/bloc/bloc/user_bloc.dart';
|
||||
import './utils/router.dart';
|
||||
import './utils/global.dart';
|
||||
|
||||
|
@ -35,23 +37,26 @@ class MyApp extends StatelessWidget {
|
|||
safeBlockHorizontal = (screenWidth - safeAreaHorizontal) / 100;
|
||||
safeBlockVertical = (screenHeight - safeAreaVertical) / 100;
|
||||
|
||||
return MaterialApp.router(
|
||||
// useInheritedMediaQuery: true,
|
||||
// locale: DevicePreview.locale(context),
|
||||
// builder: DevicePreview.appBuilder,
|
||||
routeInformationParser: goRouter.routeInformationParser,
|
||||
routerDelegate: goRouter.routerDelegate,
|
||||
// routeInformationProvider: goRouter.routeInformationProvider,
|
||||
title: 'uniT2 - Universal Tracker and Tracer',
|
||||
theme: ThemeData(
|
||||
appBarTheme: const AppBarTheme(
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarBrightness: Brightness.dark,
|
||||
statusBarColor: Colors.black),
|
||||
return BlocProvider(
|
||||
create: (context) => UserBloc(),
|
||||
child: MaterialApp.router(
|
||||
// useInheritedMediaQuery: true,
|
||||
// locale: DevicePreview.locale(context),
|
||||
// builder: DevicePreview.appBuilder,
|
||||
routeInformationParser: goRouter.routeInformationParser,
|
||||
routerDelegate: goRouter.routerDelegate,
|
||||
// routeInformationProvider: goRouter.routeInformationProvider,
|
||||
title: 'uniT2 - Universal Tracker and Tracer',
|
||||
theme: ThemeData(
|
||||
appBarTheme: const AppBarTheme(
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarBrightness: Brightness.dark,
|
||||
statusBarColor: Colors.black),
|
||||
),
|
||||
fontFamily: 'LexendDeca',
|
||||
),
|
||||
fontFamily: 'LexendDeca',
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import 'package:unit2/model/login_data/employee_info/head.dart';
|
||||
|
||||
class Department {
|
||||
Department({
|
||||
this.id,
|
||||
this.code,
|
||||
this.head,
|
||||
this.name,
|
||||
this.acronym,
|
||||
this.parentStationId,
|
||||
this.fullCode,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? code;
|
||||
Head? head;
|
||||
String? name;
|
||||
int? acronym;
|
||||
int? parentStationId;
|
||||
String? fullCode;
|
||||
|
||||
factory Department.fromJson(Map<String, dynamic> json) => Department(
|
||||
id: json["id"],
|
||||
code: json["code"],
|
||||
head: json["head"],
|
||||
name: json["name"],
|
||||
acronym: json["acronym"],
|
||||
parentStationId: json["parent_station_id"],
|
||||
fullCode: json["full_code"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"code": code,
|
||||
"head": head,
|
||||
"name": name,
|
||||
"acronym": acronym,
|
||||
"parent_station_id": parentStationId,
|
||||
"full_code": fullCode,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
import 'package:unit2/model/login_data/employee_info/office.dart';
|
||||
|
||||
class EmployeeInfo {
|
||||
EmployeeInfo({
|
||||
this.employeeId,
|
||||
this.empid,
|
||||
this.classid,
|
||||
this.uuid,
|
||||
this.office,
|
||||
this.profile,
|
||||
});
|
||||
|
||||
String? employeeId;
|
||||
int? empid;
|
||||
String? classid;
|
||||
String? uuid;
|
||||
Office? office;
|
||||
Profile? profile;
|
||||
|
||||
factory EmployeeInfo.fromJson(Map<String, dynamic> json) => EmployeeInfo(
|
||||
employeeId: json["employee_id"],
|
||||
empid: json["empid"],
|
||||
classid: json["classid"],
|
||||
uuid: json["uuid"],
|
||||
office: Office.fromJson(json["office"]),
|
||||
profile: Profile.fromJson(json["profile"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"employee_id": employeeId,
|
||||
"empid": empid,
|
||||
"classid": classid,
|
||||
"uuid": uuid,
|
||||
"office": office!.toJson(),
|
||||
"profile": profile!.toJson(),
|
||||
};
|
||||
}
|
||||
class Profile {
|
||||
Profile({
|
||||
this.id,
|
||||
this.sex,
|
||||
this.gender,
|
||||
this.deceased,
|
||||
this.heightM,
|
||||
this.birthdate,
|
||||
this.esigPath,
|
||||
this.fullName,
|
||||
this.lastName,
|
||||
this.weightKg,
|
||||
this.bloodType,
|
||||
this.firstName,
|
||||
this.photoPath,
|
||||
this.maidenName,
|
||||
this.middleName,
|
||||
this.uuidQrcode,
|
||||
this.civilStatus,
|
||||
this.titlePrefix,
|
||||
this.titleSuffix,
|
||||
this.showTitleId,
|
||||
this.lastFullName,
|
||||
this.nameExtension,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? sex;
|
||||
dynamic gender;
|
||||
bool? deceased;
|
||||
double? heightM;
|
||||
DateTime? birthdate;
|
||||
String? esigPath;
|
||||
String? fullName;
|
||||
String? lastName;
|
||||
int? weightKg;
|
||||
String? bloodType;
|
||||
String? firstName;
|
||||
String? photoPath;
|
||||
String? maidenName;
|
||||
String? middleName;
|
||||
String? uuidQrcode;
|
||||
String? civilStatus;
|
||||
String? titlePrefix;
|
||||
String? titleSuffix;
|
||||
bool? showTitleId;
|
||||
String? lastFullName;
|
||||
String? nameExtension;
|
||||
|
||||
factory Profile.fromJson(Map<String, dynamic> json) => Profile(
|
||||
id: json["id"],
|
||||
sex: json["sex"],
|
||||
gender: json["gender"],
|
||||
deceased: json["deceased"],
|
||||
heightM: json["height_m"].toDouble(),
|
||||
birthdate: DateTime.parse(json["birthdate"]),
|
||||
esigPath: json["esig_path"],
|
||||
fullName: json["full_name"],
|
||||
lastName: json["last_name"],
|
||||
weightKg: json["weight_kg"],
|
||||
bloodType: json["blood_type"],
|
||||
firstName: json["first_name"],
|
||||
photoPath: json["photo_path"],
|
||||
maidenName: json["maiden_name"],
|
||||
middleName: json["middle_name"],
|
||||
uuidQrcode: json["uuid_qrcode"],
|
||||
civilStatus: json["civil_status"],
|
||||
titlePrefix: json["title_prefix"],
|
||||
titleSuffix: json["title_suffix"],
|
||||
showTitleId: json["show_title_id"],
|
||||
lastFullName: json["last_full_name"],
|
||||
nameExtension: json["name_extension"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"sex": sex,
|
||||
"gender": gender,
|
||||
"deceased": deceased,
|
||||
"height_m": heightM,
|
||||
"birthdate":
|
||||
"${birthdate!.year.toString().padLeft(4, '0')}-${birthdate!.month.toString().padLeft(2, '0')}-${birthdate!.day.toString().padLeft(2, '0')}",
|
||||
"esig_path": esigPath,
|
||||
"full_name": fullName,
|
||||
"last_name": lastName,
|
||||
"weight_kg": weightKg,
|
||||
"blood_type": bloodType,
|
||||
"first_name": firstName,
|
||||
"photo_path": photoPath,
|
||||
"maiden_name": maidenName,
|
||||
"middle_name": middleName,
|
||||
"uuid_qrcode": uuidQrcode,
|
||||
"civil_status": civilStatus,
|
||||
"title_prefix": titlePrefix,
|
||||
"title_suffix": titleSuffix,
|
||||
"show_title_id": showTitleId,
|
||||
"last_full_name": lastFullName,
|
||||
"name_extension": nameExtension,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
class Head {
|
||||
Head({
|
||||
this.id,
|
||||
this.title,
|
||||
this.classid,
|
||||
this.fullName,
|
||||
this.personId,
|
||||
this.employeeid,
|
||||
this.officeposid,
|
||||
this.lastFullName,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? title;
|
||||
String? classid;
|
||||
String? fullName;
|
||||
int? personId;
|
||||
String? employeeid;
|
||||
int? officeposid;
|
||||
String? lastFullName;
|
||||
|
||||
factory Head.fromJson(Map<String, dynamic> json) => Head(
|
||||
id: json["id"],
|
||||
title: json["title"],
|
||||
classid: json["classid"],
|
||||
fullName: json["full_name"],
|
||||
personId: json["person_id"],
|
||||
employeeid: json["employeeid"],
|
||||
officeposid: json["officeposid"],
|
||||
lastFullName: json["last_full_name"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"title": title,
|
||||
"classid": classid,
|
||||
"full_name": fullName,
|
||||
"person_id": personId,
|
||||
"employeeid": employeeid,
|
||||
"officeposid": officeposid,
|
||||
"last_full_name": lastFullName,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import 'department.dart';
|
||||
import 'position_class.dart';
|
||||
|
||||
class Office {
|
||||
Office({
|
||||
this.unit,
|
||||
this.section,
|
||||
this.division,
|
||||
this.posstatid,
|
||||
this.department,
|
||||
this.stationId,
|
||||
this.positionClass,
|
||||
this.positionSpecificrole,
|
||||
});
|
||||
|
||||
Department? unit;
|
||||
Department? section;
|
||||
Department? division;
|
||||
int? posstatid;
|
||||
Department? department;
|
||||
int? stationId;
|
||||
PositionClass? positionClass;
|
||||
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"]),
|
||||
posstatid: json["posstatid"],
|
||||
department: Department.fromJson(json["department"]),
|
||||
stationId: json["station_id"],
|
||||
positionClass: PositionClass.fromJson(json["position_class"]),
|
||||
positionSpecificrole:
|
||||
PositionSpecificrole.fromJson(json["position_specificrole"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"unit": unit!.toJson(),
|
||||
"section": section!.toJson(),
|
||||
"division": division!.toJson(),
|
||||
"posstatid": posstatid,
|
||||
"department": department!.toJson(),
|
||||
"station_id": stationId,
|
||||
"position_class": positionClass!.toJson(),
|
||||
"position_specificrole": positionSpecificrole!.toJson(),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
class PositionClass {
|
||||
PositionClass({
|
||||
this.level,
|
||||
this.classid,
|
||||
this.groupcode,
|
||||
this.salarygrade,
|
||||
this.classSuffix,
|
||||
this.classTitleid,
|
||||
this.qualificationid,
|
||||
this.competencyModelId,
|
||||
});
|
||||
|
||||
int? level;
|
||||
String? classid;
|
||||
String? groupcode;
|
||||
int? salarygrade;
|
||||
String? classSuffix;
|
||||
PositionSpecificrole? classTitleid;
|
||||
int? qualificationid;
|
||||
int? competencyModelId;
|
||||
|
||||
factory PositionClass.fromJson(Map<String, dynamic> json) => PositionClass(
|
||||
level: json["level"],
|
||||
classid: json["classid"],
|
||||
groupcode: json["groupcode"],
|
||||
salarygrade: json["salarygrade"],
|
||||
classSuffix: json["class_suffix"],
|
||||
classTitleid: PositionSpecificrole.fromJson(json["class_titleid"]),
|
||||
qualificationid: json["qualificationid"],
|
||||
competencyModelId: json["competency_model_id"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"level": level,
|
||||
"classid": classid,
|
||||
"groupcode": groupcode,
|
||||
"salarygrade": salarygrade,
|
||||
"class_suffix": classSuffix,
|
||||
"class_titleid": classTitleid!.toJson(),
|
||||
"qualificationid": qualificationid,
|
||||
"competency_model_id": competencyModelId,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class PositionSpecificrole {
|
||||
PositionSpecificrole({
|
||||
this.title,
|
||||
this.titleid,
|
||||
});
|
||||
|
||||
String? title;
|
||||
int? titleid;
|
||||
|
||||
factory PositionSpecificrole.fromJson(Map<String, dynamic> json) =>
|
||||
PositionSpecificrole(
|
||||
title: json["title"],
|
||||
titleid: json["titleid"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"title": title,
|
||||
"titleid": titleid,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
class AssignedArea {
|
||||
AssignedArea({
|
||||
this.id,
|
||||
this.areaid,
|
||||
this.isactive,
|
||||
this.areaName,
|
||||
this.areaTypeName,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? areaid;
|
||||
bool? isactive;
|
||||
String? areaName;
|
||||
String? areaTypeName;
|
||||
|
||||
factory AssignedArea.fromJson(Map<String, dynamic> json) => AssignedArea(
|
||||
id: json["id"],
|
||||
areaid: json["areaid"],
|
||||
isactive: json["isactive"],
|
||||
areaName: json["area_name"],
|
||||
areaTypeName: json["area_type_name"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"areaid": areaid,
|
||||
"isactive": isactive,
|
||||
"area_name": areaName,
|
||||
"area_type_name": areaTypeName,
|
||||
};
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import 'role.dart';
|
||||
class LoginUser {
|
||||
LoginUser({
|
||||
this.id,
|
||||
this.profileId,
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.username,
|
||||
this.email,
|
||||
this.staff,
|
||||
this.roles,
|
||||
});
|
||||
|
||||
int? id;
|
||||
int? profileId;
|
||||
String? firstName;
|
||||
String? lastName;
|
||||
String? username;
|
||||
String? email;
|
||||
bool? staff;
|
||||
List<Role?>? roles;
|
||||
|
||||
factory LoginUser.fromJson(Map<String, dynamic> json) => LoginUser(
|
||||
id: json["id"],
|
||||
profileId: json["profile_id"],
|
||||
firstName: json["first_name"],
|
||||
lastName: json["last_name"],
|
||||
username: json["username"],
|
||||
email: json["email"],
|
||||
staff: json["staff"],
|
||||
roles: json["roles"] == null
|
||||
? []
|
||||
: List<Role?>.from(json["roles"]!.map((x) => Role.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"profile_id": profileId,
|
||||
"first_name": firstName,
|
||||
"last_name": lastName,
|
||||
"username": username,
|
||||
"email": email,
|
||||
"staff": staff,
|
||||
"roles": roles == null
|
||||
? []
|
||||
: List<dynamic>.from(roles!.map((x) => x!.toJson())),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
class Module {
|
||||
Module({
|
||||
this.id,
|
||||
this.icon,
|
||||
this.name,
|
||||
this.slug,
|
||||
this.objects,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? icon;
|
||||
String? name;
|
||||
String? slug;
|
||||
List<Object?>? objects;
|
||||
|
||||
factory Module.fromJson(Map<String, dynamic> json) => Module(
|
||||
id: json["id"],
|
||||
icon: json["icon"],
|
||||
name: json["name"],
|
||||
slug: json["slug"],
|
||||
objects: json["objects"] == null
|
||||
? []
|
||||
: List<Object?>.from(
|
||||
json["objects"]!.map((x) => Object.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"icon": icon,
|
||||
"name": name,
|
||||
"slug": slug,
|
||||
"objects": objects == null
|
||||
? []
|
||||
: List<dynamic>.from(objects!.map((x) => x!.toJson())),
|
||||
};
|
||||
}
|
||||
|
||||
class Object {
|
||||
Object({
|
||||
this.id,
|
||||
this.name,
|
||||
this.slug,
|
||||
this.operations,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? name;
|
||||
String? slug;
|
||||
List<String?>? operations;
|
||||
|
||||
factory Object.fromJson(Map<String, dynamic> json) => Object(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
slug: json["slug"],
|
||||
operations: json["operations"] == null
|
||||
? []
|
||||
: List<String?>.from(json["operations"]!.map((x) => x)),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"slug": slug,
|
||||
"operations": operations == null
|
||||
? []
|
||||
: List<dynamic>.from(operations!.map((x) => x)),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
import 'assigned_area.dart';
|
||||
import 'modue.dart';
|
||||
|
||||
class Role {
|
||||
Role({
|
||||
this.id,
|
||||
this.name,
|
||||
this.modules,
|
||||
this.assignedArea,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? name;
|
||||
List<Module?>? modules;
|
||||
List<AssignedArea?>? assignedArea;
|
||||
|
||||
factory Role.fromJson(Map<String, dynamic> json) => Role(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
modules: json["modules"] == null
|
||||
? []
|
||||
: List<Module?>.from(
|
||||
json["modules"]!.map((x) => Module.fromJson(x))),
|
||||
assignedArea: json["assigned_area"] == null
|
||||
? []
|
||||
: json["assigned_area"] == null
|
||||
? []
|
||||
: List<AssignedArea?>.from(json["assigned_area"]!
|
||||
.map((x) => AssignedArea.fromJson(x))),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"modules": modules == null
|
||||
? []
|
||||
: List<dynamic>.from(modules!.map((x) => x!.toJson())),
|
||||
"assigned_area": assignedArea == null
|
||||
? []
|
||||
: assignedArea == null
|
||||
? []
|
||||
: List<dynamic>.from(assignedArea!.map((x) => x!.toJson())),
|
||||
};
|
||||
}class Object {
|
||||
Object({
|
||||
this.id,
|
||||
this.name,
|
||||
this.slug,
|
||||
this.operations,
|
||||
});
|
||||
|
||||
int? id;
|
||||
String? name;
|
||||
String? slug;
|
||||
List<String?>? operations;
|
||||
|
||||
factory Object.fromJson(Map<String, dynamic> json) => Object(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
slug: json["slug"],
|
||||
operations: json["operations"] == null
|
||||
? []
|
||||
: List<String?>.from(json["operations"]!.map((x) => x)),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"slug": slug,
|
||||
"operations": operations == null
|
||||
? []
|
||||
: List<dynamic>.from(operations!.map((x) => x)),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/model/login_data/employee_info/employee_info.dart';
|
||||
|
||||
import 'login_user.dart';
|
||||
|
||||
UserData? userDataFromJson(String str) => UserData.fromJson(json.decode(str));
|
||||
|
||||
String userDataToJson(UserData? data) => json.encode(data!.toJson());
|
||||
|
||||
class UserData {
|
||||
UserData({
|
||||
this.user,
|
||||
this.employeeInfo,
|
||||
});
|
||||
|
||||
UserDataUser? user;
|
||||
EmployeeInfo? employeeInfo;
|
||||
|
||||
factory UserData.fromJson(Map<String, dynamic> json) => UserData(
|
||||
user: UserDataUser.fromJson(json["user"]),
|
||||
employeeInfo: EmployeeInfo.fromJson(json["employee_info"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"user": user!.toJson(),
|
||||
"employee_info": employeeInfo!.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class UserDataUser {
|
||||
UserDataUser({
|
||||
this.login,
|
||||
});
|
||||
|
||||
Login? login;
|
||||
|
||||
factory UserDataUser.fromJson(Map<String, dynamic> json) => UserDataUser(
|
||||
login: Login.fromJson(json["login"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"login": login!.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class Login {
|
||||
Login({
|
||||
this.dateTime,
|
||||
this.token,
|
||||
this.user,
|
||||
});
|
||||
|
||||
DateTime? dateTime;
|
||||
String? token;
|
||||
LoginUser? user;
|
||||
|
||||
factory Login.fromJson(Map<String, dynamic> json) => Login(
|
||||
dateTime: DateTime.parse(json["date_time"]),
|
||||
token: json["token"],
|
||||
user: LoginUser.fromJson(json["user"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"date_time": dateTime?.toIso8601String(),
|
||||
"token": token,
|
||||
"user": user!.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
class VersionInfo {
|
||||
VersionInfo({
|
||||
this.version,
|
||||
this.versionInfo,
|
||||
this.dateReleased,
|
||||
this.development,
|
||||
this.production,
|
||||
this.downloadUrl,
|
||||
this.arm64v8aDownloadUrl,
|
||||
this.armeabiv7aDownloadUrl,
|
||||
this.x8664DownloadUrl,
|
||||
});
|
||||
|
||||
String? version;
|
||||
String? versionInfo;
|
||||
DateTime? dateReleased;
|
||||
bool? development;
|
||||
bool? production;
|
||||
String? downloadUrl;
|
||||
String? arm64v8aDownloadUrl;
|
||||
String? armeabiv7aDownloadUrl;
|
||||
String? x8664DownloadUrl;
|
||||
|
||||
factory VersionInfo.fromJson(Map<String, dynamic> json) => VersionInfo(
|
||||
version: json["version"],
|
||||
versionInfo: json["version_info"],
|
||||
dateReleased: DateTime.parse(json["date_released"]),
|
||||
development: json["development"],
|
||||
production: json["production"],
|
||||
downloadUrl: json["download_url"],
|
||||
arm64v8aDownloadUrl: json["arm64_v8a_download_url"],
|
||||
armeabiv7aDownloadUrl: json["armeabi_v7a_download_url"],
|
||||
x8664DownloadUrl: json["x86_64_down_download_url"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"version": version,
|
||||
"version_info": versionInfo,
|
||||
"date_released":
|
||||
"${dateReleased!.year.toString().padLeft(4, '0')}-${dateReleased!.month.toString().padLeft(2, '0')}-${dateReleased!.day.toString().padLeft(2, '0')}",
|
||||
"development": development,
|
||||
"production": production,
|
||||
"download_url": downloadUrl,
|
||||
"arm64_v8a_download_url": arm64v8aDownloadUrl,
|
||||
"armeabi_v7a_download_url": armeabiv7aDownloadUrl,
|
||||
"x86_64_down_download_url": x8664DownloadUrl,
|
||||
};
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:fluttericon/font_awesome5_icons.dart';
|
||||
|
@ -7,10 +8,13 @@ import 'package:form_builder_validators/form_builder_validators.dart';
|
|||
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';
|
||||
|
||||
import '../../../widgets/splash_screen.dart';
|
||||
import '../../../widgets/wave.dart';
|
||||
import '../../../utils/global.dart';
|
||||
import '../../../theme-data.dart/colors.dart';
|
||||
|
@ -36,236 +40,258 @@ class _UniT2LoginState extends State<UniT2Login> {
|
|||
onWillPop: pressAgainToExit,
|
||||
child: Scaffold(
|
||||
body: ProgressHUD(
|
||||
child: Builder(builder: (context) {
|
||||
return SizedBox(
|
||||
child: SingleChildScrollView(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: WaveReverse(height: blockSizeVertical * 7)),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 100,
|
||||
child: FormBuilder(
|
||||
key: _formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(height: blockSizeVertical * 7),
|
||||
SvgPicture.asset(
|
||||
'assets/svgs/logo.svg',
|
||||
height: blockSizeVertical * 16,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
color: primary,
|
||||
),
|
||||
|
||||
Text(
|
||||
welcome,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 5,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(unitApp,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 8,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: .2,
|
||||
height: 1,
|
||||
color: primary)),
|
||||
Text(
|
||||
loginToContinue,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 2,
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
// USERNAME
|
||||
FormBuilderTextField(
|
||||
name: 'username',
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: usernameRequired),
|
||||
autofocus: false,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87),
|
||||
decoration: loginTextFieldStyle().copyWith()),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
// PASSWORD
|
||||
FormBuilderTextField(
|
||||
name: 'password',
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: passwordRequired),
|
||||
|
||||
// initialValue: state.password,
|
||||
onChanged: (value) {
|
||||
value!.isEmpty
|
||||
? setState(() {
|
||||
showSuffixIcon = false;
|
||||
})
|
||||
: setState(() {
|
||||
showSuffixIcon = true;
|
||||
});
|
||||
},
|
||||
autofocus: false,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87),
|
||||
decoration: loginTextFieldStyle().copyWith(
|
||||
suffixIcon: Visibility(
|
||||
visible: showSuffixIcon,
|
||||
child: _showPassword
|
||||
? IconButton(
|
||||
icon: Icon(FontAwesome5.eye_slash,
|
||||
size: 24,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.displayLarge
|
||||
?.color),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_showPassword = false;
|
||||
});
|
||||
},
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_showPassword = true;
|
||||
});
|
||||
},
|
||||
icon: Icon(FontAwesome5.eye,
|
||||
size: 24,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.displayLarge
|
||||
?.color)),
|
||||
),
|
||||
prefixIcon: const Icon(
|
||||
Icons.lock,
|
||||
color: primary,
|
||||
),
|
||||
labelText: "Password",
|
||||
hintText: enterPassword),
|
||||
obscureText: _showPassword ? true : false,
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 2,
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 7,
|
||||
// Login Button
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(second,
|
||||
Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
login,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
onPressed: () {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress?.showWithText(
|
||||
'Logging in...',
|
||||
);
|
||||
FocusScope.of(context).unfocus();
|
||||
Future.delayed(const Duration(seconds: 5),
|
||||
() {
|
||||
progress!.dismiss();
|
||||
|
||||
context.goNamed("home");
|
||||
});
|
||||
// if (_formKey.currentState!
|
||||
// .saveAndValidate()) {
|
||||
// context.go(context.namedLocation('home'));
|
||||
// }
|
||||
|
||||
// if (_formKey.currentState.validate()) {
|
||||
// _formKey.currentState.save();
|
||||
// BlocProvider.of<UserBloc>(context)
|
||||
// .add(UserWebLogin(
|
||||
// password: password,
|
||||
// username: username));
|
||||
// }
|
||||
},
|
||||
child: BlocConsumer<UserBloc, UserState>(listener: (context, state) {
|
||||
if (state is UserLoading) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress?.showWithText(
|
||||
'Logging in...',
|
||||
);
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
if (state is VersionLoaded) {
|
||||
return Builder(builder: (context) {
|
||||
return SizedBox(
|
||||
child: SingleChildScrollView(
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: WaveReverse(height: blockSizeVertical * 7)),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 100,
|
||||
child: FormBuilder(
|
||||
key: _formKey,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 25),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SizedBox(height: blockSizeVertical * 7),
|
||||
SvgPicture.asset(
|
||||
'assets/svgs/logo.svg',
|
||||
height: blockSizeVertical * 16,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
color: primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 7,
|
||||
child: SizedBox(
|
||||
Text(
|
||||
welcome,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 5,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
Text(unitApp,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 8,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: .2,
|
||||
height: 1,
|
||||
color: primary)),
|
||||
Text(
|
||||
loginToContinue,
|
||||
style: TextStyle(
|
||||
fontSize: blockSizeVertical * 2,
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
// USERNAME
|
||||
FormBuilderTextField(
|
||||
name: 'username',
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: usernameRequired),
|
||||
autofocus: false,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87),
|
||||
decoration:
|
||||
loginTextFieldStyle().copyWith()),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
// PASSWORD
|
||||
FormBuilderTextField(
|
||||
name: 'password',
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: passwordRequired),
|
||||
|
||||
// initialValue: state.password,
|
||||
onChanged: (value) {
|
||||
value!.isEmpty
|
||||
? setState(() {
|
||||
showSuffixIcon = false;
|
||||
})
|
||||
: setState(() {
|
||||
showSuffixIcon = true;
|
||||
});
|
||||
},
|
||||
autofocus: false,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87),
|
||||
decoration: loginTextFieldStyle().copyWith(
|
||||
suffixIcon: Visibility(
|
||||
visible: showSuffixIcon,
|
||||
child: _showPassword
|
||||
? IconButton(
|
||||
icon: Icon(
|
||||
FontAwesome5.eye_slash,
|
||||
size: 24,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.displayLarge
|
||||
?.color),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_showPassword = false;
|
||||
});
|
||||
},
|
||||
)
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_showPassword = true;
|
||||
});
|
||||
},
|
||||
icon: Icon(FontAwesome5.eye,
|
||||
size: 24,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.displayLarge
|
||||
?.color)),
|
||||
),
|
||||
prefixIcon: const Icon(
|
||||
Icons.lock,
|
||||
color: primary,
|
||||
),
|
||||
labelText: "Password",
|
||||
hintText: enterPassword),
|
||||
obscureText: _showPassword ? true : false,
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 2,
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 7,
|
||||
// Login Button
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(second,
|
||||
Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
login,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
onPressed: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
// Future.delayed(
|
||||
// const Duration(seconds: 5), () {
|
||||
// progress!.dismiss();
|
||||
|
||||
// context.goNamed("home");
|
||||
// });
|
||||
// if (_formKey.currentState!
|
||||
// .saveAndValidate()) {
|
||||
// context.go(context.namedLocation('home'));
|
||||
// }
|
||||
|
||||
// if (_formKey.currentState.validate()) {
|
||||
// _formKey.currentState.save();
|
||||
// BlocProvider.of<UserBloc>(context)
|
||||
// .add(UserWebLogin(
|
||||
// password: password,
|
||||
// username: username));
|
||||
// }
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1.5,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 7,
|
||||
child: SizedBox(
|
||||
width:
|
||||
MediaQuery.of(context).size.width,
|
||||
child: ElevatedButton.icon(
|
||||
style: mainBtnStyle(Colors.white,
|
||||
second, primary.withOpacity(.4)),
|
||||
icon: const Icon(
|
||||
Icons.qr_code,
|
||||
color: second,
|
||||
),
|
||||
label: const Text(
|
||||
loginViaQr,
|
||||
style: TextStyle(color: second),
|
||||
),
|
||||
onPressed: () async {
|
||||
context.goNamed('register');
|
||||
// ScanResult result =
|
||||
// await QRCodeBarCodeScanner.instance
|
||||
// .scanner();
|
||||
|
||||
// debugPrint(result.type.toString());
|
||||
// debugPrint(
|
||||
// result.rawContent.toString());
|
||||
// BlocProvider.of<UserBloc>(context)
|
||||
// .add(QRCodelogin());
|
||||
},
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1,
|
||||
),
|
||||
const LoginViaQr(text: emergencyReponseLabel),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1,
|
||||
),
|
||||
// REQUEST SOS
|
||||
SizedBox(
|
||||
height: screenHeight * .07,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: ElevatedButton.icon(
|
||||
style: mainBtnStyle(Colors.white, second,
|
||||
primary.withOpacity(.4)),
|
||||
icon: const Icon(
|
||||
Icons.qr_code,
|
||||
color: second,
|
||||
),
|
||||
label: const Text(
|
||||
loginViaQr,
|
||||
style: TextStyle(color: second),
|
||||
),
|
||||
onPressed: () async {
|
||||
context.goNamed('register');
|
||||
// ScanResult result =
|
||||
// await QRCodeBarCodeScanner.instance
|
||||
// .scanner();
|
||||
|
||||
// debugPrint(result.type.toString());
|
||||
// debugPrint(
|
||||
// result.rawContent.toString());
|
||||
// BlocProvider.of<UserBloc>(context)
|
||||
// .add(QRCodelogin());
|
||||
},
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1,
|
||||
icon: const Icon(
|
||||
FontAwesome5.life_ring,
|
||||
color: Colors.white,
|
||||
),
|
||||
style: mainBtnStyle(third,
|
||||
Colors.transparent, Colors.white38),
|
||||
onPressed: () {
|
||||
context.goNamed('add-mobile');
|
||||
},
|
||||
label: const Text(
|
||||
requestSOS,
|
||||
style: TextStyle(color: Colors.white),
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
const LoginViaQr(text: emergencyReponseLabel),
|
||||
SizedBox(
|
||||
height: blockSizeVertical * 1,
|
||||
),
|
||||
// REQUEST SOS
|
||||
SizedBox(
|
||||
height: screenHeight * .07,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(
|
||||
FontAwesome5.life_ring,
|
||||
color: Colors.white,
|
||||
),
|
||||
style: mainBtnStyle(third,
|
||||
Colors.transparent, Colors.white38),
|
||||
onPressed: () {
|
||||
context.goNamed('add-mobile');
|
||||
},
|
||||
label: const Text(
|
||||
requestSOS,
|
||||
style: TextStyle(color: Colors.white),
|
||||
)),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
if (state is UserError) {
|
||||
return ErrorState(
|
||||
message: state.message,
|
||||
);
|
||||
}
|
||||
if (state is SplashScreen) {
|
||||
return const UniTSplashScreen();
|
||||
}
|
||||
return Center(
|
||||
child: Text("Default"),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:unit2/model/login_data/version_info.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../../utils/text_container.dart';
|
||||
import '../../utils/urls.dart';
|
||||
|
||||
class AuthService {
|
||||
static final AuthService _instance = AuthService();
|
||||
static AuthService get instance => _instance;
|
||||
|
||||
Future<VersionInfo> getVersionInfo() async {
|
||||
VersionInfo versionInfo = VersionInfo();
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
HttpHeaders.authorizationHeader: 'UniT2',
|
||||
'X-User': ""
|
||||
};
|
||||
try {
|
||||
http.Response response = await http.get(
|
||||
Uri.https('unitylb1.agusandelnorte.gov.ph',
|
||||
'/unit2/api/sys/apk_version/latest/'),
|
||||
headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
versionInfo = VersionInfo.fromJson(data['data']);
|
||||
}
|
||||
} on TimeoutException catch (e) {
|
||||
throw (timeoutError);
|
||||
} on SocketException catch (e) {
|
||||
throw (timeoutError);
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
return versionInfo;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:unit2/bloc/bloc/user_bloc.dart';
|
||||
import 'package:unit2/screens/unit2/login/register.dart';
|
||||
import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/scan.dart';
|
||||
import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart';
|
||||
|
@ -17,7 +20,11 @@ final GoRouter goRouter = GoRouter(routes: <GoRoute>[
|
|||
GoRoute(
|
||||
path: '/',
|
||||
name: 'login',
|
||||
builder: (context, state) => UniT2Login(),
|
||||
builder: (context, state) {
|
||||
debugPrint("login bloc called");
|
||||
BlocProvider.of<UserBloc>(context).add(GetApkVersion());
|
||||
return const UniT2Login();
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'register',
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
class Url{
|
||||
static final Url _instance = Url();
|
||||
static Url get instance => instance;
|
||||
static Url get instance => _instance;
|
||||
|
||||
|
||||
String host(){
|
||||
return '192.168.10.219:3000';
|
||||
}
|
||||
|
@ -10,4 +9,9 @@ class Url{
|
|||
String authentication(){
|
||||
return '/api/account/auth/login';
|
||||
}
|
||||
|
||||
String apkUrl(){
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/src/widgets/container.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
|
||||
class ErrorState extends StatelessWidget {
|
||||
final String? message;
|
||||
const ErrorState({super.key,this.message});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(child: Text(message!));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/src/widgets/container.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
|
||||
class UniTSplashScreen extends StatelessWidget {
|
||||
const UniTSplashScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Center(child: Text("Splash Screen"),);
|
||||
}
|
||||
}
|
|
@ -50,6 +50,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -148,6 +155,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: equatable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -188,6 +202,13 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.1"
|
||||
flutter_blurhash:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -60,6 +60,8 @@ dependencies:
|
|||
signature: ^5.3.0
|
||||
awesome_dialog: ^3.0.2
|
||||
system_info2: ^2.0.4
|
||||
flutter_bloc: ^8.1.1
|
||||
equatable: ^2.0.5
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in New Issue