From 47edc00b972059bc00a6b71add5e39e3b9c7aa30 Mon Sep 17 00:00:00 2001 From: amirrezaghabeli Date: Fri, 22 Aug 2025 09:30:02 +0330 Subject: [PATCH] home and tender change --- lib/view_models/home_view_model.dart | 18 ++++--- lib/view_models/tender_detail_view_model.dart | 33 +++++++++++- .../detail/pages/detail_mobile_page.dart | 52 ++++++++++++++++++- .../detail/widgets/tender_detail_action.dart | 35 ++++++++----- lib/views/home/pages/m_home_page.dart | 17 ++++-- 5 files changed, 128 insertions(+), 27 deletions(-) diff --git a/lib/view_models/home_view_model.dart b/lib/view_models/home_view_model.dart index 744c3d9..8ae0530 100644 --- a/lib/view_models/home_view_model.dart +++ b/lib/view_models/home_view_model.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.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/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_state_response/tender_approvals_state_response.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import '../data/repositories/home_repository.dart'; @@ -14,9 +14,7 @@ class HomeViewModel with ChangeNotifier { HomeViewModel({required HomeRepository homeRepository}) : _homeRepository = homeRepository { - getHome(homeRequestModel: HomeRequestModel(id: '1')); - getYourTenders(); - getApprovedStates(); + init(); } bool _isLoading = false; @@ -40,6 +38,11 @@ class HomeViewModel with ChangeNotifier { bool get isLoadingMore => _isLoadingMore; bool get hasMore => _hasMore; + void init() async { + await getApprovedStates(); + await getYourTenders(); + } + Future getHome({HomeRequestModel? homeRequestModel}) async { _isLoading = true; _errorMessage = null; @@ -120,9 +123,7 @@ class HomeViewModel with ChangeNotifier { } else { _tenders.clear(); _tenders.addAll( - data!.data! - .map((e) => e.tender) - .whereType(), + data!.data!.map((e) => e.tender).whereType(), ); } @@ -135,7 +136,8 @@ class HomeViewModel with ChangeNotifier { _isLoading = false; notifyListeners(); } - Future getApprovedStates() async { + + Future getApprovedStates() async { _isLoading = true; _errorMessage = null; notifyListeners(); diff --git a/lib/view_models/tender_detail_view_model.dart b/lib/view_models/tender_detail_view_model.dart index 61f5ed4..3f73acb 100644 --- a/lib/view_models/tender_detail_view_model.dart +++ b/lib/view_models/tender_detail_view_model.dart @@ -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_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'; class TenderDetailViewModel with ChangeNotifier { @@ -22,14 +24,17 @@ class TenderDetailViewModel with ChangeNotifier { bool _isRejectApprovalLoading = false; String? _errorMessage; TenderData? _tenderDetail; - + TenderApprovalsData? _tenderApprovalData; bool approvalStatus = false; + String _status = ''; bool get isLoading => _isLoading; bool get isSubmitApprovalLoading => _isSubmitApprovalLoading; bool get isRejectApprovalLoading => _isRejectApprovalLoading; String? get errorMessage => _errorMessage; TenderData? get tenderDetail => _tenderDetail; + TenderApprovalsData? get tenderApprovalData => _tenderApprovalData; + String get status => _status; Future getTenderDetail({required String id}) async { _isLoading = true; @@ -40,6 +45,7 @@ class TenderDetailViewModel with ChangeNotifier { switch (result) { case Ok(): _tenderDetail = result.value.data; + await getTenderApprovals(id); break; case Error(): _errorMessage = result.error.toString(); @@ -64,6 +70,7 @@ class TenderDetailViewModel with ChangeNotifier { switch (result) { case Ok(): approvalStatus = true; + _status = result.value.data?.status ?? ''; break; case Error(): _errorMessage = result.error.toString(); @@ -73,6 +80,7 @@ class TenderDetailViewModel with ChangeNotifier { _isSubmitApprovalLoading = false; notifyListeners(); _errorMessage = null; + approvalStatus = false; notifyListeners(); } @@ -90,6 +98,7 @@ class TenderDetailViewModel with ChangeNotifier { switch (result) { case Ok(): approvalStatus = true; + _status = result.value.data?.status ?? ''; break; case Error(): _errorMessage = result.error.toString(); @@ -99,6 +108,28 @@ class TenderDetailViewModel with ChangeNotifier { _isRejectApprovalLoading = false; notifyListeners(); _errorMessage = null; + approvalStatus = false; + notifyListeners(); + } + + Future getTenderApprovals(String tenderId) async { + _errorMessage = null; + notifyListeners(); + + final result = await _tendersRepository.getTenderApprovals( + tenderId: tenderId, + ); + switch (result) { + case Ok(): + _tenderApprovalData = result.value.data; + _status = result.value.data?.status ?? ''; + break; + case Error(): + _errorMessage = result.error.toString(); + break; + } + notifyListeners(); + _errorMessage = null; notifyListeners(); } } diff --git a/lib/views/detail/pages/detail_mobile_page.dart b/lib/views/detail/pages/detail_mobile_page.dart index e786e39..252a1ab 100644 --- a/lib/views/detail/pages/detail_mobile_page.dart +++ b/lib/views/detail/pages/detail_mobile_page.dart @@ -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/shared/tender_app_bar.dart'; -class TenderDetailMobilePage extends StatelessWidget { +class TenderDetailMobilePage extends StatefulWidget { final String tenderId; const TenderDetailMobilePage({required this.tenderId, super.key}); + @override + State createState() => _TenderDetailMobilePageState(); +} + +class _TenderDetailMobilePageState extends State { + late final TenderDetailViewModel viewModel; + @override + void initState() { + viewModel = context.read(); + 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 Widget build(BuildContext context) { return Scaffold( diff --git a/lib/views/detail/widgets/tender_detail_action.dart b/lib/views/detail/widgets/tender_detail_action.dart index 7e7f6af..3855fff 100644 --- a/lib/views/detail/widgets/tender_detail_action.dart +++ b/lib/views/detail/widgets/tender_detail_action.dart @@ -63,20 +63,27 @@ class TenderDetailActions extends StatelessWidget { backgroundColor: AppColors.primary30, textColor: AppColors.mainBlue, onPressed: () { - showModalBottomSheet( - isDismissible: true, - context: context, - builder: (context) { - return SelectSubmissionBottomSheet( - onConfirm: (value) { - viewModel.submitTenderApproval( - tenderId: detail.id!, - submissionMode: value, - ); - }, - ); - }, - ); + if (viewModel.status == 'approved') { + viewModel.submitTenderApproval( + tenderId: detail.id!, + submissionMode: 'self-apply', + ); + } else { + showModalBottomSheet( + isDismissible: true, + context: context, + builder: (context) { + return SelectSubmissionBottomSheet( + onConfirm: (value) { + viewModel.submitTenderApproval( + tenderId: detail.id!, + submissionMode: value, + ); + }, + ); + }, + ); + } }, ); }, diff --git a/lib/views/home/pages/m_home_page.dart b/lib/views/home/pages/m_home_page.dart index 274f39b..350b82c 100644 --- a/lib/views/home/pages/m_home_page.dart +++ b/lib/views/home/pages/m_home_page.dart @@ -13,9 +13,20 @@ import 'package:tm_app/views/shared/tender_app_bar.dart'; import '../widgets.dart'; -class MobileHomePage extends StatelessWidget { +class MobileHomePage extends StatefulWidget { const MobileHomePage({super.key}); + @override + State createState() => _MobileHomePageState(); +} + +class _MobileHomePageState extends State { + @override + void initState() { + // context.read().init(); + super.initState(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -32,8 +43,8 @@ class MobileHomePage extends StatelessWidget { return Center(child: Text(homeViewModel.errorMessage!)); } - if (homeViewModel.homeResponse != null && - homeViewModel.tenderApprovalsStateResponse != null) { + if (homeViewModel.tenderApprovalsStateResponse != null && + homeViewModel.data != null) { return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start,