feat : request tagging
This commit is contained in:
@@ -11,6 +11,7 @@ class ExpandableListItem2 extends StatelessWidget {
|
|||||||
required this.labelIcon,
|
required this.labelIcon,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
required this.selected,
|
required this.selected,
|
||||||
|
this.isTag = false,
|
||||||
this.labelIconColor = AppColor.mediumGreyDarkHover,
|
this.labelIconColor = AppColor.mediumGreyDarkHover,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ class ExpandableListItem2 extends StatelessWidget {
|
|||||||
final Color? labelIconColor;
|
final Color? labelIconColor;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final bool selected;
|
final bool selected;
|
||||||
|
final bool isTag;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -92,21 +94,40 @@ class ExpandableListItem2 extends StatelessWidget {
|
|||||||
|
|
||||||
Positioned(
|
Positioned(
|
||||||
right: -12,
|
right: -12,
|
||||||
child: Container(
|
child: isTag
|
||||||
width: index < 999 ? 24 : null,
|
? Container(
|
||||||
height: index < 999 ? 24 : null,
|
width: index < 999 ? 24 : 34,
|
||||||
padding: EdgeInsets.all(2),
|
height: index < 999 ? 34 : 34,
|
||||||
decoration: BoxDecoration(
|
alignment: Alignment.center,
|
||||||
color: AppColor.greenLightHover,
|
child: Stack(
|
||||||
borderRadius: BorderRadius.circular(4),
|
alignment: Alignment.center,
|
||||||
border: Border.all(width: 0.50, color: AppColor.greenDarkActive),
|
children: [
|
||||||
),
|
Assets.vec.tagLabelSvg.svg(),
|
||||||
alignment: Alignment.center,
|
Positioned(
|
||||||
child: Text(
|
top: 15,
|
||||||
(index + 1).toString(),
|
child: Text(
|
||||||
style: AppFonts.yekan12.copyWith(color: Colors.black),
|
(index + 1).toString(),
|
||||||
),
|
style: AppFonts.yekan10.copyWith(color: Colors.black),
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
width: index < 999 ? 24 : null,
|
||||||
|
height: index < 999 ? 24 : null,
|
||||||
|
padding: EdgeInsets.all(2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColor.greenLightHover,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(width: 0.50, color: AppColor.greenDarkActive),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
(index + 1).toString(),
|
||||||
|
style: AppFonts.yekan12.copyWith(color: Colors.black),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
export 'r_shimmer_list.dart';
|
export 'r_shimmer_list.dart';
|
||||||
export 'r_paginated_list_view.dart';
|
export 'r_paginated_list_view.dart';
|
||||||
|
export 'r_list_view.dart';
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:rasadyar_core/presentation/widget/list_view/r_paginated_list_view.dart';
|
||||||
import 'package:rasadyar_core/utils/network/resource.dart';
|
import 'package:rasadyar_core/utils/network/resource.dart';
|
||||||
|
|
||||||
import 'r_shimmer_list.dart';
|
import 'r_shimmer_list.dart';
|
||||||
|
|
||||||
enum ListType { builder, separated }
|
|
||||||
|
|
||||||
class RListView<T> extends StatelessWidget {
|
class RListView<T> extends StatelessWidget {
|
||||||
final ListType type;
|
final ListType type;
|
||||||
final Axis scrollDirection;
|
final Axis scrollDirection;
|
||||||
@@ -68,7 +67,7 @@ class RListView<T> extends StatelessWidget {
|
|||||||
this.addAutomaticKeepAlives = true,
|
this.addAutomaticKeepAlives = true,
|
||||||
this.addRepaintBoundaries = true,
|
this.addRepaintBoundaries = true,
|
||||||
this.addSemanticIndexes = true,
|
this.addSemanticIndexes = true,
|
||||||
this.loadingWidget = const RShimmerList(isSeparated: true),
|
this.loadingWidget = const RShimmerList(isSeparated: true),
|
||||||
this.emptyWidget = const Center(child: Text("هیچ آیتمی یافت نشد")),
|
this.emptyWidget = const Center(child: Text("هیچ آیتمی یافت نشد")),
|
||||||
this.errorWidget = const Center(child: CircularProgressIndicator()),
|
this.errorWidget = const Center(child: CircularProgressIndicator()),
|
||||||
required this.resource,
|
required this.resource,
|
||||||
|
|||||||
10
packages/core/lib/utils/file_utils.dart
Normal file
10
packages/core/lib/utils/file_utils.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'logger_utils.dart';
|
||||||
|
|
||||||
|
void getFileSizeInKB(String filePath, {String? tag}) {
|
||||||
|
final file = File(filePath);
|
||||||
|
final bytes = file.lengthSync();
|
||||||
|
var size = (bytes / 1024).ceil();
|
||||||
|
iLog('${tag ?? 'Picked'} image Size: $size');
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ export 'apk_updater.dart';
|
|||||||
export 'extension/date_time_utils.dart';
|
export 'extension/date_time_utils.dart';
|
||||||
export 'extension/num_utils.dart';
|
export 'extension/num_utils.dart';
|
||||||
export 'extension/string_utils.dart';
|
export 'extension/string_utils.dart';
|
||||||
|
export 'file_utils.dart';
|
||||||
export 'local/local_utils.dart';
|
export 'local/local_utils.dart';
|
||||||
export 'logger_utils.dart';
|
export 'logger_utils.dart';
|
||||||
export 'map_utils.dart';
|
export 'map_utils.dart';
|
||||||
|
|||||||
@@ -741,6 +741,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.5.4"
|
version: "4.5.4"
|
||||||
|
image_cropper:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_cropper
|
||||||
|
sha256: "4e9c96c029eb5a23798da1b6af39787f964da6ffc78fd8447c140542a9f7c6fc"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "9.1.0"
|
||||||
|
image_cropper_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_cropper_for_web
|
||||||
|
sha256: fd81ebe36f636576094377aab32673c4e5d1609b32dec16fad98d2b71f1250a9
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.1.0"
|
||||||
|
image_cropper_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_cropper_platform_interface
|
||||||
|
sha256: "6ca6b81769abff9a4dcc3bbd3d75f5dfa9de6b870ae9613c8cd237333a4283af"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.1.0"
|
||||||
image_picker:
|
image_picker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
|
|
||||||
|
abstract class LivestockRemoteDataSource {
|
||||||
|
Future<LocationDetails> getLocationDetailsByLatLng({required double latitude, required double longitude});
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/data_source/remote/livestock/livestock_remote.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
|
|
||||||
|
class LivestockRemoteDataSourceImp implements LivestockRemoteDataSource {
|
||||||
|
@override
|
||||||
|
Future<LocationDetails> getLocationDetailsByLatLng({
|
||||||
|
required double latitude,
|
||||||
|
required double longitude,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
Dio dio = Dio();
|
||||||
|
dio.options.baseUrl = 'https://nominatim.openstreetmap.org/';
|
||||||
|
dio.options.headers['User-Agent'] = 'RasadyarLivestock/2.0';
|
||||||
|
final response = await dio.get(
|
||||||
|
'reverse',
|
||||||
|
queryParameters: {'lat': latitude, 'lon': longitude, 'format': 'json'},
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final data = response.data;
|
||||||
|
return LocationDetails.fromJson(data);
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to load address');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,14 +10,14 @@ _LoginRequestModel _$LoginRequestModelFromJson(Map<String, dynamic> json) =>
|
|||||||
_LoginRequestModel(
|
_LoginRequestModel(
|
||||||
username: json['username'] as String?,
|
username: json['username'] as String?,
|
||||||
password: json['password'] as String?,
|
password: json['password'] as String?,
|
||||||
captchaCode: json['captcha_code'] as String?,
|
captchaCode: json['captchaCode'] as String?,
|
||||||
captchaKey: json['captcha_key'] as String?,
|
captchaKey: json['captchaKey'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$LoginRequestModelToJson(_LoginRequestModel instance) =>
|
Map<String, dynamic> _$LoginRequestModelToJson(_LoginRequestModel instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'username': instance.username,
|
'username': instance.username,
|
||||||
'password': instance.password,
|
'password': instance.password,
|
||||||
'captcha_code': instance.captchaCode,
|
'captchaCode': instance.captchaCode,
|
||||||
'captcha_key': instance.captchaKey,
|
'captchaKey': instance.captchaKey,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'address.freezed.dart';
|
||||||
|
|
||||||
|
part 'address.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class Address with _$Address {
|
||||||
|
const factory Address({
|
||||||
|
String? road,
|
||||||
|
String? neighbourhood,
|
||||||
|
String? suburb,
|
||||||
|
String? state,
|
||||||
|
String? borough,
|
||||||
|
String? city,
|
||||||
|
String? district,
|
||||||
|
String? county,
|
||||||
|
String? province,
|
||||||
|
String? ISO3166_2_lvl4,
|
||||||
|
String? postcode,
|
||||||
|
String? country,
|
||||||
|
String? country_code,
|
||||||
|
}) = _Address;
|
||||||
|
|
||||||
|
factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class LocationDetails with _$LocationDetails {
|
||||||
|
const factory LocationDetails({
|
||||||
|
int? place_id,
|
||||||
|
String? licence,
|
||||||
|
String? osm_type,
|
||||||
|
int? osm_id,
|
||||||
|
String? lat,
|
||||||
|
String? lon,
|
||||||
|
String? class_,
|
||||||
|
String? type,
|
||||||
|
int? place_rank,
|
||||||
|
double? importance,
|
||||||
|
String? addresstype,
|
||||||
|
String? name,
|
||||||
|
String? display_name,
|
||||||
|
Address? address,
|
||||||
|
List<String>? boundingbox,
|
||||||
|
}) = _LocationDetails;
|
||||||
|
|
||||||
|
factory LocationDetails.fromJson(Map<String, dynamic> json) => _$LocationDetailsFromJson(json);
|
||||||
|
}
|
||||||
@@ -10,12 +10,12 @@ _AuthResponseModel _$AuthResponseModelFromJson(Map<String, dynamic> json) =>
|
|||||||
_AuthResponseModel(
|
_AuthResponseModel(
|
||||||
refresh: json['refresh'] as String?,
|
refresh: json['refresh'] as String?,
|
||||||
access: json['access'] as String?,
|
access: json['access'] as String?,
|
||||||
otpStatus: json['otp_status'] as bool?,
|
otpStatus: json['otpStatus'] as bool?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$AuthResponseModelToJson(_AuthResponseModel instance) =>
|
Map<String, dynamic> _$AuthResponseModelToJson(_AuthResponseModel instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'refresh': instance.refresh,
|
'refresh': instance.refresh,
|
||||||
'access': instance.access,
|
'access': instance.access,
|
||||||
'otp_status': instance.otpStatus,
|
'otpStatus': instance.otpStatus,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ part of 'captcha_response_model.dart';
|
|||||||
_CaptchaResponseModel _$CaptchaResponseModelFromJson(
|
_CaptchaResponseModel _$CaptchaResponseModelFromJson(
|
||||||
Map<String, dynamic> json,
|
Map<String, dynamic> json,
|
||||||
) => _CaptchaResponseModel(
|
) => _CaptchaResponseModel(
|
||||||
captchaKey: json['captcha_key'] as String?,
|
captchaKey: json['captchaKey'] as String?,
|
||||||
captchaImage: json['captcha_image'] as String?,
|
captchaImage: json['captchaImage'] as String?,
|
||||||
imageType: json['image_type'] as String?,
|
imageType: json['imageType'] as String?,
|
||||||
imageDecode: json['image_decode'] as String?,
|
imageDecode: json['imageDecode'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$CaptchaResponseModelToJson(
|
Map<String, dynamic> _$CaptchaResponseModelToJson(
|
||||||
_CaptchaResponseModel instance,
|
_CaptchaResponseModel instance,
|
||||||
) => <String, dynamic>{
|
) => <String, dynamic>{
|
||||||
'captcha_key': instance.captchaKey,
|
'captchaKey': instance.captchaKey,
|
||||||
'captcha_image': instance.captchaImage,
|
'captchaImage': instance.captchaImage,
|
||||||
'image_type': instance.imageType,
|
'imageType': instance.imageType,
|
||||||
'image_decode': instance.imageDecode,
|
'imageDecode': instance.imageDecode,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ _User _$UserFromJson(Map<String, dynamic> json) => _User(
|
|||||||
id: (json['id'] as num).toInt(),
|
id: (json['id'] as num).toInt(),
|
||||||
username: json['username'] as String,
|
username: json['username'] as String,
|
||||||
password: json['password'] as String,
|
password: json['password'] as String,
|
||||||
firstName: json['first_name'] as String,
|
firstName: json['firstName'] as String,
|
||||||
lastName: json['last_name'] as String,
|
lastName: json['lastName'] as String,
|
||||||
isActive: json['is_active'] as bool,
|
isActive: json['isActive'] as bool,
|
||||||
mobile: json['mobile'] as String,
|
mobile: json['mobile'] as String,
|
||||||
phone: json['phone'] as String,
|
phone: json['phone'] as String,
|
||||||
nationalCode: json['national_code'] as String,
|
nationalCode: json['nationalCode'] as String,
|
||||||
birthdate: DateTime.parse(json['birthdate'] as String),
|
birthdate: DateTime.parse(json['birthdate'] as String),
|
||||||
nationality: json['nationality'] as String,
|
nationality: json['nationality'] as String,
|
||||||
ownership: json['ownership'] as String,
|
ownership: json['ownership'] as String,
|
||||||
@@ -39,21 +39,21 @@ _User _$UserFromJson(Map<String, dynamic> json) => _User(
|
|||||||
photo: json['photo'] as String,
|
photo: json['photo'] as String,
|
||||||
province: (json['province'] as num).toInt(),
|
province: (json['province'] as num).toInt(),
|
||||||
city: (json['city'] as num).toInt(),
|
city: (json['city'] as num).toInt(),
|
||||||
otpStatus: json['otp_status'] as bool,
|
otpStatus: json['otpStatus'] as bool,
|
||||||
cityName: json['city_name'] as String,
|
cityName: json['cityName'] as String,
|
||||||
provinceName: json['province_name'] as String,
|
provinceName: json['provinceName'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$UserToJson(_User instance) => <String, dynamic>{
|
Map<String, dynamic> _$UserToJson(_User instance) => <String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'username': instance.username,
|
'username': instance.username,
|
||||||
'password': instance.password,
|
'password': instance.password,
|
||||||
'first_name': instance.firstName,
|
'firstName': instance.firstName,
|
||||||
'last_name': instance.lastName,
|
'lastName': instance.lastName,
|
||||||
'is_active': instance.isActive,
|
'isActive': instance.isActive,
|
||||||
'mobile': instance.mobile,
|
'mobile': instance.mobile,
|
||||||
'phone': instance.phone,
|
'phone': instance.phone,
|
||||||
'national_code': instance.nationalCode,
|
'nationalCode': instance.nationalCode,
|
||||||
'birthdate': instance.birthdate.toIso8601String(),
|
'birthdate': instance.birthdate.toIso8601String(),
|
||||||
'nationality': instance.nationality,
|
'nationality': instance.nationality,
|
||||||
'ownership': instance.ownership,
|
'ownership': instance.ownership,
|
||||||
@@ -61,14 +61,14 @@ Map<String, dynamic> _$UserToJson(_User instance) => <String, dynamic>{
|
|||||||
'photo': instance.photo,
|
'photo': instance.photo,
|
||||||
'province': instance.province,
|
'province': instance.province,
|
||||||
'city': instance.city,
|
'city': instance.city,
|
||||||
'otp_status': instance.otpStatus,
|
'otpStatus': instance.otpStatus,
|
||||||
'city_name': instance.cityName,
|
'cityName': instance.cityName,
|
||||||
'province_name': instance.provinceName,
|
'provinceName': instance.provinceName,
|
||||||
};
|
};
|
||||||
|
|
||||||
_Role _$RoleFromJson(Map<String, dynamic> json) => _Role(
|
_Role _$RoleFromJson(Map<String, dynamic> json) => _Role(
|
||||||
id: (json['id'] as num).toInt(),
|
id: (json['id'] as num).toInt(),
|
||||||
roleName: json['role_name'] as String,
|
roleName: json['roleName'] as String,
|
||||||
description: json['description'] as String,
|
description: json['description'] as String,
|
||||||
type: RoleType.fromJson(json['type'] as Map<String, dynamic>),
|
type: RoleType.fromJson(json['type'] as Map<String, dynamic>),
|
||||||
permissions: json['permissions'] as List<dynamic>,
|
permissions: json['permissions'] as List<dynamic>,
|
||||||
@@ -76,7 +76,7 @@ _Role _$RoleFromJson(Map<String, dynamic> json) => _Role(
|
|||||||
|
|
||||||
Map<String, dynamic> _$RoleToJson(_Role instance) => <String, dynamic>{
|
Map<String, dynamic> _$RoleToJson(_Role instance) => <String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'role_name': instance.roleName,
|
'roleName': instance.roleName,
|
||||||
'description': instance.description,
|
'description': instance.description,
|
||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'permissions': instance.permissions,
|
'permissions': instance.permissions,
|
||||||
@@ -91,14 +91,14 @@ Map<String, dynamic> _$RoleTypeToJson(_RoleType instance) => <String, dynamic>{
|
|||||||
};
|
};
|
||||||
|
|
||||||
_Permission _$PermissionFromJson(Map<String, dynamic> json) => _Permission(
|
_Permission _$PermissionFromJson(Map<String, dynamic> json) => _Permission(
|
||||||
pageName: json['page_name'] as String,
|
pageName: json['pageName'] as String,
|
||||||
pageAccess: (json['page_access'] as List<dynamic>)
|
pageAccess: (json['pageAccess'] as List<dynamic>)
|
||||||
.map((e) => e as String)
|
.map((e) => e as String)
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$PermissionToJson(_Permission instance) =>
|
Map<String, dynamic> _$PermissionToJson(_Permission instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'page_name': instance.pageName,
|
'pageName': instance.pageName,
|
||||||
'page_access': instance.pageAccess,
|
'pageAccess': instance.pageAccess,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart';
|
import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart';
|
||||||
import 'package:rasadyar_livestock/data/model/response/captcha/captcha_response_model.dart';
|
import 'package:rasadyar_livestock/data/model/response/captcha/captcha_response_model.dart';
|
||||||
|
|
||||||
@@ -11,4 +12,6 @@ abstract class AuthRepository {
|
|||||||
Future<bool> hasAuthenticated();
|
Future<bool> hasAuthenticated();
|
||||||
|
|
||||||
Future<AuthResponseModel?> loginWithRefreshToken({required Map<String, dynamic> authRequest});
|
Future<AuthResponseModel?> loginWithRefreshToken({required Map<String, dynamic> authRequest});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/data_source/remote/livestock/livestock_remote.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart';
|
import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart';
|
||||||
import 'package:rasadyar_livestock/data/model/response/captcha/captcha_response_model.dart';
|
import 'package:rasadyar_livestock/data/model/response/captcha/captcha_response_model.dart';
|
||||||
|
|
||||||
@@ -7,7 +9,8 @@ import 'auth_repository.dart';
|
|||||||
class AuthRepositoryImp implements AuthRepository {
|
class AuthRepositoryImp implements AuthRepository {
|
||||||
final AuthRemoteDataSource authRemote;
|
final AuthRemoteDataSource authRemote;
|
||||||
|
|
||||||
AuthRepositoryImp(this.authRemote);
|
|
||||||
|
AuthRepositoryImp({required this.authRemote});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<AuthResponseModel?> login({required Map<String, dynamic> authRequest}) async =>
|
Future<AuthResponseModel?> login({required Map<String, dynamic> authRequest}) async =>
|
||||||
@@ -34,4 +37,6 @@ class AuthRepositoryImp implements AuthRepository {
|
|||||||
Future<bool> hasAuthenticated() async {
|
Future<bool> hasAuthenticated() async {
|
||||||
return await authRemote.hasAuthenticated();
|
return await authRemote.hasAuthenticated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/auth/auth_response_model.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/captcha/captcha_response_model.dart';
|
||||||
|
|
||||||
|
abstract class LivestockRepository {
|
||||||
|
Future<LocationDetails?> getLocationDetails({
|
||||||
|
required double latitude,
|
||||||
|
required double longitude,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:rasadyar_livestock/data/data_source/remote/livestock/livestock_remote.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
|
|
||||||
|
import 'livestock_repository.dart';
|
||||||
|
|
||||||
|
class LivestockRepositoryImp implements LivestockRepository {
|
||||||
|
final LivestockRemoteDataSource livestockRemote;
|
||||||
|
|
||||||
|
LivestockRepositoryImp({required this.livestockRemote});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<LocationDetails?> getLocationDetails({required double latitude, required double longitude}) async {
|
||||||
|
return await livestockRemote.getLocationDetailsByLatLng(
|
||||||
|
latitude: latitude,
|
||||||
|
longitude: longitude,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,12 @@ import 'package:rasadyar_core/core.dart';
|
|||||||
import 'package:rasadyar_livestock/data/common/dio_exception_handeler.dart';
|
import 'package:rasadyar_livestock/data/common/dio_exception_handeler.dart';
|
||||||
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote.dart';
|
||||||
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote_imp.dart';
|
import 'package:rasadyar_livestock/data/data_source/remote/auth/auth_remote_imp.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/data_source/remote/livestock/livestock_remote.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/data_source/remote/livestock/livestock_remote_imp.dart';
|
||||||
import 'package:rasadyar_livestock/data/repository/auth/auth_repository.dart';
|
import 'package:rasadyar_livestock/data/repository/auth/auth_repository.dart';
|
||||||
import 'package:rasadyar_livestock/data/repository/auth/auth_repository_imp.dart';
|
import 'package:rasadyar_livestock/data/repository/auth/auth_repository_imp.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository_imp.dart';
|
||||||
import 'package:rasadyar_livestock/presentation/routes/app_pages.dart';
|
import 'package:rasadyar_livestock/presentation/routes/app_pages.dart';
|
||||||
|
|
||||||
GetIt get diLiveStock => GetIt.instance;
|
GetIt get diLiveStock => GetIt.instance;
|
||||||
@@ -17,7 +21,7 @@ Future<void> setupLiveStockDI() async {
|
|||||||
await tokenService.saveBaseUrl('https://api.dam.rasadyar.net/');
|
await tokenService.saveBaseUrl('https://api.dam.rasadyar.net/');
|
||||||
}
|
}
|
||||||
|
|
||||||
// First register AppInterceptor with lazy callbacks
|
// First register AppInterceptor with lazy callbacks
|
||||||
diLiveStock.registerLazySingleton<AppInterceptor>(
|
diLiveStock.registerLazySingleton<AppInterceptor>(
|
||||||
() => AppInterceptor(
|
() => AppInterceptor(
|
||||||
refreshTokenCallback: () async {
|
refreshTokenCallback: () async {
|
||||||
@@ -55,13 +59,25 @@ Future<void> setupLiveStockDI() async {
|
|||||||
await diLiveStock.get<DioRemote>().init();
|
await diLiveStock.get<DioRemote>().init();
|
||||||
|
|
||||||
// Now register the data source and repository
|
// Now register the data source and repository
|
||||||
|
|
||||||
|
//region Auth
|
||||||
diLiveStock.registerLazySingleton<AuthRemoteDataSource>(
|
diLiveStock.registerLazySingleton<AuthRemoteDataSource>(
|
||||||
() => AuthRemoteDataSourceImp(diLiveStock.get<DioRemote>()),
|
() => AuthRemoteDataSourceImp(diLiveStock.get<DioRemote>()),
|
||||||
);
|
);
|
||||||
|
|
||||||
diLiveStock.registerLazySingleton<AuthRepository>(
|
diLiveStock.registerLazySingleton<AuthRepository>(
|
||||||
() => AuthRepositoryImp(diLiveStock.get<AuthRemoteDataSource>()),
|
() => AuthRepositoryImp(authRemote: diLiveStock.get<AuthRemoteDataSource>()),
|
||||||
);
|
);
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Livestock
|
||||||
|
diLiveStock.registerLazySingleton<LivestockRemoteDataSource>(
|
||||||
|
() => LivestockRemoteDataSourceImp(),
|
||||||
|
);
|
||||||
|
diLiveStock.registerLazySingleton<LivestockRepository>(
|
||||||
|
() => LivestockRepositoryImp(livestockRemote: diLiveStock.get<LivestockRemoteDataSource>()),
|
||||||
|
);
|
||||||
|
//endregion
|
||||||
|
|
||||||
diLiveStock.registerLazySingleton<ImagePicker>(() => ImagePicker());
|
diLiveStock.registerLazySingleton<ImagePicker>(() => ImagePicker());
|
||||||
await diLiveStock.allReady();
|
await diLiveStock.allReady();
|
||||||
|
|||||||
@@ -1,22 +1,43 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/model/response/address/address.dart';
|
||||||
|
import 'package:rasadyar_livestock/data/repository/livestock/livestock_repository.dart';
|
||||||
import 'package:rasadyar_livestock/injection/live_stock_di.dart';
|
import 'package:rasadyar_livestock/injection/live_stock_di.dart';
|
||||||
|
|
||||||
class RequestTaggingLogic extends GetxController {
|
class RequestTaggingLogic extends GetxController {
|
||||||
RxInt currentIndex = 0.obs;
|
RxInt currentIndex = 0.obs;
|
||||||
final int maxStep = 3;
|
final int maxStep = 2;
|
||||||
|
|
||||||
RxBool nextButtonEnabled = true.obs;
|
RxBool nextButtonEnabled = true.obs;
|
||||||
|
|
||||||
|
LivestockRepository livestockRepository = diLiveStock.get<LivestockRepository>();
|
||||||
|
|
||||||
|
//region First Step
|
||||||
final TextEditingController phoneController = TextEditingController();
|
final TextEditingController phoneController = TextEditingController();
|
||||||
final TextEditingController fullNameController = TextEditingController();
|
final TextEditingController fullNameController = TextEditingController();
|
||||||
final TextEditingController addressController = TextEditingController();
|
final TextEditingController addressController = TextEditingController();
|
||||||
|
|
||||||
ImagePicker imagePicker = diLiveStock.get<ImagePicker>();
|
ImagePicker imagePicker = diLiveStock.get<ImagePicker>();
|
||||||
Rxn<XFile> rancherImage = Rxn<XFile>(null);
|
Rxn<XFile> rancherImage = Rxn<XFile>(null);
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Second Step
|
||||||
|
Rxn<XFile> herdImage = Rxn<XFile>(null);
|
||||||
|
Rx<Resource<LocationDetails>> addressDetails = Rx<Resource<LocationDetails>>(Resource.loading());
|
||||||
|
RxnString addressDetailsValue = RxnString(null);
|
||||||
|
RxnString addressLocationValue = RxnString(null);
|
||||||
|
|
||||||
|
RxInt selectedSegment = 0.obs;
|
||||||
|
RxBool searchIsSelected = false.obs;
|
||||||
|
RxBool filterIsSelected = false.obs;
|
||||||
|
RxList<int> filterSelected = <int>[].obs;
|
||||||
|
|
||||||
|
RxList isExpandedList = <int>[].obs;
|
||||||
|
|
||||||
|
RxBool tst1 = false.obs;
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
@@ -25,6 +46,8 @@ class RequestTaggingLogic extends GetxController {
|
|||||||
ever(rancherImage, (callback) {
|
ever(rancherImage, (callback) {
|
||||||
setUpNextButtonListeners();
|
setUpNextButtonListeners();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
determineCurrentPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -52,11 +75,11 @@ class RequestTaggingLogic extends GetxController {
|
|||||||
|
|
||||||
void setUpNextButtonListeners() {
|
void setUpNextButtonListeners() {
|
||||||
if (currentIndex.value == 0) {
|
if (currentIndex.value == 0) {
|
||||||
nextButtonEnabled.value =
|
/* nextButtonEnabled.value =
|
||||||
phoneController.text.isNotEmpty &&
|
phoneController.text.isNotEmpty &&
|
||||||
fullNameController.text.isNotEmpty &&
|
fullNameController.text.isNotEmpty &&
|
||||||
addressController.text.isNotEmpty &&
|
addressController.text.isNotEmpty &&
|
||||||
rancherImage.value != null;
|
rancherImage.value != null;*/
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -94,10 +117,47 @@ class RequestTaggingLogic extends GetxController {
|
|||||||
getFileSizeInKB(rancherImage.value?.path ?? '', tag: 'Cropped');
|
getFileSizeInKB(rancherImage.value?.path ?? '', tag: 'Cropped');
|
||||||
}
|
}
|
||||||
|
|
||||||
void getFileSizeInKB(String filePath, {String? tag}) {
|
Future<void> determineCurrentPosition() async {
|
||||||
final file = File(filePath);
|
final position = await Geolocator.getCurrentPosition(
|
||||||
final bytes = file.lengthSync();
|
locationSettings: AndroidSettings(accuracy: LocationAccuracy.best),
|
||||||
var size = (bytes / 1024).ceil();
|
);
|
||||||
iLog('${tag ?? 'Picked'} image Size: $size');
|
|
||||||
|
getLocationDetails(position.latitude, position.longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getLocationDetails(double latitude, double longitude) async {
|
||||||
|
safeCall(
|
||||||
|
call: () => livestockRepository.getLocationDetails(latitude: latitude, longitude: longitude),
|
||||||
|
onSuccess: (result) {
|
||||||
|
if (result != null) {
|
||||||
|
addressDetails.value = Resource.success(result);
|
||||||
|
buildAddressDetails(result);
|
||||||
|
addressLocationValue.value = '$latitude - $longitude';
|
||||||
|
} else {
|
||||||
|
addressDetails.value = Resource.error('Failed to fetch address');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (error, stackTrace) {
|
||||||
|
addressDetails.value = Resource.error('Error fetching address: ${error.toString()}');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildAddressDetails(LocationDetails result) {
|
||||||
|
final address = result.address;
|
||||||
|
if (address != null) {
|
||||||
|
final addressParts = [
|
||||||
|
address.state,
|
||||||
|
address.county,
|
||||||
|
address.district,
|
||||||
|
address.city,
|
||||||
|
address.suburb,
|
||||||
|
address.neighbourhood,
|
||||||
|
address.road,
|
||||||
|
].where((part) => part != null && part.isNotEmpty).join(', ');
|
||||||
|
addressDetailsValue.value = addressParts;
|
||||||
|
} else {
|
||||||
|
addressDetailsValue.value = 'Address not found';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user