enrollment-app/lib/main.dart

456 lines
14 KiB
Dart
Executable File

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhancepolicy/addons.dart';
import 'package:nhancepolicy/branch/branch_selection_page.dart';
import 'package:nhancepolicy/empReview.dart';
import 'package:nhancepolicy/empDetails.dart';
import 'package:nhancepolicy/presentation/preFileUpload.dart';
import 'package:nhancepolicy/hrHome.dart';
import 'package:nhancepolicy/hrVerify.dart';
import 'package:nhancepolicy/presentation/excelVerification.dart';
import 'package:nhancepolicy/presentation/postFileUpload.dart';
import 'package:nhancepolicy/presentation/cdList.dart';
import 'package:nhancepolicy/presentation/claims.dart';
import 'package:nhancepolicy/presentation/nonEBClaimsList.dart';
import 'package:nhancepolicy/presentation/pendingDependentApproval.dart';
import 'package:nhancepolicy/presentation/policies.dart';
import 'package:nhancepolicy/service/session/session_service.dart';
import 'package:nhancepolicy/service/token_storage_service.dart';
import 'package:nhancepolicy/home.dart';
import 'package:nhancepolicy/presentation/claims_overview/claims_overview_dashboard.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:nhancepolicy/hrLogin.dart';
import 'package:nhancepolicy/presentation/hrPolicyDetails.dart';
import 'package:nhancepolicy/oldPolicy.dart';
// import 'package:firebase_core/firebase_core.dart';
import 'presentation/cdTransactionDetails.dart';
import 'config/environment.dart';
import 'email_verify.dart';
import 'package:nhancepolicy/logger.dart';
Future<void> startApp() async {
// html.window.onBeforeUnload.listen((event) {
// logDebug('Local Storage cleared by window');
// html.window.localStorage.clear();
// });
// Ask confirmation (browser may or may not show it again)
// html.window.onBeforeUnload.listen((event) {
// final e = event as html.BeforeUnloadEvent;
// e.preventDefault();
// e.returnValue = '';
// });
// Always clear when user leaves (refresh/close)
// html.window.onUnload.listen((event) {
// html.window.localStorage.clear();
// });
// await dotenv.load(fileName: Environment.fileName);
WidgetsFlutterBinding.ensureInitialized();
// final sessionService = SessionService();
// await sessionService.restoreSession(); // ⭐ IMPORTANT
// Initialize token storage
await TokenStorageService().initialize();
// await Firebase.initializeApp(
// options: const FirebaseOptions(
// apiKey: 'AIzaSyCSvDM5fG2blDBE69Cae3S-iYRwwNBy7xo',
// appId: '1:1084115316849:web:ce28f12a426f285d6c6bd0',
// messagingSenderId: '1084115316849',
// projectId: 'nhance-ee8d1'));
// await dotenv.load(fileName: Environment.fileName);
// runApp(MaterialApp(
// title: 'Nhance HR',
// onGenerateTitle: (context) => "Nhance HR",
// initialRoute: 'hrLogin',
// debugShowCheckedModeBanner: false,
// theme: ThemeData(
// primaryColor: Color(0xFF00999E), // Primary theme color
// scaffoldBackgroundColor: Colors.white,
// colorScheme: ColorScheme.fromSeed(
// seedColor: Color(0xFF00999E),
// ),
// textTheme: GoogleFonts.poppinsTextTheme(),
// elevatedButtonTheme: ElevatedButtonThemeData(
// style: ElevatedButton.styleFrom(
// backgroundColor: Color(0xFF00999E), // Button background
// ),
// ),
// ),
// routes: {
// 'phone': (context) => MyPhone(),
// 'mailVerify': (context) => MyEmailVerify(
// type: '',
// value: '',
//
// ),
// 'verify': (context) => MyVerify(
// verificationId: '',
// mobileNumber: '',
// resendToken: null,
// onResendCode: (String, int) {},
// ),
// 'home': (context) => MyApp(),
// 'hrLogin': (context) => MyHrLogin(),
// // 'hrVerify': (context) => MyHrVerify(
// // verificationId: '',
// // mobileNumber: '',
// // resendToken: null,
// // onResendCode: (String, int) {},
// // ),
// 'hrHome': (context) => MyHrHome(),
// 'preFileUpload': (context) => const preFileUpload(
// ClientId: '',
// policyTypeId: '',
// ClientPoliyId: '',
// clientBranchId: '',
// Token: '',
// TokenType: '',
// cardType: '',
// cardPolicyNo: '',
// cardInsurer_name: '',
// cardPolicy_name: '',
// cardPolicy_ExpDate: '',
// total_premium: '',
// ),
// 'postFileUpload': (context) => const postFileUpload(
// ClientId: '',
// policyTypeId: '',
// ClientPoliyId: '',
// clientBranchId: '',
// Token: '',
// TokenType: '',
// cardType: '',
// cardPolicyNo: '',
// cardInsurer_name: '',
// cardPolicy_name: '',
// cardPolicy_ExpDate: '',
// total_premium: '',
// ),
// 'excelErrorScreen': (context) => const excelErrorScreen(
// ClientId: '',
// policy_no: '',
// action: '',
// created_at: '',
// clientBranchId: '',
// Token: '',
// TokenType: '',
// id: ''
// ),
// 'empDetails': (context) => empDetails(),
// 'addOnsDetails': (context) => addOnsDetails(),
// 'empReviewDetails': (context) => empReviewDetails(),
// 'hrDashboard': (context) => hrDashboard(),
// 'hrPolicyDetails': (context) => hrPolicyDetails(
// ClientId: '',
// policyTypeId: '',
// ClientPoliyId: '',
// clientBranchId: '',
// Token: '',
// TokenType: '',
// cardType: '',
// cardPolicyNo: '',
// cardInsurer_name: '',
// cardPolicy_name: '',
// cardPolicy_ExpDate: '',
// total_premium: '',
// is_ecard_bulk_download_for_employee: 0,
// ),
// 'oldPolicy': (context) => oldPolicy(),
// 'branchSelection': (context) => BranchSelectionPage(),
// 'policies': (context) => policies(),
// 'CdPoliciesList': (context) => CdPoliciesList(),
// 'ClaimsPolicies': (context) => ClaimsPolicies(
// empCode:'',
// ),
// 'cdTransactionDetails': (context) => cdTransactionDetails(
// insurerName: '',
// cdMasterAccountNo: '',
// insurerId: '',
// cd_ac_pk: '',
// empClientId: '',
// ),
// },
// ));
final tokenService = TokenStorageService();
final token = await tokenService.getCurrentToken();
runApp(MyApp(initialToken: token));
}
/// Routes that require an authenticated HR session.
/// Public auth-flow routes (hrLogin, mailVerify, branchSelection) stay excluded.
const Set<String> _authProtectedRoutes = {
'hrHome',
'hrDashboard',
'policies',
'pendingDependentApproval',
'claimsOverviewDashboard',
'ClaimsPolicies',
'nonEBClaimsList',
'CdPoliciesList',
'cdTransactionDetails',
'hrPolicyDetails',
'oldPolicy',
'preFileUpload',
'postFileUpload',
'excelErrorScreen',
'empDetails',
'addOnsDetails',
'empReviewDetails',
};
String _normalizeRouteName(String routeName) {
var name = routeName.trim();
if (name.startsWith('#')) {
name = name.substring(1);
}
if (name.startsWith('/')) {
name = name.substring(1);
}
// Flutter web may include query/hash fragments; keep only path segment.
final hashIndex = name.indexOf('#');
if (hashIndex != -1) {
name = name.substring(hashIndex + 1);
}
final queryIndex = name.indexOf('?');
if (queryIndex != -1) {
name = name.substring(0, queryIndex);
}
return name;
}
bool _hasValidSession() {
final token = TokenStorageService().getCurrentToken();
return token != null && token.trim().isNotEmpty;
}
class MyApp extends StatelessWidget {
final String? initialToken;
const MyApp({super.key, this.initialToken});
@override
Widget build(BuildContext context) {
final fallbackRoute =
(initialToken == null || initialToken!.isEmpty) ? 'hrLogin' : 'hrHome';
return MaterialApp(
title: 'Nhance HR',
debugShowCheckedModeBanner: false,
initialRoute: fallbackRoute,
onGenerateInitialRoutes: (String initialRouteName) {
final requested = _normalizeRouteName(initialRouteName);
final resolved = (requested.isEmpty || requested == '/')
? fallbackRoute
: requested;
// Deep-link guard: unauthenticated access to protected URLs → HR login
final targetRoute =
(!_hasValidSession() && _authProtectedRoutes.contains(resolved))
? 'hrLogin'
: resolved;
final builder = appRoutes[targetRoute] ?? appRoutes['hrLogin']!;
return [
MaterialPageRoute(
builder: builder,
settings: RouteSettings(name: targetRoute),
),
];
},
theme: ThemeData(
primaryColor: const Color(0xFF00999E),
scaffoldBackgroundColor: Colors.white,
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF00999E),
),
textTheme: GoogleFonts.poppinsTextTheme(),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF00999E),
),
),
),
routes: appRoutes,
);
}
}
final Map<String, WidgetBuilder> appRoutes = {
'mailVerify': (context) => MyEmailVerify(
type: '',
value: '',
),
'home': (context) => MyApp(),
'hrLogin': (context) => MyHrLogin(),
// 'hrVerify': (context) => MyHrVerify(
// verificationId: '',
// mobileNumber: '',
// resendToken: null,
// onResendCode: (String, int) {},
// ),
'hrHome': (context) => AuthWrapper(
builder: (_) => MyHrHome(),
),
'preFileUpload': (context) => AuthWrapper(
builder: (_) => const preFileUpload(
ClientId: '',
policyTypeId: '',
ClientPoliyId: '',
clientBranchId: '',
Token: '',
TokenType: '',
cardType: '',
cardPolicyNo: '',
cardInsurer_name: '',
cardPolicy_name: '',
cardPolicy_ExpDate: '',
total_premium: '',
),
),
'postFileUpload': (context) => AuthWrapper(
builder: (_) => const postFileUpload(
ClientId: '',
policyTypeId: '',
ClientPoliyId: '',
clientBranchId: '',
Token: '',
TokenType: '',
cardType: '',
cardPolicyNo: '',
cardInsurer_name: '',
cardPolicy_name: '',
cardPolicy_ExpDate: '',
total_premium: '',
),
),
'excelErrorScreen': (context) => AuthWrapper(
builder: (_) => const excelErrorScreen(
ClientId: '',
policy_no: '',
action: '',
created_at: '',
clientBranchId: '',
Token: '',
TokenType: '',
id: ''),
),
'empDetails': (context) => AuthWrapper(
builder: (_) => empDetails(),
),
'addOnsDetails': (context) => AuthWrapper(
builder: (_) => addOnsDetails(),
),
'empReviewDetails': (context) => AuthWrapper(
builder: (_) => empReviewDetails(),
),
'hrDashboard': (context) => AuthWrapper(
builder: (_) => const policies(),
),
'claimsOverviewDashboard': (context) => AuthWrapper(
builder: (_) => const ClaimsOverviewDashboard(),
),
'hrPolicyDetails': (context) => AuthWrapper(
builder: (_) => hrPolicyDetails(
ClientId: '',
policyTypeId: '',
ClientPoliyId: '',
clientBranchId: '',
Token: '',
TokenType: '',
cardType: '',
cardPolicyNo: '',
cardInsurer_name: '',
cardPolicy_name: '',
cardPolicy_ExpDate: '',
total_premium: '',
is_ecard_bulk_download_for_employee: 0,
),
),
'oldPolicy': (context) => AuthWrapper(
builder: (_) => oldPolicy(),
),
// Branch selection happens after login but before a branch token is set.
'branchSelection': (context) => BranchSelectionPage(),
'policies': (context) => AuthWrapper(
builder: (_) => const policies(),
),
'pendingDependentApproval': (context) => AuthWrapper(
builder: (_) => const PendingDependentApproval(),
),
'CdPoliciesList': (context) => AuthWrapper(
builder: (_) => CdPoliciesList(),
),
'ClaimsPolicies': (context) => AuthWrapper(
builder: (_) => const ClaimsPolicies(
empCode: '',
),
),
'nonEBClaimsList': (context) => AuthWrapper(
builder: (_) => const NonEBClaimsList(
empCode: '',
),
),
'cdTransactionDetails': (context) => AuthWrapper(
builder: (_) => cdTransactionDetails(
insurerName: '',
cdMasterAccountNo: '',
insurerId: '',
cd_ac_pk: '',
empClientId: '',
),
),
};
/// 🔐 Auth Wrapper — blocks protected pages until a valid session exists.
/// Uses a builder so protected widgets are not constructed without a token.
class AuthWrapper extends StatefulWidget {
final WidgetBuilder builder;
const AuthWrapper({super.key, required this.builder});
@override
State<AuthWrapper> createState() => _AuthWrapperState();
}
class _AuthWrapperState extends State<AuthWrapper> {
late final bool _isAuthenticated;
@override
void initState() {
super.initState();
_isAuthenticated = _hasValidSession();
if (!_isAuthenticated) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
Navigator.pushNamedAndRemoveUntil(
context,
'hrLogin',
(route) => false,
);
});
}
}
@override
Widget build(BuildContext context) {
if (!_isAuthenticated) {
// Do not render protected UI while redirecting to login.
return const Scaffold(
body: Center(
child: CircularProgressIndicator(
color: Color(0xFF00999E),
),
),
);
}
return widget.builder(context);
}
}