Merge pull request 'fixed your tenders filters and service and home your tneders use your tenders service' (#111) from fixed_your_tenders into main

Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/111
This commit is contained in:
a.ghabeli
2025-09-08 09:53:58 +03:30
23 changed files with 180 additions and 1279 deletions
+13 -6
View File
@@ -62,17 +62,24 @@ List<SingleChildWidget> get apiClients {
List<SingleChildWidget> get repositories {
return [
Provider(create: (context) => AuthRepository(authService: context.read())),
Provider(create: (context) => HomeRepository(homeService: context.read())),
Provider(
create:
(context) =>
TenderDetailRepository(tenderDetailService: context.read()),
),
Provider(
create:
(context) =>
YourTendersRepository(yourTendersService: context.read()),
),
Provider(
create:
(context) => HomeRepository(
homeService: context.read(),
yourTendersService: context.read(),
),
),
Provider(
create:
(context) =>
TenderDetailRepository(tenderDetailService: context.read()),
),
Provider(
create:
(context) =>
+12 -7
View File
@@ -5,11 +5,17 @@ import 'package:tm_app/data/services/model/tender_approvals_response/tender_appr
import 'package:tm_app/data/services/model/tender_approvals_state_response/tender_approvals_state_response.dart';
import '../services/model/feedback_stats_response/feedback_stat_response.dart';
import '../services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
import '../services/your_tenders_service.dart';
class HomeRepository {
HomeRepository({required HomeService homeService})
: _homeService = homeService;
HomeRepository({
required HomeService homeService,
required YourTendersService yourTendersService,
}) : _homeService = homeService,
_yourTendersService = yourTendersService;
final HomeService _homeService;
final YourTendersService _yourTendersService;
Future<Result<RecommendedTendersResponse>> getHomeRecommendedTenders({
required int limit,
@@ -19,14 +25,13 @@ class HomeRepository {
}
Future<Result<TenderApprovalsResponse>> getYourTenders({
required int limit,
required int offset,
required GetTendersRequestModel requestModel,
}) {
return _homeService.getYourTenders(limit: limit, offset: offset);
return _yourTendersService.getTenders(requestModel: requestModel);
}
Future<Result<TenderApprovalsStateResponse>> getTendersApprovalsState() {
return _homeService.getTendersApprovalsState();
Future<Result<TenderApprovalsStateResponse>> getTendersApprovalsStats() {
return _homeService.getTendersApprovalsStats();
}
Future<Result<FeedbackStatResponse>> getFeedbackStats() {
@@ -1,5 +1,6 @@
import 'package:tm_app/core/utils/result.dart';
import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart';
import 'package:tm_app/data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart';
import 'package:tm_app/data/services/your_tenders_service.dart';
@@ -23,17 +24,9 @@ class YourTendersRepository {
}
Future<Result<TenderApprovalsResponse>> getTenders({
required int limit,
required int offset,
required String createdFrom,
required String createdTo,
required GetTendersRequestModel requestModel,
}) {
return _yourTendersService.getTenders(
limit: limit,
offset: offset,
createdFrom: createdFrom,
createdTo: createdTo,
);
return _yourTendersService.getTenders(requestModel: requestModel);
}
Future<Result<LikedTendersResponse>> getTendersFeedback({
+10 -2
View File
@@ -22,11 +22,19 @@ class YourTendersApi {
required int offset,
required String createdFrom,
required String createdTo,
required String status,
}) {
String url = '$tenderApproval?limit=$limit&offset=$offset';
if (createdFrom.isNotEmpty && createdTo.isNotEmpty) {
return '$tenderApproval?limit=$limit&offset=$offset&created_from=$createdFrom&created_to=$createdTo';
url += '&created_from=$createdFrom&created_to=$createdTo';
}
return '$tenderApproval?limit=$limit&offset=$offset';
if (status.isNotEmpty) {
url += '&status=$status';
}
return url;
}
static const String tendersFeedback = '/api/v1/feedback';
+3 -15
View File
@@ -2,14 +2,13 @@ import 'package:tm_app/core/utils/result.dart';
import 'package:tm_app/data/services/api/home_api.dart';
import 'package:tm_app/data/services/model/feedback_stats_response/feedback_stat_response.dart';
import 'package:tm_app/data/services/model/recommended_tenders_response/recommended_tenders_response.dart';
import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart';
import 'package:tm_app/data/services/model/tender_approvals_state_response/tender_approvals_state_response.dart';
import '../../core/network/network_manager.dart';
class HomeService {
HomeService({required NetworkManager networkManager})
: _networkManager = networkManager;
: _networkManager = networkManager;
final NetworkManager _networkManager;
Future<Result<RecommendedTendersResponse>> getRecommendedTenders({
@@ -24,19 +23,8 @@ class HomeService {
return result;
}
Future<Result<TenderApprovalsResponse>> getYourTenders({
required int limit,
required int offset,
}) async {
final result = await _networkManager.makeRequest(
HomeApi.getYourTenders(limit: limit, offset: offset),
(json) => TenderApprovalsResponse.fromJson(json),
method: 'GET',
);
return result;
}
Future<Result<TenderApprovalsStateResponse>> getTendersApprovalsState() async {
Future<Result<TenderApprovalsStateResponse>>
getTendersApprovalsStats() async {
final result = await _networkManager.makeRequest(
HomeApi.tenderApprovalStats,
(json) => TenderApprovalsStateResponse.fromJson(json),
@@ -0,0 +1,15 @@
class GetTendersRequestModel {
final String status;
final String createdFrom;
final String createdTo;
final int limit;
final int offset;
GetTendersRequestModel({
this.status = '',
this.createdFrom = '',
this.createdTo = '',
this.limit = 10,
this.offset = 0,
});
}
@@ -1,20 +0,0 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'your_tender_model.freezed.dart';
part 'your_tender_model.g.dart';
@freezed
abstract class YourTenderModel with _$YourTenderModel {
const factory YourTenderModel({
required String date,
required String title,
required String description,
required String location,
required String countryFlag,
required String status,
required String projectStatus,
}) = _YourTenderModel;
factory YourTenderModel.fromJson(Map<String, dynamic> json) =>
_$YourTenderModelFromJson(json);
}
@@ -1,295 +0,0 @@
// 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 'your_tender_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$YourTenderModel {
String get date; String get title; String get description; String get location; String get countryFlag; String get status; String get projectStatus;
/// Create a copy of YourTenderModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$YourTenderModelCopyWith<YourTenderModel> get copyWith => _$YourTenderModelCopyWithImpl<YourTenderModel>(this as YourTenderModel, _$identity);
/// Serializes this YourTenderModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is YourTenderModel&&(identical(other.date, date) || other.date == date)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.location, location) || other.location == location)&&(identical(other.countryFlag, countryFlag) || other.countryFlag == countryFlag)&&(identical(other.status, status) || other.status == status)&&(identical(other.projectStatus, projectStatus) || other.projectStatus == projectStatus));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,title,description,location,countryFlag,status,projectStatus);
@override
String toString() {
return 'YourTenderModel(date: $date, title: $title, description: $description, location: $location, countryFlag: $countryFlag, status: $status, projectStatus: $projectStatus)';
}
}
/// @nodoc
abstract mixin class $YourTenderModelCopyWith<$Res> {
factory $YourTenderModelCopyWith(YourTenderModel value, $Res Function(YourTenderModel) _then) = _$YourTenderModelCopyWithImpl;
@useResult
$Res call({
String date, String title, String description, String location, String countryFlag, String status, String projectStatus
});
}
/// @nodoc
class _$YourTenderModelCopyWithImpl<$Res>
implements $YourTenderModelCopyWith<$Res> {
_$YourTenderModelCopyWithImpl(this._self, this._then);
final YourTenderModel _self;
final $Res Function(YourTenderModel) _then;
/// Create a copy of YourTenderModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? date = null,Object? title = null,Object? description = null,Object? location = null,Object? countryFlag = null,Object? status = null,Object? projectStatus = null,}) {
return _then(_self.copyWith(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String,location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
as String,countryFlag: null == countryFlag ? _self.countryFlag : countryFlag // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,projectStatus: null == projectStatus ? _self.projectStatus : projectStatus // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [YourTenderModel].
extension YourTenderModelPatterns on YourTenderModel {
/// 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( _YourTenderModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _YourTenderModel() 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( _YourTenderModel value) $default,){
final _that = this;
switch (_that) {
case _YourTenderModel():
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( _YourTenderModel value)? $default,){
final _that = this;
switch (_that) {
case _YourTenderModel() 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( String date, String title, String description, String location, String countryFlag, String status, String projectStatus)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _YourTenderModel() when $default != null:
return $default(_that.date,_that.title,_that.description,_that.location,_that.countryFlag,_that.status,_that.projectStatus);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( String date, String title, String description, String location, String countryFlag, String status, String projectStatus) $default,) {final _that = this;
switch (_that) {
case _YourTenderModel():
return $default(_that.date,_that.title,_that.description,_that.location,_that.countryFlag,_that.status,_that.projectStatus);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( String date, String title, String description, String location, String countryFlag, String status, String projectStatus)? $default,) {final _that = this;
switch (_that) {
case _YourTenderModel() when $default != null:
return $default(_that.date,_that.title,_that.description,_that.location,_that.countryFlag,_that.status,_that.projectStatus);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _YourTenderModel implements YourTenderModel {
const _YourTenderModel({required this.date, required this.title, required this.description, required this.location, required this.countryFlag, required this.status, required this.projectStatus});
factory _YourTenderModel.fromJson(Map<String, dynamic> json) => _$YourTenderModelFromJson(json);
@override final String date;
@override final String title;
@override final String description;
@override final String location;
@override final String countryFlag;
@override final String status;
@override final String projectStatus;
/// Create a copy of YourTenderModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$YourTenderModelCopyWith<_YourTenderModel> get copyWith => __$YourTenderModelCopyWithImpl<_YourTenderModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$YourTenderModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _YourTenderModel&&(identical(other.date, date) || other.date == date)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.location, location) || other.location == location)&&(identical(other.countryFlag, countryFlag) || other.countryFlag == countryFlag)&&(identical(other.status, status) || other.status == status)&&(identical(other.projectStatus, projectStatus) || other.projectStatus == projectStatus));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,title,description,location,countryFlag,status,projectStatus);
@override
String toString() {
return 'YourTenderModel(date: $date, title: $title, description: $description, location: $location, countryFlag: $countryFlag, status: $status, projectStatus: $projectStatus)';
}
}
/// @nodoc
abstract mixin class _$YourTenderModelCopyWith<$Res> implements $YourTenderModelCopyWith<$Res> {
factory _$YourTenderModelCopyWith(_YourTenderModel value, $Res Function(_YourTenderModel) _then) = __$YourTenderModelCopyWithImpl;
@override @useResult
$Res call({
String date, String title, String description, String location, String countryFlag, String status, String projectStatus
});
}
/// @nodoc
class __$YourTenderModelCopyWithImpl<$Res>
implements _$YourTenderModelCopyWith<$Res> {
__$YourTenderModelCopyWithImpl(this._self, this._then);
final _YourTenderModel _self;
final $Res Function(_YourTenderModel) _then;
/// Create a copy of YourTenderModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? date = null,Object? title = null,Object? description = null,Object? location = null,Object? countryFlag = null,Object? status = null,Object? projectStatus = null,}) {
return _then(_YourTenderModel(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String,location: null == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
as String,countryFlag: null == countryFlag ? _self.countryFlag : countryFlag // ignore: cast_nullable_to_non_nullable
as String,status: null == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as String,projectStatus: null == projectStatus ? _self.projectStatus : projectStatus // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on
@@ -1,29 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'your_tender_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_YourTenderModel _$YourTenderModelFromJson(Map<String, dynamic> json) =>
_YourTenderModel(
date: json['date'] as String,
title: json['title'] as String,
description: json['description'] as String,
location: json['location'] as String,
countryFlag: json['countryFlag'] as String,
status: json['status'] as String,
projectStatus: json['projectStatus'] as String,
);
Map<String, dynamic> _$YourTenderModelToJson(_YourTenderModel instance) =>
<String, dynamic>{
'date': instance.date,
'title': instance.title,
'description': instance.description,
'location': instance.location,
'countryFlag': instance.countryFlag,
'status': instance.status,
'projectStatus': instance.projectStatus,
};
@@ -1,13 +0,0 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'your_tenders_request_model.freezed.dart';
part 'your_tenders_request_model.g.dart';
@freezed
abstract class YourTendersRequestModel with _$YourTendersRequestModel {
const factory YourTendersRequestModel({required String id}) =
_YourTendersRequestModel;
factory YourTendersRequestModel.fromJson(Map<String, dynamic> json) =>
_$YourTendersRequestModelFromJson(json);
}
@@ -1,277 +0,0 @@
// 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 'your_tenders_request_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$YourTendersRequestModel {
String get id;
/// Create a copy of YourTendersRequestModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$YourTendersRequestModelCopyWith<YourTendersRequestModel> get copyWith => _$YourTendersRequestModelCopyWithImpl<YourTendersRequestModel>(this as YourTendersRequestModel, _$identity);
/// Serializes this YourTendersRequestModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is YourTendersRequestModel&&(identical(other.id, id) || other.id == id));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id);
@override
String toString() {
return 'YourTendersRequestModel(id: $id)';
}
}
/// @nodoc
abstract mixin class $YourTendersRequestModelCopyWith<$Res> {
factory $YourTendersRequestModelCopyWith(YourTendersRequestModel value, $Res Function(YourTendersRequestModel) _then) = _$YourTendersRequestModelCopyWithImpl;
@useResult
$Res call({
String id
});
}
/// @nodoc
class _$YourTendersRequestModelCopyWithImpl<$Res>
implements $YourTendersRequestModelCopyWith<$Res> {
_$YourTendersRequestModelCopyWithImpl(this._self, this._then);
final YourTendersRequestModel _self;
final $Res Function(YourTendersRequestModel) _then;
/// Create a copy of YourTendersRequestModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [YourTendersRequestModel].
extension YourTendersRequestModelPatterns on YourTendersRequestModel {
/// 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( _YourTendersRequestModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _YourTendersRequestModel() 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( _YourTendersRequestModel value) $default,){
final _that = this;
switch (_that) {
case _YourTendersRequestModel():
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( _YourTendersRequestModel value)? $default,){
final _that = this;
switch (_that) {
case _YourTendersRequestModel() 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( String id)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _YourTendersRequestModel() when $default != null:
return $default(_that.id);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( String id) $default,) {final _that = this;
switch (_that) {
case _YourTendersRequestModel():
return $default(_that.id);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( String id)? $default,) {final _that = this;
switch (_that) {
case _YourTendersRequestModel() when $default != null:
return $default(_that.id);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _YourTendersRequestModel implements YourTendersRequestModel {
const _YourTendersRequestModel({required this.id});
factory _YourTendersRequestModel.fromJson(Map<String, dynamic> json) => _$YourTendersRequestModelFromJson(json);
@override final String id;
/// Create a copy of YourTendersRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$YourTendersRequestModelCopyWith<_YourTendersRequestModel> get copyWith => __$YourTendersRequestModelCopyWithImpl<_YourTendersRequestModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$YourTendersRequestModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _YourTendersRequestModel&&(identical(other.id, id) || other.id == id));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id);
@override
String toString() {
return 'YourTendersRequestModel(id: $id)';
}
}
/// @nodoc
abstract mixin class _$YourTendersRequestModelCopyWith<$Res> implements $YourTendersRequestModelCopyWith<$Res> {
factory _$YourTendersRequestModelCopyWith(_YourTendersRequestModel value, $Res Function(_YourTendersRequestModel) _then) = __$YourTendersRequestModelCopyWithImpl;
@override @useResult
$Res call({
String id
});
}
/// @nodoc
class __$YourTendersRequestModelCopyWithImpl<$Res>
implements _$YourTendersRequestModelCopyWith<$Res> {
__$YourTendersRequestModelCopyWithImpl(this._self, this._then);
final _YourTendersRequestModel _self;
final $Res Function(_YourTendersRequestModel) _then;
/// Create a copy of YourTendersRequestModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,}) {
return _then(_YourTendersRequestModel(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on
@@ -1,15 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'your_tenders_request_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_YourTendersRequestModel _$YourTendersRequestModelFromJson(
Map<String, dynamic> json,
) => _YourTendersRequestModel(id: json['id'] as String);
Map<String, dynamic> _$YourTendersRequestModelToJson(
_YourTendersRequestModel instance,
) => <String, dynamic>{'id': instance.id};
@@ -1,16 +0,0 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:tm_app/data/services/model/your_tender_model/your_tender_model.dart';
part 'your_tender_model_response.freezed.dart';
part 'your_tender_model_response.g.dart';
@freezed
abstract class YourTendersResponseModel with _$YourTendersResponseModel {
const factory YourTendersResponseModel({
required List<YourTenderModel> approvedTenders,
required List<YourTenderModel> tendersSubmitted,
}) = _YourTendersResponseModel;
factory YourTendersResponseModel.fromJson(Map<String, dynamic> json) =>
_$YourTendersResponseModelFromJson(json);
}
@@ -1,292 +0,0 @@
// 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 'your_tender_model_response.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$YourTendersResponseModel {
List<YourTenderModel> get approvedTenders; List<YourTenderModel> get tendersSubmitted;
/// Create a copy of YourTendersResponseModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$YourTendersResponseModelCopyWith<YourTendersResponseModel> get copyWith => _$YourTendersResponseModelCopyWithImpl<YourTendersResponseModel>(this as YourTendersResponseModel, _$identity);
/// Serializes this YourTendersResponseModel to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is YourTendersResponseModel&&const DeepCollectionEquality().equals(other.approvedTenders, approvedTenders)&&const DeepCollectionEquality().equals(other.tendersSubmitted, tendersSubmitted));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(approvedTenders),const DeepCollectionEquality().hash(tendersSubmitted));
@override
String toString() {
return 'YourTendersResponseModel(approvedTenders: $approvedTenders, tendersSubmitted: $tendersSubmitted)';
}
}
/// @nodoc
abstract mixin class $YourTendersResponseModelCopyWith<$Res> {
factory $YourTendersResponseModelCopyWith(YourTendersResponseModel value, $Res Function(YourTendersResponseModel) _then) = _$YourTendersResponseModelCopyWithImpl;
@useResult
$Res call({
List<YourTenderModel> approvedTenders, List<YourTenderModel> tendersSubmitted
});
}
/// @nodoc
class _$YourTendersResponseModelCopyWithImpl<$Res>
implements $YourTendersResponseModelCopyWith<$Res> {
_$YourTendersResponseModelCopyWithImpl(this._self, this._then);
final YourTendersResponseModel _self;
final $Res Function(YourTendersResponseModel) _then;
/// Create a copy of YourTendersResponseModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? approvedTenders = null,Object? tendersSubmitted = null,}) {
return _then(_self.copyWith(
approvedTenders: null == approvedTenders ? _self.approvedTenders : approvedTenders // ignore: cast_nullable_to_non_nullable
as List<YourTenderModel>,tendersSubmitted: null == tendersSubmitted ? _self.tendersSubmitted : tendersSubmitted // ignore: cast_nullable_to_non_nullable
as List<YourTenderModel>,
));
}
}
/// Adds pattern-matching-related methods to [YourTendersResponseModel].
extension YourTendersResponseModelPatterns on YourTendersResponseModel {
/// 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( _YourTendersResponseModel value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _YourTendersResponseModel() 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( _YourTendersResponseModel value) $default,){
final _that = this;
switch (_that) {
case _YourTendersResponseModel():
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( _YourTendersResponseModel value)? $default,){
final _that = this;
switch (_that) {
case _YourTendersResponseModel() 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( List<YourTenderModel> approvedTenders, List<YourTenderModel> tendersSubmitted)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _YourTendersResponseModel() when $default != null:
return $default(_that.approvedTenders,_that.tendersSubmitted);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( List<YourTenderModel> approvedTenders, List<YourTenderModel> tendersSubmitted) $default,) {final _that = this;
switch (_that) {
case _YourTendersResponseModel():
return $default(_that.approvedTenders,_that.tendersSubmitted);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( List<YourTenderModel> approvedTenders, List<YourTenderModel> tendersSubmitted)? $default,) {final _that = this;
switch (_that) {
case _YourTendersResponseModel() when $default != null:
return $default(_that.approvedTenders,_that.tendersSubmitted);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _YourTendersResponseModel implements YourTendersResponseModel {
const _YourTendersResponseModel({required final List<YourTenderModel> approvedTenders, required final List<YourTenderModel> tendersSubmitted}): _approvedTenders = approvedTenders,_tendersSubmitted = tendersSubmitted;
factory _YourTendersResponseModel.fromJson(Map<String, dynamic> json) => _$YourTendersResponseModelFromJson(json);
final List<YourTenderModel> _approvedTenders;
@override List<YourTenderModel> get approvedTenders {
if (_approvedTenders is EqualUnmodifiableListView) return _approvedTenders;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_approvedTenders);
}
final List<YourTenderModel> _tendersSubmitted;
@override List<YourTenderModel> get tendersSubmitted {
if (_tendersSubmitted is EqualUnmodifiableListView) return _tendersSubmitted;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_tendersSubmitted);
}
/// Create a copy of YourTendersResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$YourTendersResponseModelCopyWith<_YourTendersResponseModel> get copyWith => __$YourTendersResponseModelCopyWithImpl<_YourTendersResponseModel>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$YourTendersResponseModelToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _YourTendersResponseModel&&const DeepCollectionEquality().equals(other._approvedTenders, _approvedTenders)&&const DeepCollectionEquality().equals(other._tendersSubmitted, _tendersSubmitted));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_approvedTenders),const DeepCollectionEquality().hash(_tendersSubmitted));
@override
String toString() {
return 'YourTendersResponseModel(approvedTenders: $approvedTenders, tendersSubmitted: $tendersSubmitted)';
}
}
/// @nodoc
abstract mixin class _$YourTendersResponseModelCopyWith<$Res> implements $YourTendersResponseModelCopyWith<$Res> {
factory _$YourTendersResponseModelCopyWith(_YourTendersResponseModel value, $Res Function(_YourTendersResponseModel) _then) = __$YourTendersResponseModelCopyWithImpl;
@override @useResult
$Res call({
List<YourTenderModel> approvedTenders, List<YourTenderModel> tendersSubmitted
});
}
/// @nodoc
class __$YourTendersResponseModelCopyWithImpl<$Res>
implements _$YourTendersResponseModelCopyWith<$Res> {
__$YourTendersResponseModelCopyWithImpl(this._self, this._then);
final _YourTendersResponseModel _self;
final $Res Function(_YourTendersResponseModel) _then;
/// Create a copy of YourTendersResponseModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? approvedTenders = null,Object? tendersSubmitted = null,}) {
return _then(_YourTendersResponseModel(
approvedTenders: null == approvedTenders ? _self._approvedTenders : approvedTenders // ignore: cast_nullable_to_non_nullable
as List<YourTenderModel>,tendersSubmitted: null == tendersSubmitted ? _self._tendersSubmitted : tendersSubmitted // ignore: cast_nullable_to_non_nullable
as List<YourTenderModel>,
));
}
}
// dart format on
@@ -1,27 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'your_tender_model_response.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_YourTendersResponseModel _$YourTendersResponseModelFromJson(
Map<String, dynamic> json,
) => _YourTendersResponseModel(
approvedTenders:
(json['approvedTenders'] as List<dynamic>)
.map((e) => YourTenderModel.fromJson(e as Map<String, dynamic>))
.toList(),
tendersSubmitted:
(json['tendersSubmitted'] as List<dynamic>)
.map((e) => YourTenderModel.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$YourTendersResponseModelToJson(
_YourTendersResponseModel instance,
) => <String, dynamic>{
'approvedTenders': instance.approvedTenders,
'tendersSubmitted': instance.tendersSubmitted,
};
+7 -8
View File
@@ -4,6 +4,7 @@ import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_
import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart';
import '../../../core/network/network_manager.dart';
import 'model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
class YourTendersService {
YourTendersService({required NetworkManager networkManager})
@@ -32,17 +33,15 @@ class YourTendersService {
}
Future<Result<TenderApprovalsResponse>> getTenders({
required int limit,
required int offset,
required String createdFrom,
required String createdTo,
required GetTendersRequestModel requestModel,
}) async {
final result = await _networkManager.makeRequest(
YourTendersApi.getTenders(
limit: limit,
offset: offset,
createdFrom: createdFrom,
createdTo: createdTo,
limit: requestModel.limit,
offset: requestModel.offset,
createdFrom: requestModel.createdFrom,
createdTo: requestModel.createdTo,
status: requestModel.status,
),
(json) => TenderApprovalsResponse.fromJson(json),
method: 'GET',
+7 -4
View File
@@ -9,6 +9,7 @@ import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
import '../data/repositories/home_repository.dart';
import '../data/services/model/feedback_stats_response/feedback_stat_response.dart';
import '../data/services/model/home/home_response/home_response_model.dart';
import '../data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
class HomeViewModel with ChangeNotifier {
final HomeRepository _homeRepository;
@@ -51,7 +52,7 @@ class HomeViewModel with ChangeNotifier {
await getYourTenders(reset: true);
await getFeedbackStats();
if (_errorMessage != null || _errorMessage!.isNotEmpty) {
if (_errorMessage != null) {
_isLoading = false;
notifyListeners();
return;
@@ -118,11 +119,13 @@ class HomeViewModel with ChangeNotifier {
_isLoadingMore = true;
_isRecommendedMode = false;
notifyListeners();
final result = await _homeRepository.getYourTenders(
final requestModel = GetTendersRequestModel(
limit: _pageSize,
offset: _currentPage * _pageSize,
);
final result = await _homeRepository.getYourTenders(
requestModel: requestModel,
);
switch (result) {
case Ok<TenderApprovalsResponse>():
@@ -155,7 +158,7 @@ class HomeViewModel with ChangeNotifier {
}
Future<void> getApprovedStates() async {
final result = await _homeRepository.getTendersApprovalsState();
final result = await _homeRepository.getTendersApprovalsStats();
switch (result) {
case Ok<TenderApprovalsStateResponse>():
+61 -83
View File
@@ -6,6 +6,8 @@ import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_
import 'package:tm_app/data/services/model/tender_approvals_response/tender_approvals_response.dart';
import 'package:tm_app/views/your_tenders/strings/your_tenders_strings.dart';
import '../data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
class YourTendersViewModel with ChangeNotifier {
final YourTendersRepository yourTendersRepository;
YourTendersViewModel({required this.yourTendersRepository});
@@ -51,73 +53,8 @@ class YourTendersViewModel with ChangeNotifier {
? (selectedDateRange!.end.millisecondsSinceEpoch ~/ 1000).toString()
: '';
Future<void> getApprovedTenders({
required int limit,
required int offset,
bool reset = false,
}) async {
if (!reset && (isLoadingMoreTenders || !hasMoreTenders)) {
return;
}
if (reset) {
_tendersOffset = 0;
hasMoreTenders = true;
data = null;
}
if (_tendersOffset == 0) {
isLoading = true;
} else {
isLoadingMoreTenders = true;
}
notifyListeners();
final result = await yourTendersRepository.getApprovedTenders(
limit: _tendersLimit,
offset: _tendersOffset,
createdFrom: startDateUnix,
createdTo: endDateUnix,
);
switch (result) {
case Ok<TenderApprovalsResponse>():
final incoming = result.value;
final incomingList = incoming.data?.tenders ?? [];
if (reset || data == null) {
data = incoming;
} else {
final existingList = data!.data?.tenders ?? [];
final combined = List.of(existingList)..addAll(incomingList);
final newMetadata = incoming.data?.metadata ?? data!.data?.metadata;
data = data!.copyWith(
data: data!.data!.copyWith(
tenders: combined,
metadata: newMetadata,
),
);
}
hasMoreTenders = incomingList.length == _tendersLimit;
_tendersOffset += _tendersLimit;
errorMessage = null;
break;
case Error<TenderApprovalsResponse>():
errorMessage = result.error.toString();
break;
}
isLoading = false;
isLoadingMoreTenders = false;
notifyListeners();
}
Future<void> getTenders({
required int limit,
required int offset,
required String createdFrom,
required String createdTo,
required GetTendersRequestModel requestModel,
bool reset = false,
}) async {
if (!reset && (isLoadingMoreTenders || !hasMoreTenders)) {
@@ -138,10 +75,7 @@ class YourTendersViewModel with ChangeNotifier {
notifyListeners();
final result = await yourTendersRepository.getTenders(
limit: _tendersLimit,
offset: _tendersOffset,
createdFrom: createdFrom,
createdTo: createdTo,
requestModel: requestModel,
);
switch (result) {
@@ -252,19 +186,23 @@ class YourTendersViewModel with ChangeNotifier {
}
if (selectedStatus == YourTendersStrings.all) {
await getTenders(
limit: _tendersLimit,
offset: _tendersOffset,
final requestModel = GetTendersRequestModel(
status: '',
createdFrom: startDateUnix,
createdTo: endDateUnix,
reset: false,
);
} else if (selectedStatus == YourTendersStrings.tendersSubmitted) {
await getApprovedTenders(
limit: _tendersLimit,
offset: _tendersOffset,
reset: false,
);
await getTenders(requestModel: requestModel);
} else if (selectedStatus == YourTendersStrings.tendersSubmitted) {
final requestModel = GetTendersRequestModel(
status: 'submitted',
createdFrom: startDateUnix,
createdTo: endDateUnix,
limit: _tendersLimit,
offset: _tendersOffset,
);
await getTenders(requestModel: requestModel);
}
}
@@ -275,27 +213,67 @@ class YourTendersViewModel with ChangeNotifier {
}
void setStatus(String status) {
// Clear data when status changes
_clearAllData();
selectedStatus = status;
notifyListeners();
}
void clearFilter() {
// Clear data when clearing filter
_clearAllData();
selectedDateRange = null;
selectedStatus = YourTendersStrings.all;
notifyListeners();
}
// Clear all data and reset states
void _clearAllData() {
// Clear main data
data = null;
likedTendersData = null;
// Clear loading states
isLoading = false;
isLoadingMore = false;
isLoadingMoreTenders = false;
// Clear error messages
errorMessage = null;
// Reset pagination states
_offset = 0;
_tendersOffset = 0;
hasMore = true;
hasMoreTenders = true;
_currentFeedbackType = null;
notifyListeners();
}
Future<void> callWithFilter() async {
// Clear data before applying filter
_clearAllData();
// Make fresh request based on selected status
if (selectedStatus == YourTendersStrings.all) {
await getTenders(
limit: _tendersLimit,
offset: 0,
final requestModel = GetTendersRequestModel(
status: '',
createdFrom: startDateUnix,
createdTo: endDateUnix,
reset: true,
limit: _tendersLimit,
offset: 0,
);
await getTenders(requestModel: requestModel, reset: true);
} else if (selectedStatus == YourTendersStrings.tendersSubmitted) {
await getApprovedTenders(limit: _tendersLimit, offset: 0, reset: true);
final requestModel = GetTendersRequestModel(
status: 'submitted',
createdFrom: startDateUnix,
createdTo: endDateUnix,
limit: _tendersLimit,
offset: 0,
);
await getTenders(requestModel: requestModel, reset: true);
} else if (selectedStatus == YourTendersStrings.likeTenders) {
await getTendersFeedback(feedbackType: 'like', reset: true);
} else if (selectedStatus == YourTendersStrings.dislikeTenders) {
@@ -7,6 +7,8 @@ import 'package:tm_app/views/your_tenders/pages/your_tenders_desktop_page.dart';
import 'package:tm_app/views/your_tenders/pages/your_tenders_mobile_page.dart';
import 'package:tm_app/views/your_tenders/pages/your_tenders_tablet_page.dart';
import '../../../data/services/model/request_models/get_tenders_request_model/get_tenders_request_model.dart';
class YourTendersScreen extends StatefulWidget {
const YourTendersScreen({super.key});
@@ -21,12 +23,8 @@ class _YourTendersScreenState extends State<YourTendersScreen> {
super.initState();
viewModel = context.read<YourTendersViewModel>();
WidgetsBinding.instance.addPostFrameCallback((_) {
viewModel.getTenders(
limit: 10,
offset: 0,
createdFrom: '',
createdTo: '',
);
final requestModel = GetTendersRequestModel();
viewModel.getTenders(requestModel: requestModel);
});
}
@@ -1,65 +0,0 @@
import 'package:flutter/material.dart';
import 'package:tm_app/core/constants/assets.dart';
import 'package:tm_app/core/theme/colors.dart';
import 'package:tm_app/views/your_tenders/widgets/tender_card.dart';
import '../../../data/services/model/your_tender_model/your_tender_model.dart';
class ApprovedTenders extends StatelessWidget {
const ApprovedTenders({required this.tendersSubmitted,required this.isDesktop, super.key});
final List<YourTenderModel> tendersSubmitted;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.only(top: 20),
itemCount: tendersSubmitted.length,
itemBuilder: (context, index) {
final tender = tendersSubmitted[index];
return TenderCard(
date: tender.date,
title: tender.title,
description: tender.description,
location: tender.location,
countryFlag: tender.countryFlag,
status: tender.status,
countryCode: '',
projectStatus: tender.projectStatus,
isDesktop: isDesktop,
backgroundColor:
tender.status == 'Won'
? AppColors.green0
: tender.status == 'Completed'
? AppColors.grey0
: AppColors.red0,
borderColor:
tender.status == 'Won'
? AppColors.green10
: tender.status == 'Completed'
? AppColors.grey30
: AppColors.red10,
statusIcon:
tender.status == 'Won'
? AssetsManager.tickCircle
: tender.status == 'Completed'
? null
: AssetsManager.closeCircle,
statusCardColor:
tender.status == 'Won'
? AppColors.green20
: tender.status == 'Completed'
? AppColors.blue0
: AppColors.red10,
statusTextColor:
tender.status == 'Won'
? AppColors.green30
: tender.status == 'Completed'
? AppColors.cyanTeal
: AppColors.red20,
);
},
);
}
}
@@ -80,13 +80,7 @@ class _LikedDislikedTendersListState extends State<LikedDislikedTendersList> {
return Padding(
padding: EdgeInsets.only(bottom: 16.0.h()),
child: TenderCard(
date: feedback.tender!.publicationDate?.toString() ?? '',
title: feedback.tender!.title ?? '',
description: feedback.tender!.description ?? '',
location: feedback.tender!.countryCode ?? '',
countryCode: feedback.tender!.countryCode ?? '',
status: feedback.tender!.status ?? '',
projectStatus: feedback.tender!.procurementTypeCode!,
tender: feedback.tender!,
isDesktop: widget.isDesctop,
),
);
+43 -43
View File
@@ -2,47 +2,47 @@ import 'package:country_flags/country_flags.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tm_app/core/utils/date_utils.dart';
import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
import '../../../core/constants/assets.dart';
import '../../../core/theme/colors.dart';
import '../../../core/utils/size_config.dart';
class TenderCard extends StatelessWidget {
final String date;
final String title;
final String description;
final String location;
final String countryFlag;
final String status;
final String projectStatus;
final Color? backgroundColor;
final Color? borderColor;
final String? statusIcon;
final Color? statusCardColor;
final Color? statusTextColor;
final String countryCode;
final bool isDesktop;
final TenderData tender;
const TenderCard({
required this.date,
required this.title,
required this.description,
required this.location,
required this.countryCode,
required this.isDesktop,
this.countryFlag = 'assets/icons/SE.png',
this.status = 'Completed',
this.projectStatus = 'Self Control',
this.backgroundColor,
this.borderColor,
this.statusIcon,
this.statusCardColor,
this.statusTextColor,
super.key,
});
const TenderCard({required this.isDesktop, required this.tender, super.key});
@override
Widget build(BuildContext context) {
// Determine styling based on tender status
Color backgroundColor;
Color borderColor;
String? statusIcon;
Color statusCardColor;
Color statusTextColor;
if (tender.status == 'Won') {
backgroundColor = AppColors.green0;
borderColor = AppColors.green10;
statusIcon = AssetsManager.tickCircle;
statusCardColor = AppColors.green20;
statusTextColor = AppColors.green30;
} else if (tender.status == 'submitted') {
backgroundColor = AppColors.grey0;
borderColor = AppColors.grey30;
statusIcon = null;
statusCardColor = AppColors.green20;
statusTextColor = AppColors.green30;
} else {
backgroundColor = AppColors.red0.withValues(alpha: 0.2);
borderColor = AppColors.red0;
statusIcon = AssetsManager.closeCircle;
statusCardColor = AppColors.red0;
statusTextColor = AppColors.red10;
}
return Container(
height: isDesktop ? 182.0.h() : 240.0.h(),
width: double.infinity,
@@ -52,9 +52,9 @@ class TenderCard extends StatelessWidget {
bottom: 24.0.h(),
),
decoration: BoxDecoration(
color: backgroundColor ?? AppColors.grey0,
color: backgroundColor,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: borderColor ?? AppColors.borderColor),
border: Border.all(color: borderColor),
),
child: Padding(
padding: EdgeInsets.all(16.0.w()),
@@ -67,7 +67,7 @@ class TenderCard extends StatelessWidget {
children: [
// Date
Text(
unixToDate(int.parse(date)),
unixToDate(int.parse(tender.publicationDate!.toString())),
style: TextStyle(
color: AppColors.grey60,
fontSize: 12.0.sp(),
@@ -81,26 +81,26 @@ class TenderCard extends StatelessWidget {
vertical: 4.0.h(),
),
decoration: BoxDecoration(
color: statusCardColor ?? AppColors.green20,
color: statusCardColor,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
if (statusIcon != null)
SvgPicture.asset(
statusIcon!,
statusIcon,
width: 16.0.w(),
height: 16.0.h(),
colorFilter: ColorFilter.mode(
statusTextColor ?? AppColors.green30,
statusTextColor,
BlendMode.srcIn,
),
),
SizedBox(width: 4.0.w()),
Text(
status,
tender.status!,
style: TextStyle(
color: statusTextColor ?? AppColors.green30,
color: statusTextColor,
fontSize: 12.0.sp(),
fontWeight: FontWeight.w500,
),
@@ -114,7 +114,7 @@ class TenderCard extends StatelessWidget {
// Title
Text(
title,
tender.title!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@@ -128,7 +128,7 @@ class TenderCard extends StatelessWidget {
// Description
Text(
description,
tender.description!,
maxLines: isDesktop ? 2 : 3,
style: TextStyle(
color: AppColors.grey70,
@@ -154,7 +154,7 @@ class TenderCard extends StatelessWidget {
),
SizedBox(width: 4.0.w()),
Text(
location,
tender.countryCode!,
style: TextStyle(
color: AppColors.grey80,
fontSize: 12.0.sp(),
@@ -167,7 +167,7 @@ class TenderCard extends StatelessWidget {
width: 32.0.w(),
height: 21.0.h(),
child: CountryFlag.fromCountryCode(
countryCode,
tender.countryCode!,
shape: RoundedRectangle(4),
),
),
@@ -187,7 +187,7 @@ class TenderCard extends StatelessWidget {
border: Border.all(color: AppColors.grey40),
),
child: Text(
projectStatus,
tender.procurementTypeCode!,
style: TextStyle(
color: AppColors.grey60,
fontSize: 12.0.sp(),
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/constants/assets.dart';
import 'package:tm_app/core/theme/colors.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/view_models/your_tenders_view_model.dart';
@@ -78,45 +77,8 @@ class _TendersSubmittedState extends State<TendersSubmitted> {
if (index < tenders.length) {
final tender = tenders[index];
return TenderCard(
date: tender.createdAt!.toString(),
title: tender.tender!.title!,
description: tender.tender!.description!,
location: tender.tender!.countryCode!,
countryFlag: AssetsManager.seFlag,
status: tender.status,
countryCode: tender.tender!.countryCode!,
projectStatus: tender.tender!.status!,
tender: tender.tender!,
isDesktop: widget.isDesktop,
backgroundColor:
tender.status == 'Won'
? AppColors.green0
: tender.status == 'submitted'
? AppColors.grey0
: AppColors.red0.withValues(alpha: 0.2),
borderColor:
tender.status == 'Won'
? AppColors.green10
: tender.status == 'submitted'
? AppColors.grey30
: AppColors.red0,
statusIcon:
tender.status == 'Won'
? AssetsManager.tickCircle
: tender.status == 'submitted'
? null
: AssetsManager.closeCircle,
statusCardColor:
tender.status == 'Won'
? AppColors.green20
: tender.status == 'submitted'
? AppColors.green20
: AppColors.red0,
statusTextColor:
tender.status == 'Won'
? AppColors.green30
: tender.status == 'submitted'
? AppColors.green30
: AppColors.red10,
);
} else {
return Padding(