feat : home page
This commit is contained in:
@@ -164,6 +164,8 @@ class SplashLogic extends GetxController with GetTickerProviderStateMixin {
|
||||
if (target != null) {
|
||||
var mFuns = getFunctionsList(target.functions);
|
||||
await Future.wait(mFuns ?? []);
|
||||
|
||||
iLog("target.route ===>${target.route!}");
|
||||
Get.offAndToNamed(target.route!);
|
||||
}
|
||||
} catch (e, st) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart';
|
||||
|
||||
abstract class PoultryScienceRemoteDatasource {
|
||||
Future<HomePoultryScienceModel?> getHomePoultryScience({
|
||||
required String token,
|
||||
required String type,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'poultry_science_remote.dart';
|
||||
|
||||
class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasource {
|
||||
final DioRemote _httpClient;
|
||||
|
||||
PoultryScienceRemoteDatasourceImp(this._httpClient);
|
||||
|
||||
@override
|
||||
Future<HomePoultryScienceModel?> getHomePoultryScience({
|
||||
required String token,
|
||||
required String type,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'poultry_and_hatching_for_poultry_science/',
|
||||
queryParameters: {'type': type},
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJson: (json) => HomePoultryScienceModel.fromJson(json),
|
||||
);
|
||||
|
||||
return res.data;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,14 @@ import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository_imp.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository_imp.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
GetIt diChicken = GetIt.asNewInstance();
|
||||
@@ -67,6 +71,14 @@ Future<void> setupChickenDI() async {
|
||||
local: diChicken.get<ChickenLocalDataSource>(),
|
||||
),
|
||||
);
|
||||
|
||||
diChicken.registerLazySingleton<PoultryScienceRemoteDatasource>(
|
||||
() => PoultryScienceRemoteDatasourceImp(diChicken.get<DioRemote>()),
|
||||
);
|
||||
|
||||
diChicken.registerLazySingleton<PoultryScienceRepository>(
|
||||
() => PoultryScienceRepositoryImp(diChicken.get<PoultryScienceRemoteDatasource>()),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> newSetupAuthDI(String newUrl) async {
|
||||
@@ -117,6 +129,13 @@ Future<void> newSetupAuthDI(String newUrl) async {
|
||||
local: diChicken.get<ChickenLocalDataSource>(),
|
||||
),
|
||||
);
|
||||
|
||||
await reRegister<PoultryScienceRemoteDatasource>(
|
||||
() => PoultryScienceRemoteDatasourceImp(dioRemote),
|
||||
);
|
||||
await reRegister<PoultryScienceRepository>(
|
||||
() => PoultryScienceRepositoryImp(diChicken.get<PoultryScienceRemoteDatasource>()),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> reRegister<T extends Object>(T Function() factory) async {
|
||||
|
||||
@@ -8,7 +8,7 @@ part of 'widely_used_local_model.dart';
|
||||
|
||||
class WidelyUsedLocalModelAdapter extends TypeAdapter<WidelyUsedLocalModel> {
|
||||
@override
|
||||
final typeId = 2;
|
||||
final typeId = 4;
|
||||
|
||||
@override
|
||||
WidelyUsedLocalModel read(BinaryReader reader) {
|
||||
@@ -45,7 +45,7 @@ class WidelyUsedLocalModelAdapter extends TypeAdapter<WidelyUsedLocalModel> {
|
||||
|
||||
class WidelyUsedLocalItemAdapter extends TypeAdapter<WidelyUsedLocalItem> {
|
||||
@override
|
||||
final typeId = 3;
|
||||
final typeId = 5;
|
||||
|
||||
@override
|
||||
WidelyUsedLocalItem read(BinaryReader reader) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'home_poultry_science_model.freezed.dart';
|
||||
part 'home_poultry_science_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class HomePoultryScienceModel with _$HomePoultryScienceModel {
|
||||
const factory HomePoultryScienceModel({
|
||||
int? farmCount,
|
||||
int? hatchingCount,
|
||||
int? hatchingQuantity,
|
||||
int? hatchingLeftOver,
|
||||
int? hatchingLosses,
|
||||
int? hatchingKilledQuantity,
|
||||
int? hatchingMaxAge,
|
||||
int? hatchingMinAge,
|
||||
}) = _HomePoultryScienceModel;
|
||||
|
||||
factory HomePoultryScienceModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$HomePoultryScienceModelFromJson(json);
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'home_poultry_science_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$HomePoultryScienceModel {
|
||||
|
||||
int? get farmCount; int? get hatchingCount; int? get hatchingQuantity; int? get hatchingLeftOver; int? get hatchingLosses; int? get hatchingKilledQuantity; int? get hatchingMaxAge; int? get hatchingMinAge;
|
||||
/// Create a copy of HomePoultryScienceModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$HomePoultryScienceModelCopyWith<HomePoultryScienceModel> get copyWith => _$HomePoultryScienceModelCopyWithImpl<HomePoultryScienceModel>(this as HomePoultryScienceModel, _$identity);
|
||||
|
||||
/// Serializes this HomePoultryScienceModel to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomePoultryScienceModel&&(identical(other.farmCount, farmCount) || other.farmCount == farmCount)&&(identical(other.hatchingCount, hatchingCount) || other.hatchingCount == hatchingCount)&&(identical(other.hatchingQuantity, hatchingQuantity) || other.hatchingQuantity == hatchingQuantity)&&(identical(other.hatchingLeftOver, hatchingLeftOver) || other.hatchingLeftOver == hatchingLeftOver)&&(identical(other.hatchingLosses, hatchingLosses) || other.hatchingLosses == hatchingLosses)&&(identical(other.hatchingKilledQuantity, hatchingKilledQuantity) || other.hatchingKilledQuantity == hatchingKilledQuantity)&&(identical(other.hatchingMaxAge, hatchingMaxAge) || other.hatchingMaxAge == hatchingMaxAge)&&(identical(other.hatchingMinAge, hatchingMinAge) || other.hatchingMinAge == hatchingMinAge));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,farmCount,hatchingCount,hatchingQuantity,hatchingLeftOver,hatchingLosses,hatchingKilledQuantity,hatchingMaxAge,hatchingMinAge);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomePoultryScienceModel(farmCount: $farmCount, hatchingCount: $hatchingCount, hatchingQuantity: $hatchingQuantity, hatchingLeftOver: $hatchingLeftOver, hatchingLosses: $hatchingLosses, hatchingKilledQuantity: $hatchingKilledQuantity, hatchingMaxAge: $hatchingMaxAge, hatchingMinAge: $hatchingMinAge)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $HomePoultryScienceModelCopyWith<$Res> {
|
||||
factory $HomePoultryScienceModelCopyWith(HomePoultryScienceModel value, $Res Function(HomePoultryScienceModel) _then) = _$HomePoultryScienceModelCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int? farmCount, int? hatchingCount, int? hatchingQuantity, int? hatchingLeftOver, int? hatchingLosses, int? hatchingKilledQuantity, int? hatchingMaxAge, int? hatchingMinAge
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$HomePoultryScienceModelCopyWithImpl<$Res>
|
||||
implements $HomePoultryScienceModelCopyWith<$Res> {
|
||||
_$HomePoultryScienceModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final HomePoultryScienceModel _self;
|
||||
final $Res Function(HomePoultryScienceModel) _then;
|
||||
|
||||
/// Create a copy of HomePoultryScienceModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? farmCount = freezed,Object? hatchingCount = freezed,Object? hatchingQuantity = freezed,Object? hatchingLeftOver = freezed,Object? hatchingLosses = freezed,Object? hatchingKilledQuantity = freezed,Object? hatchingMaxAge = freezed,Object? hatchingMinAge = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
farmCount: freezed == farmCount ? _self.farmCount : farmCount // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingCount: freezed == hatchingCount ? _self.hatchingCount : hatchingCount // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingQuantity: freezed == hatchingQuantity ? _self.hatchingQuantity : hatchingQuantity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingLeftOver: freezed == hatchingLeftOver ? _self.hatchingLeftOver : hatchingLeftOver // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingLosses: freezed == hatchingLosses ? _self.hatchingLosses : hatchingLosses // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingKilledQuantity: freezed == hatchingKilledQuantity ? _self.hatchingKilledQuantity : hatchingKilledQuantity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingMaxAge: freezed == hatchingMaxAge ? _self.hatchingMaxAge : hatchingMaxAge // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingMinAge: freezed == hatchingMinAge ? _self.hatchingMinAge : hatchingMinAge // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [HomePoultryScienceModel].
|
||||
extension HomePoultryScienceModelPatterns on HomePoultryScienceModel {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _HomePoultryScienceModel value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _HomePoultryScienceModel value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _HomePoultryScienceModel value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int? farmCount, int? hatchingCount, int? hatchingQuantity, int? hatchingLeftOver, int? hatchingLosses, int? hatchingKilledQuantity, int? hatchingMaxAge, int? hatchingMinAge)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel() when $default != null:
|
||||
return $default(_that.farmCount,_that.hatchingCount,_that.hatchingQuantity,_that.hatchingLeftOver,_that.hatchingLosses,_that.hatchingKilledQuantity,_that.hatchingMaxAge,_that.hatchingMinAge);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int? farmCount, int? hatchingCount, int? hatchingQuantity, int? hatchingLeftOver, int? hatchingLosses, int? hatchingKilledQuantity, int? hatchingMaxAge, int? hatchingMinAge) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel():
|
||||
return $default(_that.farmCount,_that.hatchingCount,_that.hatchingQuantity,_that.hatchingLeftOver,_that.hatchingLosses,_that.hatchingKilledQuantity,_that.hatchingMaxAge,_that.hatchingMinAge);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int? farmCount, int? hatchingCount, int? hatchingQuantity, int? hatchingLeftOver, int? hatchingLosses, int? hatchingKilledQuantity, int? hatchingMaxAge, int? hatchingMinAge)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomePoultryScienceModel() when $default != null:
|
||||
return $default(_that.farmCount,_that.hatchingCount,_that.hatchingQuantity,_that.hatchingLeftOver,_that.hatchingLosses,_that.hatchingKilledQuantity,_that.hatchingMaxAge,_that.hatchingMinAge);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _HomePoultryScienceModel implements HomePoultryScienceModel {
|
||||
const _HomePoultryScienceModel({this.farmCount, this.hatchingCount, this.hatchingQuantity, this.hatchingLeftOver, this.hatchingLosses, this.hatchingKilledQuantity, this.hatchingMaxAge, this.hatchingMinAge});
|
||||
factory _HomePoultryScienceModel.fromJson(Map<String, dynamic> json) => _$HomePoultryScienceModelFromJson(json);
|
||||
|
||||
@override final int? farmCount;
|
||||
@override final int? hatchingCount;
|
||||
@override final int? hatchingQuantity;
|
||||
@override final int? hatchingLeftOver;
|
||||
@override final int? hatchingLosses;
|
||||
@override final int? hatchingKilledQuantity;
|
||||
@override final int? hatchingMaxAge;
|
||||
@override final int? hatchingMinAge;
|
||||
|
||||
/// Create a copy of HomePoultryScienceModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$HomePoultryScienceModelCopyWith<_HomePoultryScienceModel> get copyWith => __$HomePoultryScienceModelCopyWithImpl<_HomePoultryScienceModel>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$HomePoultryScienceModelToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomePoultryScienceModel&&(identical(other.farmCount, farmCount) || other.farmCount == farmCount)&&(identical(other.hatchingCount, hatchingCount) || other.hatchingCount == hatchingCount)&&(identical(other.hatchingQuantity, hatchingQuantity) || other.hatchingQuantity == hatchingQuantity)&&(identical(other.hatchingLeftOver, hatchingLeftOver) || other.hatchingLeftOver == hatchingLeftOver)&&(identical(other.hatchingLosses, hatchingLosses) || other.hatchingLosses == hatchingLosses)&&(identical(other.hatchingKilledQuantity, hatchingKilledQuantity) || other.hatchingKilledQuantity == hatchingKilledQuantity)&&(identical(other.hatchingMaxAge, hatchingMaxAge) || other.hatchingMaxAge == hatchingMaxAge)&&(identical(other.hatchingMinAge, hatchingMinAge) || other.hatchingMinAge == hatchingMinAge));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,farmCount,hatchingCount,hatchingQuantity,hatchingLeftOver,hatchingLosses,hatchingKilledQuantity,hatchingMaxAge,hatchingMinAge);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomePoultryScienceModel(farmCount: $farmCount, hatchingCount: $hatchingCount, hatchingQuantity: $hatchingQuantity, hatchingLeftOver: $hatchingLeftOver, hatchingLosses: $hatchingLosses, hatchingKilledQuantity: $hatchingKilledQuantity, hatchingMaxAge: $hatchingMaxAge, hatchingMinAge: $hatchingMinAge)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$HomePoultryScienceModelCopyWith<$Res> implements $HomePoultryScienceModelCopyWith<$Res> {
|
||||
factory _$HomePoultryScienceModelCopyWith(_HomePoultryScienceModel value, $Res Function(_HomePoultryScienceModel) _then) = __$HomePoultryScienceModelCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int? farmCount, int? hatchingCount, int? hatchingQuantity, int? hatchingLeftOver, int? hatchingLosses, int? hatchingKilledQuantity, int? hatchingMaxAge, int? hatchingMinAge
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$HomePoultryScienceModelCopyWithImpl<$Res>
|
||||
implements _$HomePoultryScienceModelCopyWith<$Res> {
|
||||
__$HomePoultryScienceModelCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _HomePoultryScienceModel _self;
|
||||
final $Res Function(_HomePoultryScienceModel) _then;
|
||||
|
||||
/// Create a copy of HomePoultryScienceModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? farmCount = freezed,Object? hatchingCount = freezed,Object? hatchingQuantity = freezed,Object? hatchingLeftOver = freezed,Object? hatchingLosses = freezed,Object? hatchingKilledQuantity = freezed,Object? hatchingMaxAge = freezed,Object? hatchingMinAge = freezed,}) {
|
||||
return _then(_HomePoultryScienceModel(
|
||||
farmCount: freezed == farmCount ? _self.farmCount : farmCount // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingCount: freezed == hatchingCount ? _self.hatchingCount : hatchingCount // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingQuantity: freezed == hatchingQuantity ? _self.hatchingQuantity : hatchingQuantity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingLeftOver: freezed == hatchingLeftOver ? _self.hatchingLeftOver : hatchingLeftOver // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingLosses: freezed == hatchingLosses ? _self.hatchingLosses : hatchingLosses // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingKilledQuantity: freezed == hatchingKilledQuantity ? _self.hatchingKilledQuantity : hatchingKilledQuantity // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingMaxAge: freezed == hatchingMaxAge ? _self.hatchingMaxAge : hatchingMaxAge // ignore: cast_nullable_to_non_nullable
|
||||
as int?,hatchingMinAge: freezed == hatchingMinAge ? _self.hatchingMinAge : hatchingMinAge // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,33 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'home_poultry_science_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_HomePoultryScienceModel _$HomePoultryScienceModelFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _HomePoultryScienceModel(
|
||||
farmCount: (json['farm_count'] as num?)?.toInt(),
|
||||
hatchingCount: (json['hatching_count'] as num?)?.toInt(),
|
||||
hatchingQuantity: (json['hatching_quantity'] as num?)?.toInt(),
|
||||
hatchingLeftOver: (json['hatching_left_over'] as num?)?.toInt(),
|
||||
hatchingLosses: (json['hatching_losses'] as num?)?.toInt(),
|
||||
hatchingKilledQuantity: (json['hatching_killed_quantity'] as num?)?.toInt(),
|
||||
hatchingMaxAge: (json['hatching_max_age'] as num?)?.toInt(),
|
||||
hatchingMinAge: (json['hatching_min_age'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$HomePoultryScienceModelToJson(
|
||||
_HomePoultryScienceModel instance,
|
||||
) => <String, dynamic>{
|
||||
'farm_count': instance.farmCount,
|
||||
'hatching_count': instance.hatchingCount,
|
||||
'hatching_quantity': instance.hatchingQuantity,
|
||||
'hatching_left_over': instance.hatchingLeftOver,
|
||||
'hatching_losses': instance.hatchingLosses,
|
||||
'hatching_killed_quantity': instance.hatchingKilledQuantity,
|
||||
'hatching_max_age': instance.hatchingMaxAge,
|
||||
'hatching_min_age': instance.hatchingMinAge,
|
||||
};
|
||||
@@ -27,6 +27,8 @@ import '../../models/request/create_steward_free_bar/create_steward_free_bar.dar
|
||||
|
||||
abstract class ChickenRepository {
|
||||
//region Remote
|
||||
|
||||
//region Steward
|
||||
Future<List<InventoryModel>?> getInventory({required String token, CancelToken? cancelToken});
|
||||
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({required String token});
|
||||
@@ -156,6 +158,11 @@ abstract class ChickenRepository {
|
||||
|
||||
Future<SegmentationModel?> deleteSegmentation({required String token, required String key});
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
//region local
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart';
|
||||
|
||||
abstract class PoultryScienceRepository {
|
||||
Future<HomePoultryScienceModel?> getHomePoultryScience({
|
||||
required String token,
|
||||
required String type,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart';
|
||||
import 'poultry_science_repository.dart';
|
||||
|
||||
class PoultryScienceRepositoryImp implements PoultryScienceRepository {
|
||||
final PoultryScienceRemoteDatasource datasource;
|
||||
|
||||
PoultryScienceRepositoryImp(this.datasource);
|
||||
|
||||
@override
|
||||
Future<HomePoultryScienceModel?> getHomePoultryScience({
|
||||
required String token,
|
||||
required String type,
|
||||
}) async => await datasource.getHomePoultryScience(token: token, type: type);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class PoultryScienceHomeLogic extends GetxController {
|
||||
PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>();
|
||||
Rxn<HomePoultryScienceModel> homeInformation = Rxn();
|
||||
RxBool isExpanded = false.obs;
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getHomePoultryHatching();
|
||||
}
|
||||
|
||||
Future<void> getHomePoultryHatching() async {
|
||||
await safeCall<HomePoultryScienceModel?>(
|
||||
call: () async => await rootLogic.poultryRepository.getHomePoultryScience(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
type: 'home',
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
homeInformation.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,608 @@
|
||||
import 'package:flutter/cupertino.dart' hide LinearGradient;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/app_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/widely_used/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class PoultryScienceHomePage extends GetView<PoultryScienceHomeLogic> {
|
||||
const PoultryScienceHomePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.bgLight,
|
||||
appBar: chickenAppBar(hasBack: false, hasFilter: false, hasSearch: false),
|
||||
body: SingleChildScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () {
|
||||
controller.isExpanded.value = !controller.isExpanded.value;
|
||||
},
|
||||
child: Card(
|
||||
margin: EdgeInsetsGeometry.all(6),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(width: 0.50, color: const Color(0xFFA9A9A9)),
|
||||
),
|
||||
|
||||
child: ObxValue((data) {
|
||||
return AnimatedSize(
|
||||
duration: Duration(milliseconds: 300),
|
||||
child: data.value
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 8,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: ShapeDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(Assets.images.chicken.path),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 0.25,
|
||||
color: const Color(0xFFB0B0B0),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'مرغ گرم',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.darkGreyDarkActive,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
AnimatedRotation(
|
||||
turns: 180,
|
||||
duration: Duration(milliseconds: 3000),
|
||||
child: Icon(CupertinoIcons.chevron_up, size: 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
_todayShipmentWidget(),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'اطلاعات جوجه ریزی',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16,
|
||||
),
|
||||
],
|
||||
),
|
||||
_inventoryWidget(),
|
||||
killsShipment(),
|
||||
ageWidget(),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 8,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: ShapeDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(Assets.images.chicken.path),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 0.25,
|
||||
color: const Color(0xFFB0B0B0),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'مرغ گرم',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.darkGreyDarkActive,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Icon(CupertinoIcons.chevron_down, size: 18),
|
||||
],
|
||||
),
|
||||
_todayShipmentWidget(),
|
||||
_inventoryWidget(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.isExpanded),
|
||||
),
|
||||
),
|
||||
|
||||
WidelyUsedWidget(),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget ageWidget() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 8, 0, 13),
|
||||
child: ObxValue((data) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
_informationIconCard(
|
||||
title: 'کمترین سن جوجه ریزیط',
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.hatchingMinAge.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.truckSvg.path,
|
||||
iconColor: const Color.fromRGBO(85, 97, 93, 1),
|
||||
bgDescriptionColor: const Color(0xFFE6FAF5),
|
||||
bgLabelColor: const Color(0xFFB0EFDF),
|
||||
),
|
||||
_informationIconCard(
|
||||
title: 'بیشترین سن جوجه ریزی',
|
||||
description: data.value?.hatchingMaxAge?.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.convertCubeSvg.path,
|
||||
iconColor: const Color(0xFF6F6164),
|
||||
bgDescriptionColor: const Color(0xFFEDDCE0),
|
||||
bgLabelColor: const Color(0xFFE0BCC5),
|
||||
),
|
||||
],
|
||||
);
|
||||
}, controller.homeInformation),
|
||||
);
|
||||
}
|
||||
|
||||
Widget killsShipment() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 8, 0, 13),
|
||||
child: ObxValue((data) {
|
||||
return Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: _informationLabelCard(
|
||||
title: 'تلفات',
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.hatchingLosses?.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.a3dCubeSquareSvg.path,
|
||||
iconColor: const Color(0xFF6C5D60),
|
||||
bgDescriptionColor: const Color(0xFFEDDCE0),
|
||||
bgLabelColor: const Color(0xFFDDC0C7),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _informationLabelCard(
|
||||
title: 'حجم کشتار شده',
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.hatchingKilledQuantity.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.cubeSearchSvg.path,
|
||||
iconColor: Color(0xFF2D5FFF),
|
||||
bgLabelColor: const Color(0xFFAFCBFF),
|
||||
bgDescriptionColor: const Color(0xFFCEDFFF),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}, controller.homeInformation),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _inventoryWidget() {
|
||||
return ObxValue((data) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 10, 0, 13),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: _informationLabelCard(
|
||||
title: 'حجم جوجه ریزی',
|
||||
isLoading: data.value == null,
|
||||
unit: 'قطعه',
|
||||
description: data.value?.hatchingQuantity.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.cubeSearchSvg.path,
|
||||
iconColor: const Color(0xFF426060),
|
||||
bgDescriptionColor: const Color(0xFFC7DFE0),
|
||||
bgLabelColor: const Color(0xFFA5D1D2),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _informationLabelCard(
|
||||
title: 'مانده در سالن',
|
||||
unit: 'قطعه',
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.hatchingLeftOver.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.cubeRotateSvg.path,
|
||||
iconColor: Color(0xFF5C4D64),
|
||||
bgLabelColor: Color(0xFFC8B8D1),
|
||||
bgDescriptionColor: Color(0xFFDAD4DD),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}, controller.homeInformation);
|
||||
}
|
||||
|
||||
Widget _todayShipmentWidget() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 10, 0, 13),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: ObxValue(
|
||||
(data) => _informationLabelCard(
|
||||
title: 'کل فارم ها',
|
||||
titleColor: AppColor.blueNormal,
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.farmCount?.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.cubeSearchSvg.path,
|
||||
iconColor: AppColor.blueNormal,
|
||||
bgDescriptionColor: Colors.white,
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [AppColor.blueLight, Colors.white],
|
||||
),
|
||||
),
|
||||
controller.homeInformation,
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return _informationLabelCard(
|
||||
title: 'تعداد جوجه ریزی ها',
|
||||
isLoading: data.value == null,
|
||||
description: data.value?.hatchingCount.separatedByComma ?? '0',
|
||||
iconPath: Assets.vec.cubeWattingSvg.path,
|
||||
bgDescriptionColor: Colors.white,
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [const Color(0xFFFFE7BB), Colors.white],
|
||||
),
|
||||
);
|
||||
}, controller.homeInformation),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container _informationLabelCard({
|
||||
required String title,
|
||||
required String description,
|
||||
required String iconPath,
|
||||
required Color bgDescriptionColor,
|
||||
String unit = 'کیلوگرم',
|
||||
bool isLoading = false,
|
||||
Color? iconColor,
|
||||
Color? titleColor,
|
||||
Color? bgLabelColor,
|
||||
LinearGradient? gradient,
|
||||
}) {
|
||||
return Container(
|
||||
height: 82,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Row(
|
||||
children: [
|
||||
// Left side with icon and title
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 82,
|
||||
decoration: BoxDecoration(
|
||||
color: gradient == null ? bgLabelColor : null,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(8),
|
||||
bottomRight: Radius.circular(8),
|
||||
),
|
||||
gradient: gradient,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
SvgGenImage.vec(iconPath).svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: iconColor != null
|
||||
? ColorFilter.mode(iconColor, BlendMode.srcIn)
|
||||
: null,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: titleColor ?? AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Right side with description and unit
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: bgDescriptionColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(8),
|
||||
bottomLeft: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
child: isLoading
|
||||
? Center(child: CupertinoActivityIndicator())
|
||||
: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
description,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive),
|
||||
),
|
||||
Text(
|
||||
unit,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container _informationIconCard({
|
||||
required String title,
|
||||
required String description,
|
||||
String? unit,
|
||||
bool isLoading = false,
|
||||
required String iconPath,
|
||||
required Color iconColor,
|
||||
required Color bgDescriptionColor,
|
||||
required Color bgLabelColor,
|
||||
}) {
|
||||
return Container(
|
||||
height: 80.h,
|
||||
width: 145.w,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
height: 91,
|
||||
decoration: BoxDecoration(
|
||||
color: bgDescriptionColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 0.25, color: const Color(0xFFB4B4B4)),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive),
|
||||
),
|
||||
|
||||
isLoading
|
||||
? Center(child: CupertinoActivityIndicator())
|
||||
: Text(
|
||||
description,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive),
|
||||
),
|
||||
|
||||
Visibility(
|
||||
visible: unit != null,
|
||||
child: Text(
|
||||
unit ?? '',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: ShapeDecoration(
|
||||
color: bgLabelColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
side: BorderSide(width: 0.25, color: const Color(0xFFD5D5D5)),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgGenImage.vec(iconPath).svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget inventoryItem({
|
||||
required bool isExpanded,
|
||||
required int index,
|
||||
required InventoryModel model,
|
||||
}) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow('نام محصول', model.name ?? ''),
|
||||
Visibility(
|
||||
visible: isExpanded,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow('وزن خریدهای دولتی داخل استان (کیلوگرم)', '0326598653'),
|
||||
buildRow(
|
||||
'وزن خریدهای آزاد داخل استان (کیلوگرم)',
|
||||
model.receiveFreeCarcassesWeight.toString(),
|
||||
),
|
||||
buildRow(
|
||||
'وزن خریدهای خارج استان (کیلوگرم)',
|
||||
model.freeBuyingCarcassesWeight.toString(),
|
||||
),
|
||||
buildRow(
|
||||
'کل ورودی به انبار (کیلوگرم)',
|
||||
model.totalFreeBarsCarcassesWeight.toString(),
|
||||
),
|
||||
buildRow('کل فروش (کیلوگرم)', model.realAllocatedWeight.toString()),
|
||||
buildRow('مانده انبار (کیلوگرم)', model.totalRemainWeight.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildRow(String title, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Text(
|
||||
value,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget broadcastInformationWidget(KillHouseDistributionInfo? model) {
|
||||
return Container(
|
||||
height: 140,
|
||||
margin: const EdgeInsets.all(8),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.blueNormal, width: 1),
|
||||
),
|
||||
child: model != null
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
'اطلاعات ارسالی',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
buildRow(
|
||||
'فروش و توزیع داخل استان (کیلوگرم)',
|
||||
model.stewardAllocationsWeight!.toInt().toString(),
|
||||
),
|
||||
buildRow(
|
||||
'فروش و توزیع خارج استان (کیلوگرم)',
|
||||
model.freeSalesWeight!.toInt().toString(),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardWidget({
|
||||
required String title,
|
||||
required String iconPath,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return Container(
|
||||
width: Get.width / 4,
|
||||
height: 130,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Card(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(width: 1, color: AppColor.blueNormal),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgGenImage(iconPath).svg(width: 50, height: 50),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class PoultryScienceProfileLogic extends GetxController {
|
||||
PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>();
|
||||
RxInt selectedInformationType = 0.obs;
|
||||
Rxn<Jalali> birthDate = Rxn<Jalali>();
|
||||
|
||||
Rx<Resource<UserProfile>> userProfile = Rx<Resource<UserProfile>>(Resource.loading());
|
||||
|
||||
TextEditingController nameController = TextEditingController();
|
||||
TextEditingController lastNameController = TextEditingController();
|
||||
TextEditingController nationalCodeController = TextEditingController();
|
||||
TextEditingController nationalIdController = TextEditingController();
|
||||
TextEditingController birthdayController = TextEditingController();
|
||||
|
||||
TextEditingController oldPasswordController = TextEditingController();
|
||||
TextEditingController newPasswordController = TextEditingController();
|
||||
TextEditingController retryNewPasswordController = TextEditingController();
|
||||
|
||||
RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
|
||||
Rxn<IranProvinceCityModel> selectedProvince = Rxn();
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey();
|
||||
ImagePicker imagePicker = ImagePicker();
|
||||
Rxn<XFile> selectedImage = Rxn<XFile>();
|
||||
RxnString _base64Image = RxnString();
|
||||
RxBool isOnLoading = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
ever(selectedImage, (data) async {
|
||||
if (data?.path != null) {
|
||||
_base64Image.value = await convertImageToBase64(data!.path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getUserProfile();
|
||||
selectedProvince.listen((p0) => getCites());
|
||||
userProfile.listen((data) {
|
||||
nameController.text = data.data?.firstName ?? '';
|
||||
lastNameController.text = data.data?.lastName ?? '';
|
||||
nationalCodeController.text = data.data?.nationalCode ?? '';
|
||||
nationalIdController.text = data.data?.nationalId ?? '';
|
||||
birthdayController.text = data.data?.birthday?.toJalali.formatCompactDate() ?? '';
|
||||
birthDate.value = data.data?.birthday?.toJalali;
|
||||
selectedProvince.value = IranProvinceCityModel(
|
||||
name: data.data?.province ?? '',
|
||||
id: data.data?.provinceNumber ?? 0,
|
||||
);
|
||||
|
||||
selectedCity.value = IranProvinceCityModel(
|
||||
name: data.data?.city ?? '',
|
||||
id: data.data?.cityNumber ?? 0,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Future<void> getUserProfile() async {
|
||||
userProfile.value = Resource.loading();
|
||||
await safeCall<UserProfile?>(
|
||||
call: () async => await rootLogic.chickenRepository.getUserProfile(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
userProfile.value = Resource.success(result);
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getCites() async {
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
|
||||
onSuccess: (result) {
|
||||
if (result != null && result.isNotEmpty) {
|
||||
cites.value = result;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updateUserProfile() async {
|
||||
UserProfile userProfile = UserProfile(
|
||||
firstName: nameController.text,
|
||||
lastName: lastNameController.text,
|
||||
nationalCode: nationalCodeController.text,
|
||||
nationalId: nationalIdController.text,
|
||||
birthday: birthDate.value?.toDateTime().formattedDashedGregorian.toString(),
|
||||
image: _base64Image.value,
|
||||
personType: 'self',
|
||||
type: 'self_profile',
|
||||
);
|
||||
isOnLoading.value = true;
|
||||
await safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.updateUserProfile(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
userProfile: userProfile,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
isOnLoading.value = false;
|
||||
},
|
||||
onError: (error, stackTrace) {
|
||||
isOnLoading.value = false;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updatePassword() async {
|
||||
if (formKey.currentState?.validate() ?? false) {
|
||||
ChangePasswordRequestModel model = ChangePasswordRequestModel(
|
||||
username: userProfile.value.data?.mobile,
|
||||
password: newPasswordController.text,
|
||||
);
|
||||
|
||||
await safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.updatePassword(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
model: model,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void clearPasswordForm() {
|
||||
oldPasswordController.clear();
|
||||
newPasswordController.clear();
|
||||
retryNewPasswordController.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,637 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart' hide Image;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/chicken.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class PoultryScienceProfilePage extends GetView<PoultryScienceProfileLogic> {
|
||||
const PoultryScienceProfilePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
spacing: 30,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
color: AppColor.blueNormal,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(),
|
||||
ObxValue((data) {
|
||||
final status = data.value.status;
|
||||
|
||||
if (status == ResourceStatus.loading) {
|
||||
return Container(
|
||||
width: 128.w,
|
||||
height: 128.h,
|
||||
child: Center(child: CupertinoActivityIndicator(color: AppColor.greenNormal)),
|
||||
);
|
||||
}
|
||||
|
||||
if (status == ResourceStatus.error) {
|
||||
return Container(
|
||||
width: 128.w,
|
||||
height: 128.h,
|
||||
child: Center(child: Text('خطا در دریافت اطلاعات')),
|
||||
);
|
||||
}
|
||||
|
||||
// Default UI
|
||||
return Container(
|
||||
width: 128.w,
|
||||
height: 128.h,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppColor.blueLightActive,
|
||||
),
|
||||
child: Center(
|
||||
child: CircleAvatar(
|
||||
radius: 64.w,
|
||||
backgroundImage: NetworkImage(data.value.data!.image!),
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.userProfile),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 16,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10),
|
||||
child: userProfileInformation(),
|
||||
),
|
||||
),
|
||||
|
||||
Center(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
spacing: 20,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
cardActionWidget(
|
||||
title: 'تغییر رمز عبور',
|
||||
selected: true,
|
||||
onPressed: () {
|
||||
Get.bottomSheet(changePasswordBottomSheet(), isScrollControlled: true);
|
||||
},
|
||||
icon: Assets.vec.lockSvg.path,
|
||||
),
|
||||
cardActionWidget(
|
||||
title: 'خروج',
|
||||
selected: true,
|
||||
color: ColorFilter.mode(Colors.redAccent, BlendMode.srcIn),
|
||||
cardColor: Color(0xFFEFEFEF),
|
||||
textColor: AppColor.redDarkerText,
|
||||
onPressed: () {
|
||||
Get.bottomSheet(exitBottomSheet(), isScrollControlled: true);
|
||||
},
|
||||
icon: Assets.vec.logoutSvg.path,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 100),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container invoiceIssuanceInformation() => Container();
|
||||
|
||||
Widget bankInformationWidget() => Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
itemList(title: 'نام بانک', content: 'سامان'),
|
||||
itemList(title: 'نام صاحب حساب', content: 'رضا رضایی'),
|
||||
itemList(title: 'شماره کارت ', content: '54154545415'),
|
||||
itemList(title: 'شماره حساب', content: '62565263263652'),
|
||||
itemList(title: 'شماره شبا', content: '62565263263652'),
|
||||
],
|
||||
);
|
||||
|
||||
Widget userProfileInformation() {
|
||||
return ObxValue((data) {
|
||||
if (data.value.status == ResourceStatus.loading) {
|
||||
return LoadingWidget();
|
||||
} else if (data.value.status == ResourceStatus.error) {
|
||||
return ErrorWidget('خطا در دریافت اطلاعات کاربر');
|
||||
} else if (data.value.status == ResourceStatus.success) {
|
||||
UserProfile item = data.value.data!;
|
||||
return Column(
|
||||
spacing: 6,
|
||||
children: [
|
||||
buildRowOnTapped(
|
||||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
userInformationBottomSheet(),
|
||||
isScrollControlled: true,
|
||||
ignoreSafeArea: false,
|
||||
);
|
||||
},
|
||||
titleWidget: Column(
|
||||
spacing: 3,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'اطلاعات هویتی',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Container(width: 37.w, height: 1.h, color: AppColor.greenNormal),
|
||||
],
|
||||
),
|
||||
valueWidget: Assets.vec.editSvg.svg(
|
||||
width: 24.w,
|
||||
height: 24.h,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
itemList(
|
||||
title: 'نام و نام خانوادگی',
|
||||
content: item.fullname ?? 'نامشخص',
|
||||
icon: Assets.vec.userSvg.path,
|
||||
hasColoredBox: true,
|
||||
),
|
||||
itemList(
|
||||
title: 'موبایل',
|
||||
content: item.mobile ?? 'نامشخص',
|
||||
icon: Assets.vec.callSvg.path,
|
||||
),
|
||||
itemList(
|
||||
title: 'کدملی',
|
||||
content: item.nationalId ?? 'نامشخص',
|
||||
icon: Assets.vec.tagUserSvg.path,
|
||||
),
|
||||
itemList(
|
||||
title: 'شماره شناسنامه',
|
||||
content: item.nationalCode ?? 'نامشخص',
|
||||
icon: Assets.vec.userSquareSvg.path,
|
||||
),
|
||||
itemList(
|
||||
title: 'تاریخ تولد',
|
||||
content: item.birthday?.toJalali.formatCompactDate() ?? 'نامشخص',
|
||||
icon: Assets.vec.calendarSvg.path,
|
||||
),
|
||||
itemList(
|
||||
title: 'استان',
|
||||
content: item.province ?? 'نامشخص',
|
||||
icon: Assets.vec.pictureFrameSvg.path,
|
||||
),
|
||||
itemList(title: 'شهر', content: item.city ?? 'نامشخص', icon: Assets.vec.mapSvg.path),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
}, controller.userProfile);
|
||||
}
|
||||
|
||||
Widget itemList({
|
||||
required String title,
|
||||
required String content,
|
||||
String? icon,
|
||||
bool hasColoredBox = false,
|
||||
}) => Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: hasColoredBox ? AppColor.greenLight : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: hasColoredBox
|
||||
? Border.all(width: 0.25, color: AppColor.bgDark)
|
||||
: Border.all(width: 0, color: Colors.transparent),
|
||||
),
|
||||
child: Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
if (icon != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: SvgGenImage.vec(icon).svg(
|
||||
width: 20.w,
|
||||
height: 20.h,
|
||||
colorFilter: ColorFilter.mode(AppColor.mediumGreyNormalActive, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
Text(title, style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyNormalActive)),
|
||||
Spacer(),
|
||||
Text(content, style: AppFonts.yekan13.copyWith(color: AppColor.mediumGreyNormalHover)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Widget cardActionWidget({
|
||||
required String title,
|
||||
required VoidCallback onPressed,
|
||||
required String icon,
|
||||
bool selected = false,
|
||||
ColorFilter? color,
|
||||
Color? cardColor,
|
||||
Color? textColor,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onPressed,
|
||||
child: Column(
|
||||
spacing: 4,
|
||||
children: [
|
||||
Container(
|
||||
width: 52,
|
||||
height: 52,
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: ShapeDecoration(
|
||||
color: cardColor ?? AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
child: SvgGenImage.vec(icon).svg(
|
||||
width: 40,
|
||||
height: 40,
|
||||
colorFilter:
|
||||
color ??
|
||||
ColorFilter.mode(
|
||||
selected ? AppColor.blueNormal : AppColor.whiteLight,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
title,
|
||||
style: AppFonts.yekan10.copyWith(
|
||||
color: textColor ?? (selected ? AppColor.blueNormal : AppColor.blueLightActive),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget userInformationBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 750.h,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
'ویرایش اطلاعات هویتی',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
RTextField(
|
||||
controller: controller.nameController,
|
||||
label: 'نام',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.lastNameController,
|
||||
label: 'نام خانوادگی',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.nationalCodeController,
|
||||
label: 'شماره شناسنامه',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.nationalIdController,
|
||||
label: 'کد ملی',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
|
||||
ObxValue((data) {
|
||||
return RTextField(
|
||||
controller: controller.birthdayController,
|
||||
label: 'تاریخ تولد',
|
||||
initText: data.value?.formatCompactDate() ?? '',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
onTap: () {},
|
||||
);
|
||||
}, controller.birthDate),
|
||||
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
'عکس پروفایل',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
ObxValue((data) {
|
||||
return Container(
|
||||
width: Get.width,
|
||||
height: 270,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.lightGreyNormal,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: AppColor.blackLight),
|
||||
),
|
||||
child: Center(
|
||||
child: data.value == null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.fromLTRB(30, 10, 10, 30),
|
||||
child: Image.network(
|
||||
controller.userProfile.value.data?.image ?? '',
|
||||
),
|
||||
)
|
||||
: Image.file(File(data.value!.path), fit: BoxFit.cover),
|
||||
),
|
||||
);
|
||||
}, controller.selectedImage),
|
||||
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'گالری',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
onPressed: () async {
|
||||
controller.selectedImage.value = await controller.imagePicker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
ROutlinedElevated(
|
||||
text: 'دوربین',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.blueNormal),
|
||||
onPressed: () async {
|
||||
controller.selectedImage.value = await controller.imagePicker.pickImage(
|
||||
source: ImageSource.camera,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
spacing: 16,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ObxValue((data) {
|
||||
return RElevated(
|
||||
height: 40.h,
|
||||
text: 'ویرایش',
|
||||
isLoading: data.value,
|
||||
onPressed: () async {
|
||||
await controller.updateUserProfile();
|
||||
controller.getUserProfile();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
}, controller.isOnLoading),
|
||||
ROutlinedElevated(
|
||||
height: 40.h,
|
||||
text: 'انصراف',
|
||||
borderColor: AppColor.blueNormal,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _provinceWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: controller.rootLogic.provinces,
|
||||
onChanged: (value) {
|
||||
controller.selectedProvince.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProvince.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب استان'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _cityWidget() {
|
||||
return ObxValue((data) {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: data,
|
||||
onChanged: (value) {
|
||||
controller.selectedCity.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedCity.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب شهر'),
|
||||
);
|
||||
}, controller.cites);
|
||||
}
|
||||
|
||||
Widget changePasswordBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 400.h,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
'تغییر رمز عبور',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
SizedBox(),
|
||||
RTextField(
|
||||
controller: controller.oldPasswordController,
|
||||
hintText: 'رمز عبور قبلی',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'رمز عبور را وارد کنید';
|
||||
} else if (controller.userProfile.value.data?.password != value) {
|
||||
return 'رمز عبور صحیح نیست';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.newPasswordController,
|
||||
hintText: 'رمز عبور جدید',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'رمز عبور را وارد کنید';
|
||||
} else if (value.length < 6) {
|
||||
return 'رمز عبور باید بیش از 6 کارکتر باشد.';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.retryNewPasswordController,
|
||||
hintText: 'تکرار رمز عبور جدید',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'رمز عبور را وارد کنید';
|
||||
} else if (value.length < 6) {
|
||||
return 'رمز عبور باید بیش از 6 کارکتر باشد.';
|
||||
} else if (controller.newPasswordController.text != value) {
|
||||
return 'رمز عبور جدید یکسان نیست';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
|
||||
SizedBox(),
|
||||
|
||||
Row(
|
||||
spacing: 16,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
RElevated(
|
||||
height: 40.h,
|
||||
text: 'ویرایش',
|
||||
onPressed: () async {
|
||||
if (controller.formKey.currentState?.validate() != true) {
|
||||
return;
|
||||
}
|
||||
await controller.updatePassword();
|
||||
controller.getUserProfile();
|
||||
controller.clearPasswordForm();
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
ROutlinedElevated(
|
||||
height: 40.h,
|
||||
text: 'انصراف',
|
||||
borderColor: AppColor.blueNormal,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget exitBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 220.h,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text('خروج', style: AppFonts.yekan16Bold.copyWith(color: AppColor.error)),
|
||||
SizedBox(),
|
||||
Text(
|
||||
'آیا مطمئن هستید که میخواهید از حساب کاربری خود خارج شوید؟',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
SizedBox(),
|
||||
|
||||
Row(
|
||||
spacing: 16,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
RElevated(
|
||||
height: 40.h,
|
||||
text: 'خروج',
|
||||
backgroundColor: AppColor.error,
|
||||
onPressed: () async {
|
||||
await controller.rootLogic.tokenService.deleteAllTokens().then((value) {
|
||||
Get.back();
|
||||
Get.offAllNamed(ChickenRoutes.auth, arguments: Module.chicken);
|
||||
});
|
||||
},
|
||||
),
|
||||
ROutlinedElevated(
|
||||
height: 40.h,
|
||||
text: 'انصراف',
|
||||
borderColor: AppColor.blueNormal,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart';
|
||||
import 'package:rasadyar_chicken/data/di/chicken_di.dart';
|
||||
import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/home/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/buy/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/home/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/profile/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/sale/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/segmentation/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
enum ErrorLocationType { serviceDisabled, permissionDenied, none }
|
||||
|
||||
class PoultryScienceRootLogic extends GetxController {
|
||||
RxInt currentPage = 2.obs;
|
||||
List<Widget> pages = [BuyPage(), SalePage(), PoultryScienceHomePage(), SegmentationPage(), ProfilePage()];
|
||||
|
||||
late DioRemote dioRemote;
|
||||
var tokenService = Get.find<TokenStorageService>();
|
||||
late PoultryScienceRepository poultryRepository;
|
||||
RxList<ErrorLocationType> errorLocationType = RxList();
|
||||
RxMap<int, dynamic> homeExpandedList = RxMap();
|
||||
Rxn<InventoryModel> inventoryModel = Rxn<InventoryModel>();
|
||||
RxList<IranProvinceCityModel> provinces = <IranProvinceCityModel>[].obs;
|
||||
|
||||
// Cancel tokens for API calls
|
||||
CancelToken? _inventoryCancelToken;
|
||||
CancelToken? _provincesCancelToken;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
|
||||
poultryRepository = diChicken.get<PoultryScienceRepository>();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void toggleExpanded(int index) {
|
||||
if (homeExpandedList.keys.contains(index)) {
|
||||
homeExpandedList.remove(index);
|
||||
} else {
|
||||
homeExpandedList[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void rootErrorHandler(DioException error) {
|
||||
handleGeneric(error, () {
|
||||
tokenService.deleteAllTokens();
|
||||
});
|
||||
}
|
||||
|
||||
void changePage(int index) {
|
||||
currentPage.value = index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/chicken.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class PoultryScienceRootPage extends GetView<PoultryScienceRootLogic> {
|
||||
PoultryScienceRootPage({super.key});
|
||||
|
||||
DateTime? _lastBackPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ObxValue((data) {
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvokedWithResult: (didPop, result) async {
|
||||
final nestedKey = Get.nestedKey(controller.currentPage.value);
|
||||
final currentNavigator = nestedKey?.currentState;
|
||||
|
||||
if (currentNavigator?.canPop() ?? false) {
|
||||
currentNavigator?.pop();
|
||||
} else {
|
||||
final now = DateTime.now();
|
||||
if (_lastBackPressed == null ||
|
||||
now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
_lastBackPressed = now;
|
||||
Get.snackbar(
|
||||
'خروج از برنامه',
|
||||
'برای خروج دوباره بازگشت را بزنید',
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: AppColor.warning,
|
||||
);
|
||||
} else {
|
||||
await SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColor.bgLight,
|
||||
body: IndexedStack(
|
||||
children: [
|
||||
Navigator(
|
||||
key: Get.nestedKey(0),
|
||||
onGenerateRoute: (settings) {
|
||||
final page = ChickenPages.pages.firstWhere(
|
||||
(e) => e.name == settings.name,
|
||||
orElse: () =>
|
||||
ChickenPages.pages.firstWhere((e) => e.name == ChickenRoutes.buySteward),
|
||||
);
|
||||
|
||||
return buildRouteFromGetPage(page);
|
||||
},
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(1),
|
||||
onGenerateRoute: (settings) {
|
||||
final page = ChickenPages.pages.firstWhere(
|
||||
(e) => e.name == settings.name,
|
||||
orElse: () =>
|
||||
ChickenPages.pages.firstWhere((e) => e.name == ChickenRoutes.saleSteward),
|
||||
);
|
||||
|
||||
return buildRouteFromGetPage(page);
|
||||
},
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(2),
|
||||
onGenerateRoute: (settings) => GetPageRoute(page: () => controller.pages[2]),
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(3),
|
||||
onGenerateRoute: (settings) => GetPageRoute(page: () => controller.pages[3]),
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(4),
|
||||
onGenerateRoute: (settings) => GetPageRoute(page: () => controller.pages[4]),
|
||||
),
|
||||
],
|
||||
index: data.value,
|
||||
),
|
||||
|
||||
bottomNavigationBar: RBottomNavigation(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
items: [
|
||||
RBottomNavigationItem(
|
||||
label: 'اقدام',
|
||||
icon: Assets.vec.settingSvg.path,
|
||||
isSelected: controller.currentPage.value == 0,
|
||||
onTap: () {
|
||||
//Get.nestedKey(1)?.currentState?.popUntil((route) => route.isFirst);
|
||||
|
||||
controller.changePage(0);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'خانه',
|
||||
icon: Assets.vec.homeSvg.path,
|
||||
isSelected: controller.currentPage.value == 1,
|
||||
onTap: () {
|
||||
/* Get.nestedKey(1)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(0)?.currentState?.popUntil((route) => route.isFirst);*/
|
||||
controller.changePage(1);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'پروفایل',
|
||||
icon: Assets.vec.profileCircleSvg.path,
|
||||
isSelected: controller.currentPage.value == 2,
|
||||
onTap: () {
|
||||
/* Get.nestedKey(1)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(0)?.currentState?.popUntil((route) => route.isFirst);
|
||||
*/
|
||||
controller.changePage(2);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.currentPage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:rasadyar_chicken/presentation/pages/auth/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/auth/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/home/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/role/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/role/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/steward.dart';
|
||||
@@ -136,5 +139,24 @@ sealed class ChickenPages {
|
||||
),
|
||||
|
||||
//endregion
|
||||
|
||||
//region Poultry science Pages
|
||||
GetPage(
|
||||
name: ChickenRoutes.initPoultryScience,
|
||||
page: () => PoultryScienceRootPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => BaseLogic());
|
||||
Get.lazyPut(() => PoultryScienceRootLogic());
|
||||
Get.lazyPut(() => PoultryScienceHomeLogic());
|
||||
Get.lazyPut(() => BuyLogic());
|
||||
Get.lazyPut(() => SaleLogic());
|
||||
Get.lazyPut(() => ProfileLogic());
|
||||
Get.lazyPut(() => SegmentationLogic());
|
||||
Get.lazyPut(() => SearchLogic());
|
||||
}),
|
||||
),
|
||||
|
||||
//endregion
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user