apiProvider

release/mobdr-v0.0.1
Frédérik Benoist 2023-03-07 22:39:58 +01:00
parent 1824218fb0
commit 777e7e3f0d
42 changed files with 1363 additions and 601 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,5 +1,7 @@
PODS:
- Flutter (1.0.0)
- flutter_secure_storage (6.0.0):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- Toast
@ -25,6 +27,7 @@ PODS:
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- objectbox_flutter_libs (from `.symlinks/plugins/objectbox_flutter_libs/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
@ -41,6 +44,8 @@ SPEC REPOS:
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
objectbox_flutter_libs:
@ -56,6 +61,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4

View File

@ -0,0 +1,28 @@
import 'package:bloc/bloc.dart';
import 'package:mobdr/model/integration/login_model.dart';
import 'package:mobdr/network/api_provider.dart';
import 'package:meta/meta.dart';
part 'login_event.dart';
part 'login_state.dart';
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<Login>(_login);
}
}
void _login(Login event, Emitter<LoginState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(LoginWaiting());
try {
List<LoginModel> data =
await _apiProvider.login2(event.email, event.password, event.apiToken);
emit(LoginSuccess(loginData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(LoginError(errorMessage: ex.toString()));
}
}
}

View File

@ -0,0 +1,11 @@
part of 'login_bloc.dart';
@immutable
abstract class LoginEvent {}
class Login extends LoginEvent {
final String email;
final String password;
final apiToken;
Login({required this.email, required this.password, required this.apiToken});
}

View File

@ -0,0 +1,23 @@
part of 'login_bloc.dart';
@immutable
abstract class LoginState {}
class LoginInitial extends LoginState {}
class InitialLoginState extends LoginState {}
class LoginError extends LoginState {
final String errorMessage;
LoginError({
required this.errorMessage,
});
}
class LoginWaiting extends LoginState {}
class LoginSuccess extends LoginState {
final List<LoginModel> loginData;
LoginSuccess({required this.loginData});
}

View File

@ -0,0 +1,3 @@
export 'example_bloc.dart';
export 'example_event.dart';
export 'example_state.dart';

View File

@ -0,0 +1,38 @@
import 'package:bloc/bloc.dart';
import 'package:mobdr/network/api_provider.dart';
import './bloc.dart';
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
ExampleBloc() : super(InitialExampleState()) {
on<GetExample>(_getExample);
on<PostExample>(_postExample);
}
}
void _getExample(GetExample event, Emitter<ExampleState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(ExampleWaiting());
try {
String data = await _apiProvider.getExample(event.apiToken);
emit(GetExampleSuccess(exampleData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(ExampleError(errorMessage: ex.toString()));
}
}
}
void _postExample(PostExample event, Emitter<ExampleState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(ExampleWaiting());
try {
String data = await _apiProvider.postExample(event.id, event.apiToken);
emit(PostExampleSuccess(exampleData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(ExampleError(errorMessage: ex.toString()));
}
}
}

View File

@ -0,0 +1,15 @@
import 'package:meta/meta.dart';
@immutable
abstract class ExampleEvent {}
class GetExample extends ExampleEvent {
final apiToken;
GetExample({@required this.apiToken});
}
class PostExample extends ExampleEvent {
final String id;
final apiToken;
PostExample({required this.id, required this.apiToken});
}

View File

@ -0,0 +1,26 @@
import 'package:meta/meta.dart';
@immutable
abstract class ExampleState {}
class InitialExampleState extends ExampleState {}
class ExampleError extends ExampleState {
final String errorMessage;
ExampleError({
required this.errorMessage,
});
}
class ExampleWaiting extends ExampleState {}
class GetExampleSuccess extends ExampleState {
final String exampleData;
GetExampleSuccess({required this.exampleData});
}
class PostExampleSuccess extends ExampleState {
final String exampleData;
PostExampleSuccess({required this.exampleData});
}

View File

@ -0,0 +1,3 @@
export 'product_grid_bloc.dart';
export 'product_grid_event.dart';
export 'product_grid_state.dart';

View File

@ -0,0 +1,26 @@
import 'package:bloc/bloc.dart';
import 'package:mobdr/model/integration/product_grid_model.dart';
import 'package:mobdr/network/api_provider.dart';
import './bloc.dart';
class ProductGridBloc extends Bloc<ProductGridEvent, ProductGridState> {
ProductGridBloc() : super(InitialProductGridState()) {
on<GetProductGrid>(_getProductGrid);
}
}
void _getProductGrid(
GetProductGrid event, Emitter<ProductGridState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(ProductGridWaiting());
try {
List<ProductGridModel> data = await _apiProvider.getProductGrid(
event.sessionId, event.skip, event.limit, event.apiToken);
emit(GetProductGridSuccess(productGridData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(ProductGridError(errorMessage: ex.toString()));
}
}
}

View File

@ -0,0 +1,10 @@
import 'package:meta/meta.dart';
@immutable
abstract class ProductGridEvent {}
class GetProductGrid extends ProductGridEvent {
final String sessionId, skip, limit;
final apiToken;
GetProductGrid({required this.sessionId, required this.skip, required this.limit, @required this.apiToken});
}

View File

@ -0,0 +1,22 @@
import 'package:mobdr/model/integration/product_grid_model.dart';
import 'package:meta/meta.dart';
@immutable
abstract class ProductGridState {}
class InitialProductGridState extends ProductGridState {}
class ProductGridError extends ProductGridState {
final String errorMessage;
ProductGridError({
required this.errorMessage,
});
}
class ProductGridWaiting extends ProductGridState {}
class GetProductGridSuccess extends ProductGridState {
final List<ProductGridModel> productGridData;
GetProductGridSuccess({required this.productGridData});
}

View File

@ -0,0 +1,3 @@
export 'product_listview_bloc.dart';
export 'product_listview_event.dart';
export 'product_listview_state.dart';

View File

@ -0,0 +1,27 @@
import 'package:bloc/bloc.dart';
import 'package:mobdr/model/integration/product_listview_model.dart';
import 'package:mobdr/network/api_provider.dart';
import './bloc.dart';
class ProductListviewBloc
extends Bloc<ProductListviewEvent, ProductListviewState> {
ProductListviewBloc() : super(InitialProductListviewState()) {
on<GetProductListview>(_getProductListview);
}
}
void _getProductListview(
GetProductListview event, Emitter<ProductListviewState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(ProductListviewWaiting());
try {
List<ProductListviewModel> data = await _apiProvider.getProductListview(
event.sessionId, event.skip, event.limit, event.apiToken);
emit(GetProductListviewSuccess(productListviewData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(ProductListviewError(errorMessage: ex.toString()));
}
}
}

View File

@ -0,0 +1,10 @@
import 'package:meta/meta.dart';
@immutable
abstract class ProductListviewEvent {}
class GetProductListview extends ProductListviewEvent {
final String sessionId, skip, limit;
final apiToken;
GetProductListview({required this.sessionId, required this.skip, required this.limit, required this.apiToken});
}

View File

@ -0,0 +1,22 @@
import 'package:mobdr/model/integration/product_listview_model.dart';
import 'package:meta/meta.dart';
@immutable
abstract class ProductListviewState {}
class InitialProductListviewState extends ProductListviewState {}
class ProductListviewError extends ProductListviewState {
final String errorMessage;
ProductListviewError({
required this.errorMessage,
});
}
class ProductListviewWaiting extends ProductListviewState {}
class GetProductListviewSuccess extends ProductListviewState {
final List<ProductListviewModel> productListviewData;
GetProductListviewSuccess({required this.productListviewData});
}

View File

@ -0,0 +1,3 @@
export 'student_bloc.dart';
export 'student_event.dart';
export 'student_state.dart';

View File

@ -0,0 +1,121 @@
import 'package:bloc/bloc.dart';
import 'package:mobdr/model/integration/student_model.dart';
import 'package:mobdr/network/api_provider.dart';
import './bloc.dart';
class StudentBloc extends Bloc<StudentEvent, StudentState> {
StudentBloc() : super(InitialStudentState()) {
on<GetStudent>(_getStudent);
on<AddStudent>(_addStudent);
on<EditStudent>(_editStudent);
on<DeleteStudent>(_deleteStudent);
}
}
void _getStudent(GetStudent event, Emitter<StudentState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(GetStudentWaiting());
try {
List<StudentModel> data =
await _apiProvider.getStudent(event.sessionId, event.apiToken);
emit(GetStudentSuccess(studentData: data));
} catch (ex) {
if (ex != 'cancel') {
emit(GetStudentError(errorMessage: ex.toString()));
}
}
}
void _addStudent(AddStudent event, Emitter<StudentState> emit) async {
ApiProvider _apiProvider = ApiProvider();
String errorMessage = '';
if (event.studentName == '') {
errorMessage = 'Student name cannot be empty';
} else if (event.studentPhoneNumber == '') {
errorMessage = 'Student phone number can not be empty';
} else if (event.studentGender == '') {
errorMessage = 'Student gender can not be empty';
} else if (event.studentAddress == '') {
errorMessage = 'Student address can not be empty';
}
if (errorMessage == '') {
emit(AddStudentWaiting());
try {
List data = await _apiProvider.addStudent(
event.sessionId,
event.studentName,
event.studentPhoneNumber,
event.studentGender,
event.studentAddress,
event.apiToken);
emit(AddStudentSuccess(
msg: data[0],
studentId: data[1],
studentName: event.studentName,
studentPhoneNumber: event.studentPhoneNumber,
studentGender: event.studentGender,
studentAddress: event.studentAddress));
} catch (ex) {
emit(AddStudentError(errorMessage: ex.toString()));
}
} else {
emit(StudentErrorValidation(errorMessage: errorMessage));
}
}
void _editStudent(EditStudent event, Emitter<StudentState> emit) async {
ApiProvider _apiProvider = ApiProvider();
String errorMessage = '';
if (event.studentName == '') {
errorMessage = 'Student name cannot be empty';
} else if (event.studentPhoneNumber == '') {
errorMessage = 'Student phone number can not be empty';
} else if (event.studentGender == '') {
errorMessage = 'Student gender can not be empty';
} else if (event.studentAddress == '') {
errorMessage = 'Student address can not be empty';
}
if (errorMessage == '') {
emit(EditStudentWaiting());
try {
String message = await _apiProvider.editStudent(
event.sessionId,
event.studentId,
event.studentName,
event.studentPhoneNumber,
event.studentGender,
event.studentAddress,
event.apiToken);
emit(EditStudentSuccess(
msg: message,
index: event.index,
studentId: event.studentId,
studentName: event.studentName,
studentPhoneNumber: event.studentPhoneNumber,
studentGender: event.studentGender,
studentAddress: event.studentAddress));
} catch (ex) {
emit(EditStudentError(errorMessage: ex.toString()));
}
} else {
emit(StudentErrorValidation(errorMessage: errorMessage));
}
}
void _deleteStudent(DeleteStudent event, Emitter<StudentState> emit) async {
ApiProvider _apiProvider = ApiProvider();
emit(DeleteStudentWaiting());
try {
String msg = await _apiProvider.deleteStudent(
event.sessionId, event.studentId, event.apiToken);
emit(DeleteStudentSuccess(msg: msg, index: event.index));
} catch (ex) {
emit(DeleteStudentError(errorMessage: ex.toString()));
}
}

View File

@ -0,0 +1,32 @@
import 'package:meta/meta.dart';
@immutable
abstract class StudentEvent {}
class GetStudent extends StudentEvent {
final String sessionId;
final apiToken;
GetStudent({required this.sessionId, required this.apiToken});
}
class AddStudent extends StudentEvent {
final String sessionId;
final String studentName, studentPhoneNumber, studentGender, studentAddress;
final apiToken;
AddStudent({required this.sessionId, required this.studentName, required this.studentPhoneNumber, required this.studentGender, required this.studentAddress, required this.apiToken});
}
class EditStudent extends StudentEvent {
final String sessionId;
final int studentId, index;
final String studentName, studentPhoneNumber, studentGender, studentAddress;
final apiToken;
EditStudent({required this.sessionId, required this.index, required this.studentId, required this.studentName, required this.studentPhoneNumber, required this.studentGender, required this.studentAddress, required this.apiToken});
}
class DeleteStudent extends StudentEvent {
final String sessionId;
final int studentId, index;
final apiToken;
DeleteStudent({required this.sessionId, required this.studentId, required this.index, required this.apiToken});
}

View File

@ -0,0 +1,99 @@
import 'package:mobdr/model/integration/student_model.dart';
import 'package:meta/meta.dart';
@immutable
abstract class StudentState {}
class InitialStudentState extends StudentState {}
// get student state
class GetStudentWaiting extends StudentState {}
class GetStudentError extends StudentState {
final String errorMessage;
GetStudentError({
required this.errorMessage,
});
}
class GetStudentSuccess extends StudentState {
final List<StudentModel> studentData;
GetStudentSuccess({required this.studentData});
}
// general
class StudentErrorValidation extends StudentState {
final String errorMessage;
StudentErrorValidation({
required this.errorMessage,
});
}
// add student state
class AddStudentWaiting extends StudentState {}
class AddStudentError extends StudentState {
final String errorMessage;
AddStudentError({
required this.errorMessage,
});
}
class AddStudentSuccess extends StudentState {
final int studentId;
final String msg,
studentName,
studentPhoneNumber,
studentGender,
studentAddress;
AddStudentSuccess(
{required this.msg,
required this.studentId,
required this.studentName,
required this.studentPhoneNumber,
required this.studentGender,
required this.studentAddress});
}
// edit student state
class EditStudentWaiting extends StudentState {}
class EditStudentError extends StudentState {
final String errorMessage;
EditStudentError({
required this.errorMessage,
});
}
class EditStudentSuccess extends StudentState {
final int studentId, index;
final String msg,
studentName,
studentPhoneNumber,
studentGender,
studentAddress;
EditStudentSuccess(
{required this.msg,
required this.index,
required this.studentId,
required this.studentName,
required this.studentPhoneNumber,
required this.studentGender,
required this.studentAddress});
}
// delete student state
class DeleteStudentWaiting extends StudentState {}
class DeleteStudentError extends StudentState {
final String errorMessage;
DeleteStudentError({
required this.errorMessage,
});
}
class DeleteStudentSuccess extends StudentState {
final String msg;
final int index;
DeleteStudentSuccess({required this.msg, required this.index});
}

View File

@ -17,6 +17,12 @@ const Color BLACK_GREY = Color(0xff777777);
const Color SOFT_GREY = Color(0xFFaaaaaa);
const Color SOFT_BLUE = Color(0xff01aed6);
const int STATUS_OK = 200;
const int STATUS_BAD_REQUEST = 400;
const int STATUS_NOT_AUTHORIZED = 403;
const int STATUS_NOT_FOUND = 404;
const int STATUS_INTERNAL_ERROR = 500;
const String ERROR_OCCURED = 'Error occured, please try again later';
const int LIMIT_PAGE = 8;
@ -26,3 +32,14 @@ const String GLOBAL_URL = 'https://ijtechnology.net/assets/images/api/devkit';
//const String GLOBAL_URL = 'http://192.168.100.9/devkit';
const String LOCAL_IMAGES_URL = 'assets/images';
class ApiConstants {
static String baseUrl = 'https://mp4.ikksgroup.com';
static String mobDREndpoint = '/mobdr';
static String mp4Endpoint = '/MobilePortal4/webresources';
static String externalEndpoint = '/MobilePortal4_external/webresources';
static String restEndpoint = '/rest/api';
}
const String LOGIN_API = 'https://mp4.ikksgroup.com' + "/authentication/login";
const String PRODUCT_API = 'https://mp4.ikksgroup.com' + "/example/getProduct";

57
lib/model/login.dart Normal file
View File

@ -0,0 +1,57 @@
class LoginModel {
int idUtilisateur;
String email;
int expire;
String guid;
String langage;
String lastTraduction;
String login;
String nom;
String prenom;
String version;
String photo;
LoginModel(
this.idUtilisateur,
this.email,
this.expire,
this.guid,
this.langage,
this.lastTraduction,
this.login,
this.nom,
this.prenom,
this.version,
this.photo);
LoginModel.fromJson(Map<String, dynamic> json)
: idUtilisateur = json['id_utilisateur'],
email = json['email'],
expire = json['expire'],
guid = json['guid'],
langage = json['langage'],
lastTraduction = json['last_traduction'],
login = json['login'],
nom = json['nom'],
prenom = json['prenom'],
version = json['version'],
photo = json['photo'];
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id_utilisateur'] = this.idUtilisateur;
data['email'] = this.email;
data['expire'] = this.expire;
data['guid'] = this.guid;
data['langage'] = this.langage;
data['last_traduction'] = this.lastTraduction;
data['login'] = this.login;
data['nom'] = this.nom;
data['prenom'] = this.prenom;
data['version'] = this.version;
data['photo'] = this.photo;
return data;
}
}

View File

@ -0,0 +1,20 @@
class UserProfileModel {
final String name;
final String accessToken;
final int age;
UserProfileModel({this.name = '', this.accessToken = '', this.age = 0});
UserProfileModel.fromJson(Map<String, dynamic> json)
: name = json['name'],
accessToken = json['accessToken'],
age = json['age'];
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['accessToken'] = this.accessToken;
data['age'] = this.age;
return data;
}
}

View File

@ -0,0 +1,313 @@
/*
This is api provider
This page is used to get data from API
*/
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/service/local_storage.dart';
import 'package:mobdr/model/login.dart';
import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';
class ApiProvider {
Dio dio = Dio();
late Response response;
String connErr = 'Please check your internet connection and try again';
Future<Response> getCrud(url, body) async {
print('url : ' + url.toString());
try {
dio.options.headers['content-Type'] = 'application/json';
dio.options.headers['Accept'] = 'application/json';
dio.options.connectTimeout = 30000; //5s
dio.options.receiveTimeout = 25000;
dio.options.queryParameters = body;
return await dio.get(url);
} on DioError catch (e) {
//print(e.toString()+' | '+url.toString());
if (e.type == DioErrorType.response) {
int? statusCode = e.response!.statusCode;
if (statusCode == STATUS_NOT_FOUND) {
throw "Api not found";
} else if (statusCode == STATUS_INTERNAL_ERROR) {
throw "Internal Server Error";
} else {
throw e.error.message.toString();
}
} else if (e.type == DioErrorType.connectTimeout) {
throw e.message.toString();
} else if (e.type == DioErrorType.cancel) {
throw 'cancel';
}
throw connErr;
} finally {
//dio.close(); // TODO: Attention pas close
}
}
Future<Response> getConnect(url, apiToken) async {
print('url : ' + url.toString());
try {
dio.options.headers['content-Type'] = 'application/x-www-form-urlencoded';
dio.options.connectTimeout = 30000; //5s
dio.options.receiveTimeout = 25000;
return await dio.post(url, cancelToken: apiToken);
} on DioError catch (e) {
//print(e.toString()+' | '+url.toString());
if (e.type == DioErrorType.response) {
int? statusCode = e.response!.statusCode;
if (statusCode == STATUS_NOT_FOUND) {
throw "Api not found";
} else if (statusCode == STATUS_INTERNAL_ERROR) {
throw "Internal Server Error";
} else {
throw e.error.message.toString();
}
} else if (e.type == DioErrorType.connectTimeout) {
throw e.message.toString();
} else if (e.type == DioErrorType.cancel) {
throw 'cancel';
}
throw connErr;
} finally {
//dio.close();
}
}
Future<Response> postConnect(url, data, apiToken) async {
print('url : ' + url.toString());
print('postData : ' + data.toString());
try {
dio.options.headers['content-Type'] = 'application/x-www-form-urlencoded';
dio.options.connectTimeout = 30000; //5s
dio.options.receiveTimeout = 25000;
return await dio.post(url, data: data, cancelToken: apiToken);
} on DioError catch (e) {
//print(e.toString()+' | '+url.toString());
if (e.type == DioErrorType.response) {
int? statusCode = e.response!.statusCode;
if (statusCode == STATUS_NOT_FOUND) {
throw "Api not found";
} else if (statusCode == STATUS_INTERNAL_ERROR) {
throw "Internal Server Error";
} else {
throw e.error.message.toString();
}
} else if (e.type == DioErrorType.connectTimeout) {
throw e.message.toString();
} else if (e.type == DioErrorType.cancel) {
throw 'cancel';
}
throw connErr;
} finally {
dio.close();
}
}
/// login function
Future<String> login(
String userName, String pinCode, String securityCode) async {
var body = {
"application": "MobDR ", //+ ExeInfo(exeVersion)
"pin_code": md5.convert(utf8.encode(pinCode)),
"security_code": securityCode, //sCodeSecurite
"langage": "fr",
"screenheight": "0", //SysYRes()
"screenwidth": "0", //SysXRes()
"browser_name": "Natif",
"browser_version": "Application",
"engine_name": "Android",
"device_model": "",
"device_type": "mobile", //SysInfoAppareil(sysModele) WDM 23
"device_vendor": "", //SysInfoAppareil(sysFabricant) WDM 23
"ismobile": 1,
"engine_version": "", // SysVersionAndroid(sysVersionApiLevel)
"os_name": "", // SysVersionAndroid(sysVersionPlateForme)
"os_version": "", //SysVersionAndroid(sysVersionNumÈro)
"fingerprint":
"aa" // TODO: on peut mettre un fingerprint sur la version ou sur l'heure
};
try {
response = await getCrud(
ApiConstants.baseUrl +
ApiConstants.mp4Endpoint +
ApiConstants.restEndpoint +
'/login/' +
userName +
'/guid',
body);
print('res : ' + response.toString());
switch (response.data['autorisation']) {
case 1:
LocalStorage.saveLoginData(LoginModel.fromJson(response.data));
return 'OK';
case -1:
return 'Compte désactivé ...';
case -2:
return 'SECURITY_CODE';
case -3:
return 'Téléphone bloqué !';
case -4:
return 'Code PIN incorrect !';
default:
return "Une erreur inconnue s''est produite";
}
} catch (ex) {
return ex.toString(); // return ex.response!.data;
}
}
Future<String> getExample(apiToken) async {
response =
await getConnect(ApiConstants.baseUrl + '/example/getData', apiToken);
print('res : ' + response.toString());
return response.data.toString();
}
Future<String> postExample(String id, apiToken) async {
var postData = {'id': id};
response = await postConnect(
ApiConstants.baseUrl + '/example/postData', postData, apiToken);
print('res : ' + response.toString());
return response.data.toString();
}
/*
Future<List<StudentModel>> getStudent(String sessionId, apiToken) async {
var postData = {'session_id': sessionId};
response = await postConnect(
ApiConstants.baseUrl + '/student/getStudent', postData, apiToken);
if (response.data['status'] == STATUS_OK) {
List responseList = response.data['data'];
List<StudentModel> listData =
responseList.map((f) => StudentModel.fromJson(f)).toList();
return listData;
} else {
throw response.data['msg'];
}
}
*/
Future<List<dynamic>> addStudent(
String sessionId,
String studentName,
String studentPhoneNumber,
String studentGender,
String studentAddress,
apiToken) async {
var postData = {
'session_id': sessionId,
'student_name': studentName,
'student_phone_number': studentPhoneNumber,
'student_gender': studentGender,
'student_address': studentAddress,
};
response = await postConnect(
ApiConstants.baseUrl + '/student/addStudent', postData, apiToken);
if (response.data['status'] == STATUS_OK) {
List<dynamic> respList = [];
respList.add(response.data['msg']);
respList.add(response.data['data']['id']);
return respList;
} else {
throw response.data['msg'];
}
}
Future<String> editStudent(
String sessionId,
int studentId,
String studentName,
String studentPhoneNumber,
String studentGender,
String studentAddress,
apiToken) async {
var postData = {
'session_id': sessionId,
'student_id': studentId,
'student_name': studentName,
'student_phone_number': studentPhoneNumber,
'student_gender': studentGender,
'student_address': studentAddress,
};
response = await postConnect(
ApiConstants.baseUrl + '/student/editStudent', postData, apiToken);
if (response.data['status'] == STATUS_OK) {
return response.data['msg'];
} else {
throw response.data['msg'];
}
}
Future<String> deleteStudent(
String sessionId, int studentId, apiToken) async {
var postData = {
'session_id': sessionId,
'student_id': studentId,
};
response = await postConnect(
ApiConstants.baseUrl + '/student/deleteStudent', postData, apiToken);
if (response.data['status'] == STATUS_OK) {
return response.data['msg'];
} else {
throw response.data['msg'];
}
}
Future<List<LoginModel>> login2(
String email, String password, apiToken) async {
var postData = {
'email': email,
'password': password,
};
response = await postConnect(LOGIN_API, postData, apiToken);
if (response.data['status'] == STATUS_OK) {
List responseList = response.data['data'];
List<LoginModel> listData =
responseList.map((f) => LoginModel.fromJson(f)).toList();
return listData;
} else {
throw response.data['msg'];
}
}
/*
Future<List<ProductGridModel>> getProductGrid(
String sessionId, String skip, String limit, apiToken) async {
var postData = {'session_id': sessionId, 'skip': skip, 'limit': limit};
response = await postConnect(PRODUCT_API, postData, apiToken);
if (response.data['status'] == STATUS_OK) {
List responseList = response.data['data'];
//print('data : '+responseList.toString());
List<ProductGridModel> listData =
responseList.map((f) => ProductGridModel.fromJson(f)).toList();
return listData;
} else {
throw response.data['msg'];
}
}
*/
/*
Future<List<ProductListviewModel>> getProductListview(
String sessionId, String skip, String limit, apiToken) async {
var postData = {'session_id': sessionId, 'skip': skip, 'limit': limit};
response = await postConnect(PRODUCT_API, postData, apiToken);
if (response.data['status'] == STATUS_OK) {
List responseList = response.data['data'];
//print('data : '+responseList.toString());
List<ProductListviewModel> listData =
responseList.map((f) => ProductListviewModel.fromJson(f)).toList();
return listData;
} else {
throw response.data['msg'];
}
}
*/
}

View File

@ -0,0 +1,85 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
//import 'package:shared_preferences/shared_preferences.dart';
import 'package:mobdr/model/login.dart';
import 'package:mobdr/model/user_profile.dart';
class LocalStorage {
//static Future<SharedPreferences> get prefs async =>
// await SharedPreferences.getInstance();
static FlutterSecureStorage get securePref => FlutterSecureStorage();
static Future eraseProfileData() async {
var loginData = (await getLoginData());
loginData?.guid = '';
//await saveLoginData(LoginModel: loginData);
}
static Future<LoginModel?> getLoginData() async {
try {
var loginData = await securePref.read(key: 'loginData');
return LoginModel.fromJson(json.decode(loginData!));
} catch (e) {
return null;
}
}
static Future saveLoginData(LoginModel loginModel) async {
return securePref.write(
key: 'loginData', value: json.encode(loginModel.toJson()));
}
static Future<UserProfileModel?> getProfileData() async {
try {
var profileData = await securePref.read(key: 'profileData');
return UserProfileModel.fromJson(json.decode(profileData!));
} catch (e) {
return null;
}
}
static Future saveProfileData(UserProfileModel profileModel) async {
try {
return securePref.write(
key: 'profileData', value: json.encode(profileModel.toJson()));
} catch (e) {
return null;
}
}
static Future saveItem({@required item, @required key}) async {
securePref.write(key: key.toString(), value: item);
}
static Future eraseItem({@required key}) async {
securePref.delete(key: '$key');
}
static Future<bool> keyExists(String key) async {
return securePref.containsKey(key: key);
}
/*
static eraseAll() async {
var savedData = await getSavedBooks();
for (var item in savedData) {
try {
await File(await downloadDir(item.id)).delete();
} catch (e) {}
}
securePref.deleteAll();
(await prefs).clear();
return;
}
static Future<dynamic> getItemData({@required key}) async {
return await securePref.containsKey(key: '$key')
? securePref.read(key: '$key')
: null;
}
*/
}

View File

@ -19,7 +19,7 @@ import 'package:mobdr/ui/general/notification.dart';
import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:mobdr/ui/reusable/cache_image_network.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/ui/authentication/signin.dart';
class TabAccountPage extends StatefulWidget {
@override
@ -97,8 +97,24 @@ class _TabAccountPageState extends State<TabAccountPage>
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
Fluttertoast.showToast(
msg: 'Click Sign Out', toastLength: Toast.LENGTH_LONG);
Navigator.pushAndRemoveUntil(
context,
PageRouteBuilder(pageBuilder: (BuildContext context,
Animation animation, Animation secondaryAnimation) {
return SigninPage();
}, transitionsBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return new SlideTransition(
position: new Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: child,
);
}),
(Route route) => false);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,

View File

@ -1,115 +0,0 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/config/global_style.dart';
class ForgotPasswordPage extends StatefulWidget {
@override
_ForgotPasswordPageState createState() => _ForgotPasswordPageState();
}
class _ForgotPasswordPageState extends State<ForgotPasswordPage> {
TextEditingController _etEmail = TextEditingController();
@override
void initState() {
_etEmail = TextEditingController(text: 'robert.steven@ijtechnology.net');
super.initState();
}
@override
void dispose() {
_etEmail.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: EdgeInsets.fromLTRB(30, 120, 30, 30),
children: <Widget>[
Center(child: Image.asset('assets/images/logo.png', height: 32)),
SizedBox(
height: 80,
),
TextFormField(
keyboardType: TextInputType.emailAddress,
controller: _etEmail,
style: TextStyle(color: CHARCOAL),
onChanged: (textValue) {
setState(() {});
},
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Email',
labelStyle: TextStyle(color: BLACK_GREY)),
),
SizedBox(
height: 10,
),
Text(
'We will send the instruction to reset your password through the email',
style: GlobalStyle.resetPasswordNotes,
),
SizedBox(
height: 40,
),
Container(
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) => PRIMARY_COLOR,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
),
onPressed: () {
Fluttertoast.showToast(
msg: 'Click Reset Password',
toastLength: Toast.LENGTH_LONG);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: Text(
'Reset Password',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white),
textAlign: TextAlign.center,
),
)),
),
SizedBox(
height: 50,
),
// create sign in link
Center(
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GlobalStyle.iconBack,
Text(
' Back to login',
style: GlobalStyle.back,
)
],
),
),
)
],
));
}
}

View File

@ -1,8 +1,10 @@
import 'package:universal_io/io.dart';
import 'package:mobdr/ui/home.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobdr/network/api_provider.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/verification.dart';
class SigninPage extends StatefulWidget {
@override
@ -12,6 +14,10 @@ class SigninPage extends StatefulWidget {
class _SigninPageState extends State<SigninPage> {
bool _obscureText = true;
IconData _iconVisible = Icons.visibility_off;
ApiProvider _apiProvider = ApiProvider(); // TODO: A voir si bien positionné
TextEditingController _etUserName = TextEditingController();
TextEditingController _etPinCode = TextEditingController();
Color _gradientTop = Color(0xFF039be6);
Color _gradientBottom = Color(0xFF0299e2);
@ -31,11 +37,15 @@ class _SigninPageState extends State<SigninPage> {
@override
void initState() {
_etUserName = TextEditingController(text: 'fbenoist');
_etPinCode = TextEditingController(text: '9295');
super.initState();
}
@override
void dispose() {
_etUserName.dispose();
_etPinCode.dispose();
super.dispose();
}
@ -97,6 +107,7 @@ class _SigninPageState extends State<SigninPage> {
),
TextField(
keyboardType: TextInputType.emailAddress,
controller: _etUserName,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
@ -114,6 +125,7 @@ class _SigninPageState extends State<SigninPage> {
),
TextField(
obscureText: _obscureText,
controller: _etPinCode,
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
@ -122,7 +134,7 @@ class _SigninPageState extends State<SigninPage> {
borderSide:
BorderSide(color: _underlineColor),
),
labelText: 'Password',
labelText: 'Pin code',
labelStyle: TextStyle(color: Colors.grey[700]),
suffixIcon: IconButton(
icon: Icon(_iconVisible,
@ -133,24 +145,7 @@ class _SigninPageState extends State<SigninPage> {
),
),
SizedBox(
height: 20,
),
Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click forgot password',
toastLength: Toast.LENGTH_SHORT);
},
child: Text(
'Forgot Password?',
style: TextStyle(fontSize: 13),
),
),
),
SizedBox(
height: 40,
height: 60,
),
SizedBox(
width: double.maxFinite,
@ -167,12 +162,26 @@ class _SigninPageState extends State<SigninPage> {
borderRadius: BorderRadius.circular(10),
)),
),
onPressed: () {
onPressed: () async {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
Navigator.pushReplacement(
var apiResponse = await _apiProvider.login(
_etUserName.text, _etPinCode.text, '');
if (apiResponse == 'OK') {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => HomePage()),
(Route<dynamic> route) => false);
} else if (apiResponse == 'SECURITY_CODE') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage()));
builder: (_) =>
VerificationPage()));
} else {
Fluttertoast.showToast(
msg: apiResponse,
toastLength: Toast.LENGTH_SHORT);
}
},
child: Padding(
padding:
@ -188,32 +197,6 @@ class _SigninPageState extends State<SigninPage> {
],
)),
),
SizedBox(
height: 50,
),
// create sign up link
Center(
child: Wrap(
children: <Widget>[
Text('New User? '),
GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click signup',
toastLength: Toast.LENGTH_SHORT);
},
child: Text(
'Sign Up',
style: TextStyle(
color: _mainColor, fontWeight: FontWeight.w700),
),
)
],
),
),
SizedBox(
height: 20,
),
],
)
],

View File

@ -1,250 +0,0 @@
import 'package:mobdr/config/global_style.dart';
import 'package:mobdr/ui/authentication/forgot_password.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/signup.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobdr/config/constant.dart';
class SigninPage extends StatefulWidget {
@override
_SigninPageState createState() => _SigninPageState();
}
class _SigninPageState extends State<SigninPage> {
TextEditingController _etEmail = TextEditingController();
bool _obscureText = true;
IconData _iconVisible = Icons.visibility_off;
void _toggleObscureText() {
setState(() {
_obscureText = !_obscureText;
if (_obscureText == true) {
_iconVisible = Icons.visibility_off;
} else {
_iconVisible = Icons.visibility;
}
});
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
_etEmail.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: EdgeInsets.fromLTRB(30, 120, 30, 30),
children: <Widget>[
Center(child: Image.asset('assets/images/logo.png', height: 32)),
SizedBox(
height: 80,
),
Text('Sign In', style: GlobalStyle.authTitle),
TextFormField(
keyboardType: TextInputType.emailAddress,
controller: _etEmail,
style: TextStyle(color: CHARCOAL),
onChanged: (textValue) {
setState(() {});
},
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Email',
labelStyle: TextStyle(color: BLACK_GREY),
),
),
SizedBox(
height: 20,
),
TextField(
obscureText: _obscureText,
style: TextStyle(color: CHARCOAL),
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Password',
labelStyle: TextStyle(color: BLACK_GREY),
suffixIcon: IconButton(
icon: Icon(_iconVisible, color: Colors.grey[400], size: 20),
onPressed: () {
_toggleObscureText();
}),
),
),
SizedBox(
height: 20,
),
Align(
alignment: Alignment.centerRight,
child: Container(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ForgotPasswordPage()));
FocusScope.of(context).unfocus();
},
child: Text(
'Forgot Password?',
style: TextStyle(color: PRIMARY_COLOR, fontSize: 13),
),
),
)),
SizedBox(
height: 40,
),
Container(
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) => PRIMARY_COLOR,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
),
onPressed: () {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage()));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: Text(
'Login',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white),
textAlign: TextAlign.center,
),
)),
),
SizedBox(
height: 40,
),
Center(
child: Text(
'Or sign in with',
style: GlobalStyle.authSignWith,
),
),
SizedBox(
height: 20,
),
Container(
margin: EdgeInsets.fromLTRB(20, 0, 20, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
GestureDetector(
onTap: () {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage()));
Fluttertoast.showToast(
msg: 'Sign in with Google',
toastLength: Toast.LENGTH_LONG);
},
child: Image(
image: AssetImage("assets/images/google.png"),
width: 40,
),
),
GestureDetector(
onTap: () {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage()));
Fluttertoast.showToast(
msg: 'Sign in with Facebook',
toastLength: Toast.LENGTH_LONG);
},
child: Image(
image: AssetImage("assets/images/facebook.png"),
width: 40,
),
),
GestureDetector(
onTap: () {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage()));
Fluttertoast.showToast(
msg: 'Sign in with Twitter',
toastLength: Toast.LENGTH_LONG);
},
child: Image(
image: AssetImage("assets/images/twitter.png"),
width: 40,
),
)
],
),
),
SizedBox(
height: 20,
),
Center(
child: GestureDetector(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SignupPage()));
FocusScope.of(context).unfocus();
},
child: Wrap(
children: [
Text(
'No account yet? ',
style: GlobalStyle.authBottom1,
),
Text(
'Create one',
style: GlobalStyle.authBottom2,
)
],
),
),
),
SizedBox(
height: 30,
),
Center(
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GlobalStyle.iconBack,
Text(
' Back',
style: GlobalStyle.back,
)
],
),
),
),
],
));
}
}

View File

@ -1,177 +0,0 @@
import 'package:mobdr/ui/home.dart';
import 'package:flutter/material.dart';
import 'package:mobdr/config/constant.dart';
import 'package:mobdr/config/global_style.dart';
class SignupPage extends StatefulWidget {
final bool fromList;
const SignupPage({Key? key, this.fromList = false}) : super(key: key);
@override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
TextEditingController _etEmail = TextEditingController();
TextEditingController _etName = TextEditingController();
bool _obscureText = true;
IconData _iconVisible = Icons.visibility_off;
void _toggleObscureText() {
setState(() {
_obscureText = !_obscureText;
if (_obscureText == true) {
_iconVisible = Icons.visibility_off;
} else {
_iconVisible = Icons.visibility;
}
});
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
_etEmail.dispose();
_etName.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: WillPopScope(
onWillPop: () {
FocusScope.of(context).unfocus();
return Future.value(true);
},
child: ListView(
padding: EdgeInsets.fromLTRB(30, 120, 30, 30),
children: <Widget>[
Center(child: Image.asset('assets/images/logo.png', height: 32)),
SizedBox(
height: 80,
),
Text('Sign Up', style: GlobalStyle.authTitle),
TextFormField(
keyboardType: TextInputType.emailAddress,
controller: _etEmail,
style: TextStyle(color: CHARCOAL),
onChanged: (textValue) {
setState(() {});
},
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Email',
labelStyle: TextStyle(color: BLACK_GREY),
),
),
SizedBox(
height: 20,
),
TextFormField(
keyboardType: TextInputType.text,
controller: _etName,
style: TextStyle(color: CHARCOAL),
onChanged: (textValue) {
setState(() {});
},
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Name',
labelStyle: TextStyle(color: BLACK_GREY),
),
),
SizedBox(
height: 20,
),
TextField(
obscureText: _obscureText,
style: TextStyle(color: CHARCOAL),
decoration: InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: PRIMARY_COLOR, width: 2.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(0xFFCCCCCC)),
),
labelText: 'Password',
labelStyle: TextStyle(color: BLACK_GREY),
suffixIcon: IconButton(
icon: Icon(_iconVisible, color: Colors.grey[400], size: 20),
onPressed: () {
_toggleObscureText();
}),
),
),
SizedBox(
height: 40,
),
Container(
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) => PRIMARY_COLOR,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
),
onPressed: () {
//Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => HomePage()), (Route<dynamic> route) => false);
if (!widget.fromList) {
Navigator.pop(context);
}
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => HomePage()));
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: Text(
'Register',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white),
textAlign: TextAlign.center,
),
)),
),
SizedBox(
height: 30,
),
Center(
child: GestureDetector(
onTap: () {
Navigator.pop(context);
FocusScope.of(context).unfocus();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
GlobalStyle.iconBack,
Text(
' Back to login',
style: GlobalStyle.back,
)
],
),
),
),
],
),
));
}
}

View File

@ -0,0 +1,172 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:mobdr/network/api_provider.dart';
import 'package:mobdr/ui/home.dart';
import 'package:mobdr/ui/authentication/signin.dart';
class VerificationPage extends StatefulWidget {
@override
_VerificationPageState createState() => _VerificationPageState();
}
class _VerificationPageState extends State<VerificationPage> {
Color _color1 = Color(0xFF07ac12);
Color _color2 = Color(0xFF515151);
Color _color3 = Color(0xff777777);
Color _color4 = Color(0xFFaaaaaa);
bool _buttonDisabled = true;
String _securityCode = '';
ApiProvider _apiProvider = ApiProvider(); // TODO: A voir si bien positionné
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: EdgeInsets.fromLTRB(30, 120, 30, 30),
children: <Widget>[
Center(child: Icon(Icons.phone_android, color: _color1, size: 50)),
SizedBox(height: 20),
Center(
child: Text(
'Enter the Verification Code',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold, color: _color2),
)),
SizedBox(
height: 20,
),
Container(
width: MediaQuery.of(context).size.width / 1.5,
child: Text(
'The verification code has been sent by mail',
style: TextStyle(fontSize: 13, color: _color3),
textAlign: TextAlign.center,
),
),
SizedBox(
height: 40,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 50),
child: PinCodeTextField(
autoFocus: true,
appContext: context,
keyboardType: TextInputType.number,
length: 4,
showCursor: false,
obscureText: false,
animationType: AnimationType.fade,
pinTheme: PinTheme(
shape: PinCodeFieldShape.underline,
fieldHeight: 50,
fieldWidth: 40,
inactiveColor: _color4,
activeColor: _color1,
selectedColor: _color1),
animationDuration: Duration(milliseconds: 300),
backgroundColor: Colors.transparent,
onChanged: (value) {
setState(() {
if (value.length == 4) {
_buttonDisabled = false;
} else {
_buttonDisabled = true;
}
_securityCode = value;
});
},
beforeTextPaste: (text) {
return false;
},
),
),
SizedBox(
height: 40,
),
Container(
child: SizedBox(
width: double.maxFinite,
child: TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) =>
_buttonDisabled ? Colors.grey[300]! : _color1,
),
overlayColor: MaterialStateProperty.all(Colors.transparent),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3.0),
)),
),
onPressed: () async {
if (!_buttonDisabled) {
FocusScope.of(context).unfocus();
var apiResponse = await _apiProvider.login(
'fbenoist', '9295', _securityCode);
if (apiResponse == 'OK') {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => HomePage()),
(Route<dynamic> route) => false);
} else {
Fluttertoast.showToast(
msg: apiResponse, toastLength: Toast.LENGTH_SHORT);
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) => SigninPage()),
(Route<dynamic> route) => false);
}
}
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: Text(
'Verify',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: _buttonDisabled
? Colors.grey[600]
: Colors.white),
textAlign: TextAlign.center,
),
))),
),
SizedBox(
height: 40,
),
Center(
child: Wrap(
children: [
Text(
"Didn't receive the code? ",
style: TextStyle(fontSize: 13, color: _color4),
),
GestureDetector(
onTap: () {
Fluttertoast.showToast(
msg: 'Click resend', toastLength: Toast.LENGTH_SHORT);
},
child: Text(
'Resend',
style: TextStyle(fontSize: 13, color: _color1),
),
)
],
),
),
],
));
}
}

View File

@ -16,6 +16,8 @@ import 'package:mobdr/ui/reusable/reusable_widget.dart';
import 'package:mobdr/ui/reusable/cache_image_network.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:mobdr/service/local_storage.dart';
import 'package:mobdr/model/login.dart';
class TabHomePage extends StatefulWidget {
@override
@ -35,6 +37,7 @@ class _TabHomePageState extends State<TabHomePage>
bool get wantKeepAlive => true;
String defaultLang = 'en';
String UserName = '';
late LanguageCubit _languageCubit;
@ -46,6 +49,9 @@ class _TabHomePageState extends State<TabHomePage>
defaultLang = val!;
});
});
LocalStorage.getLoginData().then((value) => UserName = value!.prenom);
super.initState();
}
@ -79,7 +85,8 @@ class _TabHomePageState extends State<TabHomePage>
elevation: GlobalStyle.appBarElevation,
title: Text(
AppLocalizations.of(context)!.translate('i18n_hello')! +
', Frédérik',
', ' +
UserName,
style: GlobalStyle.appBarTitle,
),
backgroundColor: GlobalStyle.appBarBackgroundColor,

View File

@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h"
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) objectbox_flutter_libs_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ObjectboxFlutterLibsPlugin");
objectbox_flutter_libs_plugin_register_with_registrar(objectbox_flutter_libs_registrar);

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_linux
objectbox_flutter_libs
)

View File

@ -5,6 +5,7 @@
import FlutterMacOS
import Foundation
import flutter_secure_storage_macos
import objectbox_flutter_libs
import package_info_plus
import path_provider_foundation
@ -12,6 +13,7 @@ import shared_preferences_foundation
import sqflite
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
ObjectboxFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "ObjectboxFlutterLibsPlugin"))
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))

View File

@ -3,40 +3,57 @@ PODS:
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- ObjectBox (1.8.1)
- objectbox_flutter_libs (0.0.1):
- FlutterMacOS
- ObjectBox (= 1.8.1)
- package_info_plus (0.0.1):
- FlutterMacOS
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite (0.0.2):
- FlutterMacOS
- FMDB (>= 2.7.5)
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- objectbox_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/objectbox_flutter_libs/macos`)
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`)
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`)
SPEC REPOS:
trunk:
- FMDB
- ObjectBox
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
objectbox_flutter_libs:
:path: Flutter/ephemeral/.symlinks/plugins/objectbox_flutter_libs/macos
package_info_plus:
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos
sqflite:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos
SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
ObjectBox: a7900d5335218cd437cbc080b7ccc38a5211f7b4
objectbox_flutter_libs: f89ab4878f0f764a49077cfaa59030be69ae1d7e
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea
PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7

