policy validation
This commit is contained in:
parent
3477cd99f3
commit
fd64c2ef6c
File diff suppressed because one or more lines are too long
@ -36,6 +36,7 @@ import '../../presentation/screens/staff/Enquiry/enquiry_list.dart';
|
||||
import '../../presentation/screens/staff/Enquiry/staff_policy.dart';
|
||||
import '../../presentation/screens/staff/policy/policy.dart';
|
||||
import '../../presentation/screens/staff/policy/policy_list.dart';
|
||||
import '../../presentation/screens/staff/policy/policy_validation.dart';
|
||||
import '../../presentation/screens/staff/quotations/quotation.dart';
|
||||
|
||||
final GoRouter appRouter = GoRouter(
|
||||
@ -185,6 +186,39 @@ final GoRouter appRouter = GoRouter(
|
||||
path: AppRoutes.policylist,
|
||||
builder: (context, state) => const policylist(),
|
||||
),
|
||||
GoRoute(
|
||||
path: AppRoutes.policyValidation,
|
||||
name: "policyValidation",
|
||||
pageBuilder: (context, state) {
|
||||
final item = state.extra;
|
||||
|
||||
return CustomTransitionPage(
|
||||
key: state.pageKey,
|
||||
opaque: true, // ⭐ required for open animation
|
||||
barrierColor: Colors.black.withOpacity(0.3), // optional dim background
|
||||
fullscreenDialog: true,
|
||||
|
||||
transitionDuration: const Duration(milliseconds: 1000),
|
||||
|
||||
child: policyValidation(item: item),
|
||||
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||
final curved = CurvedAnimation(
|
||||
parent: animation,
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0, 1), // slide from bottom
|
||||
end: Offset.zero,
|
||||
).animate(curved),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.quotation,
|
||||
|
||||
@ -21,6 +21,7 @@ class AppRoutes {
|
||||
static const String claimlist = '/claimList';
|
||||
static const String endosement = '/endosement';
|
||||
static const String policylist = '/policylist';
|
||||
static const String policyValidation = '/policyValidation';
|
||||
static const String quotation = '/QuotationScreen';
|
||||
static const String policy = '/PolicyScreen';
|
||||
static const String policyStaffEnq = '/policyStaffEnq';
|
||||
|
||||
@ -35,10 +35,8 @@ class ApiService {
|
||||
context.go(AppRoutes.login);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _makeGetRequest(
|
||||
Uri url,
|
||||
Map<String, String> headers,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> _makeGetRequest(Uri url,
|
||||
Map<String, String> headers,) async {
|
||||
final response = await http.get(url, headers: headers);
|
||||
return _handleResponse(response);
|
||||
}
|
||||
@ -60,10 +58,8 @@ class ApiService {
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<http.Response> _makeGethttpRequest(
|
||||
Uri url,
|
||||
Map<String, String> headers,
|
||||
) async {
|
||||
Future<http.Response> _makeGethttpRequest(Uri url,
|
||||
Map<String, String> headers,) async {
|
||||
final response = await http.get(url, headers: headers);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
@ -77,11 +73,9 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _makePostRequestJson(
|
||||
Uri url,
|
||||
Map<String, dynamic> body,
|
||||
Map<String, String> headers,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> _makePostRequestJson(Uri url,
|
||||
Map<String, dynamic> body,
|
||||
Map<String, String> headers,) async {
|
||||
final response = await http.post(
|
||||
url,
|
||||
headers: headers,
|
||||
@ -89,6 +83,7 @@ class ApiService {
|
||||
);
|
||||
return _handleResponse(response);
|
||||
}
|
||||
|
||||
// --------------------------- COMMON FILES __________________________________________
|
||||
|
||||
Future<Map<String, dynamic>> createUserData(data, path) async {
|
||||
@ -156,10 +151,8 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> CheckDuplicate(
|
||||
BuildContext context,
|
||||
String value,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> CheckDuplicate(BuildContext context,
|
||||
String value,) async {
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
@ -200,7 +193,8 @@ class ApiService {
|
||||
return {};
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to load checkDuplicate data. Status code: ${response.statusCode}',
|
||||
'Failed to load checkDuplicate data. Status code: ${response
|
||||
.statusCode}',
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -294,11 +288,9 @@ class ApiService {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
Future<void> getPdfDownload(
|
||||
// BuildContext context,
|
||||
String path,
|
||||
String id,
|
||||
) async {
|
||||
Future<void> getPdfDownload(// BuildContext context,
|
||||
String path,
|
||||
String id,) async {
|
||||
print('getPdfDownload 1 - $path');
|
||||
|
||||
// if (path.isEmpty) {
|
||||
@ -352,7 +344,9 @@ class ApiService {
|
||||
final contentDisp = response.headers['content-disposition'];
|
||||
print('getPdfDownloadcontentDisp $contentDisp');
|
||||
|
||||
String fileName = extractFileName(contentDisp, path.split('/').last);
|
||||
String fileName = extractFileName(contentDisp, path
|
||||
.split('/')
|
||||
.last);
|
||||
print('Resolved fileName: $fileName');
|
||||
final anchor = html.AnchorElement(href: blobUrl)
|
||||
..setAttribute('download', fileName)
|
||||
@ -363,15 +357,16 @@ class ApiService {
|
||||
} else if (response.statusCode == 404) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('File not found.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
builder: (context) =>
|
||||
AlertDialog(
|
||||
title: const Text('File not found.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('OK'),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else if (response.statusCode == 403) {
|
||||
await clearLocalStorageAndRedirect();
|
||||
@ -455,12 +450,10 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> updateStatusMasters(
|
||||
id,
|
||||
status,
|
||||
masterName,
|
||||
userId,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> updateStatusMasters(id,
|
||||
status,
|
||||
masterName,
|
||||
userId,) async {
|
||||
print('updateStatusMaster $id $status $masterName $userId');
|
||||
final Map<String, dynamic> data = {
|
||||
"is_active": int.parse(status),
|
||||
@ -506,7 +499,8 @@ class ApiService {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id');
|
||||
} else if (role == 'handler') {
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}dashboard/handlerDashboard?manager_id=$id&handler_id=$userId',
|
||||
'${Env
|
||||
.apiUrl}dashboard/handlerDashboard?manager_id=$id&handler_id=$userId',
|
||||
);
|
||||
} else if (role == 'staff') {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$userId');
|
||||
@ -724,12 +718,11 @@ class ApiService {
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
// ------------------------------------ SALES EXECUTIVE -----------------------------------------------------
|
||||
|
||||
Future<Map<String, dynamic>> fetchSalesExecutiveList(
|
||||
int managerId,
|
||||
role,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> fetchSalesExecutiveList(int managerId,
|
||||
role,) async {
|
||||
// print(_token);
|
||||
|
||||
print('rolemanagerId - $managerId');
|
||||
@ -810,15 +803,14 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchEnquiryList(
|
||||
int managerid,
|
||||
int id,
|
||||
String role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStatus,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
Future<Map<String, dynamic>> fetchEnquiryList(int managerid,
|
||||
int id,
|
||||
String role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStatus,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
print("selectedStatusselectedStatus - $selectedStatus");
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
@ -846,12 +838,15 @@ class ApiService {
|
||||
|
||||
if (role == 'staff') {
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus',
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ??
|
||||
''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus',
|
||||
// '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus',
|
||||
);
|
||||
} else {
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&enquiry_status=$selectedStatus&staff_id=$selectedStaffId',
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ??
|
||||
''}&to_date=${toDate ??
|
||||
''}&enquiry_status=$selectedStatus&staff_id=$selectedStaffId',
|
||||
// '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId',
|
||||
);
|
||||
}
|
||||
@ -880,7 +875,8 @@ class ApiService {
|
||||
// }
|
||||
|
||||
final url = Uri.parse(
|
||||
'${Env.apiUrl}staff/monthlyLoginCount?month=${month ?? ''}&manager_id=$mangerId',
|
||||
'${Env.apiUrl}staff/monthlyLoginCount?month=${month ??
|
||||
''}&manager_id=$mangerId',
|
||||
);
|
||||
|
||||
final headers = {
|
||||
@ -995,6 +991,7 @@ class ApiService {
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
//------------------------------------ Quotation ------------------------------------------------
|
||||
|
||||
Future<Map<String, dynamic>> fetchQuickQuotationList(int managerId) async {
|
||||
@ -1051,14 +1048,13 @@ class ApiService {
|
||||
|
||||
// ----------------------------------- POLICY -------------------------------------------------
|
||||
|
||||
Future<Map<String, dynamic>> fetchPolicyList(
|
||||
int id,
|
||||
role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStatus,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
Future<Map<String, dynamic>> fetchPolicyList(int id,
|
||||
role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStatus,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
@ -1082,11 +1078,14 @@ class ApiService {
|
||||
|
||||
if (role == 'staff') {
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus',
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ??
|
||||
''}&to_date=${toDate ?? ''}&status=$selectedStatus',
|
||||
);
|
||||
} else {
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&status=$selectedStatus&staff_id=$selectedStaffId',
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ??
|
||||
''}&to_date=${toDate ??
|
||||
''}&status=$selectedStatus&staff_id=$selectedStaffId',
|
||||
);
|
||||
}
|
||||
|
||||
@ -1109,13 +1108,12 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchPolicyDataOnlyList(
|
||||
dynamic id,
|
||||
role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
Future<Map<String, dynamic>> fetchPolicyDataOnlyList(dynamic id,
|
||||
role, {
|
||||
String? fromDate,
|
||||
String? toDate,
|
||||
String? selectedStaffId,
|
||||
}) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
@ -1136,7 +1134,9 @@ class ApiService {
|
||||
}
|
||||
|
||||
final url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&staff_id=$selectedStaffId',
|
||||
'${Env
|
||||
.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ??
|
||||
''}&to_date=${toDate ?? ''}&staff_id=$selectedStaffId',
|
||||
);
|
||||
|
||||
// if (role == 'manager') {
|
||||
@ -1323,10 +1323,8 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchStaffListForEnquiryAssignDropDown(
|
||||
id,
|
||||
role,
|
||||
) async {
|
||||
Future<Map<String, dynamic>> fetchStaffListForEnquiryAssignDropDown(id,
|
||||
role,) async {
|
||||
print('fetchHandlerNameDropDown');
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
@ -1422,10 +1420,8 @@ class ApiService {
|
||||
}
|
||||
|
||||
// Update enquiry
|
||||
static Future<EnquiryModel> updateEnquiry(
|
||||
String id,
|
||||
EnquiryModel enquiry,
|
||||
) async {
|
||||
static Future<EnquiryModel> updateEnquiry(String id,
|
||||
EnquiryModel enquiry,) async {
|
||||
try {
|
||||
final response = await http.put(
|
||||
Uri.parse('$_baseUrl/api/enquiries/$id'),
|
||||
@ -1570,4 +1566,62 @@ class ApiService {
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> findPolicyApi(ID) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
|
||||
final url = Uri.parse('${Env.apiUrl}policy/findPolicy?id=$ID');
|
||||
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
'app-signature': Env.App_Signature,
|
||||
};
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> policyFilePathApi(ID, file_type) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
|
||||
final url = Uri.parse('${Env
|
||||
.apiUrl}policy/PolicyFilePath?policy_id=$ID&file_type=$file_type');
|
||||
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
'app-signature': Env.App_Signature,
|
||||
};
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> updatePolicyApi(data) async {
|
||||
final url = Uri.parse('${Env.apiUrl}policy/updatePolicy');
|
||||
|
||||
// final token = await getToken(); // Fetch token
|
||||
|
||||
if (_token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
print("data------- $data}");
|
||||
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token',
|
||||
'Content-Type': 'application/json',
|
||||
'app-signature': Env.App_Signature,
|
||||
// 'app-signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
|
||||
};
|
||||
|
||||
final response = await _makePostRequestJson(url, data, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -257,7 +257,7 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
||||
Spacer(),
|
||||
|
||||
// Dashboard
|
||||
if (roleId != 'staff' && role != 'admin') ...[
|
||||
if (roleId != 'staff' && role != 'Accounts') ...[
|
||||
_buildMenuItem(
|
||||
icon: Icons.dashboard,
|
||||
label: "Dashboard",
|
||||
@ -274,7 +274,7 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
||||
],
|
||||
|
||||
// Enquiry
|
||||
if (role != 'admin') ...[
|
||||
if (role != 'Accounts') ...[
|
||||
_buildMenuItem(
|
||||
icon: Icons.list_alt_rounded,
|
||||
label: "Enquiry",
|
||||
@ -295,7 +295,7 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
||||
const SizedBox(width: 8),
|
||||
|
||||
// User (Manager Only) - with hover popup
|
||||
if (roleId == 'manager' || role == 'admin') ...[
|
||||
if (roleId == 'manager' || role == 'Accounts') ...[
|
||||
_buildHoverMenuItem(
|
||||
icon: Icons.person_add_alt,
|
||||
label: "User",
|
||||
@ -327,8 +327,8 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
|
||||
// Pay Out button for admin
|
||||
if (role == 'admin') ...[
|
||||
// Pay Out button for Accounts
|
||||
if (role == 'Accounts') ...[
|
||||
_buildMenuItem(
|
||||
isActive: _activeMenu == 'Pay Out',
|
||||
icon: Icons.checklist_outlined,
|
||||
|
||||
@ -140,7 +140,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
} else if (roleId.toString() == "3") {
|
||||
role = "staff";
|
||||
} else if (roleId.toString() == "4") {
|
||||
role = "admin";
|
||||
role = "Accounts";
|
||||
} else {
|
||||
role = "agent"; // fallback if unexpected value
|
||||
}
|
||||
@ -343,7 +343,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
|
||||
if (userRole == 'staff') {
|
||||
context.go(AppRoutes.enquiryForStaff);
|
||||
} else if (userRole == 'admin') {
|
||||
} else if (userRole == 'Accounts') {
|
||||
context.go(AppRoutes.payout);
|
||||
} else {
|
||||
context.go(AppRoutes.dashboard);
|
||||
|
||||
@ -44,88 +44,7 @@ class _PayOutScreenState extends ConsumerState<PayOutScreen> {
|
||||
// --------------------------
|
||||
// Sample Data (replace with API later)
|
||||
// --------------------------
|
||||
final List<Map<String, dynamic>> allPolicies = [
|
||||
{
|
||||
'id': 1,
|
||||
'policyNo': 'POL456578798',
|
||||
'customer': 'Ram',
|
||||
'agentId': 1,
|
||||
'brokerId': 1,
|
||||
'premium': 1500,
|
||||
'commission': 450,
|
||||
'date': '2025-10-01',
|
||||
},
|
||||
{
|
||||
'id': 2,
|
||||
'policyNo': 'POL456578799',
|
||||
'customer': 'Shyam',
|
||||
'agentId': 1,
|
||||
'brokerId': 1,
|
||||
'premium': 2000,
|
||||
'commission': 600,
|
||||
'date': '2025-10-02',
|
||||
},
|
||||
{
|
||||
'id': 3,
|
||||
'policyNo': 'POL456578800',
|
||||
'customer': 'Mohan',
|
||||
'agentId': 1,
|
||||
'brokerId': 2,
|
||||
'premium': 3000,
|
||||
'commission': 900,
|
||||
'date': '2025-10-03',
|
||||
},
|
||||
{
|
||||
'id': 4,
|
||||
'policyNo': 'POL98765',
|
||||
'customer': 'Kumar',
|
||||
'agentId': 1,
|
||||
'brokerId': 2,
|
||||
'premium': 15000,
|
||||
'commission': 3500,
|
||||
'date': '2025-10-04',
|
||||
},
|
||||
{
|
||||
'id': 5,
|
||||
'policyNo': 'POL98766',
|
||||
'customer': 'Vijay',
|
||||
'agentId': 1,
|
||||
'brokerId': 3,
|
||||
'premium': 5000,
|
||||
'commission': 1250,
|
||||
'date': '2025-10-05',
|
||||
},
|
||||
{
|
||||
'id': 6,
|
||||
'policyNo': 'POL98767',
|
||||
'customer': 'Ajay',
|
||||
'agentId': 1,
|
||||
'brokerId': 3,
|
||||
'premium': 7500,
|
||||
'commission': 1875,
|
||||
'date': '2025-10-06',
|
||||
},
|
||||
{
|
||||
'id': 7,
|
||||
'policyNo': 'POL98768',
|
||||
'customer': 'Ravi',
|
||||
'agentId': 2,
|
||||
'brokerId': 4,
|
||||
'premium': 4000,
|
||||
'commission': 1000,
|
||||
'date': '2025-10-07',
|
||||
},
|
||||
{
|
||||
'id': 8,
|
||||
'policyNo': 'POL98769',
|
||||
'customer': 'Prakash',
|
||||
'agentId': 2,
|
||||
'brokerId': 4,
|
||||
'premium': 6000,
|
||||
'commission': 1500,
|
||||
'date': '2025-10-08',
|
||||
},
|
||||
];
|
||||
final List<Map<String, dynamic>> allPolicies = [];
|
||||
|
||||
List<Map<String, dynamic>> filteredPolicies = [];
|
||||
Set<int> selectedPolicies = {};
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
Future<Uint8List> loadNetworkPdfBytes(String url) async {
|
||||
final response = await http.get(Uri.parse(url));
|
||||
return response.bodyBytes;
|
||||
}
|
||||
@ -218,43 +218,32 @@ class policylistState extends ConsumerState<policylist> {
|
||||
|
||||
void filterData(String query) {
|
||||
print("FilterDAta - $query");
|
||||
|
||||
final lowerQuery = query.toLowerCase();
|
||||
|
||||
setState(() {
|
||||
filteredData = getStaffData.where((item) {
|
||||
// final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
|
||||
|
||||
return (item['agent_name'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['reg_no'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['insurer_name'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['insurer_short_name'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['assigned_to_name'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['insured_name'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['premium_amount'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['payment_mode_value'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(_formatDate(item['updated_on']) ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['policy_number'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
)
|
||||
// ||
|
||||
// (item['status'] ?? '-').toLowerCase().contains(query.toLowerCase());
|
||||
;
|
||||
// ⭐ Compute UI status text
|
||||
final accuracyText =
|
||||
item['is_data_accuracy_checked'] == '1'
|
||||
? 'Verified'
|
||||
: 'Click to Verify';
|
||||
|
||||
return
|
||||
(item['agent_name'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['reg_no'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['insurer_name'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['insurer_short_name'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['assigned_to_name'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['insured_name'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['premium_amount'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['payment_mode_value'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(_formatDate(item['updated_on']) ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
(item['policy_number'] ?? '-').toLowerCase().contains(lowerQuery) ||
|
||||
|
||||
// ⭐ NEW CONDITIONS for search
|
||||
accuracyText.toLowerCase().contains(lowerQuery);
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
@ -513,6 +502,10 @@ class policylistState extends ConsumerState<policylist> {
|
||||
flex: 3,
|
||||
child: Text('Policy Number', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('BDS Pushed', style: _headerStyle),
|
||||
),
|
||||
|
||||
Expanded(flex: 2, child: Text('Action', style: _headerStyle)),
|
||||
],
|
||||
@ -684,6 +677,15 @@ class policylistState extends ConsumerState<policylist> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item['is_bds_pushed'] == '1' ? 'Yes' : 'No',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Row(
|
||||
@ -729,6 +731,54 @@ class policylistState extends ConsumerState<policylist> {
|
||||
],
|
||||
),
|
||||
),
|
||||
if (roleId == 'Accounts') ...[
|
||||
const SizedBox(width: 5),
|
||||
Tooltip(
|
||||
message: '',
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
context.push(
|
||||
AppRoutes.policyValidation,
|
||||
extra: item,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 110, // ⭐ FIXED WIDTH → Equal in both states
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: item['is_data_accuracy_checked'] == '1'
|
||||
? const Color(0xFF2E7D6E)
|
||||
: Colors.redAccent,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center, // ⭐ Center content
|
||||
children: [
|
||||
Icon(
|
||||
item['is_data_accuracy_checked'] == '1'
|
||||
? Icons.check_circle
|
||||
: Icons.error,
|
||||
size: 12,
|
||||
color: Colors.white,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
item['is_data_accuracy_checked'] == '1'
|
||||
? 'Verified'
|
||||
: 'Click to Verify',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -953,3 +1003,4 @@ class policylistState extends ConsumerState<policylist> {
|
||||
fontSize: 12,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
852
lib/presentation/screens/staff/policy/policy_validation.dart
Normal file
852
lib/presentation/screens/staff/policy/policy_validation.dart
Normal file
@ -0,0 +1,852 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:pdf_render/pdf_render_widgets.dart';
|
||||
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
|
||||
|
||||
import '../../../../core/config/env.dart';
|
||||
import '../../../../core/services/api_service.dart';
|
||||
import '../../../../data/utils/toastNotification.dart';
|
||||
import '../../../providers/manager_provider.dart';
|
||||
|
||||
import 'loadNetworkPdfBytes.dart';
|
||||
import 'dart:typed_data';
|
||||
|
||||
// /// Represents Homepage for Navigation
|
||||
// class policyValidation extends ConsumerStatefulWidget {
|
||||
// final dynamic item;
|
||||
// const policyValidation({Key? key, this.item}) : super(key: key);
|
||||
//
|
||||
// @override
|
||||
// ConsumerState<policyValidation> createState() => _policyValidationState();
|
||||
// }
|
||||
//
|
||||
// class _policyValidationState extends ConsumerState<policyValidation> {
|
||||
// final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
|
||||
//
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// }
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// return Scaffold(
|
||||
// appBar: AppBar(
|
||||
// title: const Text('Syncfusion Flutter PDF Viewer'),
|
||||
// actions: <Widget>[
|
||||
// IconButton(
|
||||
// icon: const Icon(
|
||||
// Icons.bookmark,
|
||||
// color: Colors.white,
|
||||
// semanticLabel: 'Bookmark',
|
||||
// ),
|
||||
// onPressed: () {
|
||||
// _pdfViewerKey.currentState?.openBookmarkView();
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// body: SfPdfViewer.asset(
|
||||
// 'assets/pdfs/sample.pdf',
|
||||
// key: _pdfViewerKey,
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
class policyValidation extends ConsumerStatefulWidget {
|
||||
final dynamic item;
|
||||
const policyValidation({Key? key, this.item}) : super(key: key);
|
||||
|
||||
@override
|
||||
ConsumerState<policyValidation> createState() => _policyValidationState();
|
||||
}
|
||||
|
||||
class _policyValidationState extends ConsumerState<policyValidation> {
|
||||
// --- Api / state
|
||||
late ApiService apiService;
|
||||
bool isLoading = false;
|
||||
dynamic managerId;
|
||||
dynamic userId;
|
||||
|
||||
String? pdfUrl; // full file path from API
|
||||
|
||||
|
||||
// --- Controllers (all editable fields)
|
||||
late TextEditingController policyNumberController;
|
||||
late TextEditingController insuredNameController;
|
||||
late TextEditingController premiumController;
|
||||
late TextEditingController remarksController;
|
||||
|
||||
late TextEditingController rcNoController;
|
||||
late TextEditingController issuedDateController;
|
||||
late TextEditingController startDateController;
|
||||
late TextEditingController endDateController;
|
||||
|
||||
late TextEditingController tpController;
|
||||
late TextEditingController odController;
|
||||
late TextEditingController paController;
|
||||
late TextEditingController cgstController;
|
||||
late TextEditingController sgstController;
|
||||
late TextEditingController igstController;
|
||||
|
||||
late TextEditingController rtoStateCodeController;
|
||||
late TextEditingController rtoCityCodeController;
|
||||
late TextEditingController weightController;
|
||||
late TextEditingController fuelTypeController;
|
||||
late TextEditingController registrationDateController;
|
||||
late TextEditingController yomController;
|
||||
|
||||
late TextEditingController engineNoController;
|
||||
late TextEditingController chassisNoController;
|
||||
late TextEditingController makeController;
|
||||
late TextEditingController modelController;
|
||||
late TextEditingController cubicCapacityController;
|
||||
late TextEditingController vehicleTypeController;
|
||||
|
||||
late TextEditingController brokerNameController;
|
||||
late TextEditingController commissionAmountController;
|
||||
|
||||
final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
apiService = ApiService();
|
||||
|
||||
// instantiate controllers with defaults
|
||||
policyNumberController = TextEditingController();
|
||||
insuredNameController = TextEditingController();
|
||||
premiumController = TextEditingController();
|
||||
remarksController = TextEditingController();
|
||||
|
||||
rcNoController = TextEditingController();
|
||||
issuedDateController = TextEditingController();
|
||||
startDateController = TextEditingController();
|
||||
endDateController = TextEditingController();
|
||||
|
||||
tpController = TextEditingController();
|
||||
odController = TextEditingController();
|
||||
paController = TextEditingController();
|
||||
cgstController = TextEditingController();
|
||||
sgstController = TextEditingController();
|
||||
igstController = TextEditingController();
|
||||
|
||||
rtoStateCodeController = TextEditingController();
|
||||
rtoCityCodeController = TextEditingController();
|
||||
weightController = TextEditingController();
|
||||
fuelTypeController = TextEditingController();
|
||||
registrationDateController = TextEditingController();
|
||||
yomController = TextEditingController();
|
||||
|
||||
engineNoController = TextEditingController();
|
||||
chassisNoController = TextEditingController();
|
||||
makeController = TextEditingController();
|
||||
modelController = TextEditingController();
|
||||
cubicCapacityController = TextEditingController();
|
||||
vehicleTypeController = TextEditingController();
|
||||
|
||||
brokerNameController = TextEditingController();
|
||||
commissionAmountController = TextEditingController();
|
||||
|
||||
// Pre-fill controllers from initial `widget.item` (if available)
|
||||
final item = widget.item as Map<String, dynamic>? ?? {};
|
||||
policyNumberController.text = item['policy_number']?.toString() ?? '';
|
||||
insuredNameController.text = item['insured_name']?.toString() ?? '';
|
||||
premiumController.text = item['premium_amount']?.toString() ?? '';
|
||||
remarksController.text = item['remarks']?.toString() ?? '';
|
||||
|
||||
rcNoController.text = item['rc_no']?.toString() ?? '';
|
||||
issuedDateController.text = item['issued_date']?.toString() ?? '';
|
||||
startDateController.text = item['start_date']?.toString() ?? '';
|
||||
endDateController.text = item['end_date']?.toString() ?? '';
|
||||
|
||||
tpController.text = item['tp']?.toString() ?? '';
|
||||
odController.text = item['od']?.toString() ?? '';
|
||||
paController.text = item['pa']?.toString() ?? '';
|
||||
cgstController.text = item['cgst']?.toString() ?? '';
|
||||
sgstController.text = item['sgst']?.toString() ?? '';
|
||||
igstController.text = item['igst']?.toString() ?? '';
|
||||
|
||||
rtoStateCodeController.text = item['rto_state_code']?.toString() ?? '';
|
||||
rtoCityCodeController.text = item['rto_city_code']?.toString() ?? '';
|
||||
weightController.text = item['weight']?.toString() ?? '';
|
||||
fuelTypeController.text = item['fuel_type']?.toString() ?? '';
|
||||
registrationDateController.text = item['date_of_registration']?.toString() ?? '';
|
||||
yomController.text = item['year_of_manufacture']?.toString() ?? '';
|
||||
|
||||
engineNoController.text = item['engine_no']?.toString() ?? '';
|
||||
chassisNoController.text = item['chassis_no']?.toString() ?? '';
|
||||
makeController.text = item['make']?.toString() ?? '';
|
||||
modelController.text = item['model']?.toString() ?? '';
|
||||
cubicCapacityController.text = item['cubic_capacity']?.toString() ?? '';
|
||||
vehicleTypeController.text = item['vehicle_type']?.toString() ?? '';
|
||||
|
||||
brokerNameController.text = item['broker_name']?.toString() ?? '';
|
||||
commissionAmountController.text = item['commission_amount']?.toString() ?? '';
|
||||
|
||||
// read providers + call APIs
|
||||
Future.microtask(() {
|
||||
try {
|
||||
managerId = ref.read(managerIdProvider);
|
||||
} catch (e) {
|
||||
managerId = null;
|
||||
}
|
||||
try {
|
||||
userId = ref.read(userIdProvider);
|
||||
} catch (e) {
|
||||
userId = null;
|
||||
}
|
||||
|
||||
getFindPolicy();
|
||||
getPolicyFilePath();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
policyNumberController.dispose();
|
||||
insuredNameController.dispose();
|
||||
premiumController.dispose();
|
||||
remarksController.dispose();
|
||||
|
||||
rcNoController.dispose();
|
||||
issuedDateController.dispose();
|
||||
startDateController.dispose();
|
||||
endDateController.dispose();
|
||||
|
||||
tpController.dispose();
|
||||
odController.dispose();
|
||||
paController.dispose();
|
||||
cgstController.dispose();
|
||||
sgstController.dispose();
|
||||
igstController.dispose();
|
||||
|
||||
rtoStateCodeController.dispose();
|
||||
rtoCityCodeController.dispose();
|
||||
weightController.dispose();
|
||||
fuelTypeController.dispose();
|
||||
registrationDateController.dispose();
|
||||
yomController.dispose();
|
||||
|
||||
engineNoController.dispose();
|
||||
chassisNoController.dispose();
|
||||
makeController.dispose();
|
||||
modelController.dispose();
|
||||
cubicCapacityController.dispose();
|
||||
vehicleTypeController.dispose();
|
||||
|
||||
brokerNameController.dispose();
|
||||
commissionAmountController.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> getPolicyFilePath() async {
|
||||
_pdfViewerKey.currentState?.openBookmarkView();
|
||||
// 🔥 Use DIRECT FIXED URL you asked for
|
||||
// const directPdfUrl = "https://venbait.in/nhance/mypdf.pdf";
|
||||
//
|
||||
// setState(() {
|
||||
// pdfUrl = directPdfUrl;
|
||||
// });
|
||||
//
|
||||
// debugPrint("FINAL PDF URL -> $pdfUrl");
|
||||
|
||||
final policyId = widget.item?['policy_id'];
|
||||
if (policyId == null) {
|
||||
debugPrint('policyValidation: policy id is null, skipping API call');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = true);
|
||||
|
||||
try {
|
||||
final url = Uri.parse('${Env
|
||||
.apiUrl}policy/PolicyFilePath?policy_id=$policyId&file_type=policy_pdf');
|
||||
|
||||
setState(() {
|
||||
pdfUrl = "$url";
|
||||
});
|
||||
|
||||
final response = await apiService.policyFilePathApi(policyId, 'policy_pdf');
|
||||
|
||||
debugPrint('policyFilePathApi response: $response');
|
||||
|
||||
if (response != null && response['status'] == 'success') {
|
||||
|
||||
// final filePath = response['data']?.toString();
|
||||
//
|
||||
// // The API returns a server absolute path like:
|
||||
// // /home3/.../uploads/policy/policy_pdf/yourfile.pdf
|
||||
// // You must convert it to a usable URL for web/mobile.
|
||||
//
|
||||
// if (filePath != null && filePath.isNotEmpty) {
|
||||
// // EXAMPLE:
|
||||
// // Build full URL based on your domain
|
||||
// // final baseUrl = filePath;
|
||||
// final baseUrl = "https://venbait.in/nhance/mypdf.pdf";
|
||||
//
|
||||
// final fileName = filePath.split('/').last;
|
||||
//
|
||||
// setState(() {
|
||||
// pdfUrl = "$baseUrl$fileName";
|
||||
// });
|
||||
//
|
||||
// debugPrint("FINAL PDF URL -> $pdfUrl");
|
||||
// }
|
||||
} else {
|
||||
debugPrint('policyFilePathApi returned error: ${response?['message'] ?? 'unknown'}');
|
||||
}
|
||||
} catch (e, st) {
|
||||
debugPrint('Exception in getPolicyFilePath: $e\n$st');
|
||||
} finally {
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getFindPolicy() async {
|
||||
final policyId = widget.item?['policy_id'];
|
||||
if (policyId == null) {
|
||||
debugPrint('policyValidation: policy id is null, skipping API call');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = true);
|
||||
|
||||
try {
|
||||
final response = await apiService.findPolicyApi(policyId);
|
||||
debugPrint('findPolicyApi response: $response');
|
||||
|
||||
if (response != null && response['status'] == 'success') {
|
||||
final data = (response['data'] ?? {}) as Map<String, dynamic>;
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
// update controllers (overwrite with authoritative API values)
|
||||
policyNumberController.text = data['policy_number']?.toString() ?? policyNumberController.text;
|
||||
insuredNameController.text = data['insured_name']?.toString() ?? insuredNameController.text;
|
||||
premiumController.text = data['premium_amount']?.toString() ?? premiumController.text;
|
||||
remarksController.text = data['remarks']?.toString() ?? remarksController.text;
|
||||
|
||||
rcNoController.text = data['rc_no']?.toString() ?? rcNoController.text;
|
||||
issuedDateController.text = data['issued_date']?.toString() ?? issuedDateController.text;
|
||||
startDateController.text = data['start_date']?.toString() ?? startDateController.text;
|
||||
endDateController.text = data['end_date']?.toString() ?? endDateController.text;
|
||||
|
||||
tpController.text = data['tp']?.toString() ?? tpController.text;
|
||||
odController.text = data['od']?.toString() ?? odController.text;
|
||||
paController.text = data['pa']?.toString() ?? paController.text;
|
||||
cgstController.text = data['cgst']?.toString() ?? cgstController.text;
|
||||
sgstController.text = data['sgst']?.toString() ?? sgstController.text;
|
||||
igstController.text = data['igst']?.toString() ?? igstController.text;
|
||||
|
||||
rtoStateCodeController.text = data['rto_state_code']?.toString() ?? rtoStateCodeController.text;
|
||||
rtoCityCodeController.text = data['rto_city_code']?.toString() ?? rtoCityCodeController.text;
|
||||
weightController.text = data['weight']?.toString() ?? weightController.text;
|
||||
fuelTypeController.text = data['fuel_type']?.toString() ?? fuelTypeController.text;
|
||||
registrationDateController.text = data['date_of_registration']?.toString() ?? registrationDateController.text;
|
||||
yomController.text = data['year_of_manufacture']?.toString() ?? yomController.text;
|
||||
|
||||
engineNoController.text = data['engine_no']?.toString() ?? engineNoController.text;
|
||||
chassisNoController.text = data['chassis_no']?.toString() ?? chassisNoController.text;
|
||||
makeController.text = data['make']?.toString() ?? makeController.text;
|
||||
modelController.text = data['model']?.toString() ?? modelController.text;
|
||||
cubicCapacityController.text = data['cubic_capacity']?.toString() ?? cubicCapacityController.text;
|
||||
vehicleTypeController.text = data['vehicle_type']?.toString() ?? vehicleTypeController.text;
|
||||
|
||||
brokerNameController.text = data['broker_name']?.toString() ?? brokerNameController.text;
|
||||
commissionAmountController.text = data['commission_amount']?.toString() ?? commissionAmountController.text;
|
||||
});
|
||||
} else {
|
||||
debugPrint('findPolicyApi returned error: ${response?['message'] ?? 'unknown'}');
|
||||
}
|
||||
} catch (e, st) {
|
||||
debugPrint('Exception in getFindPolicy: $e\n$st');
|
||||
} finally {
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _pickDate(TextEditingController controller, BuildContext context) async {
|
||||
DateTime initial = DateTime.now();
|
||||
try {
|
||||
if (controller.text.isNotEmpty) {
|
||||
// try parse dd-MM-yyyy
|
||||
final parts = controller.text.split('-');
|
||||
if (parts.length == 3) {
|
||||
final d = int.tryParse(parts[0]) ?? initial.day;
|
||||
final m = int.tryParse(parts[1]) ?? initial.month;
|
||||
final y = int.tryParse(parts[2]) ?? initial.year;
|
||||
initial = DateTime(y, m, d);
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
final picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: initial,
|
||||
firstDate: DateTime(1900),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
if (picked != null) {
|
||||
controller.text = "${picked.day.toString().padLeft(2,'0')}-${picked.month.toString().padLeft(2,'0')}-${picked.year}";
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _save() async {
|
||||
final policyId = widget.item?['policy_id'];
|
||||
if (policyId == null) {
|
||||
ToastHelper.showWarningToast(context, 'Missing policy id');
|
||||
return;
|
||||
}
|
||||
|
||||
final payload = {
|
||||
"id": policyId,
|
||||
"rc_no": rcNoController.text,
|
||||
"insured_name": insuredNameController.text,
|
||||
"issued_date": issuedDateController.text,
|
||||
"start_date": startDateController.text,
|
||||
"end_date": endDateController.text,
|
||||
"premium_amount": premiumController.text,
|
||||
"policy_number": policyNumberController.text,
|
||||
"tp": tpController.text.isEmpty ? null : tpController.text,
|
||||
"od": odController.text.isEmpty ? null : odController.text,
|
||||
"pa": paController.text.isEmpty ? null : paController.text,
|
||||
"cgst": cgstController.text.isEmpty ? null : cgstController.text,
|
||||
"sgst": sgstController.text.isEmpty ? null : sgstController.text,
|
||||
"igst": igstController.text.isEmpty ? null : igstController.text,
|
||||
"rto_state_code": rtoStateCodeController.text.isEmpty ? null : rtoStateCodeController.text,
|
||||
"rto_city_code": rtoCityCodeController.text.isEmpty ? null : rtoCityCodeController.text,
|
||||
"weight": weightController.text.isEmpty ? null : weightController.text,
|
||||
"fuel_type": fuelTypeController.text.isEmpty ? null : fuelTypeController.text,
|
||||
"date_of_registration": registrationDateController.text.isEmpty ? null : registrationDateController.text,
|
||||
"year_of_manufacture": yomController.text.isEmpty ? null : yomController.text,
|
||||
"engine_no": engineNoController.text.isEmpty ? null : engineNoController.text,
|
||||
"chassis_no": chassisNoController.text.isEmpty ? null : chassisNoController.text,
|
||||
"make": makeController.text.isEmpty ? null : makeController.text,
|
||||
"model": modelController.text.isEmpty ? null : modelController.text,
|
||||
"cubic_capacity": cubicCapacityController.text.isEmpty ? null : cubicCapacityController.text,
|
||||
"vehicle_type": vehicleTypeController.text.isEmpty ? null : vehicleTypeController.text,
|
||||
"broker_name": brokerNameController.text.isEmpty ? null : brokerNameController.text,
|
||||
"commission_amount": commissionAmountController.text.isEmpty ? null : commissionAmountController.text,
|
||||
"updated_by": userId
|
||||
};
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = true);
|
||||
|
||||
try {
|
||||
debugPrint('FINAL SAVE PAYLOAD => $payload');
|
||||
final result = await apiService.updatePolicyApi(payload);
|
||||
debugPrint('updatePolicy result => $result');
|
||||
|
||||
if (result != null && result['status'] == 'success') {
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = false);
|
||||
context.pop();
|
||||
ToastHelper.showSuccessToast(context, "Policy updated successfully");
|
||||
} else {
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = false);
|
||||
ToastHelper.showErrorToast(context, result?['message']?.toString() ?? 'Error updating policy');
|
||||
}
|
||||
} catch (e, st) {
|
||||
debugPrint('Exception in updatePolicy: $e\n$st');
|
||||
if (!mounted) return;
|
||||
setState(() => isLoading = false);
|
||||
ToastHelper.showWarningToast(context, 'Exception: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Widget _sectionHeader(String title, {IconData icon = Icons.info}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFE3F9F8),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFF2E7D6E),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(icon, size: 16, color: Colors.white),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Widget _buildInput(String label, TextEditingController controller, {TextInputType keyboardType = TextInputType.text, bool readOnly = false, VoidCallback? onTap}) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: const TextStyle(fontWeight: FontWeight.w500)),
|
||||
const SizedBox(height: 6),
|
||||
TextField(
|
||||
controller: controller,
|
||||
keyboardType: keyboardType,
|
||||
readOnly: readOnly,
|
||||
onTap: onTap,
|
||||
decoration: InputDecoration(
|
||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(6)),
|
||||
isDense: true,
|
||||
contentPadding: const EdgeInsets.all(10),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Ensure global AppHeader remains visible by pushing content down by 64px
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: Color(0xffD9EBE8),
|
||||
// ⭐ FIXED BUTTON FOOTER
|
||||
bottomNavigationBar: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
color: const Color(0xFFF7FBFA),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end, // 👉 move button to right
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: widget.item?['is_data_accuracy_checked'] == '1' ? null : _save,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2E7D6E),
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10,
|
||||
horizontal: 20, // 👉 smaller width
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'Confirm Data Accuracy',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
// margin: const EdgeInsets.only(top: 64), // <-- keeps popup under global AppHeader
|
||||
width: double.infinity,
|
||||
// height: MediaQuery.of(context).size.height - 64,
|
||||
color: const Color(0xFFF7FBFA),
|
||||
child: Column(
|
||||
children: [
|
||||
// In-body header
|
||||
Container(
|
||||
height: 56,
|
||||
color: Color(0xFFE3F9F8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(icon: const Icon(Icons.file_open), onPressed: () => context.pop()),
|
||||
const Expanded(child: Text('Insurance Policy Review', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600))),
|
||||
if (isLoading) const SizedBox(width: 12, height: 12, child: CircularProgressIndicator(strokeWidth: 2)),
|
||||
const SizedBox(width: 8),
|
||||
IconButton(icon: const Icon(Icons.close), onPressed: () => context.pop()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Body: left PDF preview + right grouped form
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
// LEFT - PDF placeholder
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(right: 12),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.grey.shade200),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Text(
|
||||
'Orginal Policy Document',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
Expanded(
|
||||
child: FutureBuilder<Uint8List>(
|
||||
future: loadNetworkPdfBytes(pdfUrl!),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final pdfBytes = snapshot.data!;
|
||||
|
||||
return PdfDocumentLoader.openData(
|
||||
pdfBytes,
|
||||
documentBuilder: (context, pdfDocument, pageCount) {
|
||||
return ListView.builder(
|
||||
itemCount: pageCount,
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
color: Colors.black12,
|
||||
child: PdfPageView(
|
||||
pdfDocument: pdfDocument,
|
||||
pageNumber: index + 1,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
// Expanded(
|
||||
// child: PdfDocumentLoader.openAsset(
|
||||
// 'assets/pdfs/sample.pdf',
|
||||
// documentBuilder: (context, pdfDocument, pageCount) => LayoutBuilder(
|
||||
// builder: (context, constraints) => ListView.builder(
|
||||
// itemCount: pageCount,
|
||||
// itemBuilder: (context, index) => Container(
|
||||
// // margin: EdgeInsets.all(margin),
|
||||
// // padding: EdgeInsets.all(padding),
|
||||
// color: Colors.black12,
|
||||
// child: PdfPageView(
|
||||
// pdfDocument: pdfDocument,
|
||||
// pageNumber: index + 1,
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// )
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// RIGHT - Grouped Form
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: SingleChildScrollView(
|
||||
child: Card(
|
||||
elevation: 2,
|
||||
color: Colors.white,
|
||||
margin: EdgeInsets.zero, // flush with container
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
|
||||
// Policy Details
|
||||
Card(
|
||||
elevation: 5,
|
||||
color: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_sectionHeader('Policy Details', icon: Icons.policy),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Policy Number', policyNumberController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Insured Name', insuredNameController)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Issued Date', issuedDateController, readOnly: true, onTap: () => _pickDate(issuedDateController, context))),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Start Date', startDateController, readOnly: true, onTap: () => _pickDate(startDateController, context))),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('End Date', endDateController, readOnly: true, onTap: () => _pickDate(endDateController, context)),)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Premium Amount', premiumController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Remarks', remarksController)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Tax Details
|
||||
Card(
|
||||
elevation: 5,
|
||||
color: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_sectionHeader('Tax / Cover Details', icon: Icons.attach_money),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('TP', tpController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('OD', odController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('PA', paController, keyboardType: TextInputType.number)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('CGST', cgstController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('SGST', sgstController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('IGST', igstController, keyboardType: TextInputType.number)),
|
||||
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Vehicle Details
|
||||
Card(
|
||||
elevation: 5,
|
||||
color: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_sectionHeader('Vehicle Details', icon: Icons.directions_car),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('RTO State Name', rtoStateCodeController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('RTO City Code', rtoCityCodeController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Weight', weightController, keyboardType: TextInputType.number)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Fuel Type', fuelTypeController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Date of Registration', registrationDateController, readOnly: true, onTap: () => _pickDate(registrationDateController, context))),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Year of Manufacture', yomController, keyboardType: TextInputType.number)),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Engine No', engineNoController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Chassis No', chassisNoController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: Expanded(child: _buildInput('Make', makeController))),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Model', modelController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Cubic Capacity', cubicCapacityController, keyboardType: TextInputType.number)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Vehicle Type', vehicleTypeController)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Broker Details
|
||||
Card(
|
||||
elevation: 5,
|
||||
color: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
_sectionHeader('Broker / Commission', icon: Icons.person),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: _buildInput('Broker Name', brokerNameController)),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _buildInput('Commission Amount', commissionAmountController, keyboardType: TextInputType.number)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),// spacing above fixed button
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||
#include <open_file_linux/open_file_linux_plugin.h>
|
||||
#include <syncfusion_pdfviewer_linux/syncfusion_pdfviewer_linux_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
|
||||
open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) syncfusion_pdfviewer_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SyncfusionPdfviewerLinuxPlugin");
|
||||
syncfusion_pdfviewer_linux_plugin_register_with_registrar(syncfusion_pdfviewer_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
flutter_secure_storage_linux
|
||||
open_file_linux
|
||||
syncfusion_pdfviewer_linux
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import connectivity_plus
|
||||
import device_info_plus
|
||||
import file_picker
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
@ -16,11 +17,14 @@ import local_auth_darwin
|
||||
import open_file_mac
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
import pdf_render
|
||||
import shared_preferences_foundation
|
||||
import syncfusion_pdfviewer_macos
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
@ -31,6 +35,8 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SwiftPdfRenderPlugin.register(with: registry.registrar(forPlugin: "SwiftPdfRenderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
}
|
||||
|
||||
126
pubspec.lock
126
pubspec.lock
@ -233,6 +233,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.11"
|
||||
device_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.3.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.3"
|
||||
dropdown_search:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -684,26 +700,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.9"
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.9"
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -968,6 +984,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+3"
|
||||
pdf_render:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pdf_render
|
||||
sha256: bacd2ad8f4f4c9821827003065f5c2f9ca474dd418ff29c68272aab4c0e1e88b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.12"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1189,6 +1213,78 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: e1fdfcc3ed7e1f040ba95838780b2eb1857e3e5eccb817fbe94ea2b09c35eac4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_flutter_pdf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_pdf
|
||||
sha256: "4077abff3d3dcae757317c0a85cb607b98cc6ea8f3b47c7d8488d4144ef01a9f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_flutter_pdfviewer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_pdfviewer
|
||||
sha256: "4bc26c493a017ea615a2c232031f3aa46642ddb22d82a8d88d8c5e5ea7fe4c7d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_flutter_signaturepad:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_signaturepad
|
||||
sha256: "56c35321879b900f59a91e0758af7ca66973447bfdaeb643fe1da0084cbc5b22"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_pdfviewer_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_pdfviewer_linux
|
||||
sha256: bae7feb109b38ecf9f8be99bd032503adf98e56da048307a17af8515d0f9d2ed
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_pdfviewer_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_pdfviewer_macos
|
||||
sha256: "5c02ead2a430cd3f203639ede38ce2e06fb6c8aab6791b0d15c01436f882f482"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_pdfviewer_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_pdfviewer_platform_interface
|
||||
sha256: "65641e064385ac65253930ec96a6edc2eea781c9e15bf3d5fa15e459037817e7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_pdfviewer_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_pdfviewer_web
|
||||
sha256: c55201d9eda49f543b9ad21f539b0f5fbe45ca1a3b30081ee471eb4dff7132f4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
syncfusion_pdfviewer_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_pdfviewer_windows
|
||||
sha256: "1b706e58a95c794687d037e055cf0580370ceee27a59a8cd4e14368534161af8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "31.2.18"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1201,10 +1297,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
||||
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
version: "0.7.6"
|
||||
toastification:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1321,10 +1417,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1373,6 +1469,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.15.0"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1399,4 +1503,4 @@ packages:
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.8.1 <4.0.0"
|
||||
flutter: ">=3.32.0"
|
||||
flutter: ">=3.35.1"
|
||||
|
||||
@ -70,6 +70,8 @@ dependencies:
|
||||
fluttertoast: ^9.0.0
|
||||
fl_chart: ^0.70.0
|
||||
flutter_reorderable_grid_view: ^5.5.2
|
||||
syncfusion_flutter_pdfviewer: ^31.2.18
|
||||
pdf_render: ^1.4.12
|
||||
|
||||
# fl_chart: ^1.1.0
|
||||
|
||||
|
||||
@ -38,6 +38,23 @@
|
||||
<script src="flutter_bootstrap.js" async></script>
|
||||
<script src="https://www.gstatic.com/firebasejs/10.7.0/firebase-app.js"></script>
|
||||
<script src="https://www.gstatic.com/firebasejs/10.7.0/firebase-auth.js"></script>
|
||||
<!-- IMPORTANT: load pdfjs files -->
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.min.js"
|
||||
type="text/javascript"
|
||||
></script>
|
||||
<script type="text/javascript">
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.worker.min.js";
|
||||
pdfRenderOptions = {
|
||||
// where cmaps are downloaded from
|
||||
cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/cmaps/",
|
||||
// The cmaps are compressed in the case
|
||||
cMapPacked: true,
|
||||
// any other options for pdfjsLib.getDocument.
|
||||
// params: {}
|
||||
};
|
||||
</script>
|
||||
<script type="module">
|
||||
// Import the functions you need from the SDKs you need
|
||||
import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.4/firebase-app.js";
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||
#include <local_auth_windows/local_auth_plugin.h>
|
||||
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
@ -24,6 +25,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||
LocalAuthPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
|
||||
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
firebase_core
|
||||
flutter_secure_storage_windows
|
||||
local_auth_windows
|
||||
syncfusion_pdfviewer_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user