Fixed pagination tenders for desktop and
added new config for notification
This commit is contained in:
@@ -25,7 +25,7 @@ android {
|
|||||||
applicationId = "com.opplens.app"
|
applicationId = "com.opplens.app"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = flutter.minSdkVersion
|
minSdk = 23
|
||||||
targetSdk = flutter.targetSdkVersion
|
targetSdk = flutter.targetSdkVersion
|
||||||
versionCode = flutter.versionCode
|
versionCode = flutter.versionCode
|
||||||
versionName = flutter.versionName
|
versionName = flutter.versionName
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"project_info": {
|
"project_info": {
|
||||||
"project_number": "1071558853812",
|
"project_number": "6923326255",
|
||||||
"project_id": "opplens",
|
"project_id": "opplens-270d1",
|
||||||
"storage_bucket": "opplens.firebasestorage.app"
|
"storage_bucket": "opplens-270d1.firebasestorage.app"
|
||||||
},
|
},
|
||||||
"client": [
|
"client": [
|
||||||
{
|
{
|
||||||
"client_info": {
|
"client_info": {
|
||||||
"mobilesdk_app_id": "1:1071558853812:android:7831119a56a99c5948c3e1",
|
"mobilesdk_app_id": "1:6923326255:android:6704c5b71e4451abed87da",
|
||||||
"android_client_info": {
|
"android_client_info": {
|
||||||
"package_name": "com.opplens.app"
|
"package_name": "com.opplens.app"
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"oauth_client": [],
|
"oauth_client": [],
|
||||||
"api_key": [
|
"api_key": [
|
||||||
{
|
{
|
||||||
"current_key": "AIzaSyD5LaGXppjGEdTf-a0Ha25FX1p0v_h-c8A"
|
"current_key": "AIzaSyCqZ6B5iih0RdFj0lf5_erwbZvMyb7obEg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"services": {
|
"services": {
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ part 'tenders_data.g.dart';
|
|||||||
abstract class TendersData with _$TendersData {
|
abstract class TendersData with _$TendersData {
|
||||||
const factory TendersData({
|
const factory TendersData({
|
||||||
required List<TenderData>? tenders,
|
required List<TenderData>? tenders,
|
||||||
required Meta? metadata,
|
|
||||||
}) = _TendersData;
|
}) = _TendersData;
|
||||||
|
|
||||||
factory TendersData.fromJson(Map<String, Object?> json) =>
|
factory TendersData.fromJson(Map<String, Object?> json) =>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$TendersData {
|
mixin _$TendersData {
|
||||||
|
|
||||||
List<TenderData>? get tenders; Meta? get metadata;
|
List<TenderData>? get tenders;
|
||||||
/// Create a copy of TendersData
|
/// Create a copy of TendersData
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $TendersDataCopyWith<TendersData> get copyWith => _$TendersDataCopyWithImpl<Tend
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TendersData&&const DeepCollectionEquality().equals(other.tenders, tenders)&&(identical(other.metadata, metadata) || other.metadata == metadata));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is TendersData&&const DeepCollectionEquality().equals(other.tenders, tenders));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(tenders),metadata);
|
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(tenders));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TendersData(tenders: $tenders, metadata: $metadata)';
|
return 'TendersData(tenders: $tenders)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,11 +48,11 @@ abstract mixin class $TendersDataCopyWith<$Res> {
|
|||||||
factory $TendersDataCopyWith(TendersData value, $Res Function(TendersData) _then) = _$TendersDataCopyWithImpl;
|
factory $TendersDataCopyWith(TendersData value, $Res Function(TendersData) _then) = _$TendersDataCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<TenderData>? tenders, Meta? metadata
|
List<TenderData>? tenders
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$MetaCopyWith<$Res>? get metadata;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -65,26 +65,13 @@ class _$TendersDataCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of TendersData
|
/// Create a copy of TendersData
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? tenders = freezed,Object? metadata = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? tenders = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
tenders: freezed == tenders ? _self.tenders : tenders // ignore: cast_nullable_to_non_nullable
|
tenders: freezed == tenders ? _self.tenders : tenders // ignore: cast_nullable_to_non_nullable
|
||||||
as List<TenderData>?,metadata: freezed == metadata ? _self.metadata : metadata // ignore: cast_nullable_to_non_nullable
|
as List<TenderData>?,
|
||||||
as Meta?,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of TendersData
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$MetaCopyWith<$Res>? get metadata {
|
|
||||||
if (_self.metadata == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $MetaCopyWith<$Res>(_self.metadata!, (value) {
|
|
||||||
return _then(_self.copyWith(metadata: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -166,10 +153,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<TenderData>? tenders, Meta? metadata)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<TenderData>? tenders)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersData() when $default != null:
|
case _TendersData() when $default != null:
|
||||||
return $default(_that.tenders,_that.metadata);case _:
|
return $default(_that.tenders);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -187,10 +174,10 @@ return $default(_that.tenders,_that.metadata);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<TenderData>? tenders, Meta? metadata) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<TenderData>? tenders) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersData():
|
case _TendersData():
|
||||||
return $default(_that.tenders,_that.metadata);case _:
|
return $default(_that.tenders);case _:
|
||||||
throw StateError('Unexpected subclass');
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -207,10 +194,10 @@ return $default(_that.tenders,_that.metadata);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<TenderData>? tenders, Meta? metadata)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<TenderData>? tenders)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersData() when $default != null:
|
case _TendersData() when $default != null:
|
||||||
return $default(_that.tenders,_that.metadata);case _:
|
return $default(_that.tenders);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -222,7 +209,7 @@ return $default(_that.tenders,_that.metadata);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _TendersData implements TendersData {
|
class _TendersData implements TendersData {
|
||||||
const _TendersData({required final List<TenderData>? tenders, required this.metadata}): _tenders = tenders;
|
const _TendersData({required final List<TenderData>? tenders}): _tenders = tenders;
|
||||||
factory _TendersData.fromJson(Map<String, dynamic> json) => _$TendersDataFromJson(json);
|
factory _TendersData.fromJson(Map<String, dynamic> json) => _$TendersDataFromJson(json);
|
||||||
|
|
||||||
final List<TenderData>? _tenders;
|
final List<TenderData>? _tenders;
|
||||||
@@ -234,7 +221,6 @@ class _TendersData implements TendersData {
|
|||||||
return EqualUnmodifiableListView(value);
|
return EqualUnmodifiableListView(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override final Meta? metadata;
|
|
||||||
|
|
||||||
/// Create a copy of TendersData
|
/// Create a copy of TendersData
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -249,16 +235,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TendersData&&const DeepCollectionEquality().equals(other._tenders, _tenders)&&(identical(other.metadata, metadata) || other.metadata == metadata));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TendersData&&const DeepCollectionEquality().equals(other._tenders, _tenders));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_tenders),metadata);
|
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_tenders));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TendersData(tenders: $tenders, metadata: $metadata)';
|
return 'TendersData(tenders: $tenders)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -269,11 +255,11 @@ abstract mixin class _$TendersDataCopyWith<$Res> implements $TendersDataCopyWith
|
|||||||
factory _$TendersDataCopyWith(_TendersData value, $Res Function(_TendersData) _then) = __$TendersDataCopyWithImpl;
|
factory _$TendersDataCopyWith(_TendersData value, $Res Function(_TendersData) _then) = __$TendersDataCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<TenderData>? tenders, Meta? metadata
|
List<TenderData>? tenders
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $MetaCopyWith<$Res>? get metadata;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -286,27 +272,14 @@ class __$TendersDataCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of TendersData
|
/// Create a copy of TendersData
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? tenders = freezed,Object? metadata = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? tenders = freezed,}) {
|
||||||
return _then(_TendersData(
|
return _then(_TendersData(
|
||||||
tenders: freezed == tenders ? _self._tenders : tenders // ignore: cast_nullable_to_non_nullable
|
tenders: freezed == tenders ? _self._tenders : tenders // ignore: cast_nullable_to_non_nullable
|
||||||
as List<TenderData>?,metadata: freezed == metadata ? _self.metadata : metadata // ignore: cast_nullable_to_non_nullable
|
as List<TenderData>?,
|
||||||
as Meta?,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a copy of TendersData
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$MetaCopyWith<$Res>? get metadata {
|
|
||||||
if (_self.metadata == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $MetaCopyWith<$Res>(_self.metadata!, (value) {
|
|
||||||
return _then(_self.copyWith(metadata: value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
|||||||
@@ -11,14 +11,7 @@ _TendersData _$TendersDataFromJson(Map<String, dynamic> json) => _TendersData(
|
|||||||
(json['tenders'] as List<dynamic>?)
|
(json['tenders'] as List<dynamic>?)
|
||||||
?.map((e) => TenderData.fromJson(e as Map<String, dynamic>))
|
?.map((e) => TenderData.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
metadata:
|
|
||||||
json['metadata'] == null
|
|
||||||
? null
|
|
||||||
: Meta.fromJson(json['metadata'] as Map<String, dynamic>),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$TendersDataToJson(_TendersData instance) =>
|
Map<String, dynamic> _$TendersDataToJson(_TendersData instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{'tenders': instance.tenders};
|
||||||
'tenders': instance.tenders,
|
|
||||||
'metadata': instance.metadata,
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// ignore_for_file: invalid_annotation_target
|
// ignore_for_file: invalid_annotation_target
|
||||||
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:tm_app/data/services/model/meta/meta.dart';
|
||||||
|
|
||||||
import '../../error/error_model.dart';
|
import '../../error/error_model.dart';
|
||||||
import '../tenders_data/tenders_data.dart';
|
import '../tenders_data/tenders_data.dart';
|
||||||
@@ -15,6 +16,7 @@ abstract class TendersResponse with _$TendersResponse {
|
|||||||
required ErrorModel? error,
|
required ErrorModel? error,
|
||||||
required String? message,
|
required String? message,
|
||||||
required bool? success,
|
required bool? success,
|
||||||
|
required Meta? meta,
|
||||||
}) = _TendersResponse;
|
}) = _TendersResponse;
|
||||||
|
|
||||||
factory TendersResponse.fromJson(Map<String, Object?> json) =>
|
factory TendersResponse.fromJson(Map<String, Object?> json) =>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$TendersResponse {
|
mixin _$TendersResponse {
|
||||||
|
|
||||||
TendersData? get data; ErrorModel? get error; String? get message; bool? get success;
|
TendersData? get data; ErrorModel? get error; String? get message; bool? get success; Meta? get meta;
|
||||||
/// Create a copy of TendersResponse
|
/// Create a copy of TendersResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $TendersResponseCopyWith<TendersResponse> get copyWith => _$TendersResponseCopyW
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is TendersResponse&&(identical(other.data, data) || other.data == data)&&(identical(other.error, error) || other.error == error)&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is TendersResponse&&(identical(other.data, data) || other.data == data)&&(identical(other.error, error) || other.error == error)&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success)&&(identical(other.meta, meta) || other.meta == meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,data,error,message,success);
|
int get hashCode => Object.hash(runtimeType,data,error,message,success,meta);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TendersResponse(data: $data, error: $error, message: $message, success: $success)';
|
return 'TendersResponse(data: $data, error: $error, message: $message, success: $success, meta: $meta)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,11 +48,11 @@ abstract mixin class $TendersResponseCopyWith<$Res> {
|
|||||||
factory $TendersResponseCopyWith(TendersResponse value, $Res Function(TendersResponse) _then) = _$TendersResponseCopyWithImpl;
|
factory $TendersResponseCopyWith(TendersResponse value, $Res Function(TendersResponse) _then) = _$TendersResponseCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
TendersData? data, ErrorModel? error, String? message, bool? success
|
TendersData? data, ErrorModel? error, String? message, bool? success, Meta? meta
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$TendersDataCopyWith<$Res>? get data;$ErrorModelCopyWith<$Res>? get error;
|
$TendersDataCopyWith<$Res>? get data;$ErrorModelCopyWith<$Res>? get error;$MetaCopyWith<$Res>? get meta;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -65,13 +65,14 @@ class _$TendersResponseCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of TendersResponse
|
/// Create a copy of TendersResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? data = freezed,Object? error = freezed,Object? message = freezed,Object? success = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? data = freezed,Object? error = freezed,Object? message = freezed,Object? success = freezed,Object? meta = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
as TendersData?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
as TendersData?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||||
as ErrorModel?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
as ErrorModel?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||||
as bool?,
|
as bool?,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Meta?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of TendersResponse
|
/// Create a copy of TendersResponse
|
||||||
@@ -98,6 +99,18 @@ $ErrorModelCopyWith<$Res>? get error {
|
|||||||
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
||||||
return _then(_self.copyWith(error: value));
|
return _then(_self.copyWith(error: value));
|
||||||
});
|
});
|
||||||
|
}/// Create a copy of TendersResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$MetaCopyWith<$Res>? get meta {
|
||||||
|
if (_self.meta == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $MetaCopyWith<$Res>(_self.meta!, (value) {
|
||||||
|
return _then(_self.copyWith(meta: value));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,10 +193,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( TendersData? data, ErrorModel? error, String? message, bool? success)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( TendersData? data, ErrorModel? error, String? message, bool? success, Meta? meta)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersResponse() when $default != null:
|
case _TendersResponse() when $default != null:
|
||||||
return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
return $default(_that.data,_that.error,_that.message,_that.success,_that.meta);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -201,10 +214,10 @@ return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( TendersData? data, ErrorModel? error, String? message, bool? success) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( TendersData? data, ErrorModel? error, String? message, bool? success, Meta? meta) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersResponse():
|
case _TendersResponse():
|
||||||
return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
return $default(_that.data,_that.error,_that.message,_that.success,_that.meta);case _:
|
||||||
throw StateError('Unexpected subclass');
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -221,10 +234,10 @@ return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( TendersData? data, ErrorModel? error, String? message, bool? success)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( TendersData? data, ErrorModel? error, String? message, bool? success, Meta? meta)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _TendersResponse() when $default != null:
|
case _TendersResponse() when $default != null:
|
||||||
return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
return $default(_that.data,_that.error,_that.message,_that.success,_that.meta);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -236,13 +249,14 @@ return $default(_that.data,_that.error,_that.message,_that.success);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _TendersResponse implements TendersResponse {
|
class _TendersResponse implements TendersResponse {
|
||||||
const _TendersResponse({required this.data, required this.error, required this.message, required this.success});
|
const _TendersResponse({required this.data, required this.error, required this.message, required this.success, required this.meta});
|
||||||
factory _TendersResponse.fromJson(Map<String, dynamic> json) => _$TendersResponseFromJson(json);
|
factory _TendersResponse.fromJson(Map<String, dynamic> json) => _$TendersResponseFromJson(json);
|
||||||
|
|
||||||
@override final TendersData? data;
|
@override final TendersData? data;
|
||||||
@override final ErrorModel? error;
|
@override final ErrorModel? error;
|
||||||
@override final String? message;
|
@override final String? message;
|
||||||
@override final bool? success;
|
@override final bool? success;
|
||||||
|
@override final Meta? meta;
|
||||||
|
|
||||||
/// Create a copy of TendersResponse
|
/// Create a copy of TendersResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -257,16 +271,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TendersResponse&&(identical(other.data, data) || other.data == data)&&(identical(other.error, error) || other.error == error)&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TendersResponse&&(identical(other.data, data) || other.data == data)&&(identical(other.error, error) || other.error == error)&&(identical(other.message, message) || other.message == message)&&(identical(other.success, success) || other.success == success)&&(identical(other.meta, meta) || other.meta == meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,data,error,message,success);
|
int get hashCode => Object.hash(runtimeType,data,error,message,success,meta);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TendersResponse(data: $data, error: $error, message: $message, success: $success)';
|
return 'TendersResponse(data: $data, error: $error, message: $message, success: $success, meta: $meta)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -277,11 +291,11 @@ abstract mixin class _$TendersResponseCopyWith<$Res> implements $TendersResponse
|
|||||||
factory _$TendersResponseCopyWith(_TendersResponse value, $Res Function(_TendersResponse) _then) = __$TendersResponseCopyWithImpl;
|
factory _$TendersResponseCopyWith(_TendersResponse value, $Res Function(_TendersResponse) _then) = __$TendersResponseCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
TendersData? data, ErrorModel? error, String? message, bool? success
|
TendersData? data, ErrorModel? error, String? message, bool? success, Meta? meta
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@override $TendersDataCopyWith<$Res>? get data;@override $ErrorModelCopyWith<$Res>? get error;
|
@override $TendersDataCopyWith<$Res>? get data;@override $ErrorModelCopyWith<$Res>? get error;@override $MetaCopyWith<$Res>? get meta;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -294,13 +308,14 @@ class __$TendersResponseCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of TendersResponse
|
/// Create a copy of TendersResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? data = freezed,Object? error = freezed,Object? message = freezed,Object? success = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? data = freezed,Object? error = freezed,Object? message = freezed,Object? success = freezed,Object? meta = freezed,}) {
|
||||||
return _then(_TendersResponse(
|
return _then(_TendersResponse(
|
||||||
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
as TendersData?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
as TendersData?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||||
as ErrorModel?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
as ErrorModel?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
as String?,success: freezed == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||||
as bool?,
|
as bool?,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Meta?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,6 +343,18 @@ $ErrorModelCopyWith<$Res>? get error {
|
|||||||
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
return $ErrorModelCopyWith<$Res>(_self.error!, (value) {
|
||||||
return _then(_self.copyWith(error: value));
|
return _then(_self.copyWith(error: value));
|
||||||
});
|
});
|
||||||
|
}/// Create a copy of TendersResponse
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$MetaCopyWith<$Res>? get meta {
|
||||||
|
if (_self.meta == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $MetaCopyWith<$Res>(_self.meta!, (value) {
|
||||||
|
return _then(_self.copyWith(meta: value));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ _TendersResponse _$TendersResponseFromJson(Map<String, dynamic> json) =>
|
|||||||
: ErrorModel.fromJson(json['error'] as Map<String, dynamic>),
|
: ErrorModel.fromJson(json['error'] as Map<String, dynamic>),
|
||||||
message: json['message'] as String?,
|
message: json['message'] as String?,
|
||||||
success: json['success'] as bool?,
|
success: json['success'] as bool?,
|
||||||
|
meta:
|
||||||
|
json['meta'] == null
|
||||||
|
? null
|
||||||
|
: Meta.fromJson(json['meta'] as Map<String, dynamic>),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$TendersResponseToJson(_TendersResponse instance) =>
|
Map<String, dynamic> _$TendersResponseToJson(_TendersResponse instance) =>
|
||||||
@@ -26,4 +30,5 @@ Map<String, dynamic> _$TendersResponseToJson(_TendersResponse instance) =>
|
|||||||
'error': instance.error,
|
'error': instance.error,
|
||||||
'message': instance.message,
|
'message': instance.message,
|
||||||
'success': instance.success,
|
'success': instance.success,
|
||||||
|
'meta': instance.meta,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ class $AssetsIconsGen {
|
|||||||
/// File path: assets/icons/icon_contracts.svg
|
/// File path: assets/icons/icon_contracts.svg
|
||||||
String get iconContracts => 'assets/icons/icon_contracts.svg';
|
String get iconContracts => 'assets/icons/icon_contracts.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/left-arrow.svg
|
||||||
|
String get leftArrow => 'assets/icons/left-arrow.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/like.svg
|
/// File path: assets/icons/like.svg
|
||||||
String get like => 'assets/icons/like.svg';
|
String get like => 'assets/icons/like.svg';
|
||||||
|
|
||||||
@@ -113,9 +116,15 @@ class $AssetsIconsGen {
|
|||||||
/// File path: assets/icons/profile-circle_active.svg
|
/// File path: assets/icons/profile-circle_active.svg
|
||||||
String get profileCircleActive => 'assets/icons/profile-circle_active.svg';
|
String get profileCircleActive => 'assets/icons/profile-circle_active.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/search_normal.svg
|
||||||
|
String get searchNormal => 'assets/icons/search_normal.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/shield.svg
|
/// File path: assets/icons/shield.svg
|
||||||
String get shield => 'assets/icons/shield.svg';
|
String get shield => 'assets/icons/shield.svg';
|
||||||
|
|
||||||
|
/// File path: assets/icons/sort.svg
|
||||||
|
String get sort => 'assets/icons/sort.svg';
|
||||||
|
|
||||||
/// File path: assets/icons/sun.svg
|
/// File path: assets/icons/sun.svg
|
||||||
String get sun => 'assets/icons/sun.svg';
|
String get sun => 'assets/icons/sun.svg';
|
||||||
|
|
||||||
@@ -180,6 +189,7 @@ class $AssetsIconsGen {
|
|||||||
home,
|
home,
|
||||||
homeActive,
|
homeActive,
|
||||||
iconContracts,
|
iconContracts,
|
||||||
|
leftArrow,
|
||||||
like,
|
like,
|
||||||
location,
|
location,
|
||||||
logoBig,
|
logoBig,
|
||||||
@@ -191,7 +201,9 @@ class $AssetsIconsGen {
|
|||||||
notifyIconActive,
|
notifyIconActive,
|
||||||
profileCircle,
|
profileCircle,
|
||||||
profileCircleActive,
|
profileCircleActive,
|
||||||
|
searchNormal,
|
||||||
shield,
|
shield,
|
||||||
|
sort,
|
||||||
sun,
|
sun,
|
||||||
taskSquareActive,
|
taskSquareActive,
|
||||||
taskSquare,
|
taskSquare,
|
||||||
|
|||||||
+7
-7
@@ -46,13 +46,13 @@ void main() async {
|
|||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
await Firebase.initializeApp(
|
await Firebase.initializeApp(
|
||||||
options: const FirebaseOptions(
|
options: const FirebaseOptions(
|
||||||
apiKey: 'AIzaSyAUQhM789-0qZIaIWtwTQXyz9gEtN-TnnU',
|
apiKey: 'AIzaSyCTjdsk2jE34IfnvSKP1JMTIf_Abd7tbt0',
|
||||||
authDomain: 'opplens.firebaseapp.com',
|
authDomain: 'opplens-270d1.firebaseapp.com',
|
||||||
appId: '1:1071558853812:web:d9ca896b088ee7da48c3e1',
|
projectId: 'opplens-270d1',
|
||||||
messagingSenderId: '1071558853812',
|
storageBucket: 'opplens-270d1.firebasestorage.app',
|
||||||
projectId: 'opplens',
|
messagingSenderId: '6923326255',
|
||||||
storageBucket: 'opplens.firebasestorage.app',
|
appId: '1:6923326255:web:c71763ece06aaaf3ed87da',
|
||||||
measurementId: 'G-GJGP9WB28B',
|
measurementId: 'G-M5HQR4YZVS',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final _firebaseMessaging = FirebaseMessaging.instance;
|
final _firebaseMessaging = FirebaseMessaging.instance;
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
|
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
int _currentOffset = 0;
|
int _currentOffset = 0;
|
||||||
|
int _totalPages = 0;
|
||||||
|
int get totalPages => _totalPages;
|
||||||
static const int _pageSize = 10;
|
static const int _pageSize = 10;
|
||||||
bool _hasMoreData = true;
|
bool _hasMoreData = true;
|
||||||
|
|
||||||
@@ -117,6 +119,14 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
|
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
|
||||||
getTenderApprovals(_tendersResponse!.data!.tenders!.first.id!);
|
getTenderApprovals(_tendersResponse!.data!.tenders!.first.id!);
|
||||||
}
|
}
|
||||||
|
if (_tendersResponse?.meta?.pages != null) {
|
||||||
|
_totalPages = _tendersResponse!.meta!.pages!;
|
||||||
|
print('Total pages: $_totalPages');
|
||||||
|
} else {
|
||||||
|
_totalPages = 1;
|
||||||
|
print('Total pages not available, fallback to 1');
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
break;
|
break;
|
||||||
case Error<TendersResponse>():
|
case Error<TendersResponse>():
|
||||||
_errorMessage = result.error.toString();
|
_errorMessage = result.error.toString();
|
||||||
@@ -500,4 +510,35 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
_tenderApprovalErrorMessage = null;
|
_tenderApprovalErrorMessage = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jumpToPage(int page) async {
|
||||||
|
final meta = tendersResponse?.meta;
|
||||||
|
if (meta?.pages == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (page < 1 || page > meta!.pages!) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPage = page;
|
||||||
|
_currentOffset = (page - 1) * _pageSize;
|
||||||
|
|
||||||
|
final result = await _tendersRepository.getTenders(
|
||||||
|
limit: _pageSize,
|
||||||
|
offset: _currentOffset,
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case Ok<TendersResponse>():
|
||||||
|
_tendersResponse = result.value;
|
||||||
|
break;
|
||||||
|
case Error<TendersResponse>():
|
||||||
|
_errorMessage = result.error.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import 'package:tm_app/core/utils/size_config.dart';
|
|||||||
import 'package:tm_app/view_models/tenders_view_model.dart';
|
import 'package:tm_app/view_models/tenders_view_model.dart';
|
||||||
import 'package:tm_app/views/shared/base_button.dart';
|
import 'package:tm_app/views/shared/base_button.dart';
|
||||||
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
||||||
|
import 'package:tm_app/views/shared/page_selection_dialog.dart';
|
||||||
|
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
||||||
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
||||||
|
|
||||||
import '../../../core/constants/common_strings.dart';
|
import '../../../core/constants/common_strings.dart';
|
||||||
@@ -21,6 +23,7 @@ class DesktopTendersPage extends StatefulWidget {
|
|||||||
|
|
||||||
class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
||||||
late final TendersViewModel viewModel;
|
late final TendersViewModel viewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -49,23 +52,72 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
|||||||
backgroundColor: AppColors.backgroundColor,
|
backgroundColor: AppColors.backgroundColor,
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
const DesktopNavigationWidget(
|
const DesktopNavigationWidget(currentIndex: 1),
|
||||||
currentIndex: 1, // Tenders index
|
|
||||||
),
|
|
||||||
|
|
||||||
SizedBox(height: 48.0.h()),
|
SizedBox(height: 48.0.h()),
|
||||||
//search box
|
const _SearchBox(),
|
||||||
SizedBox(
|
const _ActionButtons(),
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<TendersViewModel>(
|
||||||
|
builder: (context, vm, child) {
|
||||||
|
if (vm.isLoading) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(color: AppColors.jellyBean),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (vm.errorMessage != null) {
|
||||||
|
return Center(child: Text(vm.errorMessage!));
|
||||||
|
}
|
||||||
|
final tenders = vm.tendersResponse?.data?.tenders ?? [];
|
||||||
|
if (tenders.isEmpty) {
|
||||||
|
return const Center(child: Text(CommonStrings.noData));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 740,
|
||||||
|
height: 800,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 4.0.h()),
|
||||||
|
child: MainTendersSlider(
|
||||||
|
tenders: tenders,
|
||||||
|
isDesktop: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_DesktopPagination(
|
||||||
|
totalPages: vm.totalPages,
|
||||||
|
currentPage: vm.currentPage,
|
||||||
|
onPageSelected: vm.jumpToPage,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchBox extends StatelessWidget {
|
||||||
|
const _SearchBox();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
height: 48.0.h(),
|
height: 48.0.h(),
|
||||||
width: 680,
|
width: 680,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
style: TextStyle(fontSize: 16.0.sp(), color: AppColors.grey0),
|
style: TextStyle(fontSize: 16.0.sp(), color: AppColors.grey0),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Search',
|
hintText: 'Search',
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(fontSize: 16.0.sp(), color: AppColors.grey60),
|
||||||
fontSize: 16.0.sp(),
|
|
||||||
color: AppColors.grey60,
|
|
||||||
),
|
|
||||||
prefixIcon: Padding(
|
prefixIcon: Padding(
|
||||||
padding: EdgeInsets.all(12.0.w()),
|
padding: EdgeInsets.all(12.0.w()),
|
||||||
child: SvgPicture.asset(
|
child: SvgPicture.asset(
|
||||||
@@ -82,10 +134,7 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
|||||||
),
|
),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0.w()),
|
borderRadius: BorderRadius.circular(12.0.w()),
|
||||||
borderSide: const BorderSide(
|
borderSide: const BorderSide(color: AppColors.mainBlue, width: 1),
|
||||||
color: AppColors.mainBlue,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0.w()),
|
borderRadius: BorderRadius.circular(12.0.w()),
|
||||||
@@ -93,15 +142,20 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
|||||||
),
|
),
|
||||||
focusedBorder: OutlineInputBorder(
|
focusedBorder: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(12.0.w()),
|
borderRadius: BorderRadius.circular(12.0.w()),
|
||||||
borderSide: const BorderSide(
|
borderSide: const BorderSide(color: AppColors.grey, width: 1.5),
|
||||||
color: AppColors.grey,
|
|
||||||
width: 1.5,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
),
|
}
|
||||||
Container(
|
}
|
||||||
|
|
||||||
|
class _ActionButtons extends StatelessWidget {
|
||||||
|
const _ActionButtons();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
margin: EdgeInsets.only(top: 25.0.h()),
|
margin: EdgeInsets.only(top: 25.0.h()),
|
||||||
height: 40.0.h(),
|
height: 40.0.h(),
|
||||||
width: 680,
|
width: 680,
|
||||||
@@ -130,46 +184,94 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Expanded(
|
class _DesktopPagination extends StatelessWidget {
|
||||||
child: Consumer<TendersViewModel>(
|
final int totalPages;
|
||||||
builder: (context, viewModel, child) {
|
final int currentPage;
|
||||||
if (viewModel.isLoading) {
|
final ValueChanged<int> onPageSelected;
|
||||||
return const Expanded(
|
|
||||||
child: Center(
|
const _DesktopPagination({
|
||||||
child: CircularProgressIndicator(
|
required this.totalPages,
|
||||||
color: AppColors.jellyBean,
|
required this.currentPage,
|
||||||
),
|
required this.onPageSelected,
|
||||||
),
|
});
|
||||||
);
|
|
||||||
}
|
@override
|
||||||
if (viewModel.errorMessage != null) {
|
Widget build(BuildContext context) {
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
return SizedBox(
|
||||||
}
|
width: 680,
|
||||||
if ((viewModel.tendersResponse?.data?.tenders == null ||
|
|
||||||
viewModel.tendersResponse!.data!.tenders!.isEmpty) &&
|
|
||||||
viewModel.isLoading == false) {
|
|
||||||
return const Center(child: Text(CommonStrings.noData));
|
|
||||||
}
|
|
||||||
return SingleChildScrollView(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 740,
|
|
||||||
height: 800,
|
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical: 4.0.h()),
|
padding: EdgeInsets.symmetric(vertical: 12.0.h()),
|
||||||
child: MainTendersSlider(
|
child: Row(
|
||||||
tenders: viewModel.tendersResponse?.data?.tenders ?? [],
|
children: [
|
||||||
isDesktop: true,
|
const Spacer(),
|
||||||
),
|
Text(
|
||||||
|
TendersStrings.page,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
color: AppColors.grey60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(width: 10.0.w()),
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
final selectedPage = await showDialog<int>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) =>
|
||||||
|
PageSelectionDialog(totalPages: totalPages),
|
||||||
);
|
);
|
||||||
|
if (selectedPage != null) {
|
||||||
|
onPageSelected(selectedPage);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: AppColors.grey30, width: 1),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$currentPage',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.grey70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
SvgPicture.asset(AssetsManager.arrowDownSmall),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
TendersStrings.of,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$totalPages',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,6 @@ class TendersStrings {
|
|||||||
static const String tenderDeadlineLabel = 'Deadline';
|
static const String tenderDeadlineLabel = 'Deadline';
|
||||||
static const String contracts = 'Contracts';
|
static const String contracts = 'Contracts';
|
||||||
static const String notifications = 'Notifications';
|
static const String notifications = 'Notifications';
|
||||||
|
static const String of= 'Of';
|
||||||
|
static const String page = 'Page';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,31 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
final PageController pageController = PageController(initialPage: 0);
|
final PageController pageController = PageController(initialPage: 0);
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
|
|
||||||
|
ScrollController? _scrollController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
if (widget.isDesktop) {
|
||||||
|
_scrollController = ScrollController();
|
||||||
|
_scrollController!.addListener(_onScroll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onScroll() {
|
||||||
|
if (!widget.isDesktop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final viewModel = context.read<TendersViewModel>();
|
||||||
|
if (_scrollController!.position.pixels >=
|
||||||
|
_scrollController!.position.maxScrollExtent - 200 &&
|
||||||
|
viewModel.hasMoreData &&
|
||||||
|
!viewModel.isLoadingMore) {
|
||||||
|
viewModel.loadMoreTenders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _goToPreviousPage() {
|
void _goToPreviousPage() {
|
||||||
if (currentPage == 1) {
|
if (currentPage == 1) {
|
||||||
return;
|
return;
|
||||||
@@ -88,6 +113,7 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
pageController.dispose();
|
pageController.dispose();
|
||||||
|
_scrollController?.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,19 +124,6 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
return widget.isDesktop ? _tendersListView() : _tendersSlider(isLtr);
|
return widget.isDesktop ? _tendersListView() : _tendersSlider(isLtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _tendersListView() {
|
|
||||||
return ListView.separated(
|
|
||||||
padding: EdgeInsets.all(16.0.h()),
|
|
||||||
itemCount: widget.tenders.length,
|
|
||||||
separatorBuilder:
|
|
||||||
(_, __) => SizedBox(height: widget.isDesktop ? 0 : 16.0.h()),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final tender = widget.tenders[index];
|
|
||||||
return TenderCard(tender: tender, isDesktop: widget.isDesktop);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _tendersSlider(bool isLtr) {
|
Widget _tendersSlider(bool isLtr) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [_tendersPageView(), _nextPreviousArrows(isLtr: isLtr)],
|
children: [_tendersPageView(), _nextPreviousArrows(isLtr: isLtr)],
|
||||||
@@ -251,4 +264,38 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
)
|
)
|
||||||
: SizedBox(width: 32.0.h(), height: 32.0.h());
|
: SizedBox(width: 32.0.h(), height: 32.0.h());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _tendersListView() {
|
||||||
|
final viewModel = context.watch<TendersViewModel>();
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ListView.separated(
|
||||||
|
padding: EdgeInsets.all(16.0.h()),
|
||||||
|
itemCount:
|
||||||
|
widget.tenders.length +
|
||||||
|
(widget.isDesktop && viewModel.isLoadingMore ? 1 : 0),
|
||||||
|
separatorBuilder:
|
||||||
|
(_, __) => SizedBox(height: widget.isDesktop ? 0 : 16.0.h()),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index < widget.tenders.length) {
|
||||||
|
final tender = widget.tenders[index];
|
||||||
|
return TenderCard(tender: tender, isDesktop: widget.isDesktop);
|
||||||
|
} else {
|
||||||
|
return const Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 2.0,
|
||||||
|
color: AppColors.jellyBean,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ importScripts("https://www.gstatic.com/firebasejs/9.22.2/firebase-app-compat.js"
|
|||||||
importScripts("https://www.gstatic.com/firebasejs/9.22.2/firebase-messaging-compat.js");
|
importScripts("https://www.gstatic.com/firebasejs/9.22.2/firebase-messaging-compat.js");
|
||||||
|
|
||||||
firebase.initializeApp({
|
firebase.initializeApp({
|
||||||
apiKey: 'AIzaSyAUQhM789-0qZIaIWtwTQXyz9gEtN-TnnU',
|
apiKey: "AIzaSyCTjdsk2jE34IfnvSKP1JMTIf_Abd7tbt0",
|
||||||
authDomain: 'opplens.firebaseapp.com',
|
authDomain: "opplens-270d1.firebaseapp.com",
|
||||||
appId: '1:1071558853812:web:d9ca896b088ee7da48c3e1',
|
projectId: "opplens-270d1",
|
||||||
messagingSenderId: '1071558853812',
|
storageBucket: "opplens-270d1.firebasestorage.app",
|
||||||
projectId: 'opplens',
|
messagingSenderId: "6923326255",
|
||||||
storageBucket: 'opplens.firebasestorage.app',
|
appId: "1:6923326255:web:c71763ece06aaaf3ed87da",
|
||||||
measurementId: 'G-GJGP9WB28B',
|
measurementId: "G-M5HQR4YZVS"
|
||||||
});
|
});
|
||||||
|
|
||||||
const messaging = firebase.messaging();
|
const messaging = firebase.messaging();
|
||||||
|
|||||||
Reference in New Issue
Block a user