Browse Source

upgrade flutter version

smf_upgrate
Đại Võ 1 year ago
parent
commit
1a44bbf2fa
34 changed files with 477 additions and 497 deletions
  1. +4
    -1
      .vscode/launch.json
  2. BIN
      assets/png/icActionCropStatus.png
  3. BIN
      assets/png/icActionDisease.png
  4. BIN
      assets/png/icActionDung.png
  5. BIN
      assets/png/icActionEnd.png
  6. BIN
      assets/png/icActionEnvironment.png
  7. BIN
      assets/png/icActionHarvest.png
  8. BIN
      assets/png/icActionNursery.png
  9. BIN
      assets/png/icActionOther.png
  10. BIN
      assets/png/icActionPlant.png
  11. BIN
      assets/png/icActionSpraying.png
  12. BIN
      assets/png/icActionUseWater.png
  13. +24
    -22
      ios/Podfile.lock
  14. +44
    -36
      lib/app.dart
  15. +207
    -179
      lib/data/api/rest_client.g.dart
  16. +1
    -1
      lib/data/repository/repository.dart
  17. +6
    -6
      lib/environment/app_config.dart
  18. +32
    -95
      lib/main.dart
  19. +2
    -5
      lib/presentation/custom_widgets/button/ghost_button_widget.dart
  20. +9
    -5
      lib/presentation/custom_widgets/button_icon_widget.dart
  21. +22
    -21
      lib/presentation/custom_widgets/camera_helper.dart
  22. +2
    -2
      lib/presentation/custom_widgets/loading_list_page.dart
  23. +11
    -9
      lib/presentation/screens/account/sc_account.dart
  24. +10
    -20
      lib/presentation/screens/forgot_password/sc_forgot_password.dart
  25. +11
    -24
      lib/presentation/screens/login/cubit/login_cubit.dart
  26. +55
    -41
      lib/presentation/screens/login/login_page.dart
  27. +2
    -6
      lib/presentation/screens/login/models/response_user.dart
  28. +5
    -1
      lib/presentation/screens/plot_detail/widget_tab.dart
  29. +5
    -5
      lib/presentation/screens/profile/sc_change_password.dart
  30. +0
    -3
      lib/presentation/screens/profile/sc_update_profile.dart
  31. +1
    -1
      lib/presentation/screens/qr_scan/qr_scan_page.dart
  32. +3
    -1
      lib/presentation/screens/tabbar/tabbar.dart
  33. +12
    -2
      lib/utils/app_images.dart
  34. +9
    -11
      lib/utils/local_storage.dart

+ 4
- 1
.vscode/launch.json View File

@@ -7,7 +7,10 @@
{
"name": "mobile-app",
"request": "launch",
"type": "dart"
"type": "dart",
"args": [
"--no-sound-null-safety"
]
}
]
}

BIN
assets/png/icActionCropStatus.png View File

Before After
Width: 256  |  Height: 256  |  Size: 4.1KB

BIN
assets/png/icActionDisease.png View File

Before After
Width: 256  |  Height: 256  |  Size: 8.4KB

BIN
assets/png/icActionDung.png View File

Before After
Width: 256  |  Height: 256  |  Size: 7.3KB

BIN
assets/png/icActionEnd.png View File

Before After
Width: 256  |  Height: 256  |  Size: 4.5KB

BIN
assets/png/icActionEnvironment.png View File

Before After
Width: 256  |  Height: 256  |  Size: 3.8KB

BIN
assets/png/icActionHarvest.png View File

Before After
Width: 256  |  Height: 256  |  Size: 8.8KB

BIN
assets/png/icActionNursery.png View File

Before After
Width: 256  |  Height: 256  |  Size: 4.3KB

BIN
assets/png/icActionOther.png View File

Before After
Width: 256  |  Height: 256  |  Size: 4.5KB

BIN
assets/png/icActionPlant.png View File

Before After
Width: 256  |  Height: 256  |  Size: 6.5KB

BIN
assets/png/icActionSpraying.png View File

Before After
Width: 256  |  Height: 256  |  Size: 4.0KB

BIN
assets/png/icActionUseWater.png View File

Before After
Width: 256  |  Height: 256  |  Size: 2.7KB

+ 24
- 22
ios/Podfile.lock View File

