6d674a4a1b
- Updated `pubspec.lock` to reflect new versions for several packages, including `async`, `fake_async`, `leak_tracker`, and `vm_service`. - Modified `TenderApprovalStatus` enum to include a new status `approved`. - Updated routing for `YourTendersRouteData` to accept a status parameter and pass it to the `YourTendersScreen`. - Adjusted API calls and view models to utilize the new status handling, ensuring proper filtering and display of tender data based on approval status. - Enhanced filter dialog to support new status options and improved user feedback in the UI for submitted and approved tenders.
311 lines
10 KiB
Dart
311 lines
10 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:tm_app/views/completion_of_documents/pages/m_completion_of_documents_page.dart';
|
|
import 'package:tm_app/views/detail/pages/detail_screen.dart';
|
|
import 'package:tm_app/views/forget_password_create/pages/forgot_password_create_screen.dart';
|
|
import 'package:tm_app/views/forget_password_otp/pages/forgot_password_otp_screen.dart';
|
|
import 'package:tm_app/views/home/pages/home_screen.dart';
|
|
import 'package:tm_app/views/liked_tenders/pages/liked_tenders_screen.dart';
|
|
import 'package:tm_app/views/login/pages/login_screen.dart';
|
|
|
|
import '../../views/final_completion_of_documents/pages/final_completion_of_documents_screen.dart';
|
|
import '../../views/forgot_password/pages/forgot_password_screen.dart';
|
|
import '../../views/notification/pages/notification_screen.dart';
|
|
import '../../views/profile/pages/profile_screen.dart';
|
|
import '../../views/splash/pages/splash_screen.dart';
|
|
import '../../views/tenders/pages/tenders_screen.dart';
|
|
import '../../views/your_tenders/pages/your_tenders_screen.dart';
|
|
import '../providers/final_completion_provider.dart';
|
|
import '../providers/forgot_password_provider.dart';
|
|
import '../providers/home_provider.dart';
|
|
import '../providers/liked_tenders_provider.dart';
|
|
import '../providers/notification_provider.dart';
|
|
import '../providers/profile_provider.dart';
|
|
import '../providers/reset_password_provider.dart';
|
|
import '../providers/tender_detail_provider.dart';
|
|
import '../providers/tenders_provider.dart';
|
|
import '../providers/verify_otp_provider.dart';
|
|
import '../providers/your_tenders_provider.dart';
|
|
import 'app_shell/app_shell_screen.dart';
|
|
|
|
part 'app_routes.g.dart';
|
|
|
|
// Global navigator keys
|
|
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
|
|
final GlobalKey<NavigatorState> homeNavigatorKey = GlobalKey<NavigatorState>();
|
|
final GlobalKey<NavigatorState> tendersNavigatorKey =
|
|
GlobalKey<NavigatorState>();
|
|
final GlobalKey<NavigatorState> profileNavigatorKey =
|
|
GlobalKey<NavigatorState>();
|
|
final GlobalKey<NavigatorState> notificationNavigatorKey =
|
|
GlobalKey<NavigatorState>();
|
|
|
|
// Main app router
|
|
final GoRouter appRouter = GoRouter(
|
|
routes: $appRoutes,
|
|
initialLocation: '/splash',
|
|
navigatorKey: rootNavigatorKey,
|
|
redirect: (context, state) {
|
|
final prefs = context.read<SharedPreferences>();
|
|
final hasToken = prefs.getString('bearer') != null;
|
|
final path = state.uri.path;
|
|
final location = state.matchedLocation;
|
|
final isSplash = path == '/splash' || location == '/splash';
|
|
final isLogin = path == '/login' || location == '/login';
|
|
final isForgotFlow =
|
|
path.startsWith('/forgot-password') ||
|
|
location.startsWith('/forgot-password');
|
|
final isPublic = isSplash || isLogin || isForgotFlow;
|
|
if (!hasToken && !isPublic) {
|
|
return '/splash';
|
|
}
|
|
return null;
|
|
},
|
|
);
|
|
|
|
// Login route - outside the shell
|
|
@TypedGoRoute<LoginScreenRoute>(path: '/login')
|
|
class LoginScreenRoute extends GoRouteData with _$LoginScreenRoute {
|
|
const LoginScreenRoute();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return const LoginScreen();
|
|
}
|
|
}
|
|
|
|
// splash route - outside the shell
|
|
@TypedGoRoute<SplashScreenRoute>(path: '/splash')
|
|
class SplashScreenRoute extends GoRouteData with _$SplashScreenRoute {
|
|
final bool? navigateToNotification;
|
|
const SplashScreenRoute({this.navigateToNotification});
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return SplashScreen(
|
|
navigateToNotification: navigateToNotification ?? false,
|
|
);
|
|
}
|
|
}
|
|
|
|
// Shell route with bottom navigation using StatefulShellRoute.indexedStack
|
|
@TypedStatefulShellRoute<AppShellRouteData>(
|
|
branches: <TypedStatefulShellBranch<StatefulShellBranchData>>[
|
|
TypedStatefulShellBranch<HomeBranch>(
|
|
routes: <TypedRoute<RouteData>>[
|
|
TypedGoRoute<HomeRouteData>(path: '/home'),
|
|
],
|
|
),
|
|
TypedStatefulShellBranch<TendersBranch>(
|
|
routes: <TypedRoute<RouteData>>[
|
|
TypedGoRoute<TendersRouteData>(path: '/tenders'),
|
|
],
|
|
),
|
|
TypedStatefulShellBranch<ProfileBranch>(
|
|
routes: <TypedRoute<RouteData>>[
|
|
TypedGoRoute<ProfileRouteData>(path: '/profile'),
|
|
],
|
|
),
|
|
TypedStatefulShellBranch<NotificationBranch>(
|
|
routes: <TypedRoute<RouteData>>[
|
|
TypedGoRoute<NotificationRouteData>(path: '/notification'),
|
|
],
|
|
),
|
|
],
|
|
)
|
|
class AppShellRouteData extends StatefulShellRouteData {
|
|
const AppShellRouteData();
|
|
|
|
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
|
|
|
@override
|
|
Widget builder(
|
|
BuildContext context,
|
|
GoRouterState state,
|
|
StatefulNavigationShell navigationShell,
|
|
) {
|
|
return AppShellScreen(navigationShell: navigationShell);
|
|
}
|
|
}
|
|
|
|
// Branch data classes
|
|
class HomeBranch extends StatefulShellBranchData {
|
|
const HomeBranch();
|
|
static final GlobalKey<NavigatorState> $navigatorKey = homeNavigatorKey;
|
|
}
|
|
|
|
class TendersBranch extends StatefulShellBranchData {
|
|
const TendersBranch();
|
|
static final GlobalKey<NavigatorState> $navigatorKey = tendersNavigatorKey;
|
|
}
|
|
|
|
class ProfileBranch extends StatefulShellBranchData {
|
|
const ProfileBranch();
|
|
static final GlobalKey<NavigatorState> $navigatorKey = profileNavigatorKey;
|
|
}
|
|
|
|
class NotificationBranch extends StatefulShellBranchData {
|
|
const NotificationBranch();
|
|
static final GlobalKey<NavigatorState> $navigatorKey =
|
|
notificationNavigatorKey;
|
|
}
|
|
|
|
// Route data classes
|
|
class HomeRouteData extends GoRouteData with _$HomeRouteData {
|
|
const HomeRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return homeProvider(child: const HomeScreen());
|
|
}
|
|
|
|
// @override
|
|
// Page<void> buildPage(BuildContext context, GoRouterState state) {
|
|
// return CustomTransitionPage<void>(
|
|
// key: state.pageKey,
|
|
// child: const HomeScreen(),
|
|
// transitionDuration: const Duration(milliseconds: 500),
|
|
// transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
// const begin = Offset(1.0, 0.0); // From right to left
|
|
// const end = Offset.zero;
|
|
// const curve = Curves.linearToEaseOut;
|
|
|
|
// var tween = Tween(
|
|
// begin: begin,
|
|
// end: end,
|
|
// ).chain(CurveTween(curve: curve));
|
|
// var offsetAnimation = animation.drive(tween);
|
|
// return SlideTransition(position: offsetAnimation, child: child);
|
|
// },
|
|
// );
|
|
// }
|
|
}
|
|
|
|
class TendersRouteData extends GoRouteData with _$TendersRouteData {
|
|
const TendersRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return tendersProvider(child: const TendersScreen());
|
|
}
|
|
}
|
|
|
|
class ProfileRouteData extends GoRouteData with _$ProfileRouteData {
|
|
const ProfileRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return profileProvider(child: const ProfileScreen());
|
|
}
|
|
}
|
|
|
|
class NotificationRouteData extends GoRouteData with _$NotificationRouteData {
|
|
const NotificationRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return notificationProvider(child: const NotificationScreen());
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<YourTendersRouteData>(path: '/your-tenders')
|
|
class YourTendersRouteData extends GoRouteData with _$YourTendersRouteData {
|
|
final String status;
|
|
const YourTendersRouteData({required this.status});
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return yourTendersProvider(child: YourTendersScreen(status: status));
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<FinalCompletionOfDocumentsRouteData>(
|
|
path: '/final_completion_of_documents',
|
|
)
|
|
class FinalCompletionOfDocumentsRouteData extends GoRouteData
|
|
with _$FinalCompletionOfDocumentsRouteData {
|
|
const FinalCompletionOfDocumentsRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return finalCompletionProvider(
|
|
child: const FinalCompletionOfDocumentsScreen(),
|
|
);
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<LikedTendersRouteData>(path: '/like-tenders')
|
|
class LikedTendersRouteData extends GoRouteData with _$LikedTendersRouteData {
|
|
const LikedTendersRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return likedTendersProvider(child: const LikedTendersScreen());
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<CompletionOfDocumentsMobileRouteData>(
|
|
path: '/completion-of-documents',
|
|
)
|
|
class CompletionOfDocumentsMobileRouteData extends GoRouteData
|
|
with _$CompletionOfDocumentsMobileRouteData {
|
|
const CompletionOfDocumentsMobileRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return finalCompletionProvider(
|
|
child: const CompletionOfDocumentsMobilePage(),
|
|
);
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<TenderDetailRouteData>(path: '/tender-detail')
|
|
class TenderDetailRouteData extends GoRouteData with _$TenderDetailRouteData {
|
|
final String tenderId;
|
|
const TenderDetailRouteData({required this.tenderId});
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return tenderDetailProvider(child: TenderDetailScreen(tenderId: tenderId));
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<ForgotPasswordRouteData>(path: '/forgot-password')
|
|
class ForgotPasswordRouteData extends GoRouteData
|
|
with _$ForgotPasswordRouteData {
|
|
const ForgotPasswordRouteData();
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return forgotPasswordProvider(child: const ForgotPasswordScreen());
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<ForgotPasswordOtpRouteData>(path: '/forgot-password-otp')
|
|
class ForgotPasswordOtpRouteData extends GoRouteData
|
|
with _$ForgotPasswordOtpRouteData {
|
|
final String email;
|
|
const ForgotPasswordOtpRouteData({required this.email});
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return verifyOtpProvider(child: ForgotPasswordOtpScreen(email: email));
|
|
}
|
|
}
|
|
|
|
@TypedGoRoute<ForgotPasswordCreateRouteData>(path: '/forgot-password-create')
|
|
class ForgotPasswordCreateRouteData extends GoRouteData
|
|
with _$ForgotPasswordCreateRouteData {
|
|
final String resetToken;
|
|
const ForgotPasswordCreateRouteData({required this.resetToken});
|
|
|
|
@override
|
|
Widget build(BuildContext context, GoRouterState state) {
|
|
return resetPasswordProvider(
|
|
child: ForgotPasswordCreateScreen(resetToken: resetToken),
|
|
);
|
|
}
|
|
}
|