diff --git a/lib/view_models/liked_tenders_view_model.dart b/lib/view_models/liked_tenders_view_model.dart index f4b74bc..9388ded 100644 --- a/lib/view_models/liked_tenders_view_model.dart +++ b/lib/view_models/liked_tenders_view_model.dart @@ -4,14 +4,10 @@ import 'package:tm_app/data/repositories/liked_tenders_repository.dart'; import 'package:tm_app/data/repositories/tenders_repository.dart'; import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart'; import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart'; -import 'package:tm_app/data/services/model/tender_approvals_toggle_response/tender_approvals_toggle_response.dart'; import 'package:tm_app/view_models/home_view_model.dart'; -import '../core/constants/tender_approval_status.dart'; import '../data/services/model/feedback_response/feedback_response.dart'; import '../data/services/model/request_models/tender_feedback_request_model/tender_feedback_request_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'; class LikedTendersViewModel with ChangeNotifier { final LikedTendersRepository _likedTendersRepository; @@ -30,11 +26,6 @@ class LikedTendersViewModel with ChangeNotifier { bool hasMore = true; String? errorMessage; LikedTendersResponse? data; - TenderApprovalsData? _tenderApprovalData; - - TenderApprovalsData? get tenderApprovalData => _tenderApprovalData; - - List tenderApprovals = []; int _offset = 0; final int _limit = 7; @@ -43,10 +34,10 @@ class LikedTendersViewModel with ChangeNotifier { // Approval status properties bool approvalStatus = false; - String _status = ''; + final String _status = ''; String? _errorMessage; - bool _isSubmitApprovalLoading = false; - bool _isRejectApprovalLoading = false; + final bool _isSubmitApprovalLoading = false; + final bool _isRejectApprovalLoading = false; String get status => _status; String? get approvalErrorMessage => _errorMessage; @@ -100,10 +91,6 @@ class LikedTendersViewModel with ChangeNotifier { final incoming = result.value; final incomingList = incoming.data?.feedback ?? []; - for (var element in incomingList) { - await getTenderApproval(element.tenderId!); - } - if (reset) { data = incoming; } else { @@ -195,203 +182,4 @@ class LikedTendersViewModel with ChangeNotifier { notifyListeners(); } - - Future getTenderApproval(String tenderId) async { - errorMessage = null; - notifyListeners(); - - final result = await _tendersRepository.getTenderApprovals( - tenderId: tenderId, - ); - - switch (result) { - case Ok(): - _tenderApprovalData = result.value.data; - tenderApprovals.add(_tenderApprovalData!); - break; - case Error(): - errorMessage = result.error.toString(); - break; - } - - notifyListeners(); - errorMessage = null; - notifyListeners(); - } - - TenderApprovalsData? getApprovalStatusForTender(String tenderId) { - try { - return tenderApprovals.firstWhere((a) => a.tenderId == tenderId); - } catch (e) { - return null; - } - } - - /// Check if tender approval exists for a specific tender - bool hasTenderApprovalForTender(String tenderId) { - return tenderApprovals.any((a) => a.tenderId == tenderId); - } - - /// Get approval status for a tender safely - String? getApprovalStatusForTenderId(String tenderId) { - try { - final approval = tenderApprovals.firstWhere( - (a) => a.tenderId == tenderId, - ); - return approval.status; - } catch (e) { - return null; - } - } - - /// Check if tender is submitted - bool isTenderSubmitted(String tenderId) { - return getApprovalStatusForTenderId(tenderId) == - TenderApprovalStatus.submitted.value; - } - - /// Check if tender is rejected - bool isTenderRejected(String tenderId) { - return getApprovalStatusForTenderId(tenderId) == - TenderApprovalStatus.rejected.value; - } - - Future submitTenderApproval({ - required String tenderId, - required String submissionMode, - }) async { - _isSubmitApprovalLoading = true; - _errorMessage = null; - notifyListeners(); - - // Store original state for rollback - final originalApprovals = List.of(tenderApprovals); - - // Check current approval status and update optimistically - final existingApproval = getApprovalStatusForTender(tenderId); - - if (existingApproval != null) { - if (existingApproval.status == TenderApprovalStatus.submitted.value) { - // Remove from list if already submitted - tenderApprovals.removeWhere((a) => a.tenderId == tenderId); - } else if (existingApproval.status == - TenderApprovalStatus.rejected.value) { - // Change rejected to submitted - final updatedApproval = existingApproval.copyWith( - status: TenderApprovalStatus.submitted.value, - ); - final index = tenderApprovals.indexWhere((a) => a.tenderId == tenderId); - if (index != -1) { - tenderApprovals[index] = updatedApproval; - } - } - } else { - // Add new approval with submitted status - final newApproval = TenderApprovalsData( - id: null, - status: TenderApprovalStatus.submitted.value, - tenderId: tenderId, - companyId: null, - submissionMode: submissionMode, - createdAt: null, - tender: null, - ); - tenderApprovals.add(newApproval); - } - - notifyListeners(); - - // Make server request - final result = await _tendersRepository.toggleApprovals( - tenderId: tenderId, - status: TenderApprovalStatus.submitted.value, - submissionMode: submissionMode, - ); - - switch (result) { - case Ok(): - approvalStatus = true; - _status = result.value.data?.status ?? ''; - break; - case Error(): - // Rollback changes on error - tenderApprovals = originalApprovals; - _errorMessage = result.error.toString(); - approvalStatus = false; - break; - } - approvalStatus = false; - _isSubmitApprovalLoading = false; - notifyListeners(); - } - - Future rejectTenderApproval({ - required String tenderId, - required String submissionMode, - }) async { - _isRejectApprovalLoading = true; - _errorMessage = null; - notifyListeners(); - - // Store original state for rollback - final originalApprovals = List.of(tenderApprovals); - - // Check current approval status and update optimistically - final existingApproval = getApprovalStatusForTender(tenderId); - - if (existingApproval != null) { - if (existingApproval.status == TenderApprovalStatus.rejected.value) { - // Remove from list if already rejected - tenderApprovals.removeWhere((a) => a.tenderId == tenderId); - } else if (existingApproval.status == - TenderApprovalStatus.submitted.value) { - // Change submitted to rejected - final updatedApproval = existingApproval.copyWith( - status: TenderApprovalStatus.rejected.value, - ); - final index = tenderApprovals.indexWhere((a) => a.tenderId == tenderId); - if (index != -1) { - tenderApprovals[index] = updatedApproval; - } - } - } else { - // Add new approval with rejected status - final newApproval = TenderApprovalsData( - id: null, - status: TenderApprovalStatus.rejected.value, - tenderId: tenderId, - companyId: null, - submissionMode: submissionMode, - createdAt: null, - tender: null, - ); - tenderApprovals.add(newApproval); - } - - notifyListeners(); - - // Make server request - final result = await _tendersRepository.toggleApprovals( - tenderId: tenderId, - status: TenderApprovalStatus.rejected.value, - submissionMode: submissionMode, - ); - - switch (result) { - case Ok(): - approvalStatus = true; - _status = result.value.data?.status ?? ''; - break; - case Error(): - // Rollback changes on error - tenderApprovals = originalApprovals; - _errorMessage = result.error.toString(); - approvalStatus = false; - break; - } - - approvalStatus = false; - _isRejectApprovalLoading = false; - notifyListeners(); - } } diff --git a/lib/view_models/tender_detail_view_model.dart b/lib/view_models/tender_detail_view_model.dart index 649ada4..5e4b324 100644 --- a/lib/view_models/tender_detail_view_model.dart +++ b/lib/view_models/tender_detail_view_model.dart @@ -15,7 +15,6 @@ import 'tenders_view_model.dart'; class TenderDetailViewModel with ChangeNotifier { final TenderDetailRepository _tenderDetailRepository; final TendersRepository _tendersRepository; - final TendersViewModel _tendersViewModel; final HomeViewModel _homeViewModel; TenderDetailViewModel({ @@ -25,7 +24,7 @@ class TenderDetailViewModel with ChangeNotifier { required HomeViewModel homeViewModel, }) : _tenderDetailRepository = tenderDetailRepository, _tendersRepository = tendersRepository, - _tendersViewModel = tendersViewModel, + _homeViewModel = homeViewModel; bool _isLoading = false; @@ -123,10 +122,6 @@ class TenderDetailViewModel with ChangeNotifier { notifyListeners(); } - void updateTenderApprovals(String tenderId) { - _tendersViewModel.getTenderApprovals(tenderId); - } - void updateHome() async { _homeViewModel.init(); } diff --git a/lib/view_models/tenders_view_model.dart b/lib/view_models/tenders_view_model.dart index 126cf24..ac36abd 100644 --- a/lib/view_models/tenders_view_model.dart +++ b/lib/view_models/tenders_view_model.dart @@ -5,51 +5,38 @@ import 'package:tm_app/core/utils/device_utils.dart'; import 'package:tm_app/data/repositories/tenders_repository.dart'; import 'package:tm_app/data/services/model/feedback_data/feedback_data.dart'; import 'package:tm_app/data/services/model/feedback_response/feedback_response.dart'; -import 'package:tm_app/data/services/model/tender_approvals_toggle_data/tender_approvals_toggle_data.dart'; -import 'package:tm_app/data/services/model/tender_approvals_toggle_response/tender_approvals_toggle_response.dart'; import 'package:tm_app/data/services/model/tenders/tenders_response/tenders_response.dart'; -import '../core/constants/tender_submision_mode.dart'; import '../core/utils/result.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 'home_view_model.dart'; class TendersViewModel with ChangeNotifier { final TendersRepository _tendersRepository; - final HomeViewModel _homeViewModel; TendersViewModel({ required TendersRepository tendersRepository, required HomeViewModel homeViewModel, - }) : _tendersRepository = tendersRepository, - _homeViewModel = homeViewModel; + }) : _tendersRepository = tendersRepository; bool _isLoading = false; bool _isLoadingMore = false; String? _errorMessage; String? _feedbackErrorMessage; - String? _tenderApprovalErrorMessage; TendersResponse? _tendersResponse; FeedbackData? _feedbackData; - TenderApprovalsData? _tenderApprovalData; - TenderApprovalsToggleData? _tenderApprovalToggleData; String? _searchQuery; bool get isLoading => _isLoading; bool get isLoadingMore => _isLoadingMore; String? get errorMessage => _errorMessage; String? get feedbackErrorMessage => _feedbackErrorMessage; - String? get tenderApprovalErrorMessage => _tenderApprovalErrorMessage; + TendersResponse? get tendersResponse => _tendersResponse; FeedbackData? get feedbackData => _feedbackData; - TenderApprovalsData? get tenderApprovalData => _tenderApprovalData; - TenderApprovalsToggleData? get tenderApprovalToggleData => - _tenderApprovalToggleData; + String? get searchQuery => _searchQuery; List feedbacks = []; - List tenderApprovals = []; int currentPage = 1; int _currentOffset = 0; @@ -74,27 +61,9 @@ class TendersViewModel with ChangeNotifier { return feedbacks.any((f) => f.tender == tenderId); } - /// Get tender approval for a specific tender - TenderApprovalsData? getTenderApprovalForTender(String tenderId) { - try { - return tenderApprovals.firstWhere((a) => a.tenderId == tenderId); - } catch (e) { - return null; - } - } - - /// Check if tender approval exists for a specific tender - bool hasTenderApprovalForTender(String tenderId) { - return tenderApprovals.any((a) => a.tenderId == tenderId); - } - - /// Get approval status for a specific tender - String? getApprovalStatusForTender(String tenderId) { - final approval = getTenderApprovalForTender(tenderId); - return approval?.status; - } - Future getTenders({String? query, BuildContext? context}) async { + _isLoading = true; + notifyListeners(); if (context != null && DeviceUtils.isDesktop(context)) { await getTendersDesktop(query: query); } else { @@ -103,8 +72,6 @@ class TendersViewModel with ChangeNotifier { } Future getTendersMobile({String? query}) async { - _isLoading = true; - notifyListeners(); clearAll(); // Clear all data before fetching new tenders _currentOffset = 0; @@ -126,7 +93,6 @@ class TendersViewModel with ChangeNotifier { if (_tendersResponse?.data?.tenders?.isNotEmpty == true) { // Fetch feedback and approvals for the first tender only getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!); - getTenderApprovals(_tendersResponse!.data!.tenders!.first.id!); } if (_tendersResponse?.meta?.pages != null) { _totalPages = _tendersResponse!.meta!.pages!; @@ -146,8 +112,6 @@ class TendersViewModel with ChangeNotifier { } Future getTendersDesktop({String? query}) async { - _isLoading = true; - notifyListeners(); clearAll(); // Clear all data before fetching new tenders _currentOffset = 0; @@ -167,9 +131,6 @@ class TendersViewModel with ChangeNotifier { _hasMoreData = _tendersResponse!.data!.tenders!.length >= _pageSize; } if (_tendersResponse?.data?.tenders?.isNotEmpty == true) { - // Fetch feedback and approvals for the first tender only - // getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!); - // getTenderApprovals(_tendersResponse!.data!.tenders!.first.id!); for (var tender in _tendersResponse!.data!.tenders!) { getTenderFeedback(tender.id!); } @@ -278,47 +239,6 @@ class TendersViewModel with ChangeNotifier { notifyListeners(); } - Future getTenderApprovals(String tenderId) async { - _errorMessage = null; - notifyListeners(); - - final result = await _tendersRepository.getTenderApprovals( - tenderId: tenderId, - ); - switch (result) { - case Ok(): - _tenderApprovalData = result.value.data; - // Add or update _tenderApprovalData in tenderApprovals list by tender id - if (_tenderApprovalData != null) { - final index = tenderApprovals.indexWhere( - (a) => a.tenderId == _tenderApprovalData!.tenderId, - ); - if (index != -1) { - tenderApprovals[index] = _tenderApprovalData!; - log( - 'Updated approval for tender: ${_tenderApprovalData!.tenderId}', - ); - } else { - tenderApprovals.add(_tenderApprovalData!); - log( - 'Added new approval for tender: ${_tenderApprovalData!.tenderId}', - ); - } - log('Total approvals: ${tenderApprovals.length}'); - } - break; - case Error(): - // Remove the tender from tenderApprovals if an error occurs for this tenderId - - tenderApprovals.removeWhere((a) => a.tenderId == tenderId); - _errorMessage = result.error.toString(); - break; - } - notifyListeners(); - _errorMessage = null; - notifyListeners(); - } - Future toogleFeedback({ required String tenderId, required String feedbackType, @@ -418,124 +338,6 @@ class TendersViewModel with ChangeNotifier { notifyListeners(); } - Future toggleApprovals({ - required String tenderId, - required String submissionMode, - required String status, - }) async { - _tenderApprovalErrorMessage = null; - - // Get current approval for this tender - final existingApproval = getTenderApprovalForTender(tenderId); - final existingApprovalIndex = tenderApprovals.indexWhere( - (a) => a.tenderId == tenderId, - ); - - // Create optimistic approval data - TenderApprovalsData? optimisticApproval; - - if (existingApproval == null) { - // No existing approval - create new optimistic approval - optimisticApproval = TenderApprovalsData( - id: null, // Will be filled by server - status: status, - tenderId: tenderId, - companyId: null, // Will be filled by server - submissionMode: submissionMode, - createdAt: DateTime.now().millisecondsSinceEpoch, - tender: null, - ); - tenderApprovals.add(optimisticApproval); - } else { - // Existing approval - update optimistically - if (existingApproval.status == status) { - // Same status - remove approval (toggle off) - if (existingApprovalIndex != -1) { - tenderApprovals.removeAt(existingApprovalIndex); - } - optimisticApproval = null; - } else { - // Different status - update to new status - optimisticApproval = existingApproval.copyWith( - status: status, - submissionMode: submissionMode, - ); - if (existingApprovalIndex != -1) { - tenderApprovals[existingApprovalIndex] = optimisticApproval; - } - } - } - - // Notify listeners immediately for optimistic update - notifyListeners(); - - // Call API - final result = await _tendersRepository.toggleApprovals( - tenderId: tenderId, - submissionMode: submissionMode, - status: status, - ); - - switch (result) { - case Ok(): - _tenderApprovalToggleData = result.value.data; - if (_tenderApprovalToggleData != null) { - // Convert TenderApprovalsToggleData to TenderApprovalsData - final approvalData = TenderApprovalsData( - id: _tenderApprovalToggleData!.id, - status: _tenderApprovalToggleData!.status!, - tenderId: _tenderApprovalToggleData!.tenderId, - companyId: _tenderApprovalToggleData!.companyId, - submissionMode: - (_tenderApprovalToggleData!.submissionMode?.isNotEmpty == true) - ? _tenderApprovalToggleData!.submissionMode - : TenderSubmissionMode.selfApply.value, - createdAt: _tenderApprovalToggleData!.createdAt, - tender: null, // Tender data is not included in toggle response - ); - - final index = tenderApprovals.indexWhere( - (a) => a.tenderId == approvalData.tenderId, - ); - if (index != -1) { - tenderApprovals[index] = approvalData; - } else { - tenderApprovals.add(approvalData); - } - } else { - // Server returned null data - remove approval - tenderApprovals.removeWhere((a) => a.tenderId == tenderId); - } - break; - case Error(): - // Revert optimistic update on error - if (existingApproval == null) { - // Remove the optimistic approval we added - tenderApprovals.removeWhere((a) => a.tenderId == tenderId); - } else { - // Restore the original approval - find current index and update, or add if not found - final currentIndex = tenderApprovals.indexWhere( - (a) => a.tenderId == tenderId, - ); - if (currentIndex != -1) { - tenderApprovals[currentIndex] = existingApproval; - } else { - tenderApprovals.add(existingApproval); - } - } - _tenderApprovalErrorMessage = result.error.toString(); - break; - } - - notifyListeners(); - _tenderApprovalErrorMessage = null; - notifyListeners(); - } - - void updateHome() { - _homeViewModel.init(); - } - /// Clear all feedbacks void clearFeedbacks() { feedbacks.clear(); @@ -567,10 +369,6 @@ class TendersViewModel with ChangeNotifier { void clearAll() { clearTenders(); clearFeedbacks(); - tenderApprovals.clear(); - _tenderApprovalData = null; - _tenderApprovalToggleData = null; - _tenderApprovalErrorMessage = null; _searchQuery = null; notifyListeners(); } diff --git a/lib/views/detail/pages/detail_desktop_page.dart b/lib/views/detail/pages/detail_desktop_page.dart index f7c3716..40c791a 100644 --- a/lib/views/detail/pages/detail_desktop_page.dart +++ b/lib/views/detail/pages/detail_desktop_page.dart @@ -77,74 +77,65 @@ class _TenderDetailDesktopPageState extends State { @override Widget build(BuildContext context) { - return PopScope( - onPopInvokedWithResult: (didPop, result) { - WidgetsBinding.instance.addPostFrameCallback((_) { - viewModel.updateTenderApprovals(widget.tenderId); - }); - }, - child: Scaffold( - backgroundColor: AppColors.backgroundColor, - body: Consumer( - builder: (context, tenderViewModel, child) { - if (tenderViewModel.isLoading) { - return const Center( - child: CircularProgressIndicator(color: AppColors.secondary50), - ); - } + return Scaffold( + backgroundColor: AppColors.backgroundColor, + body: Consumer( + builder: (context, tenderViewModel, child) { + if (tenderViewModel.isLoading) { + return const Center( + child: CircularProgressIndicator(color: AppColors.secondary50), + ); + } - if (tenderViewModel.errorMessage != null) { - return Center(child: Text(tenderViewModel.errorMessage!)); - } + if (tenderViewModel.errorMessage != null) { + return Center(child: Text(tenderViewModel.errorMessage!)); + } - final detail = tenderViewModel.tenderDetail; - if (detail == null) { - return const Center( - child: Text(TenderDetailsStrings.tenderNoData), - ); - } + final detail = tenderViewModel.tenderDetail; + if (detail == null) { + return const Center(child: Text(TenderDetailsStrings.tenderNoData)); + } - return Column( - children: [ - const DesktopNavigationWidget( - currentIndex: 1, // Home index - ), - Expanded( - child: SingleChildScrollView( - child: Center( - child: SizedBox( - width: 740, - child: Padding( - padding: const EdgeInsets.all(32.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const TabletDesktopAppbar( - title: TenderDetailsStrings.tenderDetailTitle, - ), - SizedBox(height: 32.0.h()), - TenderDetailHeader( - isScreenBig: true, - detail: detail, - ), - SizedBox(height: 32.0.h()), - TenderDetailCard(detail: detail), - SizedBox(height: 24.0.h()), - TenderDetailActions( - isScreenBig: true, - detail: detail, - ), - ], - ), + return Column( + children: [ + const DesktopNavigationWidget( + currentIndex: 1, // Home index + ), + Expanded( + child: SingleChildScrollView( + child: Center( + child: SizedBox( + width: 740, + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TabletDesktopAppbar( + title: TenderDetailsStrings.tenderDetailTitle, + ), + SizedBox(height: 32.0.h()), + TenderDetailHeader( + isScreenBig: true, + detail: detail, + ), + SizedBox(height: 32.0.h()), + TenderDetailCard(detail: detail), + SizedBox(height: 24.0.h()), + TenderDetailActions( + isScreenBig: true, + detail: detail, + ), + ], ), ), ), ), ), - ], - ); - }, - ), + ), + ], + ); + }, ), ); } diff --git a/lib/views/detail/pages/detail_mobile_page.dart b/lib/views/detail/pages/detail_mobile_page.dart index ced899d..2bd9777 100644 --- a/lib/views/detail/pages/detail_mobile_page.dart +++ b/lib/views/detail/pages/detail_mobile_page.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tm_app/core/theme/colors.dart'; @@ -76,65 +75,52 @@ class _TenderDetailMobilePageState extends State { @override Widget build(BuildContext context) { - return PopScope( - onPopInvokedWithResult: (didPop, result) { - if (kIsWeb) { - WidgetsBinding.instance.addPostFrameCallback((_) { - context.read().updateTenderApprovals( - widget.tenderId, - ); - }); - } - }, - child: Directionality( - textDirection: TextDirection.rtl, - child: Scaffold( - backgroundColor: AppColors.backgroundColor, - appBar: appBar( - context: context, - title: TenderDetailsStrings.tenderDetailTitle, - ), - body: Consumer( - builder: (context, tenderViewModel, child) { - if (tenderViewModel.isLoading) { - return const Center( - child: CircularProgressIndicator( - color: AppColors.secondary50, - ), - ); - } - - if (tenderViewModel.errorMessage != null) { - return Center(child: Text(tenderViewModel.errorMessage!)); - } - - final detail = tenderViewModel.tenderDetail; - if (detail == null) { - return const Center( - child: Text(TenderDetailsStrings.tenderNoData), - ); - } - - return SingleChildScrollView( - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 16.0.w(), - vertical: 16.0.h(), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TenderDetailHeader(isScreenBig: false, detail: detail), - SizedBox(height: 24.0.h()), - TenderDetailCard(detail: detail), - SizedBox(height: 24.0.h()), - TenderDetailActions(isScreenBig: false, detail: detail), - ], - ), - ), + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + backgroundColor: AppColors.backgroundColor, + appBar: appBar( + context: context, + title: TenderDetailsStrings.tenderDetailTitle, + ), + body: Consumer( + builder: (context, tenderViewModel, child) { + if (tenderViewModel.isLoading) { + return const Center( + child: CircularProgressIndicator(color: AppColors.secondary50), ); - }, - ), + } + + if (tenderViewModel.errorMessage != null) { + return Center(child: Text(tenderViewModel.errorMessage!)); + } + + final detail = tenderViewModel.tenderDetail; + if (detail == null) { + return const Center( + child: Text(TenderDetailsStrings.tenderNoData), + ); + } + + return SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 16.0.w(), + vertical: 16.0.h(), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TenderDetailHeader(isScreenBig: false, detail: detail), + SizedBox(height: 24.0.h()), + TenderDetailCard(detail: detail), + SizedBox(height: 24.0.h()), + TenderDetailActions(isScreenBig: false, detail: detail), + ], + ), + ), + ); + }, ), ), ); diff --git a/lib/views/detail/pages/detail_tablet_page.dart b/lib/views/detail/pages/detail_tablet_page.dart index 1ce8b60..a078b57 100644 --- a/lib/views/detail/pages/detail_tablet_page.dart +++ b/lib/views/detail/pages/detail_tablet_page.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:tm_app/core/theme/colors.dart'; @@ -79,70 +78,58 @@ class _TenderDetailTabletPageState extends State { @override Widget build(BuildContext context) { final GlobalKey key = GlobalKey(); - return PopScope( - onPopInvokedWithResult: (didPop, result) { - if (kIsWeb) { - WidgetsBinding.instance.addPostFrameCallback((_) { - viewModel.updateTenderApprovals(widget.tenderId); - }); - } - }, - key: key, - child: Scaffold( - backgroundColor: AppColors.backgroundColor, - appBar: tabletAppBar( - title: TenderDetailsStrings.tenderDetailTitle, - key: key, - ), + return Scaffold( + backgroundColor: AppColors.backgroundColor, + appBar: tabletAppBar( + title: TenderDetailsStrings.tenderDetailTitle, + key: key, + ), - drawer: const TabletNavigationWidget( - currentIndex: 1, // Home is index 0 - ), - body: Consumer( - builder: (context, tenderViewModel, child) { - if (tenderViewModel.isLoading) { - return const Center( - child: CircularProgressIndicator(color: AppColors.secondary50), - ); - } + drawer: const TabletNavigationWidget( + currentIndex: 1, // Home is index 0 + ), + body: Consumer( + builder: (context, tenderViewModel, child) { + if (tenderViewModel.isLoading) { + return const Center( + child: CircularProgressIndicator(color: AppColors.secondary50), + ); + } - if (tenderViewModel.errorMessage != null) { - return Center(child: Text(tenderViewModel.errorMessage!)); - } + if (tenderViewModel.errorMessage != null) { + return Center(child: Text(tenderViewModel.errorMessage!)); + } - final detail = tenderViewModel.tenderDetail; - if (detail == null) { - return const Center( - child: Text(TenderDetailsStrings.tenderNoData), - ); - } - return SingleChildScrollView( - child: Center( - child: SizedBox( - width: 768, + final detail = tenderViewModel.tenderDetail; + if (detail == null) { + return const Center(child: Text(TenderDetailsStrings.tenderNoData)); + } + return SingleChildScrollView( + child: Center( + child: SizedBox( + width: 768, - child: Padding( - padding: const EdgeInsets.all(24.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const TabletDesktopAppbar( - title: TenderDetailsStrings.tenderDetailTitle, - ), - SizedBox(height: 28.0.h()), - TenderDetailHeader(isScreenBig: true, detail: detail), - SizedBox(height: 28.0.h()), - TenderDetailCard(detail: detail), - SizedBox(height: 24.0.h()), - TenderDetailActions(isScreenBig: true, detail: detail), - ], - ), + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const TabletDesktopAppbar( + title: TenderDetailsStrings.tenderDetailTitle, + ), + SizedBox(height: 28.0.h()), + TenderDetailHeader(isScreenBig: true, detail: detail), + SizedBox(height: 28.0.h()), + TenderDetailCard(detail: detail), + SizedBox(height: 24.0.h()), + TenderDetailActions(isScreenBig: true, detail: detail), + ], ), ), ), - ); - }, - ), + ), + ); + }, ), ); } diff --git a/lib/views/liked_tenders/pages/liked_tenders_desktop_page.dart b/lib/views/liked_tenders/pages/liked_tenders_desktop_page.dart index f0c727c..8190547 100644 --- a/lib/views/liked_tenders/pages/liked_tenders_desktop_page.dart +++ b/lib/views/liked_tenders/pages/liked_tenders_desktop_page.dart @@ -5,7 +5,6 @@ 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/data/services/model/liked_tender_feedback/liked_tender_feedback.dart'; -import 'package:tm_app/data/services/model/tender_approvals_data/tender_approvals_data.dart'; import 'package:tm_app/view_models/liked_tenders_view_model.dart'; import 'package:tm_app/views/liked_tenders/widgets/liked_tenders_list_item.dart'; import 'package:tm_app/views/shared/page_selection_dialog.dart'; @@ -216,15 +215,7 @@ class _LikedTendersDesktopPageState extends State { itemCount: feedback.length, itemBuilder: (context, index) { final item = feedback[index]; - TenderApprovalsData? approval; - bool hasApproval = viewModel.hasTenderApprovalForTender( - item.tenderId!, - ); - if (hasApproval) { - approval = viewModel.getApprovalStatusForTender(item.tenderId!); - } else { - approval = null; - } + return Padding( padding: EdgeInsets.only(bottom: 20.0.h()), child: Dismissible( @@ -240,11 +231,7 @@ class _LikedTendersDesktopPageState extends State { viewModel.removeTenderById(item.tenderId!); } }, - child: LikedListItem( - tender: item.tender!, - approval: approval, - isDesktop: true, - ), + child: LikedListItem(tender: item.tender!, isDesktop: true), ), ); }, diff --git a/lib/views/liked_tenders/pages/liked_tenders_mobile_page.dart b/lib/views/liked_tenders/pages/liked_tenders_mobile_page.dart index ab957be..a402945 100644 --- a/lib/views/liked_tenders/pages/liked_tenders_mobile_page.dart +++ b/lib/views/liked_tenders/pages/liked_tenders_mobile_page.dart @@ -6,7 +6,6 @@ import 'package:tm_app/core/constants/assets.dart'; import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/core/utils/app_toast.dart'; import 'package:tm_app/core/utils/size_config.dart'; -import 'package:tm_app/data/services/model/tender_approvals_data/tender_approvals_data.dart'; import 'package:tm_app/view_models/liked_tenders_view_model.dart'; import 'package:tm_app/views/liked_tenders/strings/liked_tenders_strings.dart'; import 'package:tm_app/views/liked_tenders/widgets/liked_tenders_list_item.dart'; @@ -196,17 +195,6 @@ class _LikedTendersMobilePageState extends State { itemBuilder: (context, index) { if (index < feedback.length) { final item = feedback[index]; - TenderApprovalsData? approval; - bool hasApproval = viewModel.hasTenderApprovalForTender( - item.tenderId!, - ); - if (hasApproval) { - approval = viewModel.getApprovalStatusForTender( - item.tenderId!, - ); - } else { - approval = null; - } return Padding( padding: EdgeInsets.only(bottom: 20.0.h()), @@ -229,10 +217,7 @@ class _LikedTendersMobilePageState extends State { viewModel.removeTenderById(item.tenderId!); } }, - child: LikedListItem( - tender: item.tender!, - approval: approval, - ), + child: LikedListItem(tender: item.tender!), ), ); } else { diff --git a/lib/views/liked_tenders/pages/liked_tenders_tablet_page.dart b/lib/views/liked_tenders/pages/liked_tenders_tablet_page.dart index b2715f4..6f98193 100644 --- a/lib/views/liked_tenders/pages/liked_tenders_tablet_page.dart +++ b/lib/views/liked_tenders/pages/liked_tenders_tablet_page.dart @@ -13,7 +13,6 @@ import 'package:tm_app/views/shared/page_selection_dialog.dart'; import 'package:tm_app/views/shared/tender_app_bar.dart'; import '../../../core/utils/app_toast.dart'; -import '../../../data/services/model/tender_approvals_data/tender_approvals_data.dart'; import '../../shared/tablet_desktop_appbar.dart'; import '../../shared/tablet_navigation_widget.dart'; import '../widgets/like_filters_bottom_sheet.dart'; @@ -231,15 +230,7 @@ class _LikedTendersTabletPageState extends State { itemCount: feedback.length, itemBuilder: (context, index) { final item = feedback[index]; - TenderApprovalsData? approval; - bool hasApproval = viewModel.hasTenderApprovalForTender( - item.tenderId!, - ); - if (hasApproval) { - approval = viewModel.getApprovalStatusForTender(item.tenderId!); - } else { - approval = null; - } + return Padding( padding: EdgeInsets.only(bottom: 20.0.h()), child: Dismissible( @@ -259,7 +250,7 @@ class _LikedTendersTabletPageState extends State { viewModel.removeTenderById(item.tenderId!); } }, - child: LikedListItem(tender: item.tender!, approval: approval), + child: LikedListItem(tender: item.tender!), ), ); }, diff --git a/lib/views/liked_tenders/widgets/liked_tenders_list_item.dart b/lib/views/liked_tenders/widgets/liked_tenders_list_item.dart index 437c697..f2da7d4 100644 --- a/lib/views/liked_tenders/widgets/liked_tenders_list_item.dart +++ b/lib/views/liked_tenders/widgets/liked_tenders_list_item.dart @@ -1,4 +1,3 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; @@ -9,21 +8,16 @@ import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/view_models/liked_tenders_view_model.dart'; import 'package:tm_app/views/home/strings/home_strings.dart'; -import '../../../core/constants/tender_submision_mode.dart'; -import '../../../data/services/model/tender_approvals_data/tender_approvals_data.dart'; +import '../../../core/utils/date_utils.dart'; import '../../shared/flag.dart'; -import '../../shared/select_submission_bottom_sheet.dart'; -import '../../shared/select_submission_dialog.dart'; class LikedListItem extends StatelessWidget { const LikedListItem({ required this.tender, - this.approval, this.isDesktop = false, super.key, }); final TenderData tender; - final TenderApprovalsData? approval; final bool isDesktop; @@ -170,100 +164,8 @@ class LikedListItem extends StatelessWidget { ? Flag(countryCode: tender.countryCode!) : const Flag(countryCode: ''), const Spacer(), - InkWell( - onTap: () { - viewModel.rejectTenderApproval( - tenderId: tender.id!, - submissionMode: TenderSubmissionMode.selfApply.value, - ); - }, - child: Container( - width: 32.0.w(), - height: 32.0.h(), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: - viewModel.isTenderRejected(tender.id!) - ? AppColors.errorColor - : AppColors.grey60, - width: 1.5.w(), - ), - ), - alignment: Alignment.center, - child: Icon( - Icons.close, - color: - viewModel.isTenderRejected(tender.id!) - ? AppColors.errorColor - : AppColors.grey60, - size: 16, - ), - ), - ), + SizedBox(width: 30.0.w()), - InkWell( - onTap: () { - if (viewModel.isTenderSubmitted(tender.id!)) { - viewModel.submitTenderApproval( - tenderId: tender.id!, - submissionMode: TenderSubmissionMode.selfApply.value, - ); - } else { - (kIsWeb && MediaQuery.sizeOf(context).width > 600) - ? showDialog( - context: context, - builder: (context) { - return SelectSubmissionDialog( - onConfirm: (value) { - viewModel.submitTenderApproval( - tenderId: tender.id!, - submissionMode: value, - ); - }, - ); - }, - ) - : showModalBottomSheet( - isDismissible: true, - context: context, - builder: (context) { - return SelectSubmissionBottomSheet( - onConfirm: (value) { - viewModel.submitTenderApproval( - tenderId: tender.id!, - submissionMode: value, - ); - }, - ); - }, - ); - } - }, - child: Container( - width: 32.0.w(), - height: 32.0.h(), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: - viewModel.isTenderSubmitted(tender.id!) - ? AppColors.successColor - : AppColors.grey60, - width: 1.5.w(), - ), - ), - alignment: Alignment.center, - child: Icon( - Icons.check, - color: - viewModel.isTenderSubmitted(tender.id!) - ? AppColors.successColor - : AppColors.grey60, - size: 16, - ), - ), - ), ], ), ], @@ -272,12 +174,3 @@ class LikedListItem extends StatelessWidget { ); } } - -String timeConvertor(int time) { - DateTime date = DateTime.fromMillisecondsSinceEpoch(time); - - String formattedDate = - "${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}"; - - return formattedDate; -} diff --git a/lib/views/tenders/pages/d_tenders_page.dart b/lib/views/tenders/pages/d_tenders_page.dart index e5bced0..3222305 100644 --- a/lib/views/tenders/pages/d_tenders_page.dart +++ b/lib/views/tenders/pages/d_tenders_page.dart @@ -37,9 +37,6 @@ class _DesktopTendersPageState extends State { if (viewModel.feedbackErrorMessage != null) { AppToast.error(context, viewModel.feedbackErrorMessage!); } - if (viewModel.tenderApprovalErrorMessage != null) { - AppToast.error(context, viewModel.tenderApprovalErrorMessage!); - } } @override diff --git a/lib/views/tenders/pages/m_tenders_page.dart b/lib/views/tenders/pages/m_tenders_page.dart index 397e4a2..4dd006d 100644 --- a/lib/views/tenders/pages/m_tenders_page.dart +++ b/lib/views/tenders/pages/m_tenders_page.dart @@ -30,9 +30,6 @@ class _MobileTendersPageState extends State { if (viewModel.feedbackErrorMessage != null) { AppToast.error(context, viewModel.feedbackErrorMessage!); } - if (viewModel.tenderApprovalErrorMessage != null) { - AppToast.error(context, viewModel.tenderApprovalErrorMessage!); - } } @override diff --git a/lib/views/tenders/widgets/main_tenders_slider.dart b/lib/views/tenders/widgets/main_tenders_slider.dart index 294c709..27e5380 100644 --- a/lib/views/tenders/widgets/main_tenders_slider.dart +++ b/lib/views/tenders/widgets/main_tenders_slider.dart @@ -76,9 +76,6 @@ class _MainTendersSliderState extends State { if (!viewModel.hasFeedbackForTender(previousTenderId)) { viewModel.getTenderFeedback(previousTenderId); } - if (!viewModel.hasTenderApprovalForTender(previousTenderId)) { - viewModel.getTenderApprovals(previousTenderId); - } } void _goToNextPage() { @@ -105,9 +102,6 @@ class _MainTendersSliderState extends State { if (!viewModel.hasFeedbackForTender(nextTenderId)) { viewModel.getTenderFeedback(nextTenderId); } - if (!viewModel.hasTenderApprovalForTender(nextTenderId)) { - viewModel.getTenderApprovals(nextTenderId); - } } @override @@ -147,9 +141,6 @@ class _MainTendersSliderState extends State { if (!viewModel.hasFeedbackForTender(id)) { viewModel.getTenderFeedback(id); } - if (!viewModel.hasTenderApprovalForTender(id)) { - viewModel.getTenderApprovals(id); - } if (index >= widget.tenders.length - 1 && viewModel.hasMoreData && diff --git a/lib/views/tenders/widgets/tender_action_buttons_row.dart b/lib/views/tenders/widgets/tender_action_buttons_row.dart index f7ee40f..1a844af 100644 --- a/lib/views/tenders/widgets/tender_action_buttons_row.dart +++ b/lib/views/tenders/widgets/tender_action_buttons_row.dart @@ -4,13 +4,9 @@ import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; import 'package:tm_app/view_models/tenders_view_model.dart'; import '../../../core/constants/assets.dart'; -import '../../../core/constants/tender_approval_status.dart'; import '../../../core/constants/tender_feedback.dart'; -import '../../../core/constants/tender_submision_mode.dart'; import '../../../core/theme/colors.dart'; import '../../../core/utils/size_config.dart'; -import '../../shared/select_submission_bottom_sheet.dart'; -import '../../shared/select_submission_dialog.dart'; import '../strings/tenders_strings.dart'; import '../widgets/animated_feedback_button.dart'; @@ -35,12 +31,7 @@ class TenderActionButtonsRow extends StatelessWidget { // Dislike button _dislikeButton(viewModel), - isDesktop ? Container() : SizedBox(width: 32.0.w()), - //reject button - isDesktop ? Container() : _rejectButton(viewModel), - isDesktop ? Container() : SizedBox(width: 32.0.w()), - //submit button - isDesktop ? Container() : _submitButton(viewModel, context), + SizedBox(width: isDesktop ? 16.0.h() : 32.0.w()), // Like button _likeButton(viewModel), @@ -50,155 +41,6 @@ class TenderActionButtonsRow extends StatelessWidget { ); } - Widget _rejectButton(TendersViewModel viewModel) { - // Find approval for this specific tender - if (tender.id == null) { - return const SizedBox.shrink(); - } - - final approval = viewModel.getTenderApprovalForTender(tender.id!); - final isRejected = approval?.status == TenderApprovalStatus.rejected.value; - - return Tooltip( - message: TendersStrings.reject, - child: InkWell( - splashColor: Colors.transparent, - onTap: () { - viewModel.toggleApprovals( - tenderId: tender.id!, - submissionMode: TenderSubmissionMode.selfApply.value, - status: TenderApprovalStatus.rejected.value, - ); - }, - child: Column( - children: [ - Container( - width: 24.0.w(), - height: 24.0.w(), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: isRejected ? AppColors.errorColor : AppColors.grey60, - width: 1.5.w(), - ), - ), - alignment: Alignment.center, - child: Icon( - Icons.close, - color: isRejected ? AppColors.errorColor : AppColors.grey60, - size: 16, - ), - ), - SizedBox(height: 8.0.h()), - if (!isDesktop) - Text( - TendersStrings.reject, - style: TextStyle( - fontSize: 12.0.sp(), - fontWeight: FontWeight.w400, - color: isRejected ? AppColors.errorColor : AppColors.grey60, - ), - ), - ], - ), - ), - ); - } - - Widget _submitButton(TendersViewModel viewModel, BuildContext context) { - // Find approval for this specific tender - if (tender.id == null) { - return const SizedBox.shrink(); - } - - final approval = viewModel.getTenderApprovalForTender(tender.id!); - final isApproved = approval?.status == TenderApprovalStatus.submitted.value; - - return Tooltip( - message: TendersStrings.submit, - child: InkWell( - splashColor: Colors.transparent, - onTap: () { - if (isApproved) { - viewModel.toggleApprovals( - tenderId: tender.id!, - submissionMode: - (approval?.submissionMode?.isNotEmpty == true) - ? approval!.submissionMode! - : TenderSubmissionMode.selfApply.value, - status: TenderApprovalStatus.submitted.value, - ); - } else { - final isMobile = MediaQuery.sizeOf(context).width < 600; - if (isMobile) { - showModalBottomSheet( - isDismissible: true, - context: context, - builder: (context) { - return SelectSubmissionBottomSheet( - onConfirm: (value) { - viewModel.toggleApprovals( - tenderId: tender.id!, - submissionMode: value, - status: TenderApprovalStatus.submitted.value, - ); - }, - ); - }, - ); - } else { - showDialog( - context: context, - builder: (context) { - return SelectSubmissionDialog( - onConfirm: (String value) { - viewModel.toggleApprovals( - tenderId: tender.id!, - submissionMode: value, - status: TenderApprovalStatus.submitted.value, - ); - }, - ); - }, - ); - } - } - }, - child: Column( - children: [ - Container( - width: 24.0.w(), - height: 24.0.w(), - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: isApproved ? AppColors.successColor : AppColors.grey60, - width: 1.5.w(), - ), - ), - alignment: Alignment.center, - child: Icon( - Icons.check, - color: isApproved ? AppColors.successColor : AppColors.grey60, - size: 16, - ), - ), - SizedBox(height: 8.0.h()), - if (!isDesktop) - Text( - TendersStrings.submit, - style: TextStyle( - fontSize: 12.0.sp(), - fontWeight: FontWeight.w400, - color: isApproved ? AppColors.successColor : AppColors.grey60, - ), - ), - ], - ), - ), - ); - } - Widget _dislikeButton(TendersViewModel viewModel) { if (tender.id == null) { return const SizedBox.shrink(); diff --git a/lib/views/tenders/widgets/tender_card.dart b/lib/views/tenders/widgets/tender_card.dart index b08424a..c0e90ed 100644 --- a/lib/views/tenders/widgets/tender_card.dart +++ b/lib/views/tenders/widgets/tender_card.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart' hide DateUtils; import 'package:flutter_svg/svg.dart'; -import 'package:provider/provider.dart'; import 'package:tm_app/core/routes/app_routes.dart'; import 'package:tm_app/data/services/model/tender_data/tender_data.dart'; @@ -8,7 +7,6 @@ import '../../../core/constants/assets.dart'; import '../../../core/theme/colors.dart'; import '../../../core/utils/date_utils.dart'; import '../../../core/utils/size_config.dart'; -import '../../../view_models/tenders_view_model.dart'; import '../../detail/strings/tender_details_strings.dart'; import '../../shared/flag.dart'; import '../strings/tenders_strings.dart'; @@ -268,13 +266,7 @@ class TenderCard extends StatelessWidget { return InkWell( onTap: () { if (tender.id != null) { - TenderDetailRouteData(tenderId: tender.id!).push(context).then(( - value, - ) { - if (context.mounted) { - context.read().getTenderApprovals(tender.id!); - } - }); + TenderDetailRouteData(tenderId: tender.id!).push(context); } }, child: Container(