removed submit and reject tender ability every where except tender details

This commit is contained in:
amirrezaghabeli
2025-09-22 11:28:12 +03:30
parent 3e87145897
commit 5b1d5d2681
15 changed files with 159 additions and 939 deletions
+3 -215
View File
@@ -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/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_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/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 '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/feedback_response/feedback_response.dart';
import '../data/services/model/request_models/tender_feedback_request_model/tender_feedback_request_model.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 { class LikedTendersViewModel with ChangeNotifier {
final LikedTendersRepository _likedTendersRepository; final LikedTendersRepository _likedTendersRepository;
@@ -30,11 +26,6 @@ class LikedTendersViewModel with ChangeNotifier {
bool hasMore = true; bool hasMore = true;
String? errorMessage; String? errorMessage;
LikedTendersResponse? data; LikedTendersResponse? data;
TenderApprovalsData? _tenderApprovalData;
TenderApprovalsData? get tenderApprovalData => _tenderApprovalData;
List<TenderApprovalsData> tenderApprovals = [];
int _offset = 0; int _offset = 0;
final int _limit = 7; final int _limit = 7;
@@ -43,10 +34,10 @@ class LikedTendersViewModel with ChangeNotifier {
// Approval status properties // Approval status properties
bool approvalStatus = false; bool approvalStatus = false;
String _status = ''; final String _status = '';
String? _errorMessage; String? _errorMessage;
bool _isSubmitApprovalLoading = false; final bool _isSubmitApprovalLoading = false;
bool _isRejectApprovalLoading = false; final bool _isRejectApprovalLoading = false;
String get status => _status; String get status => _status;
String? get approvalErrorMessage => _errorMessage; String? get approvalErrorMessage => _errorMessage;
@@ -100,10 +91,6 @@ class LikedTendersViewModel with ChangeNotifier {
final incoming = result.value; final incoming = result.value;
final incomingList = incoming.data?.feedback ?? []; final incomingList = incoming.data?.feedback ?? [];
for (var element in incomingList) {
await getTenderApproval(element.tenderId!);
}
if (reset) { if (reset) {
data = incoming; data = incoming;
} else { } else {
@@ -195,203 +182,4 @@ class LikedTendersViewModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<void> getTenderApproval(String tenderId) async {
errorMessage = null;
notifyListeners();
final result = await _tendersRepository.getTenderApprovals(
tenderId: tenderId,
);
switch (result) {
case Ok<TenderApprovalsByIdResponse>():
_tenderApprovalData = result.value.data;
tenderApprovals.add(_tenderApprovalData!);
break;
case Error<TenderApprovalsByIdResponse>():
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<void> submitTenderApproval({
required String tenderId,
required String submissionMode,
}) async {
_isSubmitApprovalLoading = true;
_errorMessage = null;
notifyListeners();
// Store original state for rollback
final originalApprovals = List<TenderApprovalsData>.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<TenderApprovalsToggleResponse>():
approvalStatus = true;
_status = result.value.data?.status ?? '';
break;
case Error<TenderApprovalsToggleResponse>():
// Rollback changes on error
tenderApprovals = originalApprovals;
_errorMessage = result.error.toString();
approvalStatus = false;
break;
}
approvalStatus = false;
_isSubmitApprovalLoading = false;
notifyListeners();
}
Future<void> rejectTenderApproval({
required String tenderId,
required String submissionMode,
}) async {
_isRejectApprovalLoading = true;
_errorMessage = null;
notifyListeners();
// Store original state for rollback
final originalApprovals = List<TenderApprovalsData>.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<TenderApprovalsToggleResponse>():
approvalStatus = true;
_status = result.value.data?.status ?? '';
break;
case Error<TenderApprovalsToggleResponse>():
// Rollback changes on error
tenderApprovals = originalApprovals;
_errorMessage = result.error.toString();
approvalStatus = false;
break;
}
approvalStatus = false;
_isRejectApprovalLoading = false;
notifyListeners();
}
} }
@@ -15,7 +15,6 @@ import 'tenders_view_model.dart';
class TenderDetailViewModel with ChangeNotifier { class TenderDetailViewModel with ChangeNotifier {
final TenderDetailRepository _tenderDetailRepository; final TenderDetailRepository _tenderDetailRepository;
final TendersRepository _tendersRepository; final TendersRepository _tendersRepository;
final TendersViewModel _tendersViewModel;
final HomeViewModel _homeViewModel; final HomeViewModel _homeViewModel;
TenderDetailViewModel({ TenderDetailViewModel({
@@ -25,7 +24,7 @@ class TenderDetailViewModel with ChangeNotifier {
required HomeViewModel homeViewModel, required HomeViewModel homeViewModel,
}) : _tenderDetailRepository = tenderDetailRepository, }) : _tenderDetailRepository = tenderDetailRepository,
_tendersRepository = tendersRepository, _tendersRepository = tendersRepository,
_tendersViewModel = tendersViewModel,
_homeViewModel = homeViewModel; _homeViewModel = homeViewModel;
bool _isLoading = false; bool _isLoading = false;
@@ -123,10 +122,6 @@ class TenderDetailViewModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void updateTenderApprovals(String tenderId) {
_tendersViewModel.getTenderApprovals(tenderId);
}
void updateHome() async { void updateHome() async {
_homeViewModel.init(); _homeViewModel.init();
} }
+5 -207
View File
@@ -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/repositories/tenders_repository.dart';
import 'package:tm_app/data/services/model/feedback_data/feedback_data.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/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 '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 '../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'; import 'home_view_model.dart';
class TendersViewModel with ChangeNotifier { class TendersViewModel with ChangeNotifier {
final TendersRepository _tendersRepository; final TendersRepository _tendersRepository;
final HomeViewModel _homeViewModel;
TendersViewModel({ TendersViewModel({
required TendersRepository tendersRepository, required TendersRepository tendersRepository,
required HomeViewModel homeViewModel, required HomeViewModel homeViewModel,
}) : _tendersRepository = tendersRepository, }) : _tendersRepository = tendersRepository;
_homeViewModel = homeViewModel;
bool _isLoading = false; bool _isLoading = false;
bool _isLoadingMore = false; bool _isLoadingMore = false;
String? _errorMessage; String? _errorMessage;
String? _feedbackErrorMessage; String? _feedbackErrorMessage;
String? _tenderApprovalErrorMessage;
TendersResponse? _tendersResponse; TendersResponse? _tendersResponse;
FeedbackData? _feedbackData; FeedbackData? _feedbackData;
TenderApprovalsData? _tenderApprovalData;
TenderApprovalsToggleData? _tenderApprovalToggleData;
String? _searchQuery; String? _searchQuery;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
bool get isLoadingMore => _isLoadingMore; bool get isLoadingMore => _isLoadingMore;
String? get errorMessage => _errorMessage; String? get errorMessage => _errorMessage;
String? get feedbackErrorMessage => _feedbackErrorMessage; String? get feedbackErrorMessage => _feedbackErrorMessage;
String? get tenderApprovalErrorMessage => _tenderApprovalErrorMessage;
TendersResponse? get tendersResponse => _tendersResponse; TendersResponse? get tendersResponse => _tendersResponse;
FeedbackData? get feedbackData => _feedbackData; FeedbackData? get feedbackData => _feedbackData;
TenderApprovalsData? get tenderApprovalData => _tenderApprovalData;
TenderApprovalsToggleData? get tenderApprovalToggleData =>
_tenderApprovalToggleData;
String? get searchQuery => _searchQuery; String? get searchQuery => _searchQuery;
List<FeedbackData> feedbacks = []; List<FeedbackData> feedbacks = [];
List<TenderApprovalsData> tenderApprovals = [];
int currentPage = 1; int currentPage = 1;
int _currentOffset = 0; int _currentOffset = 0;
@@ -74,27 +61,9 @@ class TendersViewModel with ChangeNotifier {
return feedbacks.any((f) => f.tender == tenderId); 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<void> getTenders({String? query, BuildContext? context}) async { Future<void> getTenders({String? query, BuildContext? context}) async {
_isLoading = true;
notifyListeners();
if (context != null && DeviceUtils.isDesktop(context)) { if (context != null && DeviceUtils.isDesktop(context)) {
await getTendersDesktop(query: query); await getTendersDesktop(query: query);
} else { } else {
@@ -103,8 +72,6 @@ class TendersViewModel with ChangeNotifier {
} }
Future<void> getTendersMobile({String? query}) async { Future<void> getTendersMobile({String? query}) async {
_isLoading = true;
notifyListeners();
clearAll(); // Clear all data before fetching new tenders clearAll(); // Clear all data before fetching new tenders
_currentOffset = 0; _currentOffset = 0;
@@ -126,7 +93,6 @@ class TendersViewModel with ChangeNotifier {
if (_tendersResponse?.data?.tenders?.isNotEmpty == true) { if (_tendersResponse?.data?.tenders?.isNotEmpty == true) {
// Fetch feedback and approvals for the first tender only // Fetch feedback and approvals for the first tender only
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!); getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
getTenderApprovals(_tendersResponse!.data!.tenders!.first.id!);
} }
if (_tendersResponse?.meta?.pages != null) { if (_tendersResponse?.meta?.pages != null) {
_totalPages = _tendersResponse!.meta!.pages!; _totalPages = _tendersResponse!.meta!.pages!;
@@ -146,8 +112,6 @@ class TendersViewModel with ChangeNotifier {
} }
Future<void> getTendersDesktop({String? query}) async { Future<void> getTendersDesktop({String? query}) async {
_isLoading = true;
notifyListeners();
clearAll(); // Clear all data before fetching new tenders clearAll(); // Clear all data before fetching new tenders
_currentOffset = 0; _currentOffset = 0;
@@ -167,9 +131,6 @@ class TendersViewModel with ChangeNotifier {
_hasMoreData = _tendersResponse!.data!.tenders!.length >= _pageSize; _hasMoreData = _tendersResponse!.data!.tenders!.length >= _pageSize;
} }
if (_tendersResponse?.data?.tenders?.isNotEmpty == true) { 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!) { for (var tender in _tendersResponse!.data!.tenders!) {
getTenderFeedback(tender.id!); getTenderFeedback(tender.id!);
} }
@@ -278,47 +239,6 @@ class TendersViewModel with ChangeNotifier {
notifyListeners(); 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;
// 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<TenderApprovalsByIdResponse>():
// 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<void> toogleFeedback({ Future<void> toogleFeedback({
required String tenderId, required String tenderId,
required String feedbackType, required String feedbackType,
@@ -418,124 +338,6 @@ class TendersViewModel with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<void> 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<TenderApprovalsToggleResponse>():
_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<TenderApprovalsToggleResponse>():
// 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 /// Clear all feedbacks
void clearFeedbacks() { void clearFeedbacks() {
feedbacks.clear(); feedbacks.clear();
@@ -567,10 +369,6 @@ class TendersViewModel with ChangeNotifier {
void clearAll() { void clearAll() {
clearTenders(); clearTenders();
clearFeedbacks(); clearFeedbacks();
tenderApprovals.clear();
_tenderApprovalData = null;
_tenderApprovalToggleData = null;
_tenderApprovalErrorMessage = null;
_searchQuery = null; _searchQuery = null;
notifyListeners(); notifyListeners();
} }
+51 -60
View File
@@ -77,74 +77,65 @@ class _TenderDetailDesktopPageState extends State<TenderDetailDesktopPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopScope( return Scaffold(
onPopInvokedWithResult: (didPop, result) { backgroundColor: AppColors.backgroundColor,
WidgetsBinding.instance.addPostFrameCallback((_) { body: Consumer<TenderDetailViewModel>(
viewModel.updateTenderApprovals(widget.tenderId); builder: (context, tenderViewModel, child) {
}); if (tenderViewModel.isLoading) {
}, return const Center(
child: Scaffold( child: CircularProgressIndicator(color: AppColors.secondary50),
backgroundColor: AppColors.backgroundColor, );
body: Consumer<TenderDetailViewModel>( }
builder: (context, tenderViewModel, child) {
if (tenderViewModel.isLoading) {
return const Center(
child: CircularProgressIndicator(color: AppColors.secondary50),
);
}
if (tenderViewModel.errorMessage != null) { if (tenderViewModel.errorMessage != null) {
return Center(child: Text(tenderViewModel.errorMessage!)); return Center(child: Text(tenderViewModel.errorMessage!));
} }
final detail = tenderViewModel.tenderDetail; final detail = tenderViewModel.tenderDetail;
if (detail == null) { if (detail == null) {
return const Center( return const Center(child: Text(TenderDetailsStrings.tenderNoData));
child: Text(TenderDetailsStrings.tenderNoData), }
);
}
return Column( return Column(
children: [ children: [
const DesktopNavigationWidget( const DesktopNavigationWidget(
currentIndex: 1, // Home index currentIndex: 1, // Home index
), ),
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Center( child: Center(
child: SizedBox( child: SizedBox(
width: 740, width: 740,
child: Padding( child: Padding(
padding: const EdgeInsets.all(32.0), padding: const EdgeInsets.all(32.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const TabletDesktopAppbar( const TabletDesktopAppbar(
title: TenderDetailsStrings.tenderDetailTitle, title: TenderDetailsStrings.tenderDetailTitle,
), ),
SizedBox(height: 32.0.h()), SizedBox(height: 32.0.h()),
TenderDetailHeader( TenderDetailHeader(
isScreenBig: true, isScreenBig: true,
detail: detail, detail: detail,
), ),
SizedBox(height: 32.0.h()), SizedBox(height: 32.0.h()),
TenderDetailCard(detail: detail), TenderDetailCard(detail: detail),
SizedBox(height: 24.0.h()), SizedBox(height: 24.0.h()),
TenderDetailActions( TenderDetailActions(
isScreenBig: true, isScreenBig: true,
detail: detail, detail: detail,
), ),
], ],
),
), ),
), ),
), ),
), ),
), ),
], ),
); ],
}, );
), },
), ),
); );
} }
+45 -59
View File
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/core/theme/colors.dart';
@@ -76,65 +75,52 @@ class _TenderDetailMobilePageState extends State<TenderDetailMobilePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return PopScope( return Directionality(
onPopInvokedWithResult: (didPop, result) { textDirection: TextDirection.rtl,
if (kIsWeb) { child: Scaffold(
WidgetsBinding.instance.addPostFrameCallback((_) { backgroundColor: AppColors.backgroundColor,
context.read<TenderDetailViewModel>().updateTenderApprovals( appBar: appBar(
widget.tenderId, context: context,
); title: TenderDetailsStrings.tenderDetailTitle,
}); ),
} body: Consumer<TenderDetailViewModel>(
}, builder: (context, tenderViewModel, child) {
child: Directionality( if (tenderViewModel.isLoading) {
textDirection: TextDirection.rtl, return const Center(
child: Scaffold( child: CircularProgressIndicator(color: AppColors.secondary50),
backgroundColor: AppColors.backgroundColor,
appBar: appBar(
context: context,
title: TenderDetailsStrings.tenderDetailTitle,
),
body: Consumer<TenderDetailViewModel>(
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),
],
),
),
); );
}, }
),
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),
],
),
),
);
},
), ),
), ),
); );
+45 -58
View File
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/core/theme/colors.dart';
@@ -79,70 +78,58 @@ class _TenderDetailTabletPageState extends State<TenderDetailTabletPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final GlobalKey<ScaffoldState> key = GlobalKey(); final GlobalKey<ScaffoldState> key = GlobalKey();
return PopScope( return Scaffold(
onPopInvokedWithResult: (didPop, result) { backgroundColor: AppColors.backgroundColor,
if (kIsWeb) { appBar: tabletAppBar(
WidgetsBinding.instance.addPostFrameCallback((_) { title: TenderDetailsStrings.tenderDetailTitle,
viewModel.updateTenderApprovals(widget.tenderId); key: key,
}); ),
}
},
key: key,
child: Scaffold(
backgroundColor: AppColors.backgroundColor,
appBar: tabletAppBar(
title: TenderDetailsStrings.tenderDetailTitle,
key: key,
),
drawer: const TabletNavigationWidget( drawer: const TabletNavigationWidget(
currentIndex: 1, // Home is index 0 currentIndex: 1, // Home is index 0
), ),
body: Consumer<TenderDetailViewModel>( body: Consumer<TenderDetailViewModel>(
builder: (context, tenderViewModel, child) { builder: (context, tenderViewModel, child) {
if (tenderViewModel.isLoading) { if (tenderViewModel.isLoading) {
return const Center( return const Center(
child: CircularProgressIndicator(color: AppColors.secondary50), child: CircularProgressIndicator(color: AppColors.secondary50),
); );
} }
if (tenderViewModel.errorMessage != null) { if (tenderViewModel.errorMessage != null) {
return Center(child: Text(tenderViewModel.errorMessage!)); return Center(child: Text(tenderViewModel.errorMessage!));
} }
final detail = tenderViewModel.tenderDetail; final detail = tenderViewModel.tenderDetail;
if (detail == null) { if (detail == null) {
return const Center( return const Center(child: Text(TenderDetailsStrings.tenderNoData));
child: Text(TenderDetailsStrings.tenderNoData), }
); return SingleChildScrollView(
} child: Center(
return SingleChildScrollView( child: SizedBox(
child: Center( width: 768,
child: SizedBox(
width: 768,
child: Padding( child: Padding(
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.all(24.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const TabletDesktopAppbar( const TabletDesktopAppbar(
title: TenderDetailsStrings.tenderDetailTitle, title: TenderDetailsStrings.tenderDetailTitle,
), ),
SizedBox(height: 28.0.h()), SizedBox(height: 28.0.h()),
TenderDetailHeader(isScreenBig: true, detail: detail), TenderDetailHeader(isScreenBig: true, detail: detail),
SizedBox(height: 28.0.h()), SizedBox(height: 28.0.h()),
TenderDetailCard(detail: detail), TenderDetailCard(detail: detail),
SizedBox(height: 24.0.h()), SizedBox(height: 24.0.h()),
TenderDetailActions(isScreenBig: true, detail: detail), TenderDetailActions(isScreenBig: true, detail: detail),
], ],
),
), ),
), ),
), ),
); ),
}, );
), },
), ),
); );
} }
@@ -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/theme/colors.dart';
import 'package:tm_app/core/utils/size_config.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/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/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/liked_tenders/widgets/liked_tenders_list_item.dart';
import 'package:tm_app/views/shared/page_selection_dialog.dart'; import 'package:tm_app/views/shared/page_selection_dialog.dart';
@@ -216,15 +215,7 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
itemCount: feedback.length, itemCount: feedback.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = feedback[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( return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()), padding: EdgeInsets.only(bottom: 20.0.h()),
child: Dismissible( child: Dismissible(
@@ -240,11 +231,7 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
viewModel.removeTenderById(item.tenderId!); viewModel.removeTenderById(item.tenderId!);
} }
}, },
child: LikedListItem( child: LikedListItem(tender: item.tender!, isDesktop: true),
tender: item.tender!,
approval: approval,
isDesktop: true,
),
), ),
); );
}, },
@@ -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/theme/colors.dart';
import 'package:tm_app/core/utils/app_toast.dart'; import 'package:tm_app/core/utils/app_toast.dart';
import 'package:tm_app/core/utils/size_config.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/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/strings/liked_tenders_strings.dart';
import 'package:tm_app/views/liked_tenders/widgets/liked_tenders_list_item.dart'; import 'package:tm_app/views/liked_tenders/widgets/liked_tenders_list_item.dart';
@@ -196,17 +195,6 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index < feedback.length) { if (index < feedback.length) {
final item = feedback[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( return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()), padding: EdgeInsets.only(bottom: 20.0.h()),
@@ -229,10 +217,7 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
viewModel.removeTenderById(item.tenderId!); viewModel.removeTenderById(item.tenderId!);
} }
}, },
child: LikedListItem( child: LikedListItem(tender: item.tender!),
tender: item.tender!,
approval: approval,
),
), ),
); );
} else { } else {
@@ -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 'package:tm_app/views/shared/tender_app_bar.dart';
import '../../../core/utils/app_toast.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_desktop_appbar.dart';
import '../../shared/tablet_navigation_widget.dart'; import '../../shared/tablet_navigation_widget.dart';
import '../widgets/like_filters_bottom_sheet.dart'; import '../widgets/like_filters_bottom_sheet.dart';
@@ -231,15 +230,7 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
itemCount: feedback.length, itemCount: feedback.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = feedback[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( return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()), padding: EdgeInsets.only(bottom: 20.0.h()),
child: Dismissible( child: Dismissible(
@@ -259,7 +250,7 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
viewModel.removeTenderById(item.tenderId!); viewModel.removeTenderById(item.tenderId!);
} }
}, },
child: LikedListItem(tender: item.tender!, approval: approval), child: LikedListItem(tender: item.tender!),
), ),
); );
}, },
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.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/view_models/liked_tenders_view_model.dart';
import 'package:tm_app/views/home/strings/home_strings.dart'; import 'package:tm_app/views/home/strings/home_strings.dart';
import '../../../core/constants/tender_submision_mode.dart'; import '../../../core/utils/date_utils.dart';
import '../../../data/services/model/tender_approvals_data/tender_approvals_data.dart';
import '../../shared/flag.dart'; import '../../shared/flag.dart';
import '../../shared/select_submission_bottom_sheet.dart';
import '../../shared/select_submission_dialog.dart';
class LikedListItem extends StatelessWidget { class LikedListItem extends StatelessWidget {
const LikedListItem({ const LikedListItem({
required this.tender, required this.tender,
this.approval,
this.isDesktop = false, this.isDesktop = false,
super.key, super.key,
}); });
final TenderData tender; final TenderData tender;
final TenderApprovalsData? approval;
final bool isDesktop; final bool isDesktop;
@@ -170,100 +164,8 @@ class LikedListItem extends StatelessWidget {
? Flag(countryCode: tender.countryCode!) ? Flag(countryCode: tender.countryCode!)
: const Flag(countryCode: ''), : const Flag(countryCode: ''),
const Spacer(), 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()), 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;
}
@@ -37,9 +37,6 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
if (viewModel.feedbackErrorMessage != null) { if (viewModel.feedbackErrorMessage != null) {
AppToast.error(context, viewModel.feedbackErrorMessage!); AppToast.error(context, viewModel.feedbackErrorMessage!);
} }
if (viewModel.tenderApprovalErrorMessage != null) {
AppToast.error(context, viewModel.tenderApprovalErrorMessage!);
}
} }
@override @override
@@ -30,9 +30,6 @@ class _MobileTendersPageState extends State<MobileTendersPage> {
if (viewModel.feedbackErrorMessage != null) { if (viewModel.feedbackErrorMessage != null) {
AppToast.error(context, viewModel.feedbackErrorMessage!); AppToast.error(context, viewModel.feedbackErrorMessage!);
} }
if (viewModel.tenderApprovalErrorMessage != null) {
AppToast.error(context, viewModel.tenderApprovalErrorMessage!);
}
} }
@override @override
@@ -76,9 +76,6 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
if (!viewModel.hasFeedbackForTender(previousTenderId)) { if (!viewModel.hasFeedbackForTender(previousTenderId)) {
viewModel.getTenderFeedback(previousTenderId); viewModel.getTenderFeedback(previousTenderId);
} }
if (!viewModel.hasTenderApprovalForTender(previousTenderId)) {
viewModel.getTenderApprovals(previousTenderId);
}
} }
void _goToNextPage() { void _goToNextPage() {
@@ -105,9 +102,6 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
if (!viewModel.hasFeedbackForTender(nextTenderId)) { if (!viewModel.hasFeedbackForTender(nextTenderId)) {
viewModel.getTenderFeedback(nextTenderId); viewModel.getTenderFeedback(nextTenderId);
} }
if (!viewModel.hasTenderApprovalForTender(nextTenderId)) {
viewModel.getTenderApprovals(nextTenderId);
}
} }
@override @override
@@ -147,9 +141,6 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
if (!viewModel.hasFeedbackForTender(id)) { if (!viewModel.hasFeedbackForTender(id)) {
viewModel.getTenderFeedback(id); viewModel.getTenderFeedback(id);
} }
if (!viewModel.hasTenderApprovalForTender(id)) {
viewModel.getTenderApprovals(id);
}
if (index >= widget.tenders.length - 1 && if (index >= widget.tenders.length - 1 &&
viewModel.hasMoreData && viewModel.hasMoreData &&
@@ -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 'package:tm_app/view_models/tenders_view_model.dart';
import '../../../core/constants/assets.dart'; import '../../../core/constants/assets.dart';
import '../../../core/constants/tender_approval_status.dart';
import '../../../core/constants/tender_feedback.dart'; import '../../../core/constants/tender_feedback.dart';
import '../../../core/constants/tender_submision_mode.dart';
import '../../../core/theme/colors.dart'; import '../../../core/theme/colors.dart';
import '../../../core/utils/size_config.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 '../strings/tenders_strings.dart';
import '../widgets/animated_feedback_button.dart'; import '../widgets/animated_feedback_button.dart';
@@ -35,12 +31,7 @@ class TenderActionButtonsRow extends StatelessWidget {
// Dislike button // Dislike button
_dislikeButton(viewModel), _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()), SizedBox(width: isDesktop ? 16.0.h() : 32.0.w()),
// Like button // Like button
_likeButton(viewModel), _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) { Widget _dislikeButton(TendersViewModel viewModel) {
if (tender.id == null) { if (tender.id == null) {
return const SizedBox.shrink(); return const SizedBox.shrink();
+1 -9
View File
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart' hide DateUtils; import 'package:flutter/material.dart' hide DateUtils;
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/routes/app_routes.dart'; import 'package:tm_app/core/routes/app_routes.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';
@@ -8,7 +7,6 @@ import '../../../core/constants/assets.dart';
import '../../../core/theme/colors.dart'; import '../../../core/theme/colors.dart';
import '../../../core/utils/date_utils.dart'; import '../../../core/utils/date_utils.dart';
import '../../../core/utils/size_config.dart'; import '../../../core/utils/size_config.dart';
import '../../../view_models/tenders_view_model.dart';
import '../../detail/strings/tender_details_strings.dart'; import '../../detail/strings/tender_details_strings.dart';
import '../../shared/flag.dart'; import '../../shared/flag.dart';
import '../strings/tenders_strings.dart'; import '../strings/tenders_strings.dart';
@@ -268,13 +266,7 @@ class TenderCard extends StatelessWidget {
return InkWell( return InkWell(
onTap: () { onTap: () {
if (tender.id != null) { if (tender.id != null) {
TenderDetailRouteData(tenderId: tender.id!).push(context).then(( TenderDetailRouteData(tenderId: tender.id!).push(context);
value,
) {
if (context.mounted) {
context.read<TendersViewModel>().getTenderApprovals(tender.id!);
}
});
} }
}, },
child: Container( child: Container(