multi_file_upload
This commit is contained in:
parent
6a78b1c6d2
commit
53a86a8e21
File diff suppressed because one or more lines are too long
@ -363,6 +363,31 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
|||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Proposal button
|
||||||
|
Container(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(color: Colors.grey.shade200, width: 1),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.request_quote_outlined,
|
||||||
|
color: Colors.black87,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint("Notifications tapped");
|
||||||
|
},
|
||||||
|
tooltip: 'Create Proposal',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
|
||||||
// Notifications button
|
// Notifications button
|
||||||
Container(
|
Container(
|
||||||
width: 36,
|
width: 36,
|
||||||
@ -432,7 +457,7 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
(role == 'agent') ? 'partner' : role ?? 'manager',
|
(role == 'agent') ? 'Partner' : role ?? 'Manager',
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
color: Colors.grey.shade600,
|
color: Colors.grey.shade600,
|
||||||
|
|||||||
@ -556,12 +556,14 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
|
|
||||||
ThemedSearchField(
|
ThemedSearchField(
|
||||||
hintText: 'Search',
|
hintText: 'Search',
|
||||||
backgroundColor: Color(0xFFF6F8F8),
|
backgroundColor: Color(0xFFFFFFFF),
|
||||||
|
// backgroundColor: Color(0xFFF6F8F8),
|
||||||
onChanged: filterData,
|
onChanged: filterData,
|
||||||
controller: _searchStaffController,
|
controller: _searchStaffController,
|
||||||
txtwidth: ResponsiveLayout.isMobile(context)
|
txtwidth: ResponsiveLayout.isMobile(context)
|
||||||
? MediaQuery.of(context).size.width * 0.6
|
? MediaQuery.of(context).size.width * 0.6
|
||||||
: MediaQuery.of(context).size.width * 0.13,
|
: MediaQuery.of(context).size.width * 0.13,
|
||||||
|
txtHeight: 30,
|
||||||
),
|
),
|
||||||
ResponsiveLayout.isMobile(context)
|
ResponsiveLayout.isMobile(context)
|
||||||
? Spacer()
|
? Spacer()
|
||||||
@ -614,26 +616,30 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
// print('Export');
|
// print('Export');
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(5.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Color(0xFF425B5B),
|
color: const Color(0xFF2E7D6E),
|
||||||
|
// color: Color(0xFF425B5B),
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.add, color: Colors.white),
|
Tooltip(
|
||||||
|
message: 'Raise Enquiry',
|
||||||
|
child: Icon(Icons.add, color: Colors.white, size: 18),
|
||||||
|
),
|
||||||
|
|
||||||
if (!ResponsiveLayout.isMobile(context)) ...[
|
if (!ResponsiveLayout.isMobile(context)) ...[
|
||||||
SizedBox(width: 10),
|
// SizedBox(width: 10),
|
||||||
Text(
|
// Text(
|
||||||
'Raise Enquiry',
|
// 'Raise Enquiry',
|
||||||
style: GoogleFonts.inter(
|
// style: GoogleFonts.inter(
|
||||||
color: Colors.white,
|
// color: Colors.white,
|
||||||
fontWeight: FontWeight.w600,
|
// fontWeight: FontWeight.w600,
|
||||||
fontSize: 14,
|
// fontSize: 14,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
// GestureDetector(
|
// GestureDetector(
|
||||||
// onTap: () {
|
// onTap: () {
|
||||||
// ref
|
// ref
|
||||||
@ -666,10 +672,11 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
if (!ResponsiveLayout.isMobile(context))
|
if (!ResponsiveLayout.isMobile(context))
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Color(0xFFEDF6F5),
|
// color: Color(0xFFEDF6F5),
|
||||||
|
color: Color(0xFFF1F5F9),
|
||||||
borderRadius: BorderRadius.circular(6),
|
borderRadius: BorderRadius.circular(6),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
|
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
|
||||||
@ -773,10 +780,11 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
|
|
||||||
Widget _buildDataRow(Map<String, dynamic> item, sno) {
|
Widget _buildDataRow(Map<String, dynamic> item, sno) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 16),
|
||||||
// margin: const EdgeInsets.only(top: 10),
|
// margin: const EdgeInsets.only(top: 10),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|
||||||
// color: Color(0xFFE0F7F9),
|
// color: Color(0xFFE0F7F9),
|
||||||
border: const Border(
|
border: const Border(
|
||||||
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
|
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
|
||||||
@ -869,13 +877,13 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
"assets/miscellaneous/Edit.png",
|
"assets/miscellaneous/Edit.png",
|
||||||
height: 15,
|
height: 12,
|
||||||
width: 15,
|
width: 15,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
handleEdit(item);
|
handleEdit(item);
|
||||||
},
|
},
|
||||||
splashRadius: 28,
|
splashRadius: 18,
|
||||||
hoverColor: Colors.black12,
|
hoverColor: Colors.black12,
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
constraints: const BoxConstraints(),
|
constraints: const BoxConstraints(),
|
||||||
@ -1152,7 +1160,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final _dataBold = GoogleFonts.inter(
|
static final _dataBold = GoogleFonts.inter(
|
||||||
fontSize: 14,
|
fontSize: 12,
|
||||||
|
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Color(0xFF000000),
|
color: Color(0xFF000000),
|
||||||
@ -1168,9 +1176,15 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
|||||||
// color: Colors.black,
|
// color: Colors.black,
|
||||||
// fontWeight: FontWeight.bold,
|
// fontWeight: FontWeight.bold,
|
||||||
// );
|
// );
|
||||||
static final _headerStyle = GoogleFonts.inter(
|
// static final _headerStyle = GoogleFonts.inter(
|
||||||
color: Colors.black,
|
// color: Colors.black,
|
||||||
fontWeight: FontWeight.bold,
|
// fontWeight: FontWeight.bold,
|
||||||
|
// );
|
||||||
|
|
||||||
|
static final _headerStyle = GoogleFonts.poppins(
|
||||||
|
fontSize: 11.2,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Color(0xFF1E293B),
|
||||||
);
|
);
|
||||||
static final _cardheaderStyle = GoogleFonts.inter(
|
static final _cardheaderStyle = GoogleFonts.inter(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
|||||||
@ -1013,8 +1013,9 @@ class agentPendings extends StatelessWidget {
|
|||||||
print('-Data: $data');
|
print('-Data: $data');
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
color: const Color(0xFFEAF6F4),
|
color: Colors.white,
|
||||||
elevation: 0,
|
// color: const Color(0xFFEAF6F4),
|
||||||
|
elevation: 1,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(12.0),
|
padding: const EdgeInsets.all(12.0),
|
||||||
@ -1029,7 +1030,8 @@ class agentPendings extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFF3E5B56),
|
color: Color(0xFFE3F9F8),
|
||||||
|
// color: const Color(0xFF3E5B56),
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -1122,14 +1124,17 @@ class agentPendings extends StatelessWidget {
|
|||||||
onStaffEdit!(row['id'].toString(), stringFlag);
|
onStaffEdit!(row['id'].toString(), stringFlag);
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 5),
|
// margin: const EdgeInsets.symmetric(vertical: 5),
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 5,
|
vertical: 5,
|
||||||
horizontal: 12,
|
horizontal: 12,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: Colors.blueGrey.shade50),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:nhance_partner/presentation/screens/staff/Enquiry/quotationPopUpAccptReject.dart';
|
import 'package:nhance_partner/presentation/screens/staff/Enquiry/quotationPopUpAccptReject.dart';
|
||||||
import 'package:nhance_partner/presentation/screens/staff/Enquiry/raise_enq_form.dart';
|
import 'package:nhance_partner/presentation/screens/staff/Enquiry/raise_enq_form.dart';
|
||||||
import 'package:nhance_partner/presentation/screens/staff/Enquiry/tabs/tab.dart';
|
import 'package:nhance_partner/presentation/screens/staff/Enquiry/tabs/tab.dart';
|
||||||
|
import 'package:nhance_partner/presentation/themes/indicators/customizd_multi_file_upload.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import '../../../../core/config/env.dart';
|
import '../../../../core/config/env.dart';
|
||||||
@ -132,8 +133,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
"email": controllers["email"]?.text,
|
"email": controllers["email"]?.text,
|
||||||
"reg_no": controllers["regNo"]?.text,
|
"reg_no": controllers["regNo"]?.text,
|
||||||
"vehicle_type_id": selectedVehicleType,
|
"vehicle_type_id": selectedVehicleType,
|
||||||
"is_data_created_by_handler": roleId == 'handler' ? '1' : '0',
|
// "is_data_created_by_handler": roleId == 'handler' ? '1' : '0',
|
||||||
"is_data_created_by_manager": roleId == 'manager' ? '1' : '0',
|
// "is_data_created_by_manager": roleId == 'manager' ? '1' : '0',
|
||||||
|
"is_data_created_by_staff": roleId != null ? '1' : '0',
|
||||||
// "insurer_id": selectedInsurer,
|
// "insurer_id": selectedInsurer,
|
||||||
// "rc_file_name": "rc_doc.pdf",
|
// "rc_file_name": "rc_doc.pdf",
|
||||||
// "id_proof_file_name": "id_proof.pdf",
|
// "id_proof_file_name": "id_proof.pdf",
|
||||||
@ -1706,7 +1708,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
}) {
|
}) {
|
||||||
final isMobile = ResponsiveLayout.isMobile(context);
|
final isMobile = ResponsiveLayout.isMobile(context);
|
||||||
|
|
||||||
final uploadWidget = ThemedUploadField(
|
final uploadWidget = ThemedMultiFileUploadField(
|
||||||
hintText: hintText ?? "Upload Document",
|
hintText: hintText ?? "Upload Document",
|
||||||
txtwidth: width,
|
txtwidth: width,
|
||||||
// txtwidth: MediaQuery.of(context).size.width * 0.08,
|
// txtwidth: MediaQuery.of(context).size.width * 0.08,
|
||||||
@ -1720,6 +1722,20 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
onFileSelected: onFileSelected,
|
onFileSelected: onFileSelected,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// final uploadWidget = ThemedUploadField(
|
||||||
|
// hintText: hintText ?? "Upload Document",
|
||||||
|
// txtwidth: width,
|
||||||
|
// // txtwidth: MediaQuery.of(context).size.width * 0.08,
|
||||||
|
// padVertical: 6,
|
||||||
|
// padHorizontal: 8,
|
||||||
|
//
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// // backgroundColor: Color(0xffD9EBE8),
|
||||||
|
// txtName: label,
|
||||||
|
// isTxtBtnCase: true,
|
||||||
|
// onFileSelected: onFileSelected,
|
||||||
|
// );
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
@ -2120,9 +2136,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
spacing: 12,
|
spacing: 12,
|
||||||
runSpacing: 12,
|
runSpacing: 12,
|
||||||
children: [
|
children: [
|
||||||
buildAgentName(context, fromHeader: false),
|
|
||||||
buildSelectStaffMem(context),
|
buildSelectStaffMem(context),
|
||||||
|
buildAgentName(context, fromHeader: false),
|
||||||
buildInsurer(context),
|
buildInsurer(context),
|
||||||
buildInsuredName(context),
|
buildInsuredName(context),
|
||||||
buildVehicleNumber(context),
|
buildVehicleNumber(context),
|
||||||
@ -3135,25 +3150,25 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
|
|
||||||
return DataRow(
|
return DataRow(
|
||||||
cells: [
|
cells: [
|
||||||
// DataCell(
|
DataCell(
|
||||||
// SizedBox(
|
SizedBox(
|
||||||
// width: 80,
|
width: 80,
|
||||||
// child: Row(
|
child: Row(
|
||||||
// children: [
|
children: [
|
||||||
// // Text(item['created_on'], style: _dataBold),
|
// Text(item['created_on'], style: _dataBold),
|
||||||
// Text(
|
Text(
|
||||||
// formatDateTimeForTable(item['created_on'], newLine: true),
|
formatDateTimeForTable(item['created_on'], newLine: true),
|
||||||
// style: _dataBoldthm1,
|
style: _dataBoldthm1,
|
||||||
// ),
|
),
|
||||||
// ],
|
],
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// Assigned To
|
// Assigned To
|
||||||
DataCell(
|
DataCell(
|
||||||
SizedBox(
|
SizedBox(
|
||||||
// flex: 1,
|
// flex: 1,
|
||||||
width: 100,
|
width: 120,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -3164,7 +3179,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
: '-',
|
: '-',
|
||||||
style: _dataBold,
|
style: _dataBold,
|
||||||
),
|
),
|
||||||
// Text(_formatDate(item['updated_on']), style: _dataBoldthm4),
|
Text(_formatDate(item['updated_on']), style: _dataBoldthm4),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -3522,7 +3537,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
// Add this helper method to generate DataColumns
|
// Add this helper method to generate DataColumns
|
||||||
List<DataColumn> _buildDataColumns() {
|
List<DataColumn> _buildDataColumns() {
|
||||||
return [
|
return [
|
||||||
// DataColumn(label: Text('Received Date', style: _headerStyle)),
|
DataColumn(label: Text('Received Date', style: _headerStyle)),
|
||||||
DataColumn(label: Text('Assigned To *', style: _headerStyle)),
|
DataColumn(label: Text('Assigned To *', style: _headerStyle)),
|
||||||
DataColumn(label: Text('Partner *', style: _headerStyle)),
|
DataColumn(label: Text('Partner *', style: _headerStyle)),
|
||||||
|
|
||||||
@ -3545,14 +3560,14 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
|||||||
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// _buildHeaderCell('Received Date', 120),
|
_buildHeaderCell('Received Date', 110),
|
||||||
_buildHeaderCell('Assigned To *', 130),
|
_buildHeaderCell('Assigned To *', 130),
|
||||||
_buildHeaderCell('Partner *', 160),
|
_buildHeaderCell('Partner *', 160),
|
||||||
|
|
||||||
// _buildHeaderCell('Broker *', 100),
|
// _buildHeaderCell('Broker *', 100),
|
||||||
_buildHeaderCell('Insurer *', 90),
|
_buildHeaderCell('Insurer *', 90),
|
||||||
_buildHeaderCell('Insured Name *', 120),
|
_buildHeaderCell('Insured Name *', 110),
|
||||||
_buildHeaderCell('Vehicle No *', 110),
|
_buildHeaderCell('Vehicle No *', 90),
|
||||||
_buildHeaderCell('Action', 60),
|
_buildHeaderCell('Action', 60),
|
||||||
// _buildHeaderCell('Assigned Date', 100),
|
// _buildHeaderCell('Assigned Date', 100),
|
||||||
_buildHeaderCell('Premium', 100),
|
_buildHeaderCell('Premium', 100),
|
||||||
|
|||||||
@ -106,8 +106,9 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
|
|||||||
"email": controllers["email"]?.text,
|
"email": controllers["email"]?.text,
|
||||||
"reg_no": controllers["regNo"]?.text,
|
"reg_no": controllers["regNo"]?.text,
|
||||||
"vehicle_type_id": selectedVehicleType,
|
"vehicle_type_id": selectedVehicleType,
|
||||||
"is_data_created_by_handler": roleId == 'handler' ? '1' : '0',
|
// "is_data_created_by_handler": roleId == 'handler' ? '1' : '0',
|
||||||
"is_data_created_by_manager": roleId == 'manager' ? '1' : '0',
|
// "is_data_created_by_manager": roleId == 'manager' ? '1' : '0',
|
||||||
|
"is_data_created_by_staff": roleId != null ? '1' : '0',
|
||||||
// "insurer_id": selectedInsurer,
|
// "insurer_id": selectedInsurer,
|
||||||
// "rc_file_name": "rc_doc.pdf",
|
// "rc_file_name": "rc_doc.pdf",
|
||||||
// "id_proof_file_name": "id_proof.pdf",
|
// "id_proof_file_name": "id_proof.pdf",
|
||||||
@ -164,6 +165,7 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
|
|||||||
print('hansles');
|
print('hansles');
|
||||||
getStaffDetailsForEnquiryAssignment(userID);
|
getStaffDetailsForEnquiryAssignment(userID);
|
||||||
}
|
}
|
||||||
|
getBroker();
|
||||||
});
|
});
|
||||||
|
|
||||||
getVehicleType();
|
getVehicleType();
|
||||||
@ -256,6 +258,37 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> getBroker() async {
|
||||||
|
print('getBroker called');
|
||||||
|
setState(() {
|
||||||
|
isLoading = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await apiService.fetchMasterDropDown('Broker');
|
||||||
|
|
||||||
|
if (response['status'] == 200) {
|
||||||
|
print('getBroker - ${response['data']}');
|
||||||
|
setState(() {
|
||||||
|
getBrokerData = List<Map<String, dynamic>>.from(response['data']);
|
||||||
|
print('API Data - $getBrokerData');
|
||||||
|
|
||||||
|
filteredBrokerData = List.from(getBrokerData);
|
||||||
|
print('originalData - $filteredBrokerData');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getBrokerData = [];
|
||||||
|
filteredBrokerData = [];
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Exception occurred: $e');
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> getAgentList(id) async {
|
Future<void> getAgentList(id) async {
|
||||||
print('getAgentListData called');
|
print('getAgentListData called');
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -356,9 +389,11 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
|
|||||||
children: [
|
children: [
|
||||||
buildAgentName(context, fromHeader: true),
|
buildAgentName(context, fromHeader: true),
|
||||||
if (roleId != 'staff') ...[buildSelectStaffMem(context)],
|
if (roleId != 'staff') ...[buildSelectStaffMem(context)],
|
||||||
buildInsurer(context, fromHeader: true),
|
|
||||||
buildInsuredName(context, fromHeader: true),
|
|
||||||
|
|
||||||
|
buildBroker(context),
|
||||||
|
buildInsurer(context, fromHeader: true),
|
||||||
|
|
||||||
|
// buildInsuredName(context, fromHeader: true),
|
||||||
buildVehicleNumber(context),
|
buildVehicleNumber(context),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -931,6 +966,155 @@ class RaiseEnqFormState extends ConsumerState<RaiseEnqForm> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildBroker(BuildContext context) {
|
||||||
|
Map<String, dynamic>? selectedBrokers = filteredBrokerData.firstWhere(
|
||||||
|
(item) => item['id'].toString() == selectedBroker,
|
||||||
|
orElse: () => {},
|
||||||
|
);
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('Broker *', style: _subLabelTimeStyle),
|
||||||
|
|
||||||
|
SizedBox(height: 5),
|
||||||
|
SizedBox(
|
||||||
|
// height: 30,
|
||||||
|
width: MediaQuery.of(context).size.width * 0.12,
|
||||||
|
child: DropdownSearch<Map<String, dynamic>>(
|
||||||
|
key: dropDownKeyBroker,
|
||||||
|
selectedItem: selectedBrokers.isNotEmpty ? selectedBrokers : null,
|
||||||
|
items: (filter, infiniteScrollProps) {
|
||||||
|
return filteredBrokerData;
|
||||||
|
},
|
||||||
|
|
||||||
|
itemAsString: (val) => val['name'].toString(), // what to show
|
||||||
|
compareFn: (item, selectedItem) =>
|
||||||
|
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||||
|
validator: (val) {
|
||||||
|
if (val == null) {
|
||||||
|
return "Required"; // ✅ error message
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
suffixProps: DropdownSuffixProps(
|
||||||
|
// make sure the dropdown button is visible
|
||||||
|
dropdownButtonProps: DropdownButtonProps(
|
||||||
|
isVisible: true,
|
||||||
|
padding: EdgeInsets.zero, // remove default padding
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
// shrink icon tap area
|
||||||
|
minWidth: 12,
|
||||||
|
minHeight: 12,
|
||||||
|
),
|
||||||
|
iconSize: 15, // smaller icon
|
||||||
|
// icon: const Icon(Icons.arrow_drop_down),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownBuilder: (context, selectedItem) => Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(
|
||||||
|
selectedItem != null ? selectedItem['name'].toString() : "",
|
||||||
|
style: GoogleFonts.poppins(fontSize: 11, color: Colors.black),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
softWrap: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
decoratorProps: DropDownDecoratorProps(
|
||||||
|
decoration:
|
||||||
|
AppInputDecorations.dropdownDecoration(
|
||||||
|
label: "Select Broker",
|
||||||
|
).copyWith(
|
||||||
|
filled: true,
|
||||||
|
fillColor:
|
||||||
|
Colors.white, // 👈 makes the dropdown input white
|
||||||
|
isDense: true,
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Color(0xFFE2E8F0),
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
color: Color(0xFFE2E8F0),
|
||||||
|
width: 0.5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
contentPadding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
popupProps: PopupProps.menu(
|
||||||
|
fit: FlexFit.loose,
|
||||||
|
constraints: BoxConstraints(maxHeight: 250),
|
||||||
|
menuProps: MenuProps(
|
||||||
|
backgroundColor:
|
||||||
|
Colors.white, // 👈 sets dropdown background to white
|
||||||
|
),
|
||||||
|
showSearchBox: true,
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
autofocus: true,
|
||||||
|
style: GoogleFonts.inter(fontSize: 11, color: Colors.black),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.all(1),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.white,
|
||||||
|
hintText: "Search Broker...",
|
||||||
|
hintStyle: GoogleFonts.inter(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
enabledBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
), // 👈 Normal border
|
||||||
|
),
|
||||||
|
focusedBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Colors.white,
|
||||||
|
width: 1.5,
|
||||||
|
), // 👈 Focused border
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
itemBuilder: (context, item, isDisabled, isSelected) {
|
||||||
|
return Container(
|
||||||
|
// color: isSelected ? Colors.blue.withOpacity(0.1) : null,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 8,
|
||||||
|
vertical: 3,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
item['name'].toString(),
|
||||||
|
style: GoogleFonts.inter(fontSize: 12, color: Colors.black),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// constraints: BoxConstraints(),
|
||||||
|
),
|
||||||
|
|
||||||
|
onChanged: (val) {
|
||||||
|
if (val != null) {
|
||||||
|
print("Selected Broker : ${val['name']}");
|
||||||
|
print("Id: ${val['id']}");
|
||||||
|
selectedBroker = val['id'];
|
||||||
|
// controllers['agentId']?.text = val['agent_code'];
|
||||||
|
// agentId = agent['id'];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildSave(context) {
|
Widget buildSave(context) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|||||||
@ -504,8 +504,85 @@ class CreateProposalFormState extends ConsumerState<CreateProposalForm> {
|
|||||||
child: buildFormFields(context),
|
child: buildFormFields(context),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Row(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
// children: [
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () {
|
||||||
|
// handleDone();
|
||||||
|
// // widget.onSubmit(controller.text.trim());
|
||||||
|
// // Navigator.of(context).pop();
|
||||||
|
// },
|
||||||
|
// child: Container(
|
||||||
|
// padding: const EdgeInsets.symmetric(
|
||||||
|
// horizontal: 25.0,
|
||||||
|
// vertical: 10,
|
||||||
|
// ),
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.circular(8.0),
|
||||||
|
// color: const Color(0xFF425B5B),
|
||||||
|
// ),
|
||||||
|
// child: Text(
|
||||||
|
// 'Save',
|
||||||
|
// style: GoogleFonts.poppins(
|
||||||
|
// color: Colors.white,
|
||||||
|
// fontSize: 12,
|
||||||
|
// fontWeight: FontWeight.w600,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildFormFields(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
buildIdv(context),
|
||||||
|
Spacer(),
|
||||||
|
// buildInsurer(context),
|
||||||
|
buildInsurancePlanType(context),
|
||||||
|
Spacer(),
|
||||||
|
buildPremiumAmnt(context),
|
||||||
|
Spacer(),
|
||||||
|
|
||||||
|
// buildDocuments(context),
|
||||||
|
|
||||||
|
// if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10),
|
||||||
|
// _buildResponsiveRow(
|
||||||
|
// context,
|
||||||
|
// buildAdditonalDocuments(context),
|
||||||
|
// buildRemarks(context),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
buildPaymentMode(context),
|
||||||
|
Spacer(),
|
||||||
|
// buildInsurer(context),
|
||||||
|
buildBroker(context),
|
||||||
|
Spacer(),
|
||||||
|
buildDocuments(context), Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(height: 10),
|
||||||
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
@ -536,50 +613,6 @@ class CreateProposalFormState extends ConsumerState<CreateProposalForm> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildFormFields(BuildContext context) {
|
|
||||||
return Form(
|
|
||||||
key: _formKey,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
buildIdv(context),
|
|
||||||
Spacer(),
|
|
||||||
// buildInsurer(context),
|
|
||||||
buildInsurancePlanType(context),
|
|
||||||
Spacer(),
|
|
||||||
buildPremiumAmnt(context),
|
|
||||||
Spacer(),
|
|
||||||
// buildDocuments(context),
|
|
||||||
|
|
||||||
// if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10),
|
|
||||||
// _buildResponsiveRow(
|
|
||||||
// context,
|
|
||||||
// buildAdditonalDocuments(context),
|
|
||||||
// buildRemarks(context),
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 10),
|
|
||||||
|
|
||||||
Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
buildPaymentMode(context),
|
|
||||||
Spacer(),
|
|
||||||
// buildInsurer(context),
|
|
||||||
buildBroker(context),
|
|
||||||
Spacer(),
|
|
||||||
buildDocuments(context), Spacer(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -897,33 +897,33 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 1),
|
SizedBox(height: 1),
|
||||||
// if (roleId != 'manager') ...[
|
// if (roleId != 'manager') ...[
|
||||||
Row(
|
// Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
// mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
// children: [
|
||||||
InkWell(
|
// InkWell(
|
||||||
onTap: () {
|
// onTap: () {
|
||||||
handleSave();
|
// handleSave();
|
||||||
},
|
// },
|
||||||
child: Container(
|
// child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 45.0, vertical: 8),
|
// padding: EdgeInsets.symmetric(horizontal: 45.0, vertical: 8),
|
||||||
|
//
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
// borderRadius: BorderRadius.circular(8.0),
|
||||||
color: Color(0xFF425B5B),
|
// color: Color(0xFF425B5B),
|
||||||
),
|
// ),
|
||||||
child: Text(
|
// child: Text(
|
||||||
// !hasPolicyData ? 'Submit' : 'Update',
|
// // !hasPolicyData ? 'Submit' : 'Update',
|
||||||
'Submit',
|
// 'Submit',
|
||||||
style: TextStyle(
|
// style: TextStyle(
|
||||||
color: Colors.white,
|
// color: Colors.white,
|
||||||
fontSize: 12,
|
// fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
// fontWeight: FontWeight.w600,
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
// ],
|
// ],
|
||||||
// ),
|
// ),
|
||||||
],
|
],
|
||||||
@ -1160,6 +1160,37 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
handleSave();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 45.0,
|
||||||
|
vertical: 8,
|
||||||
|
),
|
||||||
|
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
color: Color(0xFF425B5B),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
// !hasPolicyData ? 'Submit' : 'Update',
|
||||||
|
'Submit',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
@ -0,0 +1,161 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
import 'fileUploadService.dart';
|
||||||
|
import 'multi_fileUploadService.dart';
|
||||||
|
|
||||||
|
class ThemedMultiFileUploadField extends StatefulWidget {
|
||||||
|
final String? hintText;
|
||||||
|
final double? txtwidth;
|
||||||
|
final double? txtheight;
|
||||||
|
final Color? backgroundColor;
|
||||||
|
final Color? borderColor;
|
||||||
|
final Color? errorBorderColor;
|
||||||
|
final Function(String fileName, PlatformFile file)? onFileSelected;
|
||||||
|
FormFieldValidator<String>? validator;
|
||||||
|
final List<String>? allowedExtensions;
|
||||||
|
final bool isTxtBtnCase;
|
||||||
|
final String? txtName;
|
||||||
|
final double? padVertical;
|
||||||
|
final double? padHorizontal;
|
||||||
|
|
||||||
|
ThemedMultiFileUploadField({
|
||||||
|
super.key,
|
||||||
|
this.hintText,
|
||||||
|
this.txtwidth,
|
||||||
|
this.txtheight,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.borderColor,
|
||||||
|
this.errorBorderColor,
|
||||||
|
this.onFileSelected,
|
||||||
|
this.validator,
|
||||||
|
this.allowedExtensions,
|
||||||
|
this.isTxtBtnCase = false,
|
||||||
|
this.txtName,
|
||||||
|
this.padVertical,
|
||||||
|
this.padHorizontal,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ThemedMultiFileUploadField> createState() =>
|
||||||
|
_ThemedMultiFileUploadFieldState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ThemedMultiFileUploadFieldState
|
||||||
|
extends State<ThemedMultiFileUploadField> {
|
||||||
|
final fileService = MultiFileUploadService();
|
||||||
|
String? selectedFileName;
|
||||||
|
String? errorMessage;
|
||||||
|
|
||||||
|
Future<void> _pickFile() async {
|
||||||
|
final error = await fileService.pickFiles(
|
||||||
|
maxFileSizeInMB: 3,
|
||||||
|
allowedExtensions: widget.allowedExtensions,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
setState(() => errorMessage = error);
|
||||||
|
ScaffoldMessenger.of(
|
||||||
|
context,
|
||||||
|
).showSnackBar(SnackBar(content: Text(error)));
|
||||||
|
} else if (fileService.pickFiles != null) {
|
||||||
|
// setState(() {
|
||||||
|
// selectedFileName = fileService.pickFiles!.name;
|
||||||
|
// errorMessage = null;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// widget.onFileSelected?.call(
|
||||||
|
// fileService.pickFiles!.name,
|
||||||
|
// fileService.pickFiles!,
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: widget.txtwidth ?? MediaQuery.of(context).size.width,
|
||||||
|
height: widget.txtheight,
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: _pickFile,
|
||||||
|
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: widget.padVertical ?? 10,
|
||||||
|
horizontal: widget.padHorizontal ?? 15,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: widget.backgroundColor ?? Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
border: Border.all(
|
||||||
|
color: errorMessage != null
|
||||||
|
? (widget.errorBorderColor ?? Colors.red)
|
||||||
|
: (widget.borderColor ??
|
||||||
|
widget.backgroundColor ??
|
||||||
|
Colors.grey.shade50),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
if (!widget.isTxtBtnCase) ...[
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
selectedFileName ??
|
||||||
|
widget.hintText ??
|
||||||
|
"Upload Document",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: errorMessage != null
|
||||||
|
? Colors.red
|
||||||
|
: Colors.black,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Icon(
|
||||||
|
Icons.file_upload_outlined,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
if (widget.isTxtBtnCase) ...[
|
||||||
|
Center(
|
||||||
|
child: Tooltip(
|
||||||
|
message: 'Upload Documents',
|
||||||
|
child: Text(
|
||||||
|
widget.txtName!,
|
||||||
|
style: GoogleFonts.inter(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// const Icon(
|
||||||
|
// Icons.file_upload_outlined,
|
||||||
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (errorMessage != null)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8, top: 4),
|
||||||
|
child: Text(
|
||||||
|
errorMessage!,
|
||||||
|
style: const TextStyle(color: Colors.red, fontSize: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
|
||||||
|
class MultiFileUploadService {
|
||||||
|
MultiFileUploadService._();
|
||||||
|
static final MultiFileUploadService _instance = MultiFileUploadService._();
|
||||||
|
factory MultiFileUploadService() => _instance;
|
||||||
|
|
||||||
|
final List<PlatformFile> _files = [];
|
||||||
|
|
||||||
|
List<PlatformFile> get files => List.unmodifiable(_files);
|
||||||
|
|
||||||
|
// Allowed extensions
|
||||||
|
// static const allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg', 'heic'];
|
||||||
|
static const defaultAllowedExtensions = ['pdf', 'png', 'jpg', 'jpeg'];
|
||||||
|
|
||||||
|
Future<String?> pickFiles({
|
||||||
|
int maxFileSizeInMB = 3,
|
||||||
|
List<String>? allowedExtensions,
|
||||||
|
}) async {
|
||||||
|
final extensions = allowedExtensions ?? defaultAllowedExtensions;
|
||||||
|
final result = await FilePicker.platform.pickFiles(
|
||||||
|
allowMultiple: true,
|
||||||
|
withData: true,
|
||||||
|
type: FileType.custom,
|
||||||
|
allowedExtensions: extensions,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
for (final file in result.files) {
|
||||||
|
final ext = file.extension?.toLowerCase() ?? '';
|
||||||
|
final sizeInMB = (file.size / (1024 * 1024));
|
||||||
|
|
||||||
|
if (!allowedExtensions!.contains(ext)) {
|
||||||
|
return "Unsupported file format: ${file.name}";
|
||||||
|
}
|
||||||
|
if (sizeInMB > maxFileSizeInMB) {
|
||||||
|
return "File too large (${file.name}). Max $maxFileSizeInMB MB allowed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_files.addAll(result.files);
|
||||||
|
}
|
||||||
|
return null; // success
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeFileAt(int index) {
|
||||||
|
if (index >= 0 && index < _files.length) _files.removeAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearAll() => _files.clear();
|
||||||
|
}
|
||||||
102
lib/presentation/themes/indicators/mutli_FileUpload.dart
Normal file
102
lib/presentation/themes/indicators/mutli_FileUpload.dart
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'multi_fileUploadService.dart';
|
||||||
|
|
||||||
|
class MultiFileUploadWidget extends StatefulWidget {
|
||||||
|
const MultiFileUploadWidget({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MultiFileUploadWidget> createState() => _MultiFileUploadWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MultiFileUploadWidgetState extends State<MultiFileUploadWidget> {
|
||||||
|
final fileService = MultiFileUploadService();
|
||||||
|
String? errorMessage;
|
||||||
|
|
||||||
|
void _pickFiles() async {
|
||||||
|
final error = await fileService.pickFiles(
|
||||||
|
maxFileSizeInMB: 10,
|
||||||
|
); // 5 MB limit
|
||||||
|
if (error != null) {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
errorMessage = error;
|
||||||
|
});
|
||||||
|
|
||||||
|
// also show alert dialog for big error messages
|
||||||
|
// showDialog(
|
||||||
|
// context: context,
|
||||||
|
// builder: (ctx) => AlertDialog(
|
||||||
|
// title: const Text("File Upload Error"),
|
||||||
|
// content: Text(error),
|
||||||
|
// actions: [
|
||||||
|
// TextButton(
|
||||||
|
// onPressed: () => Navigator.pop(ctx),
|
||||||
|
// child: const Text("OK"),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setState(() {
|
||||||
|
errorMessage = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeFile(int index) {
|
||||||
|
fileService.removeFileAt(index);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final files = fileService.files;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
OutlinedButton.icon(
|
||||||
|
onPressed: _pickFiles,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.file_upload_outlined,
|
||||||
|
color: Color(0xFFE26728),
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
label: const Text(
|
||||||
|
"Upload Documents",
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.black),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
side: const BorderSide(color: Color(0xFFE26728)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
if (errorMessage != null) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
errorMessage!,
|
||||||
|
style: const TextStyle(color: Colors.red, fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
...files.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
final file = entry.value;
|
||||||
|
|
||||||
|
return ListTile(
|
||||||
|
dense: true,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
title: Text(file.name, style: const TextStyle(fontSize: 14)),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: const Icon(Icons.close, color: Colors.red),
|
||||||
|
onPressed: () => _removeFile(index),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user