home and tender change

This commit is contained in:
amirrezaghabeli
2025-08-22 09:30:02 +03:30
parent 62b94c2655
commit 47edc00b97
5 changed files with 128 additions and 27 deletions
+10 -8
View File
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/core/utils/result.dart';
import 'package:tm_app/data/services/model/home/home_request/home_request_model.dart'; import 'package:tm_app/data/services/model/home/home_request/home_request_model.dart';
import 'package:tm_app/data/services/model/recommended_tenders_response/recommended_tenders_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_state_response/tender_approvals_state_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_response/tender_approvals_response.dart';
import 'package:tm_app/data/services/model/tender_approvals_state_response/tender_approvals_state_response.dart';
import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
import '../data/repositories/home_repository.dart'; import '../data/repositories/home_repository.dart';
@@ -14,9 +14,7 @@ class HomeViewModel with ChangeNotifier {
HomeViewModel({required HomeRepository homeRepository}) HomeViewModel({required HomeRepository homeRepository})
: _homeRepository = homeRepository { : _homeRepository = homeRepository {
getHome(homeRequestModel: HomeRequestModel(id: '1')); init();
getYourTenders();
getApprovedStates();
} }
bool _isLoading = false; bool _isLoading = false;
@@ -40,6 +38,11 @@ class HomeViewModel with ChangeNotifier {
bool get isLoadingMore => _isLoadingMore; bool get isLoadingMore => _isLoadingMore;
bool get hasMore => _hasMore; bool get hasMore => _hasMore;
void init() async {
await getApprovedStates();
await getYourTenders();
}
Future<void> getHome({HomeRequestModel? homeRequestModel}) async { Future<void> getHome({HomeRequestModel? homeRequestModel}) async {
_isLoading = true; _isLoading = true;
_errorMessage = null; _errorMessage = null;
@@ -120,9 +123,7 @@ class HomeViewModel with ChangeNotifier {
} else { } else {
_tenders.clear(); _tenders.clear();
_tenders.addAll( _tenders.addAll(
data!.data! data!.data!.map((e) => e.tender).whereType<TenderData>(),
.map((e) => e.tender)
.whereType<TenderData>(),
); );
} }
@@ -135,7 +136,8 @@ class HomeViewModel with ChangeNotifier {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
} }
Future<void> getApprovedStates() async {
Future<void> getApprovedStates() async {
_isLoading = true; _isLoading = true;
_errorMessage = null; _errorMessage = null;
notifyListeners(); notifyListeners();
+32 -1
View File
@@ -5,6 +5,8 @@ import 'package:tm_app/data/repositories/tenders_repository.dart';
import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart';
import 'package:tm_app/data/services/model/tender_detail_response/tender_detail_response_model.dart'; import 'package:tm_app/data/services/model/tender_detail_response/tender_detail_response_model.dart';
import '../data/services/model/tender_approvals_by_id_response/tender_approvals_by_id_response.dart';
import '../data/services/model/tender_approvals_data/tender_approvals_data.dart';
import '../data/services/model/tender_approvals_toggle_response/tender_approvals_toggle_response.dart'; import '../data/services/model/tender_approvals_toggle_response/tender_approvals_toggle_response.dart';
class TenderDetailViewModel with ChangeNotifier { class TenderDetailViewModel with ChangeNotifier {
@@ -22,14 +24,17 @@ class TenderDetailViewModel with ChangeNotifier {
bool _isRejectApprovalLoading = false; bool _isRejectApprovalLoading = false;
String? _errorMessage; String? _errorMessage;
TenderData? _tenderDetail; TenderData? _tenderDetail;
TenderApprovalsData? _tenderApprovalData;
bool approvalStatus = false; bool approvalStatus = false;
String _status = '';
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
bool get isSubmitApprovalLoading => _isSubmitApprovalLoading; bool get isSubmitApprovalLoading => _isSubmitApprovalLoading;
bool get isRejectApprovalLoading => _isRejectApprovalLoading; bool get isRejectApprovalLoading => _isRejectApprovalLoading;
String? get errorMessage => _errorMessage; String? get errorMessage => _errorMessage;
TenderData? get tenderDetail => _tenderDetail; TenderData? get tenderDetail => _tenderDetail;
TenderApprovalsData? get tenderApprovalData => _tenderApprovalData;
String get status => _status;
Future<void> getTenderDetail({required String id}) async { Future<void> getTenderDetail({required String id}) async {
_isLoading = true; _isLoading = true;
@@ -40,6 +45,7 @@ class TenderDetailViewModel with ChangeNotifier {
switch (result) { switch (result) {
case Ok<TenderDetailResponseModel>(): case Ok<TenderDetailResponseModel>():
_tenderDetail = result.value.data; _tenderDetail = result.value.data;
await getTenderApprovals(id);
break; break;
case Error<TenderDetailResponseModel>(): case Error<TenderDetailResponseModel>():
_errorMessage = result.error.toString(); _errorMessage = result.error.toString();
@@ -64,6 +70,7 @@ class TenderDetailViewModel with ChangeNotifier {
switch (result) { switch (result) {
case Ok<TenderApprovalsToggleResponse>(): case Ok<TenderApprovalsToggleResponse>():
approvalStatus = true; approvalStatus = true;
_status = result.value.data?.status ?? '';
break; break;
case Error<TenderApprovalsToggleResponse>(): case Error<TenderApprovalsToggleResponse>():
_errorMessage = result.error.toString(); _errorMessage = result.error.toString();
@@ -73,6 +80,7 @@ class TenderDetailViewModel with ChangeNotifier {
_isSubmitApprovalLoading = false; _isSubmitApprovalLoading = false;
notifyListeners(); notifyListeners();
_errorMessage = null; _errorMessage = null;
approvalStatus = false;
notifyListeners(); notifyListeners();
} }
@@ -90,6 +98,7 @@ class TenderDetailViewModel with ChangeNotifier {
switch (result) { switch (result) {
case Ok<TenderApprovalsToggleResponse>(): case Ok<TenderApprovalsToggleResponse>():
approvalStatus = true; approvalStatus = true;
_status = result.value.data?.status ?? '';
break; break;
case Error<TenderApprovalsToggleResponse>(): case Error<TenderApprovalsToggleResponse>():
_errorMessage = result.error.toString(); _errorMessage = result.error.toString();
@@ -99,6 +108,28 @@ class TenderDetailViewModel with ChangeNotifier {
_isRejectApprovalLoading = false; _isRejectApprovalLoading = false;
notifyListeners(); notifyListeners();
_errorMessage = null; _errorMessage = null;
approvalStatus = false;
notifyListeners();
}
Future<void> getTenderApprovals(String tenderId) async {
_errorMessage = null;
notifyListeners();
final result = await _tendersRepository.getTenderApprovals(
tenderId: tenderId,
);
switch (result) {
case Ok<TenderApprovalsByIdResponse>():
_tenderApprovalData = result.value.data;
_status = result.value.data?.status ?? '';
break;
case Error<TenderApprovalsByIdResponse>():
_errorMessage = result.error.toString();
break;
}
notifyListeners();
_errorMessage = null;
notifyListeners(); notifyListeners();
} }
} }
+51 -1
View File
@@ -9,10 +9,60 @@ import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart'; import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
import 'package:tm_app/views/shared/tender_app_bar.dart'; import 'package:tm_app/views/shared/tender_app_bar.dart';
class TenderDetailMobilePage extends StatelessWidget { class TenderDetailMobilePage extends StatefulWidget {
final String tenderId; final String tenderId;
const TenderDetailMobilePage({required this.tenderId, super.key}); const TenderDetailMobilePage({required this.tenderId, super.key});
@override
State<TenderDetailMobilePage> createState() => _TenderDetailMobilePageState();
}
class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
late final TenderDetailViewModel viewModel;
@override
void initState() {
viewModel = context.read<TenderDetailViewModel>();
viewModel.addListener(_viewModelListener);
super.initState();
}
void _viewModelListener() {
if (viewModel.status.isNotEmpty &&
viewModel.status == 'approved' &&
viewModel.approvalStatus == true) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('tender approved successfully!')));
}
if (viewModel.status.isNotEmpty &&
viewModel.status == 'unapproved' &&
viewModel.approvalStatus == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('tender approve removed sucessfully!')),
);
}
if (viewModel.status.isNotEmpty &&
viewModel.status == 'rejected' &&
viewModel.approvalStatus == true) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('tender rejected sucessfully!')));
}
if (viewModel.status.isNotEmpty &&
viewModel.status == 'unrejected' &&
viewModel.approvalStatus == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('tender reject removed sucessfully!')),
);
}
}
@override
void dispose() {
viewModel.removeListener(_viewModelListener);
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@@ -63,20 +63,27 @@ class TenderDetailActions extends StatelessWidget {
backgroundColor: AppColors.primary30, backgroundColor: AppColors.primary30,
textColor: AppColors.mainBlue, textColor: AppColors.mainBlue,
onPressed: () { onPressed: () {
showModalBottomSheet( if (viewModel.status == 'approved') {
isDismissible: true, viewModel.submitTenderApproval(
context: context, tenderId: detail.id!,
builder: (context) { submissionMode: 'self-apply',
return SelectSubmissionBottomSheet( );
onConfirm: (value) { } else {
viewModel.submitTenderApproval( showModalBottomSheet(
tenderId: detail.id!, isDismissible: true,
submissionMode: value, context: context,
); builder: (context) {
}, return SelectSubmissionBottomSheet(
); onConfirm: (value) {
}, viewModel.submitTenderApproval(
); tenderId: detail.id!,
submissionMode: value,
);
},
);
},
);
}
}, },
); );
}, },
+14 -3
View File
@@ -13,9 +13,20 @@ import 'package:tm_app/views/shared/tender_app_bar.dart';
import '../widgets.dart'; import '../widgets.dart';
class MobileHomePage extends StatelessWidget { class MobileHomePage extends StatefulWidget {
const MobileHomePage({super.key}); const MobileHomePage({super.key});
@override
State<MobileHomePage> createState() => _MobileHomePageState();
}
class _MobileHomePageState extends State<MobileHomePage> {
@override
void initState() {
// context.read<HomeViewModel>().init();
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@@ -32,8 +43,8 @@ class MobileHomePage extends StatelessWidget {
return Center(child: Text(homeViewModel.errorMessage!)); return Center(child: Text(homeViewModel.errorMessage!));
} }
if (homeViewModel.homeResponse != null && if (homeViewModel.tenderApprovalsStateResponse != null &&
homeViewModel.tenderApprovalsStateResponse != null) { homeViewModel.data != null) {
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,