@@ -1,5 +1,5 @@
PODS:
- camera (0.0.1):
- camera_avfoundation (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.4):
- DKImagePickerController/ImageDataManager
@@ -68,9 +68,10 @@ PODS:
- GoogleUtilities/UserDefaults (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- Flutter (1.0.0)
- flutter_image_compress (0.0.1):
- flutter_image_compress_common (1.0.0):
- Flutter
- Mantle
- SDWebImage
- SDWebImageWebPCoder
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
@@ -117,10 +118,11 @@ PODS:
- nanopb/encode (= 2.30909.0)
- nanopb/decode (2.30909.0)
- nanopb/encode (2.30909.0)
- package_info (0.0.1):
- package_info_plus (0.4.5):
- Flutter
- path_provider (0.0.1):
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- PromisesObjC (2.3.1)
- qr_code_scanner (0.2.0):
- Flutter
@@ -133,20 +135,20 @@ PODS:
- SDWebImage/Core (~> 5.17)
- shared_preferences (0.0.1):
- Flutter
- sqflite (0.0.2):
- sqflite (0.0.3):
- Flutter
- FMDB (>= 2.7.5)
- SwiftyGif (5.4.4)

DEPENDENCIES:
- camera (from `.symlinks/plugins/camera/ios`)
- camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_image_compress (from `.symlinks/plugins/flutter_image_compress/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
@@ -173,8 +175,8 @@ SPEC REPOS:
- SwiftyGif

EXTERNAL SOURCES:
camera:
:path: ".symlinks/plugins/camera/ios"
camera_avfoundation:
:path: ".symlinks/plugins/camera_avfoundation/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
firebase_core:
@@ -183,12 +185,12 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
flutter_image_compress:
:path: ".symlinks/plugins/flutter_image_compress/ios"
package_info:
:path: ".symlinks/plugins/package_info/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
flutter_image_compress_common:
:path: ".symlinks/plugins/flutter_image_compress_common/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/ios"
qr_code_scanner:
:path: ".symlinks/plugins/qr_code_scanner/ios"
shared_preferences:
@@ -197,7 +199,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite/ios"

SPEC CHECKSUMS:
camera: a0ca5080336f7af47b88436e5e26da3dee5568f0
camera_avfoundation: 3125e8cd1a4387f6f31c6c63abb8a55892a9eeeb
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
@@ -209,7 +211,7 @@ SPEC CHECKSUMS:
FirebaseInstallations: b822f91a61f7d1ba763e5ccc9d4f2e6f2ed3b3ee
FirebaseMessaging: 0c0ae1eb722ef0c07f7801e5ded8dccd1357d6d4
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_image_compress: 082f8daaf6c1b0c9fe798251c750ef0ecd98d7ae
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2
GoogleUtilities: 13e2c67ede716b8741c7989e26893d151b2b2084
@@ -217,14 +219,14 @@ SPEC CHECKSUMS:
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
SDWebImage: 96e0c18ef14010b7485210e92fac888587ebb958
SDWebImageWebPCoder: 3027af94522d94df79c21c070894c8a2128927ff
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f

PODFILE CHECKSUM: f08360d062df7ffa8ee251115991830e526d3068

+ 44
- 36
lib/app.dart View File

@@ -4,6 +4,7 @@ import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_enum.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';

import 'authentication/bloc/authentication_bloc.dart';
@@ -47,45 +48,52 @@ class _AppViewState extends State<AppView> {

@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
backgroundColor: Colors.white,
brightness: Brightness.light,
primaryColor: AppColors.DEFAULT,
accentColor: AppColors.DEFAULT,
hoverColor: AppColors.GREEN,
// textTheme: GoogleFonts.sairaTextTheme(
// Theme.of(context).textTheme,
// ),
),
navigatorKey: _navigatorKey,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
// _navigator!.pushAndRemoveUntil<void>(
// TabbarScreen.route(),
// (route) => false,
// );
Get.offAll(() => TabbarScreen());
break;
case AuthenticationStatus.unauthenticated:
// _navigator!.pushAndRemoveUntil<void>(
// LoginPage.route(),
// (route) => false,
// );
Get.offAll(() => const LoginPage());
break;
default:
break;
}
return ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
splitScreenMode: true,
builder: (BuildContext context, Widget? child) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
backgroundColor: Colors.white,
brightness: Brightness.light,
primaryColor: AppColors.DEFAULT,
accentColor: AppColors.DEFAULT,
hoverColor: AppColors.GREEN,
// textTheme: GoogleFonts.sairaTextTheme(
// Theme.of(context).textTheme,
// ),
),
navigatorKey: _navigatorKey,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
// _navigator!.pushAndRemoveUntil<void>(
// TabbarScreen.route(),
// (route) => false,
// );
Get.offAll(() => TabbarScreen());
break;
case AuthenticationStatus.unauthenticated:
// _navigator!.pushAndRemoveUntil<void>(
// LoginPage.route(),
// (route) => false,
// );
Get.offAll(() => const LoginPage());
break;
default:
break;
}
},
child: child,
);
},
child: child,
onGenerateRoute: (_) => SplashPage.route(),
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}

+ 207
- 179
lib/data/api/rest_client.g.dart View File

@@ -7,379 +7,430 @@ part of 'rest_client.dart';
// **************************************************************************

class _RestClient implements RestClient {
_RestClient(this._dio) {
_RestClient(this._dio, {this.baseUrl}) {
ArgumentError.checkNotNull(_dio, '_dio');
baseUrl ??= 'https://tpf.aztrace.vn/';
}

final Dio _dio;

String baseUrl = 'https://tpf.aztrace.vn';
String? baseUrl;

@override
Future<User> login(userRequest) async {
login(userRequest) async {
ArgumentError.checkNotNull(userRequest, 'userRequest');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(userRequest?.toJson() ?? <String, dynamic>{});
final _result = await _dio.request<Map<String, dynamic>>('/api/authenticate',
queryParameters: queryParameters,
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = User.fromJson(_result.data);
final Response<Map<String, dynamic>> _result = await _dio.post('/api/authenticate', queryParameters: queryParameters, data: _data);
final value = User.fromJson(_result.data!);
return value;
}

@override
Future<Account> getMe() async {
getMe() async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
final _result = await _dio.request<Map<String, dynamic>>('/api/account',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = Account.fromJson(_result.data);
final Response<Map<String, dynamic>> _result = await _dio.request('/api/account', queryParameters: queryParameters, data: _data);
final value = Account.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

@override
Future<void> forgotPassword(email) async {
forgotPassword(email) async {
ArgumentError.checkNotNull(email, 'email');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = email;
await _dio.request<void>('/api/account/reset-password/init',
queryParameters: queryParameters,
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.post<void>(
'/api/account/reset-password/init',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<void> resetPassword(password) async {
resetPassword(password) async {
ArgumentError.checkNotNull(password, 'password');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(password?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/account/reset-password/finish',
queryParameters: queryParameters,
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
_data.addAll(password.toJson() ?? <String, dynamic>{});
await _dio.post<void>('/api/account/reset-password/finish', queryParameters: queryParameters, data: _data);
return null;
}

@override
Future<void> changePassword(password) async {
changePassword(password) async {
ArgumentError.checkNotNull(password, 'password');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(password?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/account/change-password',
queryParameters: queryParameters,
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);

await _dio.post<void>(
'/api/account/change-password',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<Account> updateProfile(account) async {
updateProfile(account) async {
ArgumentError.checkNotNull(account, 'account');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(account?.toJson() ?? <String, dynamic>{});
final _result = await _dio.request<Map<String, dynamic>>('/api/update-my-profile',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = Account.fromJson(_result.data);
final Response<Map<String, dynamic>> _result = await _dio.put('/api/update-my-profile', queryParameters: queryParameters, data: _data);
final value = Account.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

@override
Future<List<Supply>> getSupplies(type, {options, query = ""}) async {
getSupplies(type, {Options? options, query = ""}) async {
ArgumentError.checkNotNull(type, 'type');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/list-supplies-in-warehouses/$type?q=$query',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/list-supplies-in-warehouses/$type?q=$query',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<void> updateFcmToken(token) async {
updateFcmToken(token) async {
ArgumentError.checkNotNull(token, 'token');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = token;
await _dio.request<void>('/api/update-fcmToken',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.put<void>(
'/api/update-fcmToken',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<void> deleteFcmToken(token) async {
deleteFcmToken(token) async {
ArgumentError.checkNotNull(token, 'token');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = token;
await _dio.request<void>('/api/delete-fcmToken',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.put<void>(
'/api/delete-fcmToken',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<List<TbCropDTO>> getPlots({page = 0, size = 20, query = ""}) async {
getPlots({page = 0, size = 20, query = ""}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<List<dynamic>>('/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data.map((dynamic i) => TbCropDTO.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => TbCropDTO.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<ActionType>> getActionTypes({options}) async {
getActionTypes({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/listActivityTypesOther',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/listActivityTypesOther',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<WaterType>> getWaterTypes({options}) async {
getWaterTypes({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/water-types',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/water-types',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<Harvest>> getHarvests({options}) async {
getHarvests({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/tb-harvests',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-harvests',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<Device>> getDeviceForActivity({options}) async {
getDeviceForActivity({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/listDeviceForActivity',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/listDeviceForActivity',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<void> updateAllNotification(status) async {
updateAllNotification(status) async {
ArgumentError.checkNotNull(status, 'status');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = status;
await _dio.request<void>('/api/notifications/update-all',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.put<void>(
'/api/notifications/update-all',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<void> updateNoti(updateNoti) async {
updateNoti(updateNoti) async {
ArgumentError.checkNotNull(updateNoti, 'updateNoti');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(updateNoti?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/notifications/update',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.put<void>(
'/api/notifications/update',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<List<LocationUnit>> getCountries({page = 0, size = 400, query = '', options}) async {
getCountries({page = 0, size = 400, query = '', Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<LocationUnit>> getProvinces(countryId, {page = 0, size = 20, query = '', options}) async {
getProvinces(countryId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(countryId, 'countryId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/tb-cities-by-country/$countryId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-cities-by-country/$countryId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<LocationUnit>> getDistricts(provinceId, {page = 0, size = 20, query = '', options}) async {
getDistricts(provinceId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(provinceId, 'provinceId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/tb-districts-by-city/$provinceId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-districts-by-city/$provinceId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<LocationUnit>> getWards(districtId, {page = 0, size = 20, query = '', options}) async {
getWards(districtId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(districtId, 'districtId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options!);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<List<dynamic>>('/api/tb-wards-by-district/$districtId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-wards-by-district/$districtId?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<CropPlot> getCropDetail(cropId, {page = 0, size = 20}) async {
getCropDetail(cropId, {page = 0, size = 20}) async {
ArgumentError.checkNotNull(cropId, 'cropId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<Map<String, dynamic>>('/api/tb-crops-detail-for-app/$cropId?page=$page&size=$size&sort=executeDate,DESC',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = CropPlot.fromJson(_result.data);
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/tb-crops-detail-for-app/$cropId?page=$page&size=$size&sort=executeDate,DESC',
queryParameters: queryParameters,
data: _data,
);
final value = CropPlot.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

@override
Future<CropPlot> getCropDetailByCode(cropCode) async {
getCropDetailByCode(cropCode, {page = 0, size = 20}) async {
ArgumentError.checkNotNull(cropCode, 'cropCode');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<Map<String, dynamic>>('/api/tb-crops-scan-qrCode/$cropCode',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = CropPlot.fromJson(_result.data);
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/tb-crops-scan-qrCode/$cropCode',
queryParameters: queryParameters,
data: _data,
);
final value = CropPlot.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

@override
Future<void> updateCrop(crop) async {
updateCrop(crop) async {
ArgumentError.checkNotNull(crop, 'crop');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(crop?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/tb-crops',
queryParameters: queryParameters,
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
await _dio.put<void>(
'/api/tb-crops',
queryParameters: queryParameters,
data: _data,
);
return null;
}

@override
Future<List<Device>> getDevices(query) async {
getDevices(String? query) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<List<dynamic>>('/api/listDeviceOfUserCustomers?query=$query',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result =
await _dio.request('/api/listDeviceOfUserCustomers?query=$query', queryParameters: queryParameters, data: _data);
var value = _result.data?.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

@override
Future<List<EnvironmentParameter>> getEnvironmentParameters(cropId, {page = 0, size = 20}) async {
getEnvironmentParameters(cropId, {page = 0, size = 20}) async {
ArgumentError.checkNotNull(cropId, 'cropId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<List<dynamic>>('/api/list-environment-updates-display/$cropId?page=$page&size=$size',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data.map((dynamic i) => EnvironmentParameter.fromJson(i as Map<String, dynamic>)).toList();
return value;
final Response<List<dynamic>> _result = await _dio.request(
'/api/list-environment-updates-display/$cropId?page=$page&size=$size',
queryParameters: queryParameters,
data: _data,
);
var value = _result.data?.map((dynamic i) => EnvironmentParameter.fromJson(i as Map<String, dynamic>)).toList();
return value ?? [];
}

RequestOptions newRequestOptions(Options? options) {
// if (options is RequestOptions) {
// // return options ?? RequestOptions(path: '');
// return RequestOptions!;
// }
if (options == null) {
return RequestOptions(path: '');
}
return RequestOptions(
method: options.method,
sendTimeout: options.sendTimeout,
receiveTimeout: options.receiveTimeout,
extra: options.extra,
headers: options.headers,
responseType: options.responseType,
contentType: options.contentType.toString(),
validateStatus: options.validateStatus,
receiveDataWhenStatusError: options.receiveDataWhenStatusError,
followRedirects: options.followRedirects,
maxRedirects: options.maxRedirects,
requestEncoder: options.requestEncoder,
responseDecoder: options.responseDecoder,
path: '',
);
}

@override
Future<ActionUIForm> getActionUIForm(idAction, options) async {
getActionUIForm(idAction, options) async {
ArgumentError.checkNotNull(idAction, 'idAction');
ArgumentError.checkNotNull(options, 'options');
const _extra = <String, dynamic>{};
@@ -388,14 +439,14 @@ class _RestClient implements RestClient {
final newOptions = newRequestOptions(options!);
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final _result = await _dio.request<Map<String, dynamic>>('/api/display-object-param-dynamic-form/$idAction',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
final value = ActionUIForm.fromJson(_result.data);
final _result =
await _dio.request<Map<String, dynamic>>('/api/display-object-param-dynamic-form/$idAction', queryParameters: queryParameters, data: _data);
final value = ActionUIForm.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

@override
Future<RequestActivity> getDetailActivityCommon(actionType, activityId) async {
getDetailActivityCommon(actionType, activityId) async {
ArgumentError.checkNotNull(actionType, 'actionType');
ArgumentError.checkNotNull(activityId, 'activityId');
const _extra = <String, dynamic>{};
@@ -403,31 +454,8 @@ class _RestClient implements RestClient {
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final _result = await _dio.request<Map<String, dynamic>>('/api/get-detail-common-activity/$actionType/$activityId',
queryParameters: queryParameters,
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = RequestActivity.fromJson(_result.data);
queryParameters: queryParameters, data: _data);
final value = RequestActivity.fromJson(_result.data ?? Map<String, dynamic>());
return value;
}

RequestOptions newRequestOptions(Options? options) {
if (options == null) {
return RequestOptions();
}
return RequestOptions(
method: options.method,
sendTimeout: options.sendTimeout,
receiveTimeout: options.receiveTimeout,
extra: options.extra,
headers: options.headers,
responseType: options.responseType,
contentType: options.contentType.toString(),
validateStatus: options.validateStatus,
receiveDataWhenStatusError: options.receiveDataWhenStatusError,
followRedirects: options.followRedirects,
maxRedirects: options.maxRedirects,
requestEncoder: options.requestEncoder,
responseDecoder: options.responseDecoder,
);
}
}

+ 1
- 1
lib/data/repository/repository.dart View File

@@ -34,7 +34,7 @@ class Repository {
required RequestUser requestUser,
}) async {
try {
var url = ConstCommon.baseUrl + '/account/token';
var url = ConstCommon.baseUrl + '/api/authenticate';
await dio.post(
url,
data: {

+ 6
- 6
lib/environment/app_config.dart View File

@@ -37,8 +37,8 @@ void setFlavorDevelopment() {
AppEnvironment.DEV,
FlavorValues(
appName: '[DEV] Thaco Agri',
server: 'https://dev-trangtraibo.aristqnu.com/',
baseUrl: 'https://dev-trangtraibo.aristqnu.com/',
server: 'https://tpf.aztrace.vn',
baseUrl: 'https://tpf.aztrace.vn',
LocalDBName: 'AppLocalStorage-DEV',
),
);
@@ -49,8 +49,8 @@ void setFlavorTest() {
AppEnvironment.TEST,
FlavorValues(
appName: 'Thaco Agri',
server: 'https://test-trangtraibo.aristqnu.com/',
baseUrl: 'https://test-trangtraibo.aristqnu.com/',
server: 'https://tpf.aztrace.vn',
baseUrl: 'https://tpf.aztrace.vn',
LocalDBName: 'AppLocalStorage-TEST',
),
);
@@ -61,8 +61,8 @@ void setFlavorProduction() {
AppEnvironment.PROD,
FlavorValues(
appName: 'Trang Trai Bo',
server: 'https://trangtraibo.thacoagri.com.vn/',
baseUrl: 'https://trangtraibo.thacoagri.com.vn/',
server: 'https://tpf.aztrace.vn',
baseUrl: 'https://tpf.aztrace.vn',
LocalDBName: 'AppLocalStorage',
),
);

+ 32
- 95
lib/main.dart View File

@@ -1,103 +1,40 @@
import 'package:camera/camera.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
// import 'package:barcode_scan/barcode_scan.dart';
import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/route_manager.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'app.dart';
// import 'data/repository/auth_repository.dart';
import 'data/repository/authentication_repository.dart';
import 'data/repository/repository.dart';
import 'presentation/custom_widgets/widget_utils.dart';
import 'environment/app_config.dart';

List<CameraDescription> cameras = [];
final GlobalKey<NavigatorState> globalNavigator = GlobalKey<NavigatorState>();
Future<void> main() async {
// Fetch the available cameras before initializing the app.
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
} on CameraException catch (e) {
print(e.description);
}
runApp(App(authenticationRepository: AuthenticationRepository()));
}

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
}

if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
}
return Future(() => true);

// Or do other work.
}

// Future scan(BuildContext context) async {
// var _aspectTolerance = 0.00;
// var _selectedCamera = -1;
// var _useAutoFocus = true;
// var _autoEnableFlash = false;
// var repository = Repository();
// try {
// var options = ScanOptions(
// strings: {
// "cancel": "Huỷ",
// "flash_on": "Bật flash",
// "flash_off": "Tắt flash",
// },
// useCamera: _selectedCamera,
// autoEnableFlash: _autoEnableFlash,
// android: AndroidOptions(
// aspectTolerance: _aspectTolerance,
// useAutoFocus: _useAutoFocus,
// ),
// );
// var result = await BarcodeScanner.scan(options: options);
// print(result.toString());
// if (result.type == ResultType.Cancelled) {
// print("canncel");
// } else if (result.type == ResultType.Error) {
// print("error");
// } else {
// print("show check crop");
// _showAlertCheckCropCode(context, result.rawContent, repository);
// }
// } on PlatformException catch (e) {
// print("error: ${e.message}");
// }
// }
WidgetsFlutterBinding.ensureInitialized();
Firebase.initializeApp();
// if (Platform.isAndroid) {
// await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform,
// );
// } else {
// await Firebase.initializeApp();
// }
// await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true);
// FirebaseMessaging.onBackgroundMessage(FirebaseMessages.firebaseMessagingBackgroundHandler);
// FirebaseMessaging.onMessageOpenedApp.listen(FirebaseMessages.firebaseMessagingBackgroundHandler);

_showAlertCheckCropCode(String cropCode) async {
var repository = Repository();
Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: CircularProgressIndicator());
try {
await repository.getPlotDetailByCode(cropCode).then((value) {
print("ok");
if (Get.isDialogOpen) Get.back();
Get.to(PlotDetailScreen(cropId: value.tbCropDTO?.id ?? -1, cropType: value.tbCropDTO?.tbCropTypeId ?? -1, initialIndex: 0));
}).catchError((onError) {
Utils.showDialog(
title: "Không tìm thấy lô",
message: "Thử lại với mã tem khác?",
textConfirm: "Thử lại",
textCancel: "Huỷ",
onConfirm: () {
Get.back();
// scan(context);
});
});
} catch (e) {
Utils.showDialog(
title: "Không tìm thấy lô",
message: "Thử lại với mã tem khác?",
textConfirm: "Thử lại",
textCancel: "Huỷ",
onConfirm: () {
Get.back();
// scan(context);
});
}
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitDown,
DeviceOrientation.portraitUp,
]);
setFlavorDevelopment();
final appDocumentDirectory = await getApplicationDocumentsDirectory();
Hive..init(appDocumentDirectory.path);
await Hive.openBox('LocalDBName');
runApp(App(
authenticationRepository: AuthenticationRepository(),
));
}

+ 2
- 5
lib/presentation/custom_widgets/button/ghost_button_widget.dart View File

@@ -6,11 +6,9 @@ import '../../../themes/styles_text.dart';
class GhostButtonWidget extends StatelessWidget {
final String title;
final Function() onPressed;
final Color? color;
const GhostButtonWidget({
required this.title,
required this.onPressed,
this.color,
});
@override
Widget build(BuildContext context) {
@@ -18,9 +16,8 @@ class GhostButtonWidget extends StatelessWidget {
onTap: onPressed,
child: Text(
title,
style: StylesText.body3.copyWith(
color: color ?? AppColors.black,
decoration: TextDecoration.underline,
style: StylesText.caption2.copyWith(
color: AppColors.primary1,
),
),
);

+ 9
- 5
lib/presentation/custom_widgets/button_icon_widget.dart View File

@@ -2,6 +2,8 @@ import 'package:farm_tpf/utils/const_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

import '../../themes/styles_text.dart';

class ButtonIconWidget extends StatelessWidget {
final String? title;
final TextStyle? titleStyle;
@@ -32,9 +34,11 @@ class ButtonIconWidget extends StatelessWidget {
child: Container(
padding: EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border(
top: isTopBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none,
bottom: isBottomBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none)),
border: Border(
top: isTopBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none,
bottom: isBottomBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none,
),
),
width: double.infinity,
child: Row(
mainAxisSize: MainAxisSize.max,
@@ -56,13 +60,13 @@ class ButtonIconWidget extends StatelessWidget {
children: [
Text(
title ?? '',
style: titleStyle ?? TextStyle(fontSize: 16, fontWeight: FontWeight.w100),
style: StylesText.body3,
),
subTitle == null
? SizedBox()
: Text(
subTitle ?? '',
style: TextStyle(fontSize: 14),
style: StylesText.body6,
)
],
),

+ 22
- 21
lib/presentation/custom_widgets/camera_helper.dart View File

@@ -39,7 +39,7 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver
@override
void initState() {
super.initState();
controller = CameraController(cameras[indexCamera], ResolutionPreset.medium);
// controller = CameraController(cameras[indexCamera], ResolutionPreset.medium);
controller?.initialize().then((_) {
if (!mounted) {
return;
@@ -167,26 +167,27 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver

/// Display a row of toggle to select the camera (or a message if no camera is available).
Widget _cameraTogglesRowWidget() {
if (cameras.isEmpty) {
return const Text('Không có camera');
} else {
bool disableSwitch = controller != null && controller!.value.isRecordingVideo;
if (indexCamera == cameras.length - 1) {
indexCamera = 0;
} else {
indexCamera++;
}
return IconButton(
icon: Icon(
Icons.switch_camera,
color: Colors.green,
),
onPressed: disableSwitch == true
? null
: () {
onNewCameraSelected(cameras[indexCamera]);
});
}
// if (cameras.isEmpty) {
// return const Text('Không có camera');
// } else {
// bool disableSwitch = controller != null && controller!.value.isRecordingVideo;
// if (indexCamera == cameras.length - 1) {
// indexCamera = 0;
// } else {
// indexCamera++;
// }
// return IconButton(
// icon: Icon(
// Icons.switch_camera,
// color: Colors.green,
// ),
// onPressed: disableSwitch == true
// ? null
// : () {
// onNewCameraSelected(cameras[indexCamera]);
// });
// }
return Container();
}

String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();

+ 2
- 2
lib/presentation/custom_widgets/loading_list_page.dart View File

@@ -20,8 +20,8 @@ class _LoadingListPageState extends State<LoadingListPage> {
children: <Widget>[
Expanded(
child: Shimmer.fromColors(
baseColor: Colors.grey,
highlightColor: Colors.grey,
baseColor: Colors.grey.shade200,
highlightColor: Colors.grey.shade200,
enabled: _enabled,
child: ListView.builder(
itemBuilder: (_, __) => Padding(

+ 11
- 9
lib/presentation/screens/account/sc_account.dart View File

@@ -83,14 +83,15 @@ class _AccountScreenState extends State<AccountScreen> {
Get.to(UpdateProfileScreen());
}),
ButtonIconWidget(
title: 'Bảo mật',
leadingIcon: AppIcons.icSecurity,
trailingIcon: AppIcons.icArrowRight,
isTopBorder: false,
isBottomBorder: false,
onTap: () {
Get.to(ChangePasswordScreen());
}),
title: 'Bảo mật',
leadingIcon: AppIcons.icSecurity,
trailingIcon: AppIcons.icArrowRight,
isTopBorder: false,
isBottomBorder: false,
onTap: () {
Get.to(ChangePasswordScreen());
},
),
Container(
width: double.infinity,
height: 20,
@@ -113,7 +114,8 @@ class _AccountScreenState extends State<AccountScreen> {
title: 'Đăng xuất',
titleStyle: TextStyle(fontSize: 16, fontWeight: FontWeight.w100, color: Colors.red),
leadingIcon: AppIcons.icLogout,
trailingIcon: AppIcons.icArrowRight,
// trailingIcon: AppIcons.icArrowRight,
isTopBorder: false,
onTap: () {
_clickSignOut();
}),

+ 10
- 20
lib/presentation/screens/forgot_password/sc_forgot_password.dart View File

@@ -1,5 +1,6 @@
import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
import 'package:farm_tpf/utils/const_color.dart';
@@ -57,26 +58,15 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
}

Widget _btnSubmit() {
return SizedBox(
width: double.infinity,
height: 55,
child: TextButton(
onPressed: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
_validateInputs();
},
// color: AppColors.DEFAULT,
// shape: RoundedRectangleBorder(
// borderRadius: new BorderRadius.circular(7.0),
// ),
child: Text(
'Gửi'.toUpperCase(),
style: TextStyle(fontWeight: FontWeight.bold, color: AppColors.WHITE),
),
),
return ButtonWidget(
title: 'Gửi',
onPressed: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
_validateInputs();
},
);
}


+ 11
- 24
lib/presentation/screens/login/cubit/login_cubit.dart View File

@@ -1,6 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../../data/repository/repository.dart';
import '../../../../utils/local_storage.dart';
import '../../../../utils/validators.dart';
@@ -22,9 +23,9 @@ class LoginCubit extends Cubit<LoginState> {
var isRemember = ValueNotifier(true);

Future<void> loginWithCredential() async {
if (!formKey.currentState!.validate()) {
return;
}
// if (!formKey.currentState!.validate()) {
// return;
// }

emit(LoginLoading());
var userLoginRequest = RequestUser()
@@ -38,7 +39,7 @@ class LoginCubit extends Cubit<LoginState> {
);
},
(error) {
emit(LoginFailure(error));
emit(LoginFailure('Tên đăng nhập hoặc mật khẩu không đúng'));
},
requestUser: userLoginRequest,
);
@@ -50,24 +51,7 @@ class LoginCubit extends Cubit<LoginState> {
}) async {
try {
LocalStorage.saveUserInfo(responseUser, username);
// // var dsTrai = await _repository.getdanhSachTrais(LocalStorage.getString(LocalStorageKey.user_id));
// // if (dsTrai.isNotEmpty) {
// // LocalStorage.save(LocalStorageKey.trai_hien_tai, dsTrai[0].maTrai ?? '0');
// // LocalStorage.save(LocalStorageKey.ten_hien_tai, dsTrai[0].tenTrai ?? '0');
// // LocalStorage.save(LocalStorageKey.ma_trais, dsTrai.map((e) => e.maTrai).toList());
// // LocalStorage.save(LocalStorageKey.ten_trais, dsTrai.map((e) => e.tenTrai).toList());
// // } else {
// // LocalStorage.save(LocalStorageKey.trai_hien_tai, '0');
// // LocalStorage.save(LocalStorageKey.ten_hien_tai, 'IAPUCH');
// // LocalStorage.save(LocalStorageKey.ma_trais, ['0']);
// // LocalStorage.save(LocalStorageKey.ten_trais, ['IAPUCH']);
// // }
} catch (_) {
// LocalStorage.save(LocalStorageKey.trai_hien_tai, '0');
// LocalStorage.save(LocalStorageKey.ten_hien_tai, 'IAPUCH');
// LocalStorage.save(LocalStorageKey.ma_trais, ['0']);
// LocalStorage.save(LocalStorageKey.ten_trais, ['IAPUCH']);
}
} catch (_) {}
emit(
LoginSuccess(
routeName: '',
@@ -77,14 +61,17 @@ class LoginCubit extends Cubit<LoginState> {

String? validateEmail(String value) {
if (!Validators.stringNotNullOrEmpty(value)) {
return 'Vui lòng nhập tên đăng nhập';
return 'Nhập email';
}
if (!Validators.isValidEmail(value)) {
return 'Nhập email';
}
return null;
}

String? validatePassword(String value) {
if (!Validators.stringNotNullOrEmpty(value)) {
return 'Vui lòng nhập mật khẩu';
return 'Nhập mật khẩu';
}
return null;
}

+ 55
- 41
lib/presentation/screens/login/login_page.dart View File

@@ -1,9 +1,12 @@
import 'package:farm_tpf/presentation/custom_widgets/button/ghost_button_widget.dart';
import 'package:farm_tpf/presentation/screens/forgot_password/sc_forgot_password.dart';
import 'package:farm_tpf/themes/app_dimension.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutter_switch/flutter_switch.dart';
import 'package:get/get.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import '../../../authentication/bloc/authentication_bloc.dart';
import '../../../themes/app_colors.dart';
@@ -32,8 +35,8 @@ class _LoginPageState extends State<LoginPage> {
void initState() {
super.initState();
if (kDebugMode) {
loginBloc.usernameCtl.text = 'admin';
loginBloc.passwordCtl.text = 'admintest';
loginBloc.usernameCtl.text = 'lecaoanhquoc';
loginBloc.passwordCtl.text = '123456';
}
}

@@ -75,44 +78,53 @@ class _LoginPageState extends State<LoginPage> {
body: KeyboardDismisser(
child: Container(
decoration: BoxDecoration(
//color: AppColors.primary1.withOpacity(0.2),
color: AppColors.primary1,
gradient: LinearGradient(
colors: [
AppColors.primary1,
AppColors.primary1.withOpacity(0),
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
child: Stack(
children: <Widget>[
Positioned(
top: 0,
right: 0,
left: 0,
child: Container(
height: 370.h,
decoration: BoxDecoration(
color: AppColors.background1,
image: const DecorationImage(
image: AssetImage(AssetPNG.backgroundLogin),
fit: BoxFit.cover,
),
),
),
),
Positioned(
top: 0,
right: 0,
left: 0,
child: Container(
height: 371.h,
decoration: BoxDecoration(
color: AppColors.primary1,
gradient: LinearGradient(
colors: [
AppColors.primary1,
AppColors.primary1.withOpacity(0),
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
),
),
// Positioned(
// top: 0,
// right: 0,
// left: 0,
// child: Container(
// height: 370.h,
// decoration: BoxDecoration(
// color: AppColors.background1,
// image: const DecorationImage(
// image: AssetImage(AssetPNG.backgroundLogin),
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// Positioned(
// top: 0,
// right: 0,
// left: 0,
// child: Container(
// height: 371.h,
// decoration: BoxDecoration(
// color: AppColors.primary1,
// gradient: LinearGradient(
// colors: [
// AppColors.primary1,
// AppColors.primary1.withOpacity(0),
// ],
// begin: Alignment.bottomCenter,
// end: Alignment.topCenter,
// ),
// ),
// ),
// ),
Positioned(
top: 140.h,
right: 40.w,
@@ -259,11 +271,13 @@ class _LoginPageState extends State<LoginPage> {
style: StylesText.caption3,
),
),
Text(
'Quên Mật Khẩu',
style: StylesText.caption2.copyWith(
color: AppColors.primary1,
),
GhostButtonWidget(
title: 'Quên Mật Khẩu',
onPressed: () {
Get.to(
() => ForgotPasswordScreen(),
);
},
),
],
),

+ 2
- 6
lib/presentation/screens/login/models/response_user.dart View File

@@ -1,13 +1,9 @@
class ResponseUser {
String? accessToken;
String? refreshToken;
int? expiresIn;

ResponseUser({this.accessToken, this.refreshToken, this.expiresIn});
ResponseUser({this.accessToken});

ResponseUser.fromJson(Map<String, dynamic> json) {
accessToken = json['accessToken'];
refreshToken = json['refresh_token'];
expiresIn = json['expires_in'];
accessToken = json['id_token'];
}
}

+ 5
- 1
lib/presentation/screens/plot_detail/widget_tab.dart View File

@@ -97,7 +97,11 @@ class _HomeTabbarWidgetState extends State<HomeTabbarWidget> with TickerProvider
PlotInformationScreen(
cropId: widget.cropId ?? -1,
),
PlotActionScreen(cropId: widget.cropId ?? -1, cropCode: widget.cropCode ?? '', cropType: widget.cropType ?? -1),
PlotActionScreen(
cropId: widget.cropId ?? -1,
cropCode: widget.cropCode ?? '',
cropType: widget.cropType ?? -1,
),
PlotHistoryScreen(
cropId: widget.cropId ?? -1,
cropCode: widget.cropCode ?? '',

+ 5
- 5
lib/presentation/screens/profile/sc_change_password.dart View File

@@ -2,6 +2,7 @@ import 'package:farm_tpf/custom_model/password.dart';
import 'package:farm_tpf/data/api/app_exception.dart';
import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/button/primary_button_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
import 'package:farm_tpf/utils/const_color.dart';
@@ -9,6 +10,8 @@ import 'package:farm_tpf/utils/validators.dart';
import 'package:flutter/material.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';

import '../../custom_widgets/button_widget.dart';

class ChangePasswordScreen extends StatefulWidget {
@override
_ChangePasswordScreenState createState() => _ChangePasswordScreenState();
@@ -92,7 +95,8 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
return SizedBox(
width: double.infinity,
height: 55,
child: TextButton(
child: ButtonWidget(
title: 'Cập nhật',
onPressed: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
@@ -100,10 +104,6 @@ class _ChangePasswordScreenState extends State<ChangePasswordScreen> {
}
_validateInputs();
},
child: Text(
'Cập nhật'.toUpperCase(),
style: TextStyle(fontWeight: FontWeight.bold, color: AppColors.WHITE),
),
),
);
}

+ 0
- 3
lib/presentation/screens/profile/sc_update_profile.dart View File

@@ -4,13 +4,10 @@ import 'package:farm_tpf/data/repository/user_repository.dart';
import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_toast.dart';
import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart';
import 'package:farm_tpf/presentation/screens/location_unit/sc_location.dart';
import 'package:farm_tpf/presentation/screens/profile/controller/check_change_another_dropdown.dart';
import 'package:farm_tpf/presentation/screens/profile/sc_change_password.dart';
import 'package:farm_tpf/utils/const_color.dart';
import 'package:farm_tpf/utils/const_common.dart';
import 'package:farm_tpf/utils/const_string.dart';
import 'package:farm_tpf/utils/const_style.dart';

+ 1
- 1
lib/presentation/screens/qr_scan/qr_scan_page.dart View File

@@ -58,7 +58,7 @@ class _QrCodeScannerScreenState extends State<QrCodeScannerScreen> {
});
controller.scannedDataStream.listen((scanData) {
if (scanData != null) {
Get.back(result: scanData);
Get.back(result: scanData.code);
}
});
}

+ 3
- 1
lib/presentation/screens/tabbar/tabbar.dart View File

@@ -280,7 +280,9 @@ class _TabbarScreenState extends State<TabbarScreen> {
if (index == 2) {
changeTabbar.changeIndex(changeTabbar.index ?? TabBarIndex.plot);
// scan(context);
Get.to(QrCodeScannerScreen()).then((value) {
Get.to(
QrCodeScannerScreen(),
).then((value) {
if (value != null) {
_showAlertCheckCropCode(value);
}

+ 12
- 2
lib/utils/app_images.dart View File

@@ -5,6 +5,17 @@ class AssetPNG {
static const backgroundLogin = baseAssets + 'background_login.png';
static const chart = baseAssets + 'chart.png';
static const icNoData = baseAssets + 'ic_no_data.png';
static const icActionCropStatus = baseAssets + 'icActionCropStatus.png';
static const icActionDisease = baseAssets + 'icActionDisease.png';
static const icActionDung = baseAssets + 'icActionDung.png';
static const icActionEnd = baseAssets + 'icActionEnd.png';
static const icActionEnvironment = baseAssets + 'icActionEnvironment.png';
static const icActionNursery = baseAssets + 'icActionNursery.png';
static const icActionHarvest = baseAssets + 'icActionHarvest.png';
static const icActionOther = baseAssets + 'icActionOther.png';
static const icActionPlant = baseAssets + 'icActionPlant.png';
static const icActionSpraying = baseAssets + 'icActionSpraying.png';
static const icActionUseWater = baseAssets + 'icActionUseWater.png';
}

class AssetSVG {
@@ -59,8 +70,7 @@ class AssetSVG {
static const icVeterinaryMedicine = baseAssets + 'ic_veterinary_medicine.svg';
static const icMeadow = baseAssets + 'ic_meadow.svg';
static const icFoodProcessing = baseAssets + 'ic_food_processing.svg';
static const icFertilizerProduction =
baseAssets + 'ic_fertilizer_production.svg';
static const icFertilizerProduction = baseAssets + 'ic_fertilizer_production.svg';
static const icLogout = baseAssets + 'ic_logout.svg';
static const icCart = baseAssets + 'ic_cart.svg';
static const icCartChecked = baseAssets + 'ic_cart_checked.svg';

+ 9
- 11
lib/utils/local_storage.dart View File

@@ -1,17 +1,15 @@
import 'dart:developer';

import 'package:hive/hive.dart';

import '../environment/app_config.dart';
import '../presentation/screens/login/models/response_user.dart';

final LocalStorage = HiveLocalStorage();

class HiveLocalStorage {
final box = Hive.box(FlavorConfig.values.LocalDBName);
final box = Hive.box('LocalDBName');

void open() {
Hive.openBox(FlavorConfig.values.LocalDBName);
Hive.openBox('LocalDBName');
}

String getString(String key, {String? defaultValue}) {
@@ -72,14 +70,14 @@ class HiveLocalStorage {
// var userId = decodedToken['userid'] ?? '';

// var roles = decodedToken['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'] as List;
// // var roles = decodedToken['resource_access']['uca']['roles'] as List;
// // var userRoles = roles.join('|');
// // LocalStorage.save(LocalStorageKey.user_permission, userRoles);
// var roles = decodedToken['resource_access']['uca']['roles'] as List;
// var userRoles = roles.join('|');
// LocalStorage.save(LocalStorageKey.user_permission, userRoles);

// LocalStorage.save(LocalStorageKey.is_logged, true);
// LocalStorage.save(LocalStorageKey.username, username);
// LocalStorage.save(LocalStorageKey.access_token, data.accessToken);
// LocalStorage.save(LocalStorageKey.refresh_token, '');
LocalStorage.save(LocalStorageKey.is_logged, true);
LocalStorage.save(LocalStorageKey.username, username);
LocalStorage.save(LocalStorageKey.access_token, data.accessToken);
LocalStorage.save(LocalStorageKey.refresh_token, '');
// LocalStorage.save(LocalStorageKey.given_name, givenName);
// LocalStorage.save(LocalStorageKey.full_name, fullName);
// LocalStorage.save(LocalStorageKey.user_id, userId);

Loading…
Cancel
Save