UI_HEADER_ICON UI_ERR_MSG_CONTENT
This commit is contained in:
parent
3c7ce422a9
commit
5e6c091faa
@ -368,7 +368,6 @@ class ApiService {
|
|||||||
await _initializeToken();
|
await _initializeToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
final userId = '1';
|
|
||||||
final url;
|
final url;
|
||||||
|
|
||||||
if (role == 'manager') {
|
if (role == 'manager') {
|
||||||
@ -389,6 +388,20 @@ class ApiService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> findSingleEnquiryData(id) async {
|
||||||
|
// print(_token);
|
||||||
|
if (_token == null) {
|
||||||
|
await _initializeToken();
|
||||||
|
}
|
||||||
|
final url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?enquiry_id=$id');
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $_token' ?? '',
|
||||||
|
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
|
||||||
|
};
|
||||||
|
final response = await _makeGetRequest(url, headers);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------ Quotation ------------------------------------------------
|
//------------------------------------ Quotation ------------------------------------------------
|
||||||
|
|
||||||
Future<Map<String, dynamic>> fetchQuotationList(int managerId) async {
|
Future<Map<String, dynamic>> fetchQuotationList(int managerId) async {
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
import 'package:dropdown_search/dropdown_search.dart';
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
|
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
|
import '../../../../core/config/env.dart';
|
||||||
|
import '../../../../core/routing/routes.dart';
|
||||||
import '../../../../core/services/api_service.dart';
|
import '../../../../core/services/api_service.dart';
|
||||||
import '../../../../data/services/auth_service.dart';
|
import '../../../../data/services/auth_service.dart';
|
||||||
import '../../../../data/utils/Pagination.dart';
|
import '../../../../data/utils/Pagination.dart';
|
||||||
@ -47,18 +52,24 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
'remarks',
|
'remarks',
|
||||||
];
|
];
|
||||||
late String isActive = "1";
|
late String isActive = "1";
|
||||||
html.File? docUploadedRCFile;
|
|
||||||
html.File? docUploadedIDProof;
|
PlatformFile? docUploadedRCFile;
|
||||||
html.File? docUploadedPrevPolicy;
|
PlatformFile? docUploadedIDProof;
|
||||||
// PlatformFile? passportFile;
|
PlatformFile? docUploadedPrevPolicy;
|
||||||
|
|
||||||
String? selectedRCFile;
|
String? selectedRCFile;
|
||||||
String? selectedIdProof;
|
String? selectedIdProof;
|
||||||
String? selectedPrevPolicy;
|
String? selectedPrevPolicy;
|
||||||
String? passportFileUrlFromApi;
|
|
||||||
|
String? rcFileUrlFromApi;
|
||||||
|
String? idProofFileUrlFromApi;
|
||||||
|
String? prevPolicyFileUrlFromApi;
|
||||||
|
|
||||||
String? selectedId;
|
String? selectedId;
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
|
|
||||||
String? selectedVehicleType;
|
String? selectedVehicleType;
|
||||||
|
int? selectedVehicleTypeId;
|
||||||
String? selectedInsurer;
|
String? selectedInsurer;
|
||||||
|
|
||||||
Map<String, TextEditingController> controllers = {};
|
Map<String, TextEditingController> controllers = {};
|
||||||
@ -109,7 +120,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
for (String field in tabHeader) {
|
for (String field in tabHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
}
|
}
|
||||||
// updateData();
|
|
||||||
_initializeToken();
|
_initializeToken();
|
||||||
Future.microtask(() {
|
Future.microtask(() {
|
||||||
managerId = ref.watch(managerIdProvider);
|
managerId = ref.watch(managerIdProvider);
|
||||||
@ -118,8 +129,10 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
|
|
||||||
getVehicleType();
|
getVehicleType();
|
||||||
getInsurers();
|
getInsurers();
|
||||||
|
updateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// api/enquiry/enquiryList?enquiry_id=1
|
||||||
Future<void> _initializeToken() async {
|
Future<void> _initializeToken() async {
|
||||||
_token = await AuthService.getToken();
|
_token = await AuthService.getToken();
|
||||||
print("APISERTOKEN - $_token");
|
print("APISERTOKEN - $_token");
|
||||||
@ -189,119 +202,205 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleSave() async {
|
void updateData() async {
|
||||||
print("Handl1");
|
// if (widget.id != null && widget.id != 'create') {
|
||||||
final dataSet = dataDetails();
|
|
||||||
print("dataSetAgent - $dataSet");
|
|
||||||
print("Handl13f");
|
|
||||||
if (!_formKey.currentState!.validate()) return;
|
|
||||||
// if (passportFile == null) {
|
|
||||||
// print("❌ No file selected!");
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
// const SnackBar(content: Text("Please select a file before submitting")),
|
|
||||||
// );
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
dynamic response = await apiService.findSingleEnquiryData(1);
|
||||||
|
// dynamic response = await apiService.findSingleAgentData(widget.id!);
|
||||||
|
final data = response['data'];
|
||||||
|
print("updateData - ${response['data']}");
|
||||||
|
|
||||||
|
if (data == null) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
// uploadIncentiveData(dataSet);
|
// selectedId = widget.id;
|
||||||
});
|
controllers['name']?.text = data['name'] ?? '';
|
||||||
|
controllers['email']?.text = data['email'] ?? '';
|
||||||
|
controllers['mobile']?.text = data['mobile'] ?? '';
|
||||||
|
controllers['regNo']?.text = data['reg_no'] ?? '';
|
||||||
|
controllers['remarks']?.text = data['remarks'] ?? '';
|
||||||
|
isActive = data["is_active"];
|
||||||
|
// selectedVehicleType = data['vehicle_type_id'] ?? '2';
|
||||||
|
selectedVehicleTypeId = 2;
|
||||||
|
selectedInsurer = data['insurer_id'] ?? '3';
|
||||||
|
|
||||||
print("Handl2");
|
String? apiDocPath = data["rc_file_name"];
|
||||||
|
if (apiDocPath != null && apiDocPath.isNotEmpty) {
|
||||||
|
print('apiDocPath - $apiDocPath');
|
||||||
|
selectedRCFile = apiDocPath.split('/').last;
|
||||||
|
print('selectedRCFile - $selectedRCFile');
|
||||||
|
rcFileUrlFromApi = apiDocPath;
|
||||||
|
print('rcFileUrlFromApi - $rcFileUrlFromApi');
|
||||||
|
docUploadedRCFile = null;
|
||||||
|
} else {
|
||||||
|
selectedRCFile = null;
|
||||||
|
docUploadedRCFile = null;
|
||||||
|
rcFileUrlFromApi = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String? apiDocPathRC = data["id_proof_file_name"];
|
||||||
|
if (apiDocPathRC != null && apiDocPathRC.isNotEmpty) {
|
||||||
|
print('apiDocPathRC - $apiDocPathRC');
|
||||||
|
selectedIdProof = apiDocPathRC.split('/').last;
|
||||||
|
print('selectedIdProof - $selectedIdProof');
|
||||||
|
prevPolicyFileUrlFromApi = apiDocPathRC;
|
||||||
|
print('prevPolicyFileUrlFromApi - $prevPolicyFileUrlFromApi');
|
||||||
|
docUploadedIDProof = null;
|
||||||
|
} else {
|
||||||
|
selectedIdProof = null;
|
||||||
|
docUploadedIDProof = null;
|
||||||
|
prevPolicyFileUrlFromApi = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String? apiDocPathPrevPolicy = data["previous_policy_file_name"];
|
||||||
|
if (apiDocPathPrevPolicy != null && apiDocPathPrevPolicy.isNotEmpty) {
|
||||||
|
print('apiDocPathPrevPolicy - $apiDocPathPrevPolicy');
|
||||||
|
selectedPrevPolicy = apiDocPathPrevPolicy.split('/').last;
|
||||||
|
print('selectedPrevPolicy - $selectedPrevPolicy');
|
||||||
|
idProofFileUrlFromApi = apiDocPathPrevPolicy;
|
||||||
|
print('idProofFileUrlFromApi - $idProofFileUrlFromApi');
|
||||||
|
docUploadedPrevPolicy = null;
|
||||||
|
} else {
|
||||||
|
selectedPrevPolicy = null;
|
||||||
|
docUploadedPrevPolicy = null;
|
||||||
|
idProofFileUrlFromApi = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<void> uploadIncentiveData(Map<String, dynamic> dataSet) async {
|
Future<void> handleSave() async {
|
||||||
// final uri = Uri.parse('${Env.apiUrl}agent/uploadAgentIncentiveFile');
|
if (!_formKey.currentState!.validate()) return;
|
||||||
// // 'https://venbait.in/nhance/partner/dev/api/agent/uploadAgentIncentiveFile',
|
setState(() {
|
||||||
// if (_token == null) {
|
if (_formKey.currentState!.validate()) {
|
||||||
// throw Exception('Token not found. Please log in.');
|
dataDetails();
|
||||||
// }
|
final dataSet = dataDetails();
|
||||||
// // Use MultipartRequest (POST only)
|
print("dataSetAgent - $dataSet");
|
||||||
// final request = http.MultipartRequest('POST', uri);
|
print("managerId - $managerId ,userId - $userId ");
|
||||||
// request.headers['Authorization'] = 'Bearer $_token';
|
createUserData(dataSet);
|
||||||
// request.headers['app-signature'] =
|
} else {
|
||||||
// 'nhance-partner-2025-signature-35468846JRhH551HK';
|
// isDisable = false;
|
||||||
//
|
}
|
||||||
// print("USerDAta - $dataSet");
|
});
|
||||||
//
|
}
|
||||||
// dataSet.forEach((key, value) {
|
|
||||||
// request.fields[key] = value.toString();
|
Future<void> attachFiles(http.MultipartRequest request) async {
|
||||||
// print("✅ Encoded travel_details2: ${request.fields[key]}");
|
Future<void> addFile(PlatformFile? file, String fieldName) async {
|
||||||
// });
|
if (file == null) return;
|
||||||
//
|
try {
|
||||||
// // Attach file if selected
|
if (file.bytes != null) {
|
||||||
// if (passportFile != null) {
|
final multipartFile = http.MultipartFile.fromBytes(
|
||||||
// try {
|
fieldName,
|
||||||
// final reader = html.FileReader();
|
file.bytes!,
|
||||||
// reader.readAsArrayBuffer(passportFile!);
|
filename: file.name,
|
||||||
// await reader.onLoad.first;
|
);
|
||||||
//
|
request.files.add(multipartFile);
|
||||||
// final data = reader.result as Uint8List;
|
} else if (file.path != null) {
|
||||||
//
|
final multipartFile = await http.MultipartFile.fromPath(
|
||||||
// final multipartFile = http.MultipartFile.fromBytes(
|
fieldName,
|
||||||
// 'incentive_file_name',
|
file.path!,
|
||||||
// data,
|
filename: file.name,
|
||||||
// filename: passportFile!.name,
|
);
|
||||||
// );
|
request.files.add(multipartFile);
|
||||||
//
|
}
|
||||||
// request.files.add(multipartFile);
|
print("📎 File attached: ${file.name} → $fieldName");
|
||||||
// print("📎 File attached: ${passportFile!.name}");
|
} catch (e) {
|
||||||
// } catch (e) {
|
print("❌ Failed to attach $fieldName: $e");
|
||||||
// print("❌ Failed to read file: $e");
|
}
|
||||||
// }
|
}
|
||||||
// } else {
|
|
||||||
// print("⚠️ No passport file selected.");
|
await addFile(docUploadedRCFile, 'rc_file_name');
|
||||||
// }
|
await addFile(docUploadedIDProof, 'id_proof_file_name');
|
||||||
//
|
await addFile(docUploadedPrevPolicy, 'previous_policy_file_name');
|
||||||
// print("🚀 Sending request with fields: ${request.fields}");
|
}
|
||||||
//
|
|
||||||
// try {
|
Future<void> createUserData(Map<String, dynamic> userData) async {
|
||||||
// final streamedResponse = await request.send();
|
// final bool isUpdating = widget.id != null && widget.id != 'create';
|
||||||
// final response = await http.Response.fromStream(streamedResponse);
|
// final id = widget.id;
|
||||||
// print("Response status: ${response.statusCode}");
|
final bool isUpdating = false;
|
||||||
// print("Response body: ${response.body}");
|
final uri = Uri.parse(
|
||||||
//
|
// isUpdating
|
||||||
// if (response.statusCode == 200 || response.statusCode == 201) {
|
// ? '${Env.apiUrl}agent/updateAgent'
|
||||||
// // dispose();
|
// : '${Env.apiUrl}agent/createAgent',
|
||||||
// print("✅ Agent submitted successfully!");
|
'${Env.apiUrl}enquiry/createEnquiry',
|
||||||
//
|
);
|
||||||
// print("📨 Response: ${response.body}");
|
if (_token == null) {
|
||||||
//
|
throw Exception('Token not found. Please log in.');
|
||||||
// final data = dataDetails(); // this is a Map<String, dynamic>
|
}
|
||||||
// final agentId = data["agent_id"];
|
|
||||||
//
|
// Use MultipartRequest (POST only)
|
||||||
// getAgentIncenctiveFileList(agentId);
|
final request = http.MultipartRequest('POST', uri);
|
||||||
// // context.go(AppRoutes.agentLst);
|
request.headers['Authorization'] = 'Bearer $_token';
|
||||||
// } else {
|
request.headers['app-signature'] =
|
||||||
// print("❌ Submission failed. Status: ${response.statusCode}");
|
'nhance-partner-2025-signature-35468846JRhH551HK';
|
||||||
// print("📨 Body: ${response.body}");
|
|
||||||
//
|
// If updating, spoof the method Laravel-style
|
||||||
// // Sort by created_on (latest first)
|
if (isUpdating) {
|
||||||
//
|
// request.fields['id'] = id!;
|
||||||
// showDialog(
|
request.fields['updated_by'] = userId!.toString();
|
||||||
// context: context,
|
} else {
|
||||||
// builder: (BuildContext context) {
|
request.fields['created_by'] = userId!.toString();
|
||||||
// return AlertDialog(
|
}
|
||||||
// title: Text("Agent Creation Failed"),
|
|
||||||
// content: Text(
|
print("USerDAta - $userData");
|
||||||
// "There was a problem in creating user. Please try again.",
|
|
||||||
// ),
|
// userData.forEach((key, value) {
|
||||||
// actions: [
|
// request.fields[key] = value.toString();
|
||||||
// TextButton(
|
// print("✅ Encoded travel_details2: ${request.fields[key]}");
|
||||||
// child: Text("OK"),
|
// });
|
||||||
// onPressed: () {
|
|
||||||
// Navigator.of(context).pop();
|
userData.forEach((key, value) {
|
||||||
// },
|
if (key != 'certificate_file_name') {
|
||||||
// ),
|
request.fields[key] = value.toString();
|
||||||
// ],
|
print("✅ Encoded $key: ${request.fields[key]}");
|
||||||
// );
|
}
|
||||||
// },
|
});
|
||||||
// );
|
|
||||||
// }
|
// attach files
|
||||||
// } catch (e) {
|
await attachFiles(request);
|
||||||
// print("🔥 Error submitting user: $e");
|
|
||||||
// }
|
// request.fields['agent_id'] = selectedId.toString();
|
||||||
// }
|
|
||||||
|
print(" Sending request with fields: ${request.fields}");
|
||||||
|
|
||||||
|
try {
|
||||||
|
final streamedResponse = await request.send();
|
||||||
|
final response = await http.Response.fromStream(streamedResponse);
|
||||||
|
print("Response status: ${response.statusCode}");
|
||||||
|
print("Response body: ${response.body}");
|
||||||
|
|
||||||
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||||
|
// dispose();
|
||||||
|
print("✅ Agent submitted successfully!");
|
||||||
|
|
||||||
|
print("Response: ${response.body}");
|
||||||
|
context.go(AppRoutes.tabEnquiry);
|
||||||
|
} else {
|
||||||
|
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||||
|
print("Body: ${response.body}");
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text("Agent Creation Failed"),
|
||||||
|
content: Text(
|
||||||
|
"There was a problem in creating user. Please try again.",
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
child: Text("OK"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("🔥 Error submitting user: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -425,7 +524,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
field,
|
field,
|
||||||
],
|
],
|
||||||
@ -440,12 +539,6 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
}) {
|
}) {
|
||||||
final isMobile = ResponsiveLayout.isMobile(context);
|
final isMobile = ResponsiveLayout.isMobile(context);
|
||||||
|
|
||||||
// final uploadWidget = ThemedUploadField(
|
|
||||||
// hintText: hintText ?? "Upload Document",
|
|
||||||
// txtwidth: isMobile ? null : MediaQuery.of(context).size.width * 0.26,
|
|
||||||
// onFileSelected: onFileSelected,
|
|
||||||
// );
|
|
||||||
|
|
||||||
final uploadWidget = ThemedUploadField(
|
final uploadWidget = ThemedUploadField(
|
||||||
hintText: hintText ?? "Upload Document",
|
hintText: hintText ?? "Upload Document",
|
||||||
txtwidth: MediaQuery.of(context).size.width * 0.26,
|
txtwidth: MediaQuery.of(context).size.width * 0.26,
|
||||||
@ -466,7 +559,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
uploadWidget,
|
uploadWidget,
|
||||||
],
|
],
|
||||||
@ -476,7 +569,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
|
|
||||||
Widget buildName(BuildContext context) {
|
Widget buildName(BuildContext context) {
|
||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Name *",
|
label: "Full Name ",
|
||||||
field: ThemedFormField(
|
field: ThemedFormField(
|
||||||
controller: controllers['name']!,
|
controller: controllers['name']!,
|
||||||
validator: (value) => Validators.requiredField(value, "name"),
|
validator: (value) => Validators.requiredField(value, "name"),
|
||||||
@ -489,7 +582,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
|
|
||||||
Widget buildEmail(BuildContext context) {
|
Widget buildEmail(BuildContext context) {
|
||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Email *",
|
label: "Email",
|
||||||
field: ThemedFormField(
|
field: ThemedFormField(
|
||||||
controller: controllers['email']!,
|
controller: controllers['email']!,
|
||||||
validator: (value) => Validators.email(value, "email"),
|
validator: (value) => Validators.email(value, "email"),
|
||||||
@ -502,7 +595,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
|
|
||||||
Widget buildPhNumber(BuildContext context) {
|
Widget buildPhNumber(BuildContext context) {
|
||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Phone Number *",
|
label: "Phone Number",
|
||||||
field: ThemedFormField(
|
field: ThemedFormField(
|
||||||
controller: controllers['mobile']!,
|
controller: controllers['mobile']!,
|
||||||
validator: (value) => Validators.phone(value, "phNumber"),
|
validator: (value) => Validators.phone(value, "phNumber"),
|
||||||
@ -515,7 +608,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
|
|
||||||
Widget buildId(BuildContext context) {
|
Widget buildId(BuildContext context) {
|
||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Registration Number *",
|
label: "Registration Number",
|
||||||
field: ThemedFormField(
|
field: ThemedFormField(
|
||||||
controller: controllers['regNo']!,
|
controller: controllers['regNo']!,
|
||||||
validator: (value) => Validators.requiredField(value, "regNo"),
|
validator: (value) => Validators.requiredField(value, "regNo"),
|
||||||
@ -527,6 +620,12 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildVehicleType(BuildContext context) {
|
Widget buildVehicleType(BuildContext context) {
|
||||||
|
// Find the matching map from your list
|
||||||
|
Map<String, dynamic>? selectedVehicle = filteredVechicleData.firstWhere(
|
||||||
|
(item) => item['id'] == selectedVehicleTypeId,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
|
||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Vehicle Type",
|
label: "Vehicle Type",
|
||||||
field: Container(
|
field: Container(
|
||||||
@ -537,12 +636,12 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
// height: 40,
|
// height: 40,
|
||||||
child: DropdownSearch<Map<String, dynamic>>(
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
key: dropDownKey,
|
key: dropDownKey,
|
||||||
selectedItem: null,
|
selectedItem: selectedVehicle.isNotEmpty ? selectedVehicle : null,
|
||||||
items: (filter, infiniteScrollProps) {
|
items: (filter, infiniteScrollProps) {
|
||||||
return filteredVechicleData;
|
return filteredVechicleData;
|
||||||
},
|
},
|
||||||
|
|
||||||
itemAsString: (val) => val['vehicle_type'].toString(), // what to show
|
itemAsString: (val) => val['vehicle_type'].toString(),
|
||||||
compareFn: (item, selectedItem) =>
|
compareFn: (item, selectedItem) =>
|
||||||
item['id'] == selectedItem['id'], // ✅ compare by id
|
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||||
decoratorProps: DropDownDecoratorProps(
|
decoratorProps: DropDownDecoratorProps(
|
||||||
@ -713,7 +812,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
|||||||
return buildResponsiveField(
|
return buildResponsiveField(
|
||||||
label: "Remarks",
|
label: "Remarks",
|
||||||
field: ThemedFormField(
|
field: ThemedFormField(
|
||||||
maxLength: 3,
|
maxLength: 500,
|
||||||
controller: controllers['remarks']!,
|
controller: controllers['remarks']!,
|
||||||
txtwidth: ResponsiveLayout.isMobile(context)
|
txtwidth: ResponsiveLayout.isMobile(context)
|
||||||
? null
|
? null
|
||||||
|
|||||||
@ -302,7 +302,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
field,
|
field,
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
@ -312,7 +312,7 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
field,
|
field,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -409,7 +409,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
field,
|
field,
|
||||||
],
|
],
|
||||||
@ -444,7 +444,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
|||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(label, style: _textStyle),
|
Expanded(child: Text(label, style: _textStyle)),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
uploadWidget,
|
uploadWidget,
|
||||||
],
|
],
|
||||||
@ -465,38 +465,6 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildDataTable5(BuildContext context) {
|
|
||||||
if (filteredData.isEmpty) {
|
|
||||||
return const SizedBox(
|
|
||||||
height: 50,
|
|
||||||
child: Center(child: Text('No available data')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final sortedData = [...filteredData]
|
|
||||||
..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));
|
|
||||||
return ListView.builder(
|
|
||||||
itemCount: ResponsiveLayout.isMobile(context)
|
|
||||||
? sortedData
|
|
||||||
.length // only cards for mobile
|
|
||||||
: sortedData.length + 1, // +1 for header in desktop
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (!ResponsiveLayout.isMobile(context) && index == 0) {
|
|
||||||
return _buildHeader();
|
|
||||||
}
|
|
||||||
|
|
||||||
final startIndex = (currentPage - 1) * itemsPerPage;
|
|
||||||
final item =
|
|
||||||
sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)];
|
|
||||||
final sno = startIndex + index;
|
|
||||||
|
|
||||||
return !ResponsiveLayout.isMobile(context)
|
|
||||||
? _buildDataRow(item, sno)
|
|
||||||
: _buildDataCard(item, sno);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildDataTable(BuildContext context) {
|
Widget _buildDataTable(BuildContext context) {
|
||||||
if (filteredData.isEmpty) {
|
if (filteredData.isEmpty) {
|
||||||
return const SizedBox(
|
return const SizedBox(
|
||||||
|
|||||||
@ -239,6 +239,8 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
print("Response: ${response.body}");
|
print("Response: ${response.body}");
|
||||||
context.go(AppRoutes.agentLst);
|
context.go(AppRoutes.agentLst);
|
||||||
} else {
|
} else {
|
||||||
|
final responseBody = jsonDecode(response.body);
|
||||||
|
dynamic msg = responseBody['data'];
|
||||||
print("❌ Submission failed. Status: ${response.statusCode}");
|
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||||
print("Body: ${response.body}");
|
print("Body: ${response.body}");
|
||||||
|
|
||||||
@ -246,9 +248,10 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text("Agent Creation Failed"),
|
title: Text("Agent User Creation Failed"),
|
||||||
content: Text(
|
content: Text(
|
||||||
"There was a problem in creating user. Please try again.",
|
msg,
|
||||||
|
// "There was a problem in creating user. Please try again.",
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
@ -570,7 +573,8 @@ class AgentState extends ConsumerState<Agent> {
|
|||||||
padding: const EdgeInsets.all(5),
|
padding: const EdgeInsets.all(5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
color: Colors.green.shade300,
|
color: Color(0xFF425B5B),
|
||||||
|
// color: Colors.green.shade300,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: const [
|
children: const [
|
||||||
|
|||||||
@ -161,6 +161,9 @@ class StaffState extends ConsumerState<Staff> {
|
|||||||
print("Response: ${response.body}");
|
print("Response: ${response.body}");
|
||||||
context.go(AppRoutes.staffLst);
|
context.go(AppRoutes.staffLst);
|
||||||
} else {
|
} else {
|
||||||
|
final responseBody = jsonDecode(response.body);
|
||||||
|
dynamic msg = responseBody['data'];
|
||||||
|
|
||||||
print("Failed to submit plan. Status: ${response.statusCode}");
|
print("Failed to submit plan. Status: ${response.statusCode}");
|
||||||
print("Error: ${response.body}");
|
print("Error: ${response.body}");
|
||||||
|
|
||||||
@ -168,10 +171,8 @@ class StaffState extends ConsumerState<Staff> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text("Staff Creation Failed"),
|
title: Text("Staff User Creation Failed"),
|
||||||
content: Text(
|
content: Text(msg),
|
||||||
"There was a problem submitting your plan. Please try again.",
|
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text("OK"),
|
child: Text("OK"),
|
||||||
|
|||||||
@ -19,11 +19,25 @@ class _MobileTabsState extends State<MobileTabs> {
|
|||||||
setState(() => _currentIndex = index);
|
setState(() => _currentIndex = index);
|
||||||
widget.onTabChanged(index);
|
widget.onTabChanged(index);
|
||||||
},
|
},
|
||||||
items: const [
|
items: [
|
||||||
BottomNavigationBarItem(icon: Icon(Icons.dashboard), label: "Home"),
|
|
||||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profile"),
|
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.event_note_sharp),
|
icon: Image.asset(
|
||||||
|
"assets/drawer/drawerImg1.png",
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
label: "Dashboard",
|
||||||
|
),
|
||||||
|
const BottomNavigationBarItem(
|
||||||
|
icon: Icon(Icons.person),
|
||||||
|
label: "Profile",
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Image.asset(
|
||||||
|
"assets/drawer/drawerImg2.png",
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
label: "Enquiry",
|
label: "Enquiry",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -29,10 +29,16 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
backgroundColor: const Color(0xFFD6F6F4), // light cyan
|
backgroundColor: const Color(0xFFD6F6F4), // light cyan
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
titleSpacing: 0,
|
titleSpacing: isMobile ? 0 : 30,
|
||||||
title: Row(
|
title: Row(
|
||||||
children: [
|
children: [
|
||||||
if (isMobile)
|
if (!isMobile)
|
||||||
|
Image.asset(
|
||||||
|
"assets/login/nhance-partner-logo.png",
|
||||||
|
height: 60,
|
||||||
|
width: 120,
|
||||||
|
),
|
||||||
|
if (isMobile) ...[
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.arrow_back_ios,
|
Icons.arrow_back_ios,
|
||||||
@ -40,38 +46,70 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
size: 18,
|
size: 18,
|
||||||
),
|
),
|
||||||
onPressed: onBack ?? () => Navigator.pop(context),
|
onPressed: onBack ?? () => Navigator.pop(context),
|
||||||
)
|
|
||||||
else if (onMenuPressed != null)
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.menu, color: Colors.black87),
|
|
||||||
onPressed: onMenuPressed,
|
|
||||||
),
|
),
|
||||||
Expanded(
|
|
||||||
child: Text(
|
Expanded(
|
||||||
title,
|
child: Text(
|
||||||
style: const TextStyle(
|
title,
|
||||||
color: Colors.black87,
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.w500,
|
color: Colors.black87,
|
||||||
fontSize: 16,
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.notifications_none, color: Colors.black87),
|
Spacer(),
|
||||||
onPressed: onNotifications,
|
|
||||||
|
// else if (onMenuPressed != null)
|
||||||
|
// IconButton(
|
||||||
|
// icon: const Icon(Icons.menu, color: Colors.black87),
|
||||||
|
// onPressed: onMenuPressed,
|
||||||
|
// ),
|
||||||
|
Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.notifications_none, color: Colors.black87),
|
||||||
|
onPressed: onNotifications,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
if (!isMobile) ...[
|
if (!isMobile) ...[
|
||||||
GestureDetector(
|
SizedBox(width: 10),
|
||||||
onTapDown: (details) => onProfile!(details),
|
Container(
|
||||||
child: const Icon(Icons.person_outline, color: Colors.black87),
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTapDown: (details) => onProfile!(details),
|
||||||
|
child: const Icon(Icons.person_outline, color: Colors.black87),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// icon: const Icon(Icons.person_outline, color: Colors.black87),
|
// icon: const Icon(Icons.person_outline, color: Colors.black87),
|
||||||
// onPressed: onProfile,
|
// onPressed: onProfile,
|
||||||
// ),
|
// ),
|
||||||
IconButton(
|
SizedBox(width: 10),
|
||||||
icon: const Icon(Icons.logout, color: Colors.black87),
|
Container(
|
||||||
onPressed: onLogout,
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(50.0),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(Icons.logout, color: Colors.black87),
|
||||||
|
onPressed: onLogout,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user