some changes and fixes

This commit is contained in:
amirrezaghabeli
2025-09-06 13:18:12 +03:30
parent 2fbd8018c8
commit 5649634464
24 changed files with 691 additions and 815 deletions
+1
View File
@@ -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,7 +162,8 @@ class TenderDetailActions extends StatelessWidget {
submissionMode: 'self-apply', submissionMode: 'self-apply',
); );
} else { } else {
showDialog( (MediaQuery.sizeOf(context).width > 600)
? showDialog(
context: context, context: context,
builder: (context) { builder: (context) {
return SelectSubmissionDialog( return SelectSubmissionDialog(
@@ -174,6 +175,19 @@ class TenderDetailActions extends StatelessWidget {
}, },
); );
}, },
)
: showModalBottomSheet(
context: context,
builder: (context) {
return SelectSubmissionBottomSheet(
onConfirm: (String value) {
viewModel.submitTenderApproval(
tenderId: detail.id!,
submissionMode: value,
);
},
);
},
); );
} }
}, },
+6 -37
View File
@@ -31,38 +31,14 @@ 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(
child: Column(
children: [ children: [
DesktopNavigationWidget( DesktopNavigationWidget(
currentIndex: 0, // Home index currentIndex: 0, // Home index
onTabChanged: (index) {
// Navigate to different screens based on index
switch (index) {
case 0:
// Already on home
break;
case 1:
// Navigate to tenders
Router.neglect(
context,
() => TendersRouteData().go(context),
);
break;
case 2:
// Navigate to profile
Router.neglect(
context,
() => ProfileRouteData().go(context),
);
break;
}
},
), ),
Expanded( SizedBox(
child: Center(
child: SizedBox(
width: 780, width: 780,
child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
@@ -72,13 +48,8 @@ class DesktopHomePage extends StatelessWidget {
_progressBarsRow(homeViewModel), _progressBarsRow(homeViewModel),
SizedBox(height: 32.0.h()), SizedBox(height: 32.0.h()),
Padding( Padding(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(horizontal: 15.0.w()),
horizontal: 15.0.w(), child: _firstTenderCardsRow(context, homeViewModel),
),
child: _firstTenderCardsRow(
context,
homeViewModel,
),
), ),
SizedBox(height: 32.0.h()), SizedBox(height: 32.0.h()),
_yourTenderText(homeViewModel), _yourTenderText(homeViewModel),
@@ -87,10 +58,8 @@ class DesktopHomePage extends StatelessWidget {
], ],
), ),
), ),
),
),
),
], ],
),
); );
} }
return const Center( return const Center(
-19
View File
@@ -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,27 +20,26 @@ 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(
onPopInvokedWithResult: (didPop, result) {
WidgetsBinding.instance.addPostFrameCallback((_) {
viewModel.updateHome();
});
},
child: Scaffold(
backgroundColor: AppColors.backgroundColor, backgroundColor: AppColors.backgroundColor,
body: Column( body: Column(
children: [ children: [
DesktopNavigationWidget( DesktopNavigationWidget(currentIndex: 1),
currentIndex: 1,
onTabChanged: (index) {
switch (index) {
case 0:
Router.neglect(context, () => HomeRouteData().go(context));
break;
case 1:
break;
case 2:
Router.neglect(context, () => ProfileRouteData().go(context));
break;
}
},
),
Expanded( Expanded(
child: SizedBox( child: SizedBox(
width: 740, width: 740,
@@ -63,7 +62,7 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
if (feedback.isEmpty) { if (feedback.isEmpty) {
return const Center( return const Center(
child: Text('You havent liked any tenders yet.'), child: Text(LikedTendersStrings.noLikedTenders),
); );
} }
@@ -89,7 +88,8 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
bool hasApproval = viewModel bool hasApproval = viewModel
.hasTenderApprovalForTender(item.tenderId!); .hasTenderApprovalForTender(item.tenderId!);
if (hasApproval) { if (hasApproval) {
approval = viewModel.getApprovalStatusForTender( approval = viewModel
.getApprovalStatusForTender(
item.tenderId!, item.tenderId!,
); );
} else { } else {
@@ -235,6 +235,7 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
), ),
], ],
), ),
),
); );
} }
} }
@@ -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,9 +51,20 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return PopScope(
onPopInvokedWithResult: (didPop, result) {
if (kIsWeb) {
WidgetsBinding.instance.addPostFrameCallback((_) {
viewModel.updateHome();
});
}
},
child: Scaffold(
backgroundColor: AppColors.backgroundColor, backgroundColor: AppColors.backgroundColor,
appBar: appBar(context: context, title: LikedTendersStrings.likedTenders), appBar: appBar(
context: context,
title: LikedTendersStrings.likedTenders,
),
body: Column( body: Column(
children: [ children: [
Expanded( Expanded(
@@ -73,7 +87,7 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
if (feedback.isEmpty) { if (feedback.isEmpty) {
return const Center( return const Center(
child: Text('You havent liked any tenders yet.'), child: Text(LikedTendersStrings.noLikedTenders),
); );
} }
@@ -95,9 +109,8 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
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!,
@@ -116,7 +129,11 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 20.0.w(), horizontal: 20.0.w(),
), ),
child: SvgPicture.asset(AssetsManager.trash,width: 32.0.w(),height: 32.0.h(),), child: SvgPicture.asset(
AssetsManager.trash,
width: 32.0.w(),
height: 32.0.h(),
),
), ),
onDismissed: (_) { onDismissed: (_) {
if (item.tenderId != null) { if (item.tenderId != null) {
@@ -152,6 +169,7 @@ class _LikedTendersMobilePageState extends State<LikedTendersMobilePage> {
), ),
], ],
), ),
),
); );
} }
} }
@@ -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,29 +21,29 @@ 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(
onPopInvokedWithResult: (didPop, result) {
if (kIsWeb) {
WidgetsBinding.instance.addPostFrameCallback((_) {
viewModel.updateHome();
});
}
},
child: Scaffold(
key: key, key: key,
backgroundColor: AppColors.backgroundColor, backgroundColor: AppColors.backgroundColor,
appBar: tabletAppBar(title: LikedTendersStrings.likedTenders, key: key), appBar: tabletAppBar(title: LikedTendersStrings.likedTenders, key: key),
drawer: TabletNavigationWidget( drawer: TabletNavigationWidget(currentIndex: 1),
currentIndex: 1,
onTabChanged: (index) {
switch (index) {
case 0:
Router.neglect(context, () => HomeRouteData().go(context));
break;
case 1:
break;
case 2:
context.pop();
Router.neglect(context, () => ProfileRouteData().go(context));
break;
}
},
),
body: Center( body: Center(
child: SizedBox( child: SizedBox(
width: 720, width: 720,
@@ -70,7 +69,7 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
if (feedback.isEmpty) { if (feedback.isEmpty) {
return const Center( return const Center(
child: Text('You havent liked any tenders yet.'), child: Text(LikedTendersStrings.noLikedTenders),
); );
} }
@@ -94,7 +93,9 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
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 approval = viewModel
.getApprovalStatusForTender( .getApprovalStatusForTender(
@@ -115,7 +116,8 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
), ),
child: SvgPicture.asset( child: SvgPicture.asset(
AssetsManager.trash, AssetsManager.trash,
width: 32.0.w(),height: 32.0.h(), width: 32.0.w(),
height: 32.0.h(),
), ),
), ),
onDismissed: (_) { onDismissed: (_) {
@@ -245,6 +247,7 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
), ),
), ),
), ),
),
); );
} }
} }
@@ -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 havent 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 -20
View File
@@ -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,
), ),
+31 -9
View File
@@ -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,
), ),
+12 -37
View File
@@ -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,38 +53,12 @@ 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: [
DesktopNavigationWidget(
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));
viewModel.updateHome();
break;
case 1:
// Already on tenders
break;
case 2:
// Navigate to profile
Router.neglect(context, () => ProfileRouteData().go(context));
break;
}
},
),
Expanded(
child: Center(
child: SingleChildScrollView(
child: Consumer<TendersViewModel>( child: Consumer<TendersViewModel>(
builder: (context, viewModel, child) { builder: (context, viewModel, child) {
if (viewModel.isLoading) { if (viewModel.isLoading) {
return Center( return Center(
child: CircularProgressIndicator( child: CircularProgressIndicator(color: AppColors.jellyBean),
color: AppColors.jellyBean,
),
); );
} }
if (viewModel.errorMessage != null) { if (viewModel.errorMessage != null) {
@@ -95,24 +68,26 @@ class _DesktopTendersPageState extends State<DesktopTendersPage> {
viewModel.tendersResponse!.data!.tenders!.isEmpty) { viewModel.tendersResponse!.data!.tenders!.isEmpty) {
return Center(child: Text(CommonStrings.noData)); return Center(child: Text(CommonStrings.noData));
} }
return SizedBox( return Column(
children: [
DesktopNavigationWidget(
currentIndex: 1, // Tenders index
),
SizedBox(
width: 740, width: 740,
height: 800, height: 800,
child: Padding( child: Padding(
padding: EdgeInsets.symmetric(vertical: 24.0.h()), padding: EdgeInsets.symmetric(vertical: 24.0.h()),
child: MainTendersSlider( child: MainTendersSlider(
tenders: tenders: viewModel.tendersResponse?.data?.tenders ?? [],
viewModel.tendersResponse?.data?.tenders ?? [],
isDesktop: true, isDesktop: true,
), ),
), ),
);
},
),
),
),
), ),
], ],
);
},
),
), ),
); );
} }
+1 -19
View File
@@ -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,