View File

@ -233,6 +233,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.4"
dio:
dependency: "direct main"
description:
name: dio
sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8"
url: "https://pub.dev"
source: hosted
version: "4.0.6"
fake_async:
dependency: transitive
description:
@ -315,6 +323,54 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
sha256: "98352186ee7ad3639ccc77ad7924b773ff6883076ab952437d20f18a61f0a7c5"
url: "https://pub.dev"
source: hosted
version: "8.0.0"
flutter_secure_storage_linux:
dependency: transitive
description:
name: flutter_secure_storage_linux
sha256: "0912ae29a572230ad52d8a4697e5518d7f0f429052fd51df7e5a7952c7efe2a3"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
flutter_secure_storage_macos:
dependency: transitive
description:
name: flutter_secure_storage_macos
sha256: "083add01847fc1c80a07a08e1ed6927e9acd9618a35e330239d4422cd2a58c50"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
flutter_secure_storage_platform_interface:
dependency: transitive
description:
name: flutter_secure_storage_platform_interface
sha256: b3773190e385a3c8a382007893d678ae95462b3c2279e987b55d140d3b0cb81b
url: "https://pub.dev"
source: hosted
version: "1.0.1"
flutter_secure_storage_web:
dependency: transitive
description:
name: flutter_secure_storage_web
sha256: "42938e70d4b872e856e678c423cc0e9065d7d294f45bc41fc1981a4eb4beaffe"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flutter_secure_storage_windows:
dependency: transitive
description:
name: flutter_secure_storage_windows
sha256: fc2910ec9b28d60598216c29ea763b3a96c401f0ce1d13cdf69ccb0e5c93c3ee
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
@ -341,6 +397,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.2.0"
get_it:
dependency: "direct main"
description:
name: get_it
sha256: "290fde3a86072e4b37dbb03c07bec6126f0ecc28dad403c12ffe2e5a2d751ab7"
url: "https://pub.dev"
source: hosted
version: "7.2.0"
glob:
dependency: transitive
description:
@ -597,6 +661,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.11.1"
pin_code_fields:
dependency: "direct main"
description:
name: pin_code_fields
sha256: c8652519d14688f3fe2a8288d86910a46aa0b9046d728f292d3bf6067c31b4c7
url: "https://pub.dev"
source: hosted
version: "7.4.0"
platform:
dependency: transitive
description:
@ -665,10 +737,10 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9"
sha256: ee6257848f822b8481691f20c3e6d2bfee2e9eccb2a3d249907fcfb198c55b41
url: "https://pub.dev"
source: hosted
version: "2.0.17"
version: "2.0.18"
shared_preferences_android:
dependency: transitive
description:

View File

@ -30,8 +30,11 @@ environment:
dependencies:
flutter:
sdk: flutter
dio: 4.0.6
objectbox: ^1.7.2
objectbox_flutter_libs: any
pin_code_fields: 7.4.0
flutter_localizations:
sdk: flutter
@ -43,13 +46,16 @@ dependencies:
package_info_plus: 3.0.3
flutter_bloc: 8.1.2
flutter_html: 3.0.0-alpha.6
flutter_secure_storage: ^8.0.0
#https://pub.dev/packages/intl
intl: 0.17.0
carousel_slider: 4.2.1
cached_network_image: 3.2.3
shared_preferences: 2.0.17
get_it: ^7.2.0
shared_preferences: 2.0.18
universal_io: 2.2.0
dev_dependencies:

View File

@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h"
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <objectbox_flutter_libs/objectbox_flutter_libs_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
ObjectboxFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ObjectboxFlutterLibsPlugin"));
}

View File

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_windows
objectbox_flutter_libs
)