branch module
This commit is contained in:
parent
f5cd4d89ad
commit
01f99fa2ca
@ -1,4 +1,4 @@
|
||||
API_URL=https://venbait.in/enrollment/employeeRest/
|
||||
API_URL_POST=https://venbait.in/nhance/dev/employeeRest/
|
||||
BASE_HREF=/nhance/hr/dev/
|
||||
ENV=development
|
||||
API_URL=https://app.nhanceindia.in/enrolment/employeeRest/
|
||||
API_URL_POST=https://app.nhanceindia.in/zenith/employeeRest/
|
||||
BASE_HREF=/hr/
|
||||
ENV=production
|
||||
@ -45,7 +45,7 @@ android {
|
||||
applicationId "com.example.nhance_app_pwa"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdkVersion 23
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
||||
63
lib/branch/branch_card_widget.dart
Normal file
63
lib/branch/branch_card_widget.dart
Normal file
@ -0,0 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
class BranchCard extends StatelessWidget {
|
||||
final String clientName;
|
||||
final String branchName;
|
||||
final bool isSelected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const BranchCard({
|
||||
Key? key,
|
||||
required this.clientName,
|
||||
required this.branchName,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? Color(0xFF00999E) : Color(0xFFF0F9F9),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
color: Color(0xFF00999E),
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
clientName,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isSelected ? Colors.white : Color(0xFF00999E),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
branchName,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: isSelected ? Color(0xFFFDFDFD) : Color(0xFF000000),
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
272
lib/branch/branch_selection_page.dart
Normal file
272
lib/branch/branch_selection_page.dart
Normal file
@ -0,0 +1,272 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../service/token_storage_service.dart';
|
||||
import 'branch_card_widget.dart';
|
||||
|
||||
|
||||
class BranchSelectionPage extends StatefulWidget {
|
||||
const BranchSelectionPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BranchSelectionPage> createState() => _BranchSelectionPageState();
|
||||
}
|
||||
|
||||
class _BranchSelectionPageState extends State<BranchSelectionPage> {
|
||||
List<Map<String, dynamic>> branches = [];
|
||||
int? selectedIndex;
|
||||
final tokenStorage = TokenStorageService();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadBranches();
|
||||
}
|
||||
|
||||
void _loadBranches() {
|
||||
setState(() {
|
||||
branches = tokenStorage.getCombinedBranches();
|
||||
});
|
||||
}
|
||||
|
||||
void _selectBranch(int index) {
|
||||
setState(() {
|
||||
selectedIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _handleNext() async {
|
||||
if (selectedIndex == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Please select a branch'),
|
||||
backgroundColor: Colors.orange,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final selectedBranch = branches[selectedIndex!];
|
||||
|
||||
// Save selected branch and decode token
|
||||
await tokenStorage.saveSelectedBranch(selectedBranch);
|
||||
|
||||
// Debug: Print decoded token
|
||||
final decodedToken = tokenStorage.getDecodedToken();
|
||||
print('Selected Branch: $selectedBranch');
|
||||
print('Decoded Token: $decodedToken');
|
||||
|
||||
// Navigate to home
|
||||
if (mounted) {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
//Post Token Decode Details
|
||||
final empClientBranchId = decodedToken?['post_branch_id'];
|
||||
await prefs.setString('empClientBranchId', empClientBranchId);
|
||||
|
||||
final empPrimaryId = decodedToken?['post_hr_id'];
|
||||
await prefs.setString('empPrimaryId', empPrimaryId);
|
||||
|
||||
final empClientId = decodedToken?['post_client_id'];
|
||||
await prefs.setString('empClientId', empClientId);
|
||||
|
||||
final empHrId = decodedToken?['post_hr_id'];
|
||||
await prefs.setString('empHrId', empHrId);
|
||||
|
||||
dynamic allowedModules = decodedToken?['allowed_modules'];
|
||||
|
||||
// If it's a String, decode it again
|
||||
if (allowedModules is String) {
|
||||
allowedModules = jsonDecode(allowedModules);
|
||||
}
|
||||
|
||||
final empAllowedModules = allowedModules['post'];
|
||||
|
||||
await prefs.setString('empAllowed_modules', jsonEncode(empAllowedModules));
|
||||
|
||||
// final empAllowed_modules = decodedToken?['allowed_modules'][0]['post'];
|
||||
// await prefs.setString('empAllowed_modules', jsonEncode(empAllowed_modules));
|
||||
|
||||
|
||||
//Pre Token Decode Details
|
||||
final enrollmentEmpClientBranchId = decodedToken?['pre_branch_id'];
|
||||
await prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId);
|
||||
|
||||
final enrollmentEmpPrimaryId = decodedToken?['pre_hr_id'];
|
||||
await prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId);
|
||||
|
||||
final enrollmentClient_id = decodedToken?['pre_client_id'];
|
||||
await prefs.setString('enrollmentClient_id', enrollmentClient_id);
|
||||
|
||||
final enrollmentHrId = decodedToken?['pre_hr_id'];
|
||||
await prefs.setString('enrollmentHrId', enrollmentHrId);
|
||||
|
||||
|
||||
final enrollmentAllowedModules = allowedModules['pre'];
|
||||
|
||||
await prefs.setString('enrollmentAllowed_modules', jsonEncode(enrollmentAllowedModules));
|
||||
|
||||
// final enrollmentAllowed_modules = decodedToken?['allowed_modules'][1]['pre'];
|
||||
// await prefs.setString('enrollmentAllowed_modules', jsonEncode(enrollmentAllowed_modules));
|
||||
|
||||
final token = await tokenStorage.getCurrentToken();
|
||||
print('tokenbranch - $token');
|
||||
await prefs.setString('token', token!);
|
||||
ToastHelper.showSuccessToast(context, 'Successfully Login');
|
||||
Navigator.pushReplacementNamed(context, 'hrDashboard');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
// Calculate dynamic horizontal padding (10% of screen width)
|
||||
final horizontalPadding = screenWidth * 0.1;
|
||||
|
||||
// Calculate dynamic grid height
|
||||
double gridHeight = screenHeight * 0.45;
|
||||
if (gridHeight < 300) gridHeight = 300;
|
||||
if (gridHeight > 600) gridHeight = 600;
|
||||
|
||||
// Determine crossAxisCount with multiple breakpoints
|
||||
int crossAxisCount;
|
||||
double childAspectRatio;
|
||||
|
||||
if (screenWidth < 600) {
|
||||
// Mobile phones
|
||||
crossAxisCount = 2;
|
||||
childAspectRatio = 2.5;
|
||||
} else if (screenWidth < 900) {
|
||||
// Small tablets
|
||||
crossAxisCount = 2;
|
||||
childAspectRatio = 2.8;
|
||||
} else if (screenWidth < 1200) {
|
||||
// Large tablets
|
||||
crossAxisCount = 3;
|
||||
childAspectRatio = 3;
|
||||
} else {
|
||||
// Desktop
|
||||
crossAxisCount = 3;
|
||||
childAspectRatio = 5;
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFEFF3F6),
|
||||
appBar: CustomAppBar(),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: horizontalPadding , // Inner horizontal padding
|
||||
vertical: 20, // Inner vertical padding
|
||||
), // Outer padding
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.05),
|
||||
blurRadius: 10,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24.0, // Inner horizontal padding
|
||||
vertical: 28.0, // Inner vertical padding
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Select Client',
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 25),
|
||||
|
||||
Container(
|
||||
height: gridHeight, // Shows approximately 3 rows
|
||||
child: branches.isEmpty
|
||||
? Center(
|
||||
child: Text(
|
||||
'No branches available',
|
||||
style: TextStyle(fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
)
|
||||
: GridView.builder(
|
||||
// Enable scrolling if content exceeds height
|
||||
physics: ClampingScrollPhysics(),
|
||||
padding: EdgeInsets.zero,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAxisCount,
|
||||
childAspectRatio: childAspectRatio,
|
||||
crossAxisSpacing: 15,
|
||||
mainAxisSpacing: 15,
|
||||
),
|
||||
itemCount: branches.length,
|
||||
itemBuilder: (context, index) {
|
||||
final branch = branches[index];
|
||||
return BranchCard(
|
||||
clientName: branch['client_name'] ?? 'Unknown Client',
|
||||
branchName: branch['branch_name'] ?? 'Unknown Branch',
|
||||
isSelected: selectedIndex == index,
|
||||
onTap: () => _selectBranch(index),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 24),
|
||||
|
||||
Center(
|
||||
child: SizedBox(
|
||||
width: 120,
|
||||
height: 48,
|
||||
child: ElevatedButton(
|
||||
onPressed: _handleNext,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFFFF6B35),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
elevation: 0,
|
||||
),
|
||||
child: Text(
|
||||
'Next',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
child: CustomFooter(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -87,12 +87,29 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
// },
|
||||
// ),
|
||||
// if (showBackToHR)
|
||||
// NavBarItem(
|
||||
// text: "Back To HR",
|
||||
// onTap: () {
|
||||
// // hrLogout(context);
|
||||
// },
|
||||
// ),
|
||||
NavBarItem(
|
||||
text: "Change Branch",
|
||||
onTap: () async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove('selected_branch');
|
||||
await prefs.remove('decoded_token');
|
||||
await prefs.remove('clientLogo');
|
||||
await prefs.remove('clientName');
|
||||
await prefs.remove('empAllowed_modules');
|
||||
await prefs.remove('empClientBranchId');
|
||||
await prefs.remove('empClientId');
|
||||
await prefs.remove('empEmail');
|
||||
await prefs.remove('empHrId');
|
||||
await prefs.remove('empPrimaryId');
|
||||
await prefs.remove('enrollmentAllowed_modules');
|
||||
await prefs.remove('enrollmentClient_id');
|
||||
await prefs.remove('enrollmentEmpClientBranchId');
|
||||
await prefs.remove('enrollmentEmpPrimaryId');
|
||||
await prefs.remove('enrollmentHrId');
|
||||
await prefs.remove('token');
|
||||
Navigator.pushNamed(context, 'branchSelection');
|
||||
},
|
||||
),
|
||||
NavBarItem(
|
||||
text: "Logout",
|
||||
onTap: () async {
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:nhancepolicy/responsive.dart';
|
||||
import 'package:nhancepolicy/service/api_service.dart';
|
||||
import 'package:nhancepolicy/service/token_storage_service.dart';
|
||||
import 'package:pinput/pinput.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@ -17,16 +18,15 @@ import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import '../models/platform_helper_mobile.dart'
|
||||
if (dart.library.html) '../models/platform_helper_other.dart';
|
||||
import 'branch/branch_selection_page.dart';
|
||||
|
||||
// import 'dart:html' as html;
|
||||
|
||||
class MyEmailVerify extends StatefulWidget {
|
||||
final String email;
|
||||
final String type; // 'email' or 'mobile'
|
||||
final String value;
|
||||
|
||||
const MyEmailVerify({
|
||||
Key? key,
|
||||
required this.email,
|
||||
}) : super(key: key);
|
||||
const MyEmailVerify({super.key, required this.type, required this.value});
|
||||
|
||||
@override
|
||||
State<MyEmailVerify> createState() => _MyEmailVerifyState();
|
||||
@ -99,9 +99,12 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
|
||||
|
||||
void verifyOTP(String otp) async {
|
||||
try {
|
||||
final Map<String, dynamic> payload = (widget.type == 'mobile')
|
||||
? {'otp': _otpController.text,'mobile_no': widget.value}
|
||||
: {'otp': _otpController.text, 'email': widget.value};
|
||||
final response = await http.post(
|
||||
Uri.parse(Environment.apiUrl + 'getVerifiedHrData'),
|
||||
body: json.encode({'email': widget.email, 'otp': _otpController.text}),
|
||||
body: json.encode(payload),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json',
|
||||
},
|
||||
@ -112,35 +115,56 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
|
||||
_isLoading = false;
|
||||
});
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
print('data: $data');
|
||||
_token = data['data'];
|
||||
String status = data['status'];
|
||||
print('Response data: $data');
|
||||
|
||||
// Directly access the post_enrollment data
|
||||
Map<String, dynamic> post = data['post_enrollment'];
|
||||
print('post: $post');
|
||||
// Extract enrollment data
|
||||
List<dynamic> preEnrollmentData = data['data'] ?? [];
|
||||
Map<String, dynamic> postEnrollment = data['post_enrollment'] ?? {};
|
||||
List<dynamic> postEnrollmentData = postEnrollment['data'] ?? [];
|
||||
|
||||
_postToken = post['data'];
|
||||
String postStatus = post['status'];
|
||||
// Save to global storage
|
||||
final tokenStorage = TokenStorageService();
|
||||
await tokenStorage.saveEnrollmentData(
|
||||
preEnrollmentData,
|
||||
postEnrollmentData,
|
||||
);
|
||||
|
||||
if (postStatus == 'success') {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
postSuccessData(post, data);
|
||||
} else if (status == 'success') {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
enrollmentSuccessData(data);
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
// Show a Snackbar if the OTP is invalid
|
||||
print('Invalid OTP. Please try again');
|
||||
}
|
||||
// Navigate to branch selection
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BranchSelectionPage(),
|
||||
),
|
||||
);
|
||||
// print('data: $data');
|
||||
// _token = data['data'];
|
||||
// String status = data['status'];
|
||||
//
|
||||
// // Directly access the post_enrollment data
|
||||
// Map<String, dynamic> post = data['post_enrollment'];
|
||||
// print('post: $post');
|
||||
//
|
||||
// _postToken = post['data'];
|
||||
// String postStatus = post['status'];
|
||||
//
|
||||
// if (postStatus == 'success') {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// postSuccessData(post, data);
|
||||
// } else if (status == 'success') {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// enrollmentSuccessData(data);
|
||||
// } else {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
// // Show a Snackbar if the OTP is invalid
|
||||
// print('Invalid OTP. Please try again');
|
||||
// }
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
@ -289,9 +313,17 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
|
||||
Future<void> verifyMobileAndEmailNumber() async {
|
||||
try {
|
||||
// var enteredMobileNumber = mobileController.text;
|
||||
final Map<String, dynamic> payload = (widget.type == 'mobile')
|
||||
? {'mobile_number': widget.value}
|
||||
: {'email': widget.value};
|
||||
|
||||
String apiEndpoint = (widget.type == 'mobile')
|
||||
? Environment.apiUrl + 'verifyHrWithMobileNumber'
|
||||
: Environment.apiUrl + 'verifyHrWithEmail';
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse(Environment.apiUrl + 'verifyEmployeeEmailId'),
|
||||
body: json.encode({'email': widget.email}),
|
||||
Uri.parse(apiEndpoint),
|
||||
body: json.encode(payload),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json',
|
||||
},
|
||||
@ -303,7 +335,7 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
|
||||
String message = data['data']['message'];
|
||||
if (userVerification) {
|
||||
ToastHelper.showSuccessToast(
|
||||
context, 'Verification code sent to ${widget.email}');
|
||||
context, 'Verification code sent to ${widget.value}');
|
||||
} else {
|
||||
ToastHelper.showErrorToast(context, message);
|
||||
print('Invalid mobile number');
|
||||
@ -622,14 +654,17 @@ class _MyEmailVerifyState extends State<MyEmailVerify> {
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text:
|
||||
"Please enter the one-time usage code sent to your mobile number ${widget.email}",
|
||||
"Please enter the one-time usage code sent to your ",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1.5,
|
||||
color: Color(0xFF000000)),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: " (Change Email)",
|
||||
text: widget.type == 'mobile' ? 'mobile number ${widget.value}' : 'Email Id ${widget.value}',
|
||||
),
|
||||
TextSpan(
|
||||
text: widget.type == 'mobile' ? ' (Change Mobile)' : ' (Change Email)',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(
|
||||
|
||||
@ -495,6 +495,9 @@ class _excelVerifyState extends State<excelVerify> {
|
||||
});
|
||||
handleImportAction();
|
||||
} else {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
ToastHelper.showErrorToast(context, data['message']);
|
||||
print('Table');
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import 'package:nhancepolicy/service/hrDashboardTabs/activePolicies.dart';
|
||||
import 'package:nhancepolicy/service/hrDashboardTabs/cd.dart';
|
||||
import 'package:nhancepolicy/service/hrDashboardTabs/claims.dart';
|
||||
import 'package:nhancepolicy/service/hrDashboardTabs/preEnrollment.dart';
|
||||
import 'package:nhancepolicy/service/token_storage_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'customAppBar/customAppBar.dart';
|
||||
@ -75,6 +76,7 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
];
|
||||
ScrollController _scrollController = ScrollController();
|
||||
int selectedIndex = 0;
|
||||
final tokenService = TokenStorageService();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -94,6 +96,7 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
// isLoading = false;
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
@ -104,11 +107,15 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
|
||||
checkToken() async {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
enrollToken = prefs.getString('enrollToken');
|
||||
_postToken = prefs.getString('_postToken');
|
||||
// enrollToken = prefs.getString('pre_enrollment_data');
|
||||
// _postToken = prefs.getString('post_enrollment_data');
|
||||
|
||||
// Get the current token
|
||||
final token = await tokenService.getCurrentToken();
|
||||
print('token - $token');
|
||||
|
||||
print('token check in');
|
||||
if((enrollToken != null && enrollToken!.isNotEmpty) || (_postToken != null && _postToken!.isNotEmpty)){
|
||||
if((token != null && token!.isNotEmpty)){
|
||||
print('token check done');
|
||||
_loadToken();
|
||||
} else {
|
||||
@ -120,17 +127,21 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
_postToken = prefs.getString('_postToken');
|
||||
enrollToken = prefs.getString('enrollToken');
|
||||
enrollToken = await tokenService.getCurrentToken();
|
||||
_postToken = await tokenService.getCurrentToken();
|
||||
print(enrollToken);
|
||||
print(_postToken);
|
||||
|
||||
|
||||
if (enrollToken != null && enrollToken!.isNotEmpty) {
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(enrollToken!);
|
||||
enrollmentClient_id = decodedToken['client_id'].toString();
|
||||
// Map<String, dynamic>? decodedToken = Jwt.parseJwt(enrollToken!);
|
||||
// enrollmentClient_id = decodedToken['client_id'].toString();
|
||||
enrollmentClient_id = prefs.getString('enrollmentClient_id');
|
||||
enrollmentEmpClientBranchId =
|
||||
prefs.getString('enrollmentEmpClientBranchId');
|
||||
enrollmentHrId = prefs.getString('enrollmentHrId');
|
||||
|
||||
print("Pre decodedToken - $decodedToken");
|
||||
// print("Pre decodedToken - $decodedToken");
|
||||
print("Pre enrollmentClient_id - $enrollmentClient_id");
|
||||
print("Pre enrollmentEmpClientBranchId - $enrollmentEmpClientBranchId");
|
||||
print("Pre enrollmentHrId - $enrollmentHrId");
|
||||
@ -163,7 +174,9 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
clientLogo = prefs.getString('clientLogo');
|
||||
clientName = prefs.getString('clientName');
|
||||
} else {
|
||||
getClientLogoAndDetails(
|
||||
empClientId = prefs.getString('empClientId');
|
||||
empClientBranchId = prefs.getString('empClientBranchId');
|
||||
getClientLogoAndDetails(empClientId,empClientBranchId,
|
||||
enrollmentEmpClientBranchId, enrollmentClient_id, enrollToken);
|
||||
}
|
||||
getCashDepositDetails(enrollmentEmpClientBranchId, enrollmentClient_id,
|
||||
@ -171,14 +184,15 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
}
|
||||
|
||||
if (_postToken != null && _postToken!.isNotEmpty) {
|
||||
Map<String, dynamic>? postdecodedToken = Jwt.parseJwt(_postToken!);
|
||||
// Map<String, dynamic>? postdecodedToken = Jwt.parseJwt(_postToken!);
|
||||
|
||||
empClientId = postdecodedToken['client_id'].toString();
|
||||
// empClientId = postdecodedToken['client_id'].toString();
|
||||
empClientId = prefs.getString('empClientId');
|
||||
empClientBranchId = prefs.getString('empClientBranchId');
|
||||
empHrId = prefs.getString('empHrId');
|
||||
|
||||
print('post empHrId- $empHrId');
|
||||
print('postdecodedToken- $postdecodedToken');
|
||||
// print('postdecodedToken- $postdecodedToken');
|
||||
print('post empClientId- $empClientId');
|
||||
print('post empClientBranchId- $empClientBranchId');
|
||||
|
||||
@ -250,7 +264,10 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
clientLogo = prefs.getString('clientLogo');
|
||||
clientName = prefs.getString('clientName');
|
||||
} else {
|
||||
getClientLogoAndDetails(empClientBranchId, empClientId, _postToken);
|
||||
empClientId = prefs.getString('empClientId');
|
||||
empClientBranchId = prefs.getString('empClientBranchId');
|
||||
getClientLogoAndDetails(empClientId,empClientBranchId,
|
||||
enrollmentEmpClientBranchId, enrollmentClient_id, _postToken);
|
||||
}
|
||||
print("getCashDepositDetails");
|
||||
}
|
||||
@ -344,9 +361,10 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<void> getClientLogoAndDetails(clintBranchId, clintID, token) async {
|
||||
Future<void> getClientLogoAndDetails(post_client_id, post_client_branch_id,
|
||||
pre_client_branch_id, pre_client_id, token) async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getClientDetails?client_id=$clintID&client_branch_id=$clintBranchId');
|
||||
'getClientDetails?post_client_id=$post_client_id&post_branch_id=$post_client_branch_id&pre_client_id=$pre_client_id&pre_branch_id=$pre_client_branch_id');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
@ -525,6 +543,7 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
width: double.infinity,
|
||||
// height: 75,
|
||||
height: MediaQuery.of(context).size.height * 0.12,
|
||||
|
||||
padding: Responsive.isDesktop(context)
|
||||
? const EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 20, right: 20)
|
||||
@ -542,32 +561,48 @@ class _hrDashboardState extends State<hrDashboard>
|
||||
height: 80,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Image.network(
|
||||
clientLogo ?? '',
|
||||
width: 80, // Set the width here
|
||||
height: 60, // Set the height here
|
||||
loadingBuilder: (BuildContext context,
|
||||
Widget child,
|
||||
ImageChunkEvent? loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
Uri.encodeFull(clientLogo ?? ''),
|
||||
width: 200,
|
||||
height: 200,
|
||||
fit: BoxFit.contain,
|
||||
frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
|
||||
if (wasSynchronouslyLoaded) {
|
||||
return child;
|
||||
}
|
||||
return AnimatedOpacity(
|
||||
opacity: frame == null ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeOut,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||
if (loadingProgress == null) {
|
||||
return child;
|
||||
}
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
value: loadingProgress.expectedTotalBytes !=
|
||||
null
|
||||
? loadingProgress
|
||||
.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: null,
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.grey),
|
||||
value: loadingProgress.expectedTotalBytes != null
|
||||
? loadingProgress.cumulativeBytesLoaded /
|
||||
(loadingProgress.expectedTotalBytes ?? 1)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
errorBuilder: (BuildContext context, Object error,
|
||||
StackTrace? stackTrace) {
|
||||
return Image.asset(
|
||||
'assets/Solid_gray.png', // Replace 'default_image.png' with your default image asset path
|
||||
width: 80,
|
||||
height: 60,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
|
||||
return Text('');
|
||||
// Image.asset(
|
||||
// 'assets/Solid_gray.png',
|
||||
// width: 80,
|
||||
// height: 60,
|
||||
// fit: BoxFit.cover,
|
||||
// );
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
267
lib/hrLogin.dart
267
lib/hrLogin.dart
@ -49,12 +49,12 @@ class _MyPhoneState extends State<MyHrLogin> {
|
||||
|
||||
clearLocalStorageWhenStarts(fromData) async {
|
||||
print(fromData);
|
||||
if(kIsWeb) {
|
||||
// if(kIsWeb) {
|
||||
print('vndbbcbdskbvkj3');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.clear();
|
||||
print('Local Storage Clear');
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -99,8 +99,6 @@ class _MyPhoneState extends State<MyHrLogin> {
|
||||
if (userVerification) {
|
||||
final SharedPreferences prefs =
|
||||
await SharedPreferences.getInstance();
|
||||
// var enteredMobileNumber = mobileController.text;
|
||||
// prefs.setString('empMobileNo', enteredMobileNumber);
|
||||
if (isEmailFieldVisible) {
|
||||
print('isEmailFieldVisible $isEmailFieldVisible');
|
||||
prefs.setString('empEmail', emailController.text);
|
||||
@ -111,12 +109,23 @@ class _MyPhoneState extends State<MyHrLogin> {
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MyEmailVerify(
|
||||
email: emailController.text, // Pass the phone number
|
||||
type: 'email',
|
||||
value: emailController.text.trim(), // Pass the phone number
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
_verifyPhoneNumber();
|
||||
ToastHelper.showSuccessToast(
|
||||
context, 'Verification code sent to ${emailController.text}');
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MyEmailVerify(
|
||||
type: 'mobile',
|
||||
value: mobileController.text.trim(), // Pass the phone number
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ToastHelper.showSuccessToast(context, message);
|
||||
@ -144,129 +153,129 @@ class _MyPhoneState extends State<MyHrLogin> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _verifyPhoneNumber() async {
|
||||
var enteredMobileNumber = mobileController.text;
|
||||
var countryCode = countryController.text;
|
||||
print('${countryCode + enteredMobileNumber}');
|
||||
await _auth.verifyPhoneNumber(
|
||||
phoneNumber: '${countryCode + enteredMobileNumber}',
|
||||
timeout: const Duration(seconds: 60),
|
||||
verificationCompleted: (PhoneAuthCredential credential) async {
|
||||
await _auth.signInWithCredential(credential);
|
||||
// ToastHelper.showSuccessToast(context, 'Verified Successfully!');
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
},
|
||||
verificationFailed: (FirebaseAuthException e) {
|
||||
print('Verification Failed: ${e.code} - ${e.message}');
|
||||
String errorMessage;
|
||||
if (e.code == 'invalid-app-credential') {
|
||||
errorMessage = 'Invalid Credential. Please try again.';
|
||||
} else if (e.code == 'invalid-phone-number') {
|
||||
errorMessage = 'The provided phone number is not valid.';
|
||||
} else if (e.code == 'too-many-requests') {
|
||||
errorMessage = 'Too many requests. Try again later.';
|
||||
} else {
|
||||
errorMessage = 'Verification Failed: ${e.message}';
|
||||
}
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(errorMessage),
|
||||
duration: Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
|
||||
ToastHelper.showSuccessToast(context, errorMessage);
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
},
|
||||
codeSent: (String verificationId, int? resendToken) async {
|
||||
setState(() {
|
||||
_verificationId = verificationId;
|
||||
_resendToken = resendToken;
|
||||
});
|
||||
|
||||
// When getting the verificationId
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString('verificationId', _verificationId);
|
||||
|
||||
ToastHelper.showSuccessToast(
|
||||
context, 'Verification code sent to ${enteredMobileNumber}');
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MyHrVerify(
|
||||
verificationId: _verificationId,
|
||||
mobileNumber: enteredMobileNumber,
|
||||
resendToken: _resendToken,
|
||||
onResendCode: _resendCode, // Pass the phone number
|
||||
),
|
||||
),
|
||||
);
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
},
|
||||
codeAutoRetrievalTimeout: (String verificationId) async {
|
||||
setState(() {
|
||||
_verificationId = verificationId;
|
||||
});
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('verificationId', verificationId);
|
||||
ToastHelper.showSuccessToast(context, 'Code auto-retrieval timed out.');
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _resendCode(String mobileNumber, int? resendToken) async {
|
||||
await _auth.verifyPhoneNumber(
|
||||
phoneNumber: '${countryController.text + mobileNumber}',
|
||||
timeout: const Duration(seconds: 60),
|
||||
forceResendingToken: resendToken,
|
||||
verificationCompleted: (PhoneAuthCredential credential) async {
|
||||
await _auth.signInWithCredential(credential);
|
||||
},
|
||||
verificationFailed: (FirebaseAuthException e) {
|
||||
if (e.code == 'invalid-phone-number') {
|
||||
print('The provided phone number is not valid.');
|
||||
}
|
||||
},
|
||||
codeSent: (String verificationId, int? resendToken) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('verificationId', verificationId);
|
||||
setState(() {
|
||||
_verificationId = verificationId;
|
||||
_resendToken = resendToken;
|
||||
});
|
||||
ToastHelper.showSuccessToast(
|
||||
context, 'Verification code resent to ${mobileNumber}');
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MyHrVerify(
|
||||
verificationId: _verificationId,
|
||||
mobileNumber: mobileNumber,
|
||||
resendToken: _resendToken,
|
||||
onResendCode: _resendCode,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
codeAutoRetrievalTimeout: (String verificationId) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('verificationId', verificationId);
|
||||
setState(() {
|
||||
_verificationId = verificationId;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
// Future<void> _verifyPhoneNumber() async {
|
||||
// var enteredMobileNumber = mobileController.text;
|
||||
// var countryCode = countryController.text;
|
||||
// print('${countryCode + enteredMobileNumber}');
|
||||
// await _auth.verifyPhoneNumber(
|
||||
// phoneNumber: '${countryCode + enteredMobileNumber}',
|
||||
// timeout: const Duration(seconds: 60),
|
||||
// verificationCompleted: (PhoneAuthCredential credential) async {
|
||||
// await _auth.signInWithCredential(credential);
|
||||
// // ToastHelper.showSuccessToast(context, 'Verified Successfully!');
|
||||
// // setState(() {
|
||||
// // _isLoading = false;
|
||||
// // });
|
||||
// },
|
||||
// verificationFailed: (FirebaseAuthException e) {
|
||||
// print('Verification Failed: ${e.code} - ${e.message}');
|
||||
// String errorMessage;
|
||||
// if (e.code == 'invalid-app-credential') {
|
||||
// errorMessage = 'Invalid Credential. Please try again.';
|
||||
// } else if (e.code == 'invalid-phone-number') {
|
||||
// errorMessage = 'The provided phone number is not valid.';
|
||||
// } else if (e.code == 'too-many-requests') {
|
||||
// errorMessage = 'Too many requests. Try again later.';
|
||||
// } else {
|
||||
// errorMessage = 'Verification Failed: ${e.message}';
|
||||
// }
|
||||
// ScaffoldMessenger.of(context).showSnackBar(
|
||||
// SnackBar(
|
||||
// content: Text(errorMessage),
|
||||
// duration: Duration(seconds: 2),
|
||||
// ),
|
||||
// );
|
||||
//
|
||||
// ToastHelper.showSuccessToast(context, errorMessage);
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// },
|
||||
// codeSent: (String verificationId, int? resendToken) async {
|
||||
// setState(() {
|
||||
// _verificationId = verificationId;
|
||||
// _resendToken = resendToken;
|
||||
// });
|
||||
//
|
||||
// // When getting the verificationId
|
||||
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
// prefs.setString('verificationId', _verificationId);
|
||||
//
|
||||
// ToastHelper.showSuccessToast(
|
||||
// context, 'Verification code sent to ${enteredMobileNumber}');
|
||||
//
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => MyHrVerify(
|
||||
// verificationId: _verificationId,
|
||||
// mobileNumber: enteredMobileNumber,
|
||||
// resendToken: _resendToken,
|
||||
// onResendCode: _resendCode, // Pass the phone number
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// },
|
||||
// codeAutoRetrievalTimeout: (String verificationId) async {
|
||||
// setState(() {
|
||||
// _verificationId = verificationId;
|
||||
// });
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.setString('verificationId', verificationId);
|
||||
// ToastHelper.showSuccessToast(context, 'Code auto-retrieval timed out.');
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// void _resendCode(String mobileNumber, int? resendToken) async {
|
||||
// await _auth.verifyPhoneNumber(
|
||||
// phoneNumber: '${countryController.text + mobileNumber}',
|
||||
// timeout: const Duration(seconds: 60),
|
||||
// forceResendingToken: resendToken,
|
||||
// verificationCompleted: (PhoneAuthCredential credential) async {
|
||||
// await _auth.signInWithCredential(credential);
|
||||
// },
|
||||
// verificationFailed: (FirebaseAuthException e) {
|
||||
// if (e.code == 'invalid-phone-number') {
|
||||
// print('The provided phone number is not valid.');
|
||||
// }
|
||||
// },
|
||||
// codeSent: (String verificationId, int? resendToken) async {
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.setString('verificationId', verificationId);
|
||||
// setState(() {
|
||||
// _verificationId = verificationId;
|
||||
// _resendToken = resendToken;
|
||||
// });
|
||||
// ToastHelper.showSuccessToast(
|
||||
// context, 'Verification code resent to ${mobileNumber}');
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => MyHrVerify(
|
||||
// verificationId: _verificationId,
|
||||
// mobileNumber: mobileNumber,
|
||||
// resendToken: _resendToken,
|
||||
// onResendCode: _resendCode,
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// codeAutoRetrievalTimeout: (String verificationId) async {
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
// await prefs.setString('verificationId', verificationId);
|
||||
// setState(() {
|
||||
// _verificationId = verificationId;
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:nhancepolicy/customAppBar/toastHelper.dart';
|
||||
import 'package:nhancepolicy/models/environment.dart';
|
||||
import 'package:nhancepolicy/service/api_service.dart';
|
||||
import 'package:nhancepolicy/service/token_storage_service.dart';
|
||||
import 'package:pinput/pinput.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@ -14,6 +15,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:nhancepolicy/responsive.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
|
||||
import 'branch/branch_selection_page.dart';
|
||||
|
||||
class MyHrVerify extends StatefulWidget {
|
||||
final String verificationId;
|
||||
final String mobileNumber;
|
||||
@ -139,35 +142,58 @@ class _MyVerifyState extends State<MyHrVerify> {
|
||||
_isLoading = false;
|
||||
});
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
print('data: $data');
|
||||
_token = data['data'];
|
||||
String status = data['status'];
|
||||
|
||||
// Directly access the post_enrollment data
|
||||
Map<String, dynamic> post = data['post_enrollment'];
|
||||
print('post: $post');
|
||||
print('Response data: $data');
|
||||
|
||||
_postToken = post['data'];
|
||||
String postStatus = post['status'];
|
||||
// Extract enrollment data
|
||||
List<dynamic> preEnrollmentData = data['data'] ?? [];
|
||||
Map<String, dynamic> postEnrollment = data['post_enrollment'] ?? {};
|
||||
List<dynamic> postEnrollmentData = postEnrollment['data'] ?? [];
|
||||
|
||||
if (postStatus == 'success') {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
postSuccessData(post, data);
|
||||
} else if (status == 'success') {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
enrollmentSuccessData(data);
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
// Show a Snackbar if the OTP is invalid
|
||||
print('Invalid OTP. Please try again');
|
||||
}
|
||||
// Save to global storage
|
||||
final tokenStorage = TokenStorageService();
|
||||
await tokenStorage.saveEnrollmentData(
|
||||
preEnrollmentData,
|
||||
postEnrollmentData,
|
||||
);
|
||||
|
||||
// Navigate to branch selection
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => BranchSelectionPage(),
|
||||
),
|
||||
);
|
||||
|
||||
// print('data: $data');
|
||||
// _token = data['data'];
|
||||
// String status = data['status'];
|
||||
//
|
||||
// // Directly access the post_enrollment data
|
||||
// Map<String, dynamic> post = data['post_enrollment'];
|
||||
// print('post: $post');
|
||||
//
|
||||
// _postToken = post['data'];
|
||||
// String postStatus = post['status'];
|
||||
//
|
||||
// if (postStatus == 'success') {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// postSuccessData(post, data);
|
||||
// } else if (status == 'success') {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// enrollmentSuccessData(data);
|
||||
// } else {
|
||||
// setState(() {
|
||||
// _isLoading = false;
|
||||
// });
|
||||
// ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
// // Show a Snackbar if the OTP is invalid
|
||||
// print('Invalid OTP. Please try again');
|
||||
// }
|
||||
} else {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
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/excel_verification.dart';
|
||||
@ -10,6 +11,7 @@ import 'package:nhancepolicy/hrVerify.dart';
|
||||
import 'package:nhancepolicy/models/environment.dart';
|
||||
import 'package:nhancepolicy/phone.dart';
|
||||
import 'package:nhancepolicy/postFileUpload.dart';
|
||||
import 'package:nhancepolicy/service/token_storage_service.dart';
|
||||
import 'package:nhancepolicy/verify.dart';
|
||||
import 'package:nhancepolicy/home.dart';
|
||||
import 'package:nhancepolicy/hrDashboard.dart';
|
||||
@ -28,8 +30,23 @@ Future<void> main() async {
|
||||
// print('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();
|
||||
|
||||
// Initialize token storage
|
||||
await TokenStorageService().initialize();
|
||||
|
||||
await Firebase.initializeApp(
|
||||
options: const FirebaseOptions(
|
||||
apiKey: 'AIzaSyCSvDM5fG2blDBE69Cae3S-iYRwwNBy7xo',
|
||||
@ -57,7 +74,9 @@ Future<void> main() async {
|
||||
routes: {
|
||||
'phone': (context) => MyPhone(),
|
||||
'mailVerify': (context) => MyEmailVerify(
|
||||
email: '',
|
||||
type: '',
|
||||
value: '',
|
||||
|
||||
),
|
||||
'verify': (context) => MyVerify(
|
||||
verificationId: '',
|
||||
@ -130,6 +149,7 @@ Future<void> main() async {
|
||||
cardPolicy_ExpDate: '',
|
||||
),
|
||||
'oldPolicy': (context) => oldPolicy(),
|
||||
'branchSelection': (context) => BranchSelectionPage(),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
@ -19,8 +19,8 @@ class ApiService {
|
||||
Future<void> _initializeToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_token = prefs.getString('token') ?? '';
|
||||
final hrprefs = await SharedPreferences.getInstance();
|
||||
_hrtoken = hrprefs.getString('hrtoken') ?? '';
|
||||
// final hrprefs = await SharedPreferences.getInstance();
|
||||
// _hrtoken = hrprefs.getString('hrtoken') ?? '';
|
||||
}
|
||||
|
||||
Future<void> getTokenLoadAPI(token) async {
|
||||
|
||||
157
lib/service/token_storage_service.dart
Normal file
157
lib/service/token_storage_service.dart
Normal file
@ -0,0 +1,157 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
class TokenStorageService {
|
||||
static final TokenStorageService _instance = TokenStorageService._internal();
|
||||
factory TokenStorageService() => _instance;
|
||||
TokenStorageService._internal();
|
||||
|
||||
// Storage keys
|
||||
static const String _preEnrollmentKey = 'pre_enrollment_data';
|
||||
static const String _postEnrollmentKey = 'post_enrollment_data';
|
||||
static const String _selectedBranchKey = 'selected_branch';
|
||||
static const String _decodedTokenKey = 'decoded_token';
|
||||
|
||||
// In-memory cache
|
||||
List<dynamic>? _preEnrollmentData;
|
||||
List<dynamic>? _postEnrollmentData;
|
||||
Map<String, dynamic>? _selectedBranch;
|
||||
Map<String, dynamic>? _decodedToken;
|
||||
|
||||
// Initialize - Load data from storage
|
||||
Future<void> initialize() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final preData = prefs.getString(_preEnrollmentKey);
|
||||
if (preData != null) {
|
||||
_preEnrollmentData = json.decode(preData);
|
||||
}
|
||||
|
||||
final postData = prefs.getString(_postEnrollmentKey);
|
||||
if (postData != null) {
|
||||
_postEnrollmentData = json.decode(postData);
|
||||
}
|
||||
|
||||
final branchData = prefs.getString(_selectedBranchKey);
|
||||
if (branchData != null) {
|
||||
_selectedBranch = json.decode(branchData);
|
||||
}
|
||||
|
||||
final tokenData = prefs.getString(_decodedTokenKey);
|
||||
if (tokenData != null) {
|
||||
_decodedToken = json.decode(tokenData);
|
||||
}
|
||||
}
|
||||
|
||||
// Save enrollment data
|
||||
Future<void> saveEnrollmentData(List<dynamic> preData, List<dynamic> postData) async {
|
||||
_preEnrollmentData = preData;
|
||||
_postEnrollmentData = postData;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_preEnrollmentKey, json.encode(preData));
|
||||
await prefs.setString(_postEnrollmentKey, json.encode(postData));
|
||||
}
|
||||
|
||||
// Get combined unique branches
|
||||
List<Map<String, dynamic>> getCombinedBranches() {
|
||||
List<Map<String, dynamic>> combined = [];
|
||||
Set<String> seenTokens = {};
|
||||
Set<String> seenIds = {};
|
||||
|
||||
// Add pre-enrollment data
|
||||
if (_preEnrollmentData != null) {
|
||||
for (var item in _preEnrollmentData!) {
|
||||
String token = item['token']?.toString() ?? '';
|
||||
String uniqueId = '${item['id']}_${item['client_id']}_${item['client_branch_id']}';
|
||||
|
||||
if (seenIds.contains(uniqueId)) continue;
|
||||
if (token.isNotEmpty && seenTokens.contains(token)) continue;
|
||||
|
||||
if (token.isNotEmpty) seenTokens.add(token);
|
||||
seenIds.add(uniqueId);
|
||||
|
||||
combined.add({...item, 'enrollment_type': 'pre'});
|
||||
}
|
||||
}
|
||||
|
||||
// Add post-enrollment data
|
||||
if (_postEnrollmentData != null) {
|
||||
for (var item in _postEnrollmentData!) {
|
||||
String token = item['token']?.toString() ?? '';
|
||||
String uniqueId = '${item['id']}_${item['client_id']}_${item['client_branch_id']}';
|
||||
|
||||
if (seenIds.contains(uniqueId)) continue;
|
||||
if (token.isNotEmpty && seenTokens.contains(token)) continue;
|
||||
|
||||
if (token.isNotEmpty) seenTokens.add(token);
|
||||
seenIds.add(uniqueId);
|
||||
|
||||
combined.add({...item, 'enrollment_type': 'post'});
|
||||
}
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
|
||||
// Save selected branch and decode token
|
||||
Future<void> saveSelectedBranch(Map<String, dynamic> branch) async {
|
||||
_selectedBranch = branch;
|
||||
|
||||
String token = branch['token']?.toString() ?? '';
|
||||
if (token.isNotEmpty) {
|
||||
_decodedToken = _decodeJWT(token);
|
||||
} else {
|
||||
_decodedToken = null;
|
||||
}
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_selectedBranchKey, json.encode(branch));
|
||||
|
||||
if (_decodedToken != null) {
|
||||
await prefs.setString(_decodedTokenKey, json.encode(_decodedToken));
|
||||
}
|
||||
}
|
||||
|
||||
// Decode JWT token
|
||||
Map<String, dynamic>? _decodeJWT(String token) {
|
||||
try {
|
||||
final parts = token.split('.');
|
||||
if (parts.length != 3) return null;
|
||||
|
||||
final payload = parts[1];
|
||||
var normalized = base64Url.normalize(payload);
|
||||
var decoded = utf8.decode(base64Url.decode(normalized));
|
||||
|
||||
return json.decode(decoded);
|
||||
} catch (e) {
|
||||
print('Error decoding token: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
Map<String, dynamic>? getSelectedBranch() => _selectedBranch;
|
||||
Map<String, dynamic>? getDecodedToken() => _decodedToken;
|
||||
String? getCurrentToken() => _selectedBranch?['token'];
|
||||
|
||||
bool isLoggedIn() {
|
||||
return _selectedBranch != null &&
|
||||
_selectedBranch!['token'] != null &&
|
||||
_selectedBranch!['token'].toString().isNotEmpty;
|
||||
}
|
||||
|
||||
// Clear all data (logout)
|
||||
Future<void> clearAll() async {
|
||||
_preEnrollmentData = null;
|
||||
_postEnrollmentData = null;
|
||||
_selectedBranch = null;
|
||||
_decodedToken = null;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_preEnrollmentKey);
|
||||
await prefs.remove(_postEnrollmentKey);
|
||||
await prefs.remove(_selectedBranchKey);
|
||||
await prefs.remove(_decodedTokenKey);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user