some changes and fixes
This commit is contained in:
@@ -122,6 +122,7 @@ List<SingleChildWidget> get viewModels {
|
|||||||
(context) => LikedTendersViewModel(
|
(context) => LikedTendersViewModel(
|
||||||
likedTendersRepository: context.read(),
|
likedTendersRepository: context.read(),
|
||||||
tendersRepository: context.read(),
|
tendersRepository: context.read(),
|
||||||
|
homeViewModel: context.read(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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/data/services/model/tender_approvals_toggle_response/tender_approvals_toggle_response.dart';
|
||||||
|
import 'package:tm_app/view_models/home_view_model.dart';
|
||||||
|
|
||||||
import '../data/services/model/feedback_response/feedback_response.dart';
|
import '../data/services/model/feedback_response/feedback_response.dart';
|
||||||
import '../data/services/model/tender_approvals_by_id_response/tender_approvals_by_id_response.dart';
|
import '../data/services/model/tender_approvals_by_id_response/tender_approvals_by_id_response.dart';
|
||||||
@@ -13,10 +14,13 @@ 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;
|
||||||
final TendersRepository _tendersRepository;
|
final TendersRepository _tendersRepository;
|
||||||
|
final HomeViewModel _homeViewModel;
|
||||||
LikedTendersViewModel({
|
LikedTendersViewModel({
|
||||||
required LikedTendersRepository likedTendersRepository,
|
required LikedTendersRepository likedTendersRepository,
|
||||||
required TendersRepository tendersRepository,
|
required TendersRepository tendersRepository,
|
||||||
|
required HomeViewModel homeViewModel,
|
||||||
}) : _likedTendersRepository = likedTendersRepository,
|
}) : _likedTendersRepository = likedTendersRepository,
|
||||||
|
_homeViewModel = homeViewModel,
|
||||||
_tendersRepository = tendersRepository;
|
_tendersRepository = tendersRepository;
|
||||||
|
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
@@ -47,6 +51,10 @@ class LikedTendersViewModel with ChangeNotifier {
|
|||||||
bool get isSubmitApprovalLoading => _isSubmitApprovalLoading;
|
bool get isSubmitApprovalLoading => _isSubmitApprovalLoading;
|
||||||
bool get isRejectApprovalLoading => _isRejectApprovalLoading;
|
bool get isRejectApprovalLoading => _isRejectApprovalLoading;
|
||||||
|
|
||||||
|
void updateHome() {
|
||||||
|
_homeViewModel.init();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> getLikedTenders({bool reset = false}) async {
|
Future<void> getLikedTenders({bool reset = false}) async {
|
||||||
if (!reset && (isLoadingMore || !hasMore)) {
|
if (!reset && (isLoadingMore || !hasMore)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import 'package:tm_app/views/detail/widgets/tender_detail_action.dart';
|
|||||||
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
||||||
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
||||||
|
|
||||||
import '../../../core/routes/app_routes.dart';
|
|
||||||
import '../../shared/desktop_navigation_widget.dart';
|
import '../../shared/desktop_navigation_widget.dart';
|
||||||
import '../strings/tender_details_strings.dart';
|
import '../strings/tender_details_strings.dart';
|
||||||
|
|
||||||
@@ -115,27 +114,6 @@ class _TenderDetailDesktopPageState extends State<TenderDetailDesktopPage> {
|
|||||||
children: [
|
children: [
|
||||||
DesktopNavigationWidget(
|
DesktopNavigationWidget(
|
||||||
currentIndex: 1, // Home index
|
currentIndex: 1, // Home index
|
||||||
onTabChanged: (index) {
|
|
||||||
// Navigate to different screens based on index
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => HomeRouteData().go(context),
|
|
||||||
);
|
|
||||||
viewModel.updateHome();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Navigate to profile
|
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => ProfileRouteData().go(context),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.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';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
@@ -10,7 +9,6 @@ import 'package:tm_app/views/detail/widgets/tender_detail_card.dart';
|
|||||||
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
import 'package:tm_app/views/detail/widgets/tender_detail_header.dart';
|
||||||
import 'package:tm_app/views/shared/tablet_navigation_widget.dart';
|
import 'package:tm_app/views/shared/tablet_navigation_widget.dart';
|
||||||
|
|
||||||
import '../../../core/routes/app_routes.dart';
|
|
||||||
import '../../shared/tender_app_bar.dart';
|
import '../../shared/tender_app_bar.dart';
|
||||||
import '../strings/tender_details_strings.dart';
|
import '../strings/tender_details_strings.dart';
|
||||||
|
|
||||||
@@ -105,22 +103,6 @@ class _TenderDetailTabletPageState extends State<TenderDetailTabletPage> {
|
|||||||
|
|
||||||
drawer: TabletNavigationWidget(
|
drawer: TabletNavigationWidget(
|
||||||
currentIndex: 1, // Home is index 0
|
currentIndex: 1, // Home is index 0
|
||||||
onTabChanged: (index) {
|
|
||||||
// Handle navigation to other tabs
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
|
||||||
viewModel.updateHome();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Navigate to profile
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
body: Consumer<TenderDetailViewModel>(
|
body: Consumer<TenderDetailViewModel>(
|
||||||
builder: (context, tenderViewModel, child) {
|
builder: (context, tenderViewModel, child) {
|
||||||
|
|||||||
@@ -162,19 +162,33 @@ class TenderDetailActions extends StatelessWidget {
|
|||||||
submissionMode: 'self-apply',
|
submissionMode: 'self-apply',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
showDialog(
|
(MediaQuery.sizeOf(context).width > 600)
|
||||||
context: context,
|
? showDialog(
|
||||||
builder: (context) {
|
context: context,
|
||||||
return SelectSubmissionDialog(
|
builder: (context) {
|
||||||
onConfirm: (String value) {
|
return SelectSubmissionDialog(
|
||||||
viewModel.submitTenderApproval(
|
onConfirm: (String value) {
|
||||||
tenderId: detail.id!,
|
viewModel.submitTenderApproval(
|
||||||
submissionMode: value,
|
tenderId: detail.id!,
|
||||||
|
submissionMode: value,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return SelectSubmissionBottomSheet(
|
||||||
|
onConfirm: (String value) {
|
||||||
|
viewModel.submitTenderApproval(
|
||||||
|
tenderId: detail.id!,
|
||||||
|
submissionMode: value,
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
width: 120.0.w(),
|
width: 120.0.w(),
|
||||||
|
|||||||
@@ -31,66 +31,35 @@ class DesktopHomePage extends StatelessWidget {
|
|||||||
if (homeViewModel.tenderApprovalsStateResponse != null &&
|
if (homeViewModel.tenderApprovalsStateResponse != null &&
|
||||||
homeViewModel.data != null &&
|
homeViewModel.data != null &&
|
||||||
homeViewModel.feedbackStats != null) {
|
homeViewModel.feedbackStats != null) {
|
||||||
return Column(
|
return SingleChildScrollView(
|
||||||
children: [
|
child: Column(
|
||||||
DesktopNavigationWidget(
|
children: [
|
||||||
currentIndex: 0, // Home index
|
DesktopNavigationWidget(
|
||||||
onTabChanged: (index) {
|
currentIndex: 0, // Home index
|
||||||
// Navigate to different screens based on index
|
),
|
||||||
switch (index) {
|
SizedBox(
|
||||||
case 0:
|
width: 780,
|
||||||
// Already on home
|
child: Column(
|
||||||
break;
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
case 1:
|
children: [
|
||||||
// Navigate to tenders
|
SizedBox(height: 55),
|
||||||
Router.neglect(
|
// SizedBox(width: 780, child: NotificationCard()),
|
||||||
context,
|
SizedBox(height: 40.0),
|
||||||
() => TendersRouteData().go(context),
|
_progressBarsRow(homeViewModel),
|
||||||
);
|
SizedBox(height: 32.0.h()),
|
||||||
break;
|
Padding(
|
||||||
case 2:
|
padding: EdgeInsets.symmetric(horizontal: 15.0.w()),
|
||||||
// Navigate to profile
|
child: _firstTenderCardsRow(context, homeViewModel),
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => ProfileRouteData().go(context),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 780,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(height: 55),
|
|
||||||
// SizedBox(width: 780, child: NotificationCard()),
|
|
||||||
SizedBox(height: 40.0),
|
|
||||||
_progressBarsRow(homeViewModel),
|
|
||||||
SizedBox(height: 32.0.h()),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 15.0.w(),
|
|
||||||
),
|
|
||||||
child: _firstTenderCardsRow(
|
|
||||||
context,
|
|
||||||
homeViewModel,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(height: 32.0.h()),
|
|
||||||
_yourTenderText(homeViewModel),
|
|
||||||
SizedBox(height: 8.0.h()),
|
|
||||||
_bottomListView(homeViewModel),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
SizedBox(height: 32.0.h()),
|
||||||
|
_yourTenderText(homeViewModel),
|
||||||
|
SizedBox(height: 8.0.h()),
|
||||||
|
_bottomListView(homeViewModel),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return const Center(
|
return const Center(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:provider/provider.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/core/theme/colors.dart';
|
import 'package:tm_app/core/theme/colors.dart';
|
||||||
@@ -27,24 +26,6 @@ class TabletHomePage extends StatelessWidget {
|
|||||||
|
|
||||||
drawer: TabletNavigationWidget(
|
drawer: TabletNavigationWidget(
|
||||||
currentIndex: 0, // Home is index 0
|
currentIndex: 0, // Home is index 0
|
||||||
onTabChanged: (index) {
|
|
||||||
// Handle navigation to other tabs
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
// Already on home
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Navigate to tenders
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => TendersRouteData().go(context));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Navigate to profile
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
body: Consumer<HomeViewModel>(
|
body: Consumer<HomeViewModel>(
|
||||||
builder: (context, homeViewModel, child) {
|
builder: (context, homeViewModel, child) {
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import 'package:tm_app/data/services/model/tender_approvals_data/tender_approval
|
|||||||
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 '../../../core/routes/app_routes.dart';
|
|
||||||
import '../../shared/desktop_navigation_widget.dart';
|
import '../../shared/desktop_navigation_widget.dart';
|
||||||
|
import '../strings/liked_tenders_strings.dart';
|
||||||
|
|
||||||
class LikedTendersDesktopPage extends StatefulWidget {
|
class LikedTendersDesktopPage extends StatefulWidget {
|
||||||
const LikedTendersDesktopPage({super.key});
|
const LikedTendersDesktopPage({super.key});
|
||||||
@@ -20,220 +20,221 @@ class LikedTendersDesktopPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
|
class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
|
||||||
|
late final LikedTendersViewModel viewModel;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
viewModel = context.read<LikedTendersViewModel>();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
backgroundColor: AppColors.backgroundColor,
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
body: Column(
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
children: [
|
viewModel.updateHome();
|
||||||
DesktopNavigationWidget(
|
});
|
||||||
currentIndex: 1,
|
},
|
||||||
onTabChanged: (index) {
|
child: Scaffold(
|
||||||
switch (index) {
|
backgroundColor: AppColors.backgroundColor,
|
||||||
case 0:
|
body: Column(
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
children: [
|
||||||
break;
|
DesktopNavigationWidget(currentIndex: 1),
|
||||||
case 1:
|
Expanded(
|
||||||
break;
|
child: SizedBox(
|
||||||
case 2:
|
width: 740,
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
child: Consumer<LikedTendersViewModel>(
|
||||||
break;
|
builder: (context, viewModel, child) {
|
||||||
}
|
if (viewModel.isLoading &&
|
||||||
},
|
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
||||||
),
|
return const Center(
|
||||||
Expanded(
|
child: CircularProgressIndicator(
|
||||||
child: SizedBox(
|
color: AppColors.secondary50,
|
||||||
width: 740,
|
),
|
||||||
child: Consumer<LikedTendersViewModel>(
|
);
|
||||||
builder: (context, viewModel, child) {
|
}
|
||||||
if (viewModel.isLoading &&
|
|
||||||
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: AppColors.secondary50,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewModel.errorMessage != null) {
|
if (viewModel.errorMessage != null) {
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
return Center(child: Text(viewModel.errorMessage!));
|
||||||
}
|
}
|
||||||
|
|
||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: Text('You haven’t liked any tenders yet.'),
|
child: Text(LikedTendersStrings.noLikedTenders),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final currentPage = viewModel.currentPage;
|
final currentPage = viewModel.currentPage;
|
||||||
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
|
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await viewModel.getLikedTenders(reset: true);
|
await viewModel.getLikedTenders(reset: true);
|
||||||
},
|
},
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.0.w(),
|
horizontal: 24.0.w(),
|
||||||
vertical: 15.0.h(),
|
vertical: 15.0.h(),
|
||||||
),
|
),
|
||||||
itemCount: feedback.length,
|
itemCount: feedback.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = feedback[index];
|
final item = feedback[index];
|
||||||
TenderApprovalsData? approval;
|
TenderApprovalsData? approval;
|
||||||
bool hasApproval = viewModel
|
bool hasApproval = viewModel
|
||||||
.hasTenderApprovalForTender(item.tenderId!);
|
.hasTenderApprovalForTender(item.tenderId!);
|
||||||
if (hasApproval) {
|
if (hasApproval) {
|
||||||
approval = viewModel.getApprovalStatusForTender(
|
approval = viewModel
|
||||||
item.tenderId!,
|
.getApprovalStatusForTender(
|
||||||
);
|
|
||||||
} else {
|
|
||||||
approval = null;
|
|
||||||
}
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 20.0.h()),
|
|
||||||
child: Dismissible(
|
|
||||||
key: ValueKey(item.tenderId ?? index),
|
|
||||||
direction: DismissDirection.endToStart,
|
|
||||||
background: Container(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 20.0.w(),
|
|
||||||
),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
AssetsManager.trash,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onDismissed: (_) {
|
|
||||||
if (item.tenderId != null) {
|
|
||||||
viewModel.removeTenderById(
|
|
||||||
item.tenderId!,
|
item.tenderId!,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
},
|
approval = null;
|
||||||
child: LikedListItem(
|
}
|
||||||
tender: item.tender!,
|
return Padding(
|
||||||
approval: approval,
|
padding: EdgeInsets.only(bottom: 20.0.h()),
|
||||||
isDesktop: true,
|
child: Dismissible(
|
||||||
),
|
key: ValueKey(item.tenderId ?? index),
|
||||||
),
|
direction: DismissDirection.endToStart,
|
||||||
);
|
background: Container(
|
||||||
},
|
alignment: Alignment.centerRight,
|
||||||
),
|
padding: EdgeInsets.symmetric(
|
||||||
),
|
horizontal: 20.0.w(),
|
||||||
),
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
SizedBox(height: 10.0.h()),
|
AssetsManager.trash,
|
||||||
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
const Spacer(),
|
|
||||||
Text(
|
|
||||||
'Page',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13.0.sp(),
|
|
||||||
fontWeight: FontWeight.w300,
|
|
||||||
color: AppColors.grey60,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 10.0.w()),
|
|
||||||
|
|
||||||
InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
final selectedPage = await showDialog<int>(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Select Page'),
|
|
||||||
content: SizedBox(
|
|
||||||
width: 200,
|
|
||||||
height: 300,
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: totalPages,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final pageNumber = index + 1;
|
|
||||||
return ListTile(
|
|
||||||
title: Text('Page $pageNumber'),
|
|
||||||
onTap:
|
|
||||||
() => Navigator.pop(
|
|
||||||
context,
|
|
||||||
pageNumber,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
onDismissed: (_) {
|
||||||
},
|
if (item.tenderId != null) {
|
||||||
);
|
viewModel.removeTenderById(
|
||||||
|
item.tenderId!,
|
||||||
if (selectedPage != null) {
|
);
|
||||||
await viewModel.jumpToPage(selectedPage);
|
}
|
||||||
}
|
},
|
||||||
},
|
child: LikedListItem(
|
||||||
child: Container(
|
tender: item.tender!,
|
||||||
decoration: BoxDecoration(
|
approval: approval,
|
||||||
border: Border.all(
|
isDesktop: true,
|
||||||
color: AppColors.grey30,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 5.0.w()),
|
|
||||||
Text(
|
|
||||||
'$currentPage',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: AppColors.grey70,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 5.0.w()),
|
);
|
||||||
SvgPicture.asset(
|
},
|
||||||
AssetsManager.arrowdownSmall,
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 5.0.w()),
|
),
|
||||||
],
|
|
||||||
|
SizedBox(height: 10.0.h()),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
'Page',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
color: AppColors.grey60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 10.0.w()),
|
||||||
|
|
||||||
SizedBox(width: 5.0.w()),
|
InkWell(
|
||||||
Text(
|
onTap: () async {
|
||||||
'Of',
|
final selectedPage = await showDialog<int>(
|
||||||
style: TextStyle(
|
context: context,
|
||||||
fontSize: 14.0.sp(),
|
builder: (context) {
|
||||||
fontWeight: FontWeight.w400,
|
return AlertDialog(
|
||||||
color: AppColors.grey60,
|
title: const Text('Select Page'),
|
||||||
),
|
content: SizedBox(
|
||||||
),
|
width: 200,
|
||||||
SizedBox(width: 5.0.w()),
|
height: 300,
|
||||||
Text(
|
child: ListView.builder(
|
||||||
'$totalPages',
|
itemCount: totalPages,
|
||||||
style: TextStyle(
|
itemBuilder: (context, index) {
|
||||||
fontSize: 13.0.sp(),
|
final pageNumber = index + 1;
|
||||||
fontWeight: FontWeight.w400,
|
return ListTile(
|
||||||
color: AppColors.grey60,
|
title: Text('Page $pageNumber'),
|
||||||
),
|
onTap:
|
||||||
),
|
() => Navigator.pop(
|
||||||
],
|
context,
|
||||||
),
|
pageNumber,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
SizedBox(height: 30.0.h()),
|
if (selectedPage != null) {
|
||||||
],
|
await viewModel.jumpToPage(selectedPage);
|
||||||
);
|
}
|
||||||
},
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColors.grey30,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$currentPage',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.grey70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
SvgPicture.asset(
|
||||||
|
AssetsManager.arrowdownSmall,
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'Of',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$totalPages',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.0.h()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
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';
|
||||||
@@ -19,9 +20,11 @@ class LikedTendersMobilePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
|
class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
|
||||||
late final ScrollController _scrollController;
|
late final ScrollController _scrollController;
|
||||||
|
late final LikedTendersViewModel viewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
viewModel = context.read<LikedTendersViewModel>();
|
||||||
super.initState();
|
super.initState();
|
||||||
_scrollController = ScrollController()..addListener(_onScroll);
|
_scrollController = ScrollController()..addListener(_onScroll);
|
||||||
}
|
}
|
||||||
@@ -48,109 +51,124 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
backgroundColor: AppColors.backgroundColor,
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
appBar: appBar(context: context, title: LikedTendersStrings.likedTenders),
|
if (kIsWeb) {
|
||||||
body: Column(
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
children: [
|
viewModel.updateHome();
|
||||||
Expanded(
|
});
|
||||||
child: Consumer<LikedTendersViewModel>(
|
}
|
||||||
builder: (context, viewModel, child) {
|
},
|
||||||
if (viewModel.isLoading &&
|
child: Scaffold(
|
||||||
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
backgroundColor: AppColors.backgroundColor,
|
||||||
return const Center(
|
appBar: appBar(
|
||||||
child: CircularProgressIndicator(
|
context: context,
|
||||||
color: AppColors.secondary50,
|
title: LikedTendersStrings.likedTenders,
|
||||||
),
|
),
|
||||||
);
|
body: Column(
|
||||||
}
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Consumer<LikedTendersViewModel>(
|
||||||
|
builder: (context, viewModel, child) {
|
||||||
|
if (viewModel.isLoading &&
|
||||||
|
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: AppColors.secondary50,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (viewModel.errorMessage != null) {
|
if (viewModel.errorMessage != null) {
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
return Center(child: Text(viewModel.errorMessage!));
|
||||||
}
|
}
|
||||||
|
|
||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: Text('You haven’t liked any tenders yet.'),
|
child: Text(LikedTendersStrings.noLikedTenders),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final itemCount =
|
final itemCount =
|
||||||
feedback.length + (viewModel.isLoadingMore ? 1 : 0);
|
feedback.length + (viewModel.isLoadingMore ? 1 : 0);
|
||||||
|
|
||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await viewModel.getLikedTenders(reset: true);
|
await viewModel.getLikedTenders(reset: true);
|
||||||
},
|
},
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.0.w(),
|
horizontal: 24.0.w(),
|
||||||
vertical: 15.0.h(),
|
vertical: 15.0.h(),
|
||||||
),
|
),
|
||||||
itemCount: itemCount,
|
itemCount: itemCount,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index < feedback.length) {
|
if (index < feedback.length) {
|
||||||
final item = feedback[index];
|
final item = feedback[index];
|
||||||
TenderApprovalsData? approval;
|
TenderApprovalsData? approval;
|
||||||
bool hasApproval = viewModel.hasTenderApprovalForTender(
|
bool hasApproval = viewModel
|
||||||
item.tenderId!,
|
.hasTenderApprovalForTender(item.tenderId!);
|
||||||
);
|
if (hasApproval) {
|
||||||
if (hasApproval) {
|
approval = viewModel.getApprovalStatusForTender(
|
||||||
approval = viewModel.getApprovalStatusForTender(
|
item.tenderId!,
|
||||||
item.tenderId!,
|
);
|
||||||
|
} else {
|
||||||
|
approval = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 20.0.h()),
|
||||||
|
child: Dismissible(
|
||||||
|
key: ValueKey(item.tenderId ?? index),
|
||||||
|
direction: DismissDirection.endToStart,
|
||||||
|
background: Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 20.0.w(),
|
||||||
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
AssetsManager.trash,
|
||||||
|
width: 32.0.w(),
|
||||||
|
height: 32.0.h(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onDismissed: (_) {
|
||||||
|
if (item.tenderId != null) {
|
||||||
|
viewModel.removeTenderById(item.tenderId!);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: LikedListItem(
|
||||||
|
tender: item.tender!,
|
||||||
|
approval: approval,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
approval = null;
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 20.0.h()),
|
||||||
|
child: Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 24.0.w(),
|
||||||
|
height: 24.0.h(),
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: AppColors.secondary50,
|
||||||
|
strokeWidth: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
return Padding(
|
),
|
||||||
padding: EdgeInsets.only(bottom: 20.0.h()),
|
);
|
||||||
child: Dismissible(
|
},
|
||||||
key: ValueKey(item.tenderId ?? index),
|
),
|
||||||
direction: DismissDirection.endToStart,
|
|
||||||
background: Container(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 20.0.w(),
|
|
||||||
),
|
|
||||||
child: SvgPicture.asset(AssetsManager.trash,width: 32.0.w(),height: 32.0.h(),),
|
|
||||||
),
|
|
||||||
onDismissed: (_) {
|
|
||||||
if (item.tenderId != null) {
|
|
||||||
viewModel.removeTenderById(item.tenderId!);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: LikedListItem(
|
|
||||||
tender: item.tender!,
|
|
||||||
approval: approval,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 20.0.h()),
|
|
||||||
child: Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: 24.0.w(),
|
|
||||||
height: 24.0.h(),
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: AppColors.secondary50,
|
|
||||||
strokeWidth: 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
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:go_router/go_router.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/constants/assets.dart';
|
import 'package:tm_app/core/constants/assets.dart';
|
||||||
import 'package:tm_app/core/routes/app_routes.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/view_models/liked_tenders_view_model.dart';
|
import 'package:tm_app/view_models/liked_tenders_view_model.dart';
|
||||||
@@ -22,226 +21,230 @@ class LikedTendersTabletPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
|
class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
|
||||||
|
late final LikedTendersViewModel viewModel;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
viewModel = context.read<LikedTendersViewModel>();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final GlobalKey<ScaffoldState> key = GlobalKey();
|
final GlobalKey<ScaffoldState> key = GlobalKey();
|
||||||
return Scaffold(
|
return PopScope(
|
||||||
key: key,
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
backgroundColor: AppColors.backgroundColor,
|
if (kIsWeb) {
|
||||||
appBar: tabletAppBar(title: LikedTendersStrings.likedTenders, key: key),
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
drawer: TabletNavigationWidget(
|
viewModel.updateHome();
|
||||||
currentIndex: 1,
|
});
|
||||||
onTabChanged: (index) {
|
}
|
||||||
switch (index) {
|
},
|
||||||
case 0:
|
child: Scaffold(
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
key: key,
|
||||||
break;
|
backgroundColor: AppColors.backgroundColor,
|
||||||
case 1:
|
appBar: tabletAppBar(title: LikedTendersStrings.likedTenders, key: key),
|
||||||
break;
|
drawer: TabletNavigationWidget(currentIndex: 1),
|
||||||
case 2:
|
body: Center(
|
||||||
context.pop();
|
child: SizedBox(
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
width: 720,
|
||||||
break;
|
child: Column(
|
||||||
}
|
children: [
|
||||||
},
|
Expanded(
|
||||||
),
|
child: Consumer<LikedTendersViewModel>(
|
||||||
body: Center(
|
builder: (context, viewModel, child) {
|
||||||
child: SizedBox(
|
if (viewModel.isLoading &&
|
||||||
width: 720,
|
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
||||||
child: Column(
|
return const Center(
|
||||||
children: [
|
child: CircularProgressIndicator(
|
||||||
Expanded(
|
color: AppColors.secondary50,
|
||||||
child: Consumer<LikedTendersViewModel>(
|
),
|
||||||
builder: (context, viewModel, child) {
|
);
|
||||||
if (viewModel.isLoading &&
|
}
|
||||||
(viewModel.data?.data?.feedback ?? []).isEmpty) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: AppColors.secondary50,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewModel.errorMessage != null) {
|
if (viewModel.errorMessage != null) {
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
return Center(child: Text(viewModel.errorMessage!));
|
||||||
}
|
}
|
||||||
|
|
||||||
final feedback = viewModel.data?.data?.feedback ?? [];
|
final feedback = viewModel.data?.data?.feedback ?? [];
|
||||||
|
|
||||||
if (feedback.isEmpty) {
|
if (feedback.isEmpty) {
|
||||||
return const Center(
|
return const Center(
|
||||||
child: Text('You haven’t liked any tenders yet.'),
|
child: Text(LikedTendersStrings.noLikedTenders),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final currentPage = viewModel.currentPage;
|
final currentPage = viewModel.currentPage;
|
||||||
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
|
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await viewModel.getLikedTenders(reset: true);
|
await viewModel.getLikedTenders(reset: true);
|
||||||
},
|
},
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.0.w(),
|
horizontal: 24.0.w(),
|
||||||
vertical: 15.0.h(),
|
vertical: 15.0.h(),
|
||||||
),
|
),
|
||||||
itemCount: feedback.length,
|
itemCount: feedback.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = feedback[index];
|
final item = feedback[index];
|
||||||
TenderApprovalsData? approval;
|
TenderApprovalsData? approval;
|
||||||
bool hasApproval = viewModel
|
bool hasApproval = viewModel
|
||||||
.hasTenderApprovalForTender(item.tenderId!);
|
.hasTenderApprovalForTender(
|
||||||
if (hasApproval) {
|
|
||||||
approval = viewModel
|
|
||||||
.getApprovalStatusForTender(
|
|
||||||
item.tenderId!,
|
item.tenderId!,
|
||||||
);
|
);
|
||||||
} else {
|
if (hasApproval) {
|
||||||
approval = null;
|
approval = viewModel
|
||||||
}
|
.getApprovalStatusForTender(
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.only(bottom: 20.0.h()),
|
|
||||||
child: Dismissible(
|
|
||||||
key: ValueKey(item.tenderId ?? index),
|
|
||||||
direction: DismissDirection.endToStart,
|
|
||||||
background: Container(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 20.0.w(),
|
|
||||||
),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
AssetsManager.trash,
|
|
||||||
width: 32.0.w(),height: 32.0.h(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onDismissed: (_) {
|
|
||||||
if (item.tenderId != null) {
|
|
||||||
viewModel.removeTenderById(
|
|
||||||
item.tenderId!,
|
item.tenderId!,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
},
|
approval = null;
|
||||||
child: LikedListItem(
|
}
|
||||||
tender: item.tender!,
|
return Padding(
|
||||||
approval: approval!,
|
padding: EdgeInsets.only(bottom: 20.0.h()),
|
||||||
),
|
child: Dismissible(
|
||||||
),
|
key: ValueKey(item.tenderId ?? index),
|
||||||
);
|
direction: DismissDirection.endToStart,
|
||||||
},
|
background: Container(
|
||||||
),
|
alignment: Alignment.centerRight,
|
||||||
),
|
padding: EdgeInsets.symmetric(
|
||||||
),
|
horizontal: 20.0.w(),
|
||||||
|
),
|
||||||
SizedBox(height: 10.0.h()),
|
child: SvgPicture.asset(
|
||||||
|
AssetsManager.trash,
|
||||||
Row(
|
width: 32.0.w(),
|
||||||
children: [
|
height: 32.0.h(),
|
||||||
const Spacer(),
|
|
||||||
Text(
|
|
||||||
'Page',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13.0.sp(),
|
|
||||||
fontWeight: FontWeight.w300,
|
|
||||||
color: AppColors.grey60,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 10.0.w()),
|
|
||||||
|
|
||||||
InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
final selectedPage = await showDialog<int>(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Select Page'),
|
|
||||||
content: SizedBox(
|
|
||||||
width: 200,
|
|
||||||
height: 300,
|
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: totalPages,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final pageNumber = index + 1;
|
|
||||||
return ListTile(
|
|
||||||
title: Text('Page $pageNumber'),
|
|
||||||
onTap:
|
|
||||||
() => Navigator.pop(
|
|
||||||
context,
|
|
||||||
pageNumber,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
onDismissed: (_) {
|
||||||
},
|
if (item.tenderId != null) {
|
||||||
);
|
viewModel.removeTenderById(
|
||||||
|
item.tenderId!,
|
||||||
if (selectedPage != null) {
|
);
|
||||||
await viewModel.jumpToPage(selectedPage);
|
}
|
||||||
}
|
},
|
||||||
},
|
child: LikedListItem(
|
||||||
child: Container(
|
tender: item.tender!,
|
||||||
decoration: BoxDecoration(
|
approval: approval!,
|
||||||
border: Border.all(
|
|
||||||
color: AppColors.grey30,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: 5.0.w()),
|
|
||||||
Text(
|
|
||||||
'$currentPage',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14.0.sp(),
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: AppColors.grey70,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 5.0.w()),
|
);
|
||||||
SvgPicture.asset(
|
},
|
||||||
AssetsManager.arrowdownSmall,
|
),
|
||||||
),
|
),
|
||||||
SizedBox(width: 5.0.w()),
|
),
|
||||||
],
|
|
||||||
|
SizedBox(height: 10.0.h()),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
'Page',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
|
color: AppColors.grey60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 10.0.w()),
|
||||||
|
|
||||||
SizedBox(width: 5.0.w()),
|
InkWell(
|
||||||
Text(
|
onTap: () async {
|
||||||
'Of',
|
final selectedPage = await showDialog<int>(
|
||||||
style: TextStyle(
|
context: context,
|
||||||
fontSize: 14.0.sp(),
|
builder: (context) {
|
||||||
fontWeight: FontWeight.w400,
|
return AlertDialog(
|
||||||
color: AppColors.grey60,
|
title: const Text('Select Page'),
|
||||||
),
|
content: SizedBox(
|
||||||
),
|
width: 200,
|
||||||
SizedBox(width: 5.0.w()),
|
height: 300,
|
||||||
Text(
|
child: ListView.builder(
|
||||||
'$totalPages',
|
itemCount: totalPages,
|
||||||
style: TextStyle(
|
itemBuilder: (context, index) {
|
||||||
fontSize: 13.0.sp(),
|
final pageNumber = index + 1;
|
||||||
fontWeight: FontWeight.w400,
|
return ListTile(
|
||||||
color: AppColors.grey60,
|
title: Text('Page $pageNumber'),
|
||||||
),
|
onTap:
|
||||||
),
|
() => Navigator.pop(
|
||||||
SizedBox(width: 30.0.w()),
|
context,
|
||||||
],
|
pageNumber,
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
SizedBox(height: 30.0.h()),
|
if (selectedPage != null) {
|
||||||
],
|
await viewModel.jumpToPage(selectedPage);
|
||||||
);
|
}
|
||||||
},
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: AppColors.grey30,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$currentPage',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: AppColors.grey70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
SvgPicture.asset(
|
||||||
|
AssetsManager.arrowdownSmall,
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'Of',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5.0.w()),
|
||||||
|
Text(
|
||||||
|
'$totalPages',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13.0.sp(),
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: AppColors.grey60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 30.0.w()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 30.0.h()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ class LikedTendersStrings {
|
|||||||
static const startDate = 'YYYY/MM/DD';
|
static const startDate = 'YYYY/MM/DD';
|
||||||
static const endDate = 'YYYY/MM/DD';
|
static const endDate = 'YYYY/MM/DD';
|
||||||
static const approvedTenders = 'Approved tenders';
|
static const approvedTenders = 'Approved tenders';
|
||||||
|
static const noLikedTenders = 'You haven’t liked any tenders yet.';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ class LikedListItem extends StatelessWidget {
|
|||||||
submissionMode: 'self-apply',
|
submissionMode: 'self-apply',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
kIsWeb
|
(kIsWeb && MediaQuery.sizeOf(context).width > 600)
|
||||||
? showDialog(
|
? showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
|
|||||||
@@ -72,28 +72,6 @@ class _DesktopProfilePageState extends State<DesktopProfilePage> {
|
|||||||
children: [
|
children: [
|
||||||
DesktopNavigationWidget(
|
DesktopNavigationWidget(
|
||||||
currentIndex: 2, // Tenders index
|
currentIndex: 2, // Tenders index
|
||||||
onTabChanged: (index) {
|
|
||||||
// Navigate to different screens based on index
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
// Navigate to home
|
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => HomeRouteData().go(context),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Navigate to profile
|
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => TendersRouteData().go(context),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Already on profile
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 740,
|
width: 740,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/constants/assets.dart';
|
import 'package:tm_app/core/constants/assets.dart';
|
||||||
import 'package:tm_app/core/constants/common_strings.dart';
|
import 'package:tm_app/core/constants/common_strings.dart';
|
||||||
@@ -75,25 +74,7 @@ class _TabletProfilePageState extends State<TabletProfilePage> {
|
|||||||
backgroundColor: AppColors.backgroundColor,
|
backgroundColor: AppColors.backgroundColor,
|
||||||
appBar: tabletAppBar(title: ProfileStrings.profileTitle, key: key),
|
appBar: tabletAppBar(title: ProfileStrings.profileTitle, key: key),
|
||||||
|
|
||||||
drawer: TabletNavigationWidget(
|
drawer: TabletNavigationWidget(currentIndex: 2),
|
||||||
currentIndex: 2,
|
|
||||||
onTabChanged: (index) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(
|
|
||||||
context,
|
|
||||||
() => TendersRouteData().go(context),
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: 24.0.w(),
|
horizontal: 24.0.w(),
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
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:tm_app/core/constants/assets.dart';
|
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/view_models/home_view_model.dart';
|
||||||
|
import 'package:tm_app/view_models/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 'package:tm_app/views/profile/strings/profile_strings.dart';
|
import 'package:tm_app/views/profile/strings/profile_strings.dart';
|
||||||
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
||||||
|
|
||||||
|
import '../../core/routes/app_routes.dart';
|
||||||
|
|
||||||
class DesktopNavigationWidget extends StatelessWidget {
|
class DesktopNavigationWidget extends StatelessWidget {
|
||||||
const DesktopNavigationWidget({
|
const DesktopNavigationWidget({required this.currentIndex, super.key});
|
||||||
required this.currentIndex,
|
|
||||||
required this.onTabChanged,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final int currentIndex;
|
final int currentIndex;
|
||||||
final ValueChanged<int> onTabChanged;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -36,7 +36,14 @@ class DesktopNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: HomeStrings.home,
|
text: HomeStrings.home,
|
||||||
isActive: currentIndex == 0,
|
isActive: currentIndex == 0,
|
||||||
onTap: () => onTabChanged(0),
|
onTap: () {
|
||||||
|
if (currentIndex == 0) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => HomeRouteData().go(context));
|
||||||
|
context.read<HomeViewModel>().init();
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.home,
|
iconPath: AssetsManager.home,
|
||||||
activeIconPath: AssetsManager.homeActive,
|
activeIconPath: AssetsManager.homeActive,
|
||||||
),
|
),
|
||||||
@@ -45,7 +52,14 @@ class DesktopNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: TendersStrings.tendersTitle,
|
text: TendersStrings.tendersTitle,
|
||||||
isActive: currentIndex == 1,
|
isActive: currentIndex == 1,
|
||||||
onTap: () => onTabChanged(1),
|
onTap: () {
|
||||||
|
if (currentIndex == 1) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => TendersRouteData().go(context));
|
||||||
|
context.read<TendersViewModel>().getTenders();
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.tenders,
|
iconPath: AssetsManager.tenders,
|
||||||
activeIconPath: AssetsManager.tendersActive,
|
activeIconPath: AssetsManager.tendersActive,
|
||||||
),
|
),
|
||||||
@@ -54,7 +68,13 @@ class DesktopNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: ProfileStrings.profileTitle,
|
text: ProfileStrings.profileTitle,
|
||||||
isActive: currentIndex == 2,
|
isActive: currentIndex == 2,
|
||||||
onTap: () => onTabChanged(2),
|
onTap: () {
|
||||||
|
if (currentIndex == 2) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => ProfileRouteData().go(context));
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.profile,
|
iconPath: AssetsManager.profile,
|
||||||
activeIconPath: AssetsManager.profileActive,
|
activeIconPath: AssetsManager.profileActive,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/constants/assets.dart';
|
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/view_models/home_view_model.dart';
|
||||||
|
import 'package:tm_app/view_models/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 'package:tm_app/views/profile/strings/profile_strings.dart';
|
import 'package:tm_app/views/profile/strings/profile_strings.dart';
|
||||||
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
import 'package:tm_app/views/tenders/strings/tenders_strings.dart';
|
||||||
|
|
||||||
|
import '../../core/routes/app_routes.dart';
|
||||||
|
|
||||||
class TabletNavigationWidget extends StatelessWidget {
|
class TabletNavigationWidget extends StatelessWidget {
|
||||||
const TabletNavigationWidget({
|
const TabletNavigationWidget({required this.currentIndex, super.key});
|
||||||
required this.currentIndex,
|
|
||||||
required this.onTabChanged,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final int currentIndex;
|
final int currentIndex;
|
||||||
final ValueChanged<int> onTabChanged;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -30,7 +31,14 @@ class TabletNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: HomeStrings.home,
|
text: HomeStrings.home,
|
||||||
isActive: currentIndex == 0,
|
isActive: currentIndex == 0,
|
||||||
onTap: () => onTabChanged(0),
|
onTap: () {
|
||||||
|
if (currentIndex == 0) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => HomeRouteData().go(context));
|
||||||
|
context.read<HomeViewModel>().init();
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.home,
|
iconPath: AssetsManager.home,
|
||||||
activeIconPath: AssetsManager.homeActive,
|
activeIconPath: AssetsManager.homeActive,
|
||||||
),
|
),
|
||||||
@@ -38,7 +46,14 @@ class TabletNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: TendersStrings.tendersTitle,
|
text: TendersStrings.tendersTitle,
|
||||||
isActive: currentIndex == 1,
|
isActive: currentIndex == 1,
|
||||||
onTap: () => onTabChanged(1),
|
onTap: () {
|
||||||
|
if (currentIndex == 1) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => TendersRouteData().go(context));
|
||||||
|
context.read<TendersViewModel>().getTenders();
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.tenders,
|
iconPath: AssetsManager.tenders,
|
||||||
activeIconPath: AssetsManager.tendersActive,
|
activeIconPath: AssetsManager.tendersActive,
|
||||||
),
|
),
|
||||||
@@ -46,7 +61,14 @@ class TabletNavigationWidget extends StatelessWidget {
|
|||||||
context: context,
|
context: context,
|
||||||
text: ProfileStrings.profileTitle,
|
text: ProfileStrings.profileTitle,
|
||||||
isActive: currentIndex == 2,
|
isActive: currentIndex == 2,
|
||||||
onTap: () => onTabChanged(2),
|
onTap: () {
|
||||||
|
if (currentIndex == 2) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
context.pop();
|
||||||
|
Router.neglect(context, () => ProfileRouteData().go(context));
|
||||||
|
}
|
||||||
|
},
|
||||||
iconPath: AssetsManager.profile,
|
iconPath: AssetsManager.profile,
|
||||||
activeIconPath: AssetsManager.profileActive,
|
activeIconPath: AssetsManager.profileActive,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import 'package:tm_app/views/shared/desktop_navigation_widget.dart';
|
|||||||
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
||||||
|
|
||||||
import '../../../core/constants/common_strings.dart';
|
import '../../../core/constants/common_strings.dart';
|
||||||
import '../../../core/routes/app_routes.dart';
|
|
||||||
|
|
||||||
class DesktopTendersPage extends StatefulWidget {
|
class DesktopTendersPage extends StatefulWidget {
|
||||||
const DesktopTendersPage({super.key});
|
const DesktopTendersPage({super.key});
|
||||||
@@ -54,65 +53,41 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: AppColors.backgroundColor,
|
backgroundColor: AppColors.backgroundColor,
|
||||||
body: Column(
|
body: SingleChildScrollView(
|
||||||
children: [
|
child: Consumer<TendersViewModel>(
|
||||||
DesktopNavigationWidget(
|
builder: (context, viewModel, child) {
|
||||||
currentIndex: 1, // Tenders index
|
if (viewModel.isLoading) {
|
||||||
onTabChanged: (index) {
|
return Center(
|
||||||
// Navigate to different screens based on index
|
child: CircularProgressIndicator(color: AppColors.jellyBean),
|
||||||
switch (index) {
|
);
|
||||||
case 0:
|
}
|
||||||
// Navigate to home
|
if (viewModel.errorMessage != null) {
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
return Center(child: Text(viewModel.errorMessage!));
|
||||||
viewModel.updateHome();
|
}
|
||||||
break;
|
if (viewModel.tendersResponse?.data?.tenders == null ||
|
||||||
case 1:
|
viewModel.tendersResponse!.data!.tenders!.isEmpty) {
|
||||||
// Already on tenders
|
return Center(child: Text(CommonStrings.noData));
|
||||||
break;
|
}
|
||||||
case 2:
|
return Column(
|
||||||
// Navigate to profile
|
children: [
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
DesktopNavigationWidget(
|
||||||
break;
|
currentIndex: 1, // Tenders index
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Center(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Consumer<TendersViewModel>(
|
|
||||||
builder: (context, viewModel, child) {
|
|
||||||
if (viewModel.isLoading) {
|
|
||||||
return Center(
|
|
||||||
child: CircularProgressIndicator(
|
|
||||||
color: AppColors.jellyBean,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (viewModel.errorMessage != null) {
|
|
||||||
return Center(child: Text(viewModel.errorMessage!));
|
|
||||||
}
|
|
||||||
if (viewModel.tendersResponse?.data?.tenders == null ||
|
|
||||||
viewModel.tendersResponse!.data!.tenders!.isEmpty) {
|
|
||||||
return Center(child: Text(CommonStrings.noData));
|
|
||||||
}
|
|
||||||
return SizedBox(
|
|
||||||
width: 740,
|
|
||||||
height: 800,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 24.0.h()),
|
|
||||||
child: MainTendersSlider(
|
|
||||||
tenders:
|
|
||||||
viewModel.tendersResponse?.data?.tenders ?? [],
|
|
||||||
isDesktop: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
SizedBox(
|
||||||
),
|
width: 740,
|
||||||
),
|
height: 800,
|
||||||
],
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 24.0.h()),
|
||||||
|
child: MainTendersSlider(
|
||||||
|
tenders: viewModel.tendersResponse?.data?.tenders ?? [],
|
||||||
|
isDesktop: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.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';
|
||||||
import 'package:tm_app/core/utils/size_config.dart';
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
@@ -8,7 +7,6 @@ import 'package:tm_app/views/shared/tablet_navigation_widget.dart';
|
|||||||
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
import 'package:tm_app/views/tenders/widgets/main_tenders_slider.dart';
|
||||||
|
|
||||||
import '../../../core/constants/common_strings.dart';
|
import '../../../core/constants/common_strings.dart';
|
||||||
import '../../../core/routes/app_routes.dart';
|
|
||||||
import '../../shared/tender_app_bar.dart';
|
import '../../shared/tender_app_bar.dart';
|
||||||
import '../strings/tenders_strings.dart';
|
import '../strings/tenders_strings.dart';
|
||||||
|
|
||||||
@@ -35,23 +33,7 @@ class _TabletTendersPageState extends State<TabletTendersPage> {
|
|||||||
key: key,
|
key: key,
|
||||||
backgroundColor: AppColors.backgroundColor,
|
backgroundColor: AppColors.backgroundColor,
|
||||||
appBar: tabletAppBar(title: TendersStrings.tendersTitle, key: key),
|
appBar: tabletAppBar(title: TendersStrings.tendersTitle, key: key),
|
||||||
drawer: TabletNavigationWidget(
|
drawer: TabletNavigationWidget(currentIndex: 1),
|
||||||
currentIndex: 1,
|
|
||||||
onTabChanged: (index) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
|
||||||
viewModel.updateHome();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Consumer<TendersViewModel>(
|
child: Consumer<TendersViewModel>(
|
||||||
builder: (context, viewModel, child) {
|
builder: (context, viewModel, child) {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
Widget _tendersPageView() {
|
Widget _tendersPageView() {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 719.0.h(),
|
height: 722.0.h(),
|
||||||
child: PageView.builder(
|
child: PageView.builder(
|
||||||
controller: pageController,
|
controller: pageController,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
@@ -145,8 +145,8 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius: BorderRadius.circular(100),
|
||||||
onTap: _goToPreviousPage,
|
onTap: _goToPreviousPage,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 32.0.w(),
|
width: 32.0.h(),
|
||||||
height: 32.0.w(),
|
height: 32.0.h(),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
||||||
@@ -194,8 +194,8 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
borderRadius: BorderRadius.circular(100),
|
borderRadius: BorderRadius.circular(100),
|
||||||
onTap: _goToNextPage,
|
onTap: _goToNextPage,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 32.0.w(),
|
width: 32.0.h(),
|
||||||
height: 32.0.w(),
|
height: 32.0.h(),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
border: Border.all(color: AppColors.iconColor, width: 1.5),
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import 'package:tm_app/views/your_tenders/widgets/liked_disliked_tenders_list.da
|
|||||||
import 'package:tm_app/views/your_tenders/widgets/tablet_desktop_appbar.dart';
|
import 'package:tm_app/views/your_tenders/widgets/tablet_desktop_appbar.dart';
|
||||||
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
|
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
|
||||||
|
|
||||||
import '../../../core/routes/app_routes.dart';
|
|
||||||
import '../../shared/desktop_navigation_widget.dart';
|
import '../../shared/desktop_navigation_widget.dart';
|
||||||
|
|
||||||
class YourTendersDesktopPage extends StatefulWidget {
|
class YourTendersDesktopPage extends StatefulWidget {
|
||||||
@@ -43,22 +42,6 @@ class _YourTendersDesktopPageState extends State<YourTendersDesktopPage>
|
|||||||
children: [
|
children: [
|
||||||
DesktopNavigationWidget(
|
DesktopNavigationWidget(
|
||||||
currentIndex: 1, // Tenders index
|
currentIndex: 1, // Tenders index
|
||||||
onTabChanged: (index) {
|
|
||||||
// Navigate to different screens based on index
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
// Navigate to home
|
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// Already on tenders
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Navigate to profile
|
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@@ -68,14 +51,6 @@ class _YourTendersDesktopPageState extends State<YourTendersDesktopPage>
|
|||||||
SizedBox(height: 64.0),
|
SizedBox(height: 64.0),
|
||||||
TabletDesktopAppbar(),
|
TabletDesktopAppbar(),
|
||||||
SizedBox(height: 20.0),
|
SizedBox(height: 20.0),
|
||||||
|
|
||||||
// MainTabBar(
|
|
||||||
// controller: controller,
|
|
||||||
// titles: [
|
|
||||||
// AppStrings.approvedTenders,
|
|
||||||
// AppStrings.tenderSubmitted,
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
FilterButton(platformType: PlatformType.tabletDesktop),
|
FilterButton(platformType: PlatformType.tabletDesktop),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -115,15 +90,10 @@ class _YourTendersDesktopPageState extends State<YourTendersDesktopPage>
|
|||||||
isDesktop: true,
|
isDesktop: true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: Text('No data available'));
|
return const Center(
|
||||||
|
child: Text(YourTendersStrings.noTenders),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// return TabBarView(
|
|
||||||
// controller: controller,
|
|
||||||
// children: [
|
|
||||||
// // ApprovedTenders(tendersSubmitted: []),
|
|
||||||
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ class _YourTendersMobilePageState extends State<YourTendersMobilePage> {
|
|||||||
)
|
)
|
||||||
else
|
else
|
||||||
const Expanded(
|
const Expanded(
|
||||||
child: Center(child: Text('No data available')),
|
child: Center(
|
||||||
|
child: Text(YourTendersStrings.noTenders),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tm_app/core/routes/app_routes.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/view_models/your_tenders_view_model.dart';
|
import 'package:tm_app/view_models/your_tenders_view_model.dart';
|
||||||
@@ -46,21 +44,6 @@ class _YourTendersTabletPageState extends State<YourTendersTabletPage>
|
|||||||
appBar: tabletAppBar(title: YourTendersStrings.yourTenders, key: key),
|
appBar: tabletAppBar(title: YourTendersStrings.yourTenders, key: key),
|
||||||
drawer: TabletNavigationWidget(
|
drawer: TabletNavigationWidget(
|
||||||
currentIndex: 1, // Home is index 0
|
currentIndex: 1, // Home is index 0
|
||||||
onTabChanged: (index) {
|
|
||||||
// Handle navigation to other tabs
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
Router.neglect(context, () => HomeRouteData().go(context));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Navigate to profile
|
|
||||||
context.pop();
|
|
||||||
Router.neglect(context, () => ProfileRouteData().go(context));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
@@ -114,9 +97,14 @@ class _YourTendersTabletPageState extends State<YourTendersTabletPage>
|
|||||||
isDesctop: false,
|
isDesctop: false,
|
||||||
);
|
);
|
||||||
} else if (viewModel.data != null) {
|
} else if (viewModel.data != null) {
|
||||||
return TendersSubmitted(approvedTenders: viewModel.data!,isDesktop: false,);
|
return TendersSubmitted(
|
||||||
|
approvedTenders: viewModel.data!,
|
||||||
|
isDesktop: false,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: Text('No data available'));
|
return const Center(
|
||||||
|
child: Text(YourTendersStrings.noTenders),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ class YourTendersStrings {
|
|||||||
static const startDate = 'YYYY/MM/DD';
|
static const startDate = 'YYYY/MM/DD';
|
||||||
static const endDate = 'YYYY/MM/DD';
|
static const endDate = 'YYYY/MM/DD';
|
||||||
static const approvedTenders = 'Approved tenders';
|
static const approvedTenders = 'Approved tenders';
|
||||||
|
static const noTenders = 'No data available';
|
||||||
|
static const selectPublicationRangeDate = 'Select publication date range';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class TendersFilterDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 16.0.h()),
|
SizedBox(height: 16.0.h()),
|
||||||
Text(
|
Text(
|
||||||
'Select date range',
|
YourTendersStrings.selectPublicationRangeDate,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16.0.sp(),
|
fontSize: 16.0.sp(),
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
Reference in New Issue
Block a user