manager_enq_chnages multiselect_handler

This commit is contained in:
venbaittech 2025-11-07 09:31:23 +05:30
parent 7ff6c82a9c
commit 857179ca65
17 changed files with 676 additions and 375 deletions

File diff suppressed because one or more lines are too long

View File

@ -1025,6 +1025,7 @@ class ApiService {
Future<Map<String, dynamic>> fetchStaffListForEnquiryAssignDropDown(
id,
role,
) async {
print('fetchHandlerNameDropDown');
if (_token == null) {
@ -1033,9 +1034,16 @@ class ApiService {
dynamic url;
print('fetchHandlerNameDropDown 1');
url = Uri.parse(
'${Env.apiUrl}/staff/staffListForEnquiryAssignDropdown?handler_id=$id',
);
if (role == 'manager') {
url = Uri.parse(
'${Env.apiUrl}staff/staffListForEnquiryAssignDropdown?manager_id=$id',
);
} else {
url = Uri.parse(
'${Env.apiUrl}staff/staffListForEnquiryAssignDropdown?handler_id=$id',
);
}
print('fetchHandlerNameDropDown 2');
final headers = {
'Authorization': 'Bearer $_token' ?? '',

View File

@ -8,8 +8,6 @@ class PaginationControls extends StatelessWidget {
final Function(int) onPageChanged;
final Function(int) onItemsPerPageChanged;
// final Color? activeColor;
const PaginationControls({
Key? key,
required this.currentPage,
@ -17,12 +15,40 @@ class PaginationControls extends StatelessWidget {
required this.totalItems,
required this.onPageChanged,
required this.onItemsPerPageChanged,
// this.activeColor = Colors.blue, // fallback if no color given
}) : super(key: key);
List<int> _visiblePages(int totalPages, int currentPage) {
const int maxVisible = 5; // Show up to 5 visible pages
if (totalPages <= maxVisible) {
return List<int>.generate(totalPages, (i) => i + 1);
}
// Near the start
if (currentPage <= 3) {
return [1, 2, 3, -1, totalPages]; // -1 means ellipsis (...)
}
// Near the end
if (currentPage >= totalPages - 2) {
return [1, -1, totalPages - 2, totalPages - 1, totalPages];
}
// Middle pages
return [
1,
-1,
currentPage - 1,
currentPage,
currentPage + 1,
-1,
totalPages,
];
}
@override
Widget build(BuildContext context) {
final int totalPages = (totalItems / itemsPerPage).ceil();
final List<int> pages = _visiblePages(totalPages, currentPage);
return Row(
mainAxisAlignment: MainAxisAlignment.end,
@ -39,219 +65,308 @@ class PaginationControls extends StatelessWidget {
onChanged: (newValue) {
if (newValue != null) {
onItemsPerPageChanged(newValue);
onPageChanged(1); // reset to page 1 when rows change
onPageChanged(1);
}
},
),
// Previous button
// Previous Button
IconButton(
onPressed: currentPage > 1
? () => onPageChanged(currentPage - 1)
: null,
icon: Icon(Icons.arrow_back),
icon: const Icon(Icons.chevron_left),
),
// Page buttons
for (int i = 1; i <= totalPages; i++)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: currentPage == i
? Color(0xFFD4F8F3)
: Color(0xFFEDF6F5),
foregroundColor: currentPage == i ? Colors.black : Colors.grey,
minimumSize: const Size(36, 36),
padding: EdgeInsets.zero,
// Page buttons with ellipsis
for (final i in pages)
if (i == -1)
const Padding(
padding: EdgeInsets.symmetric(horizontal: 4),
child: Text("..."),
)
else
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: currentPage == i
? const Color(0xFFD4F8F3)
: const Color(0xFFEDF6F5),
foregroundColor: currentPage == i
? Colors.black
: Colors.grey,
minimumSize: const Size(36, 36),
padding: EdgeInsets.zero,
),
onPressed: () => onPageChanged(i),
child: Text(i.toString()),
),
onPressed: () => onPageChanged(i),
child: Text(i.toString()),
),
),
// Next button
// Next Button
IconButton(
onPressed: currentPage < totalPages
? () => onPageChanged(currentPage + 1)
: null,
icon: Icon(Icons.arrow_forward),
icon: const Icon(Icons.chevron_right),
),
],
);
}
// Widget build(BuildContext context) {
// // int totalPages = (totalItems / itemsPerPage).ceil();
// final int totalPages = (widget.totalItems / widget.itemsPerPage).ceil();
//
// return Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// DropdownButton<int>(
// value: itemsPerPage,
// items: [5, 10, 15, 20, 50].map((int value) {
// return DropdownMenuItem<int>(
// value: value,
// child: Text(' $value ', style: GoogleFonts.poppins(fontSize: 15)),
// );
// }).toList(),
// onChanged: (newValue) {
// setState(() {
// itemsPerPage = newValue!;
// currentPage = 1; // Reset to first page when rows per page changes
// });
// },
// ),
// IconButton(
// onPressed: currentPage > 1
// ? () {
// setState(() {
// currentPage--;
// });
// }
// : null,
// icon: Icon(Icons.chevron_left),
// ),
// for (int i = 1; i <= (totalItems / itemsPerPage).ceil(); i++)
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 4),
// child: ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: _currentPage == i
// ? Color(0xFF00A6A6)
// : Colors.grey[300],
// foregroundColor: _currentPage == i
// ? Colors.white
// : Colors.black,
// minimumSize: Size(36, 36),
// padding: EdgeInsets.zero,
// ),
// onPressed: () {
// setState(() {
// _currentPage = i;
// });
// },
// child: Text(i.toString()),
// ),
// ),
// IconButton(
// onPressed: currentPage < (totalItems / itemsPerPage).ceil()
// ? () {
// setState(() {
// currentPage++;
// });
// }
// : null,
// icon: Icon(Icons.chevron_right),
// ),
// ],
// // children: [
// // DropdownButton<int>(
// // value: itemsPerPage,
// // items: [10, 20, 50, 100]
// // .map(
// // (value) => DropdownMenuItem<int>(
// // value: value,
// // child: Text(
// // '$value',
// // style: TextStyle(fontSize: 12, fontFamily: "Inter"),
// // ),
// // ),
// // )
// // .toList(),
// // onChanged: (value) {
// // if (value != null) {
// // onItemsPerPageChanged(value);
// // }
// // },
// // style: TextStyle(
// // fontSize: 12,
// // color: Colors.black,
// // fontFamily: "Inter",
// // ),
// // underline: SizedBox(),
// // iconSize: 16,
// // ),
// // SizedBox(width: 16),
// // IconButton(
// // icon: Icon(Icons.arrow_back, size: 18),
// // onPressed: currentPage > 0
// // ? () => onPageChanged(currentPage - 1)
// // : null,
// // ),
// //
// // SingleChildScrollView(
// // scrollDirection: Axis.horizontal,
// // child: Row(children: _buildPageButtons()),
// // ),
// //
// // IconButton(
// // icon: Icon(Icons.arrow_forward, size: 18),
// // onPressed: (currentPage + 1) * itemsPerPage < totalItems
// // ? () => onPageChanged(currentPage + 1)
// // : null,
// // ),
// // ],
// );
// }
List<Widget> _buildPageButtons() {
final int totalPages = (totalItems / itemsPerPage).ceil();
List<Widget> buttons = [];
// Always show first page
buttons.add(_buildPageButton(0));
// Add left ellipsis if needed
if (currentPage > 2) {
buttons.add(_buildEllipsis());
}
// Add previous, current, next page if in range
for (int i = currentPage - 1; i <= currentPage + 1; i++) {
if (i > 0 && i < totalPages - 1) {
buttons.add(_buildPageButton(i));
}
}
// Add right ellipsis if needed
if (currentPage < totalPages - 3) {
buttons.add(_buildEllipsis());
}
// Always show last page
if (totalPages > 1) {
buttons.add(_buildPageButton(totalPages - 1));
}
return buttons;
}
Widget _buildPageButton(int pageIndex) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: ElevatedButton(
onPressed: () => onPageChanged(pageIndex),
style: ElevatedButton.styleFrom(
backgroundColor: currentPage == pageIndex
? Color(0xFFD4F8F3)
: Color(0xFFEDF6F5),
foregroundColor: currentPage == pageIndex
? Colors.black
: Colors.grey,
minimumSize: Size(36, 36),
padding: EdgeInsets.zero,
),
child: Text('${pageIndex + 1}'),
),
);
}
Widget _buildEllipsis() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text('...', style: TextStyle(fontSize: 16)),
);
}
}
// class PaginationControls extends StatelessWidget {
// final int currentPage;
// final int itemsPerPage;
// final int totalItems;
// final Function(int) onPageChanged;
// final Function(int) onItemsPerPageChanged;
//
// // final Color? activeColor;
//
// const PaginationControls({
// Key? key,
// required this.currentPage,
// required this.itemsPerPage,
// required this.totalItems,
// required this.onPageChanged,
// required this.onItemsPerPageChanged,
// // this.activeColor = Colors.blue, // fallback if no color given
// }) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// final int totalPages = (totalItems / itemsPerPage).ceil();
//
// return Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// // Dropdown for rows per page
// DropdownButton<int>(
// value: itemsPerPage,
// items: [5, 10, 15, 20, 50].map((int value) {
// return DropdownMenuItem<int>(
// value: value,
// child: Text('$value', style: GoogleFonts.poppins(fontSize: 15)),
// );
// }).toList(),
// onChanged: (newValue) {
// if (newValue != null) {
// onItemsPerPageChanged(newValue);
// onPageChanged(1); // reset to page 1 when rows change
// }
// },
// ),
//
// // Previous button
// IconButton(
// onPressed: currentPage > 1
// ? () => onPageChanged(currentPage - 1)
// : null,
// icon: Icon(Icons.arrow_back),
// ),
//
// // Page buttons
// for (int i = 1; i <= totalPages; i++)
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 4),
// child: ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: currentPage == i
// ? Color(0xFFD4F8F3)
// : Color(0xFFEDF6F5),
// foregroundColor: currentPage == i ? Colors.black : Colors.grey,
// minimumSize: const Size(36, 36),
// padding: EdgeInsets.zero,
// ),
// onPressed: () => onPageChanged(i),
// child: Text(i.toString()),
// ),
// ),
//
// // Next button
// IconButton(
// onPressed: currentPage < totalPages
// ? () => onPageChanged(currentPage + 1)
// : null,
// icon: Icon(Icons.arrow_forward),
// ),
// ],
// );
// }
// // Widget build(BuildContext context) {
// // // int totalPages = (totalItems / itemsPerPage).ceil();
// // final int totalPages = (widget.totalItems / widget.itemsPerPage).ceil();
// //
// // return Row(
// // mainAxisAlignment: MainAxisAlignment.end,
// // children: [
// // DropdownButton<int>(
// // value: itemsPerPage,
// // items: [5, 10, 15, 20, 50].map((int value) {
// // return DropdownMenuItem<int>(
// // value: value,
// // child: Text(' $value ', style: GoogleFonts.poppins(fontSize: 15)),
// // );
// // }).toList(),
// // onChanged: (newValue) {
// // setState(() {
// // itemsPerPage = newValue!;
// // currentPage = 1; // Reset to first page when rows per page changes
// // });
// // },
// // ),
// // IconButton(
// // onPressed: currentPage > 1
// // ? () {
// // setState(() {
// // currentPage--;
// // });
// // }
// // : null,
// // icon: Icon(Icons.chevron_left),
// // ),
// // for (int i = 1; i <= (totalItems / itemsPerPage).ceil(); i++)
// // Padding(
// // padding: const EdgeInsets.symmetric(horizontal: 4),
// // child: ElevatedButton(
// // style: ElevatedButton.styleFrom(
// // backgroundColor: _currentPage == i
// // ? Color(0xFF00A6A6)
// // : Colors.grey[300],
// // foregroundColor: _currentPage == i
// // ? Colors.white
// // : Colors.black,
// // minimumSize: Size(36, 36),
// // padding: EdgeInsets.zero,
// // ),
// // onPressed: () {
// // setState(() {
// // _currentPage = i;
// // });
// // },
// // child: Text(i.toString()),
// // ),
// // ),
// // IconButton(
// // onPressed: currentPage < (totalItems / itemsPerPage).ceil()
// // ? () {
// // setState(() {
// // currentPage++;
// // });
// // }
// // : null,
// // icon: Icon(Icons.chevron_right),
// // ),
// // ],
// // // children: [
// // // DropdownButton<int>(
// // // value: itemsPerPage,
// // // items: [10, 20, 50, 100]
// // // .map(
// // // (value) => DropdownMenuItem<int>(
// // // value: value,
// // // child: Text(
// // // '$value',
// // // style: TextStyle(fontSize: 12, fontFamily: "Inter"),
// // // ),
// // // ),
// // // )
// // // .toList(),
// // // onChanged: (value) {
// // // if (value != null) {
// // // onItemsPerPageChanged(value);
// // // }
// // // },
// // // style: TextStyle(
// // // fontSize: 12,
// // // color: Colors.black,
// // // fontFamily: "Inter",
// // // ),
// // // underline: SizedBox(),
// // // iconSize: 16,
// // // ),
// // // SizedBox(width: 16),
// // // IconButton(
// // // icon: Icon(Icons.arrow_back, size: 18),
// // // onPressed: currentPage > 0
// // // ? () => onPageChanged(currentPage - 1)
// // // : null,
// // // ),
// // //
// // // SingleChildScrollView(
// // // scrollDirection: Axis.horizontal,
// // // child: Row(children: _buildPageButtons()),
// // // ),
// // //
// // // IconButton(
// // // icon: Icon(Icons.arrow_forward, size: 18),
// // // onPressed: (currentPage + 1) * itemsPerPage < totalItems
// // // ? () => onPageChanged(currentPage + 1)
// // // : null,
// // // ),
// // // ],
// // );
// // }
//
// List<Widget> _buildPageButtons() {
// final int totalPages = (totalItems / itemsPerPage).ceil();
// List<Widget> buttons = [];
//
// // Always show first page
// buttons.add(_buildPageButton(0));
//
// // Add left ellipsis if needed
// if (currentPage > 2) {
// buttons.add(_buildEllipsis());
// }
//
// // Add previous, current, next page if in range
// for (int i = currentPage - 1; i <= currentPage + 1; i++) {
// if (i > 0 && i < totalPages - 1) {
// buttons.add(_buildPageButton(i));
// }
// }
//
// // Add right ellipsis if needed
// if (currentPage < totalPages - 3) {
// buttons.add(_buildEllipsis());
// }
//
// // Always show last page
// if (totalPages > 1) {
// buttons.add(_buildPageButton(totalPages - 1));
// }
//
// return buttons;
// }
//
// Widget _buildPageButton(int pageIndex) {
// return Padding(
// padding: const EdgeInsets.symmetric(horizontal: 4),
// child: ElevatedButton(
// onPressed: () => onPageChanged(pageIndex),
// style: ElevatedButton.styleFrom(
// backgroundColor: currentPage == pageIndex
// ? Color(0xFFD4F8F3)
// : Color(0xFFEDF6F5),
//
// foregroundColor: currentPage == pageIndex
// ? Colors.black
// : Colors.grey,
// minimumSize: Size(36, 36),
// padding: EdgeInsets.zero,
// ),
// child: Text('${pageIndex + 1}'),
// ),
// );
// }
//
// Widget _buildEllipsis() {
// return Padding(
// padding: const EdgeInsets.symmetric(horizontal: 6),
// child: Text('...', style: TextStyle(fontSize: 16)),
// );
// }
// }

View File

@ -113,8 +113,15 @@ class _MyAppState extends ConsumerState<MyApp> {
return MaterialApp.router(
debugShowCheckedModeBanner: false,
title: 'Nhance Partner',
theme: ThemeData(
primarySwatch: Colors.blue,
// primarySwatch: Colors.blue,
// primaryColor: Color(0xFFE26728), // active color (selected / focused)
primaryColorLight: Color(0xFFEDF6F5),
colorScheme: ColorScheme.fromSeed(
seedColor: Color(0xFFEDF6F5), // Generates harmonious colors
),
textTheme: GoogleFonts.interTextTheme(
Theme.of(context).textTheme, // base on default styles
),

View File

@ -103,13 +103,16 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
Map<String, dynamic> dataDetails() {
final data = {
"agent_id": role == 'handler' ? selectedAgent : userId,
"agent_id": ((role == 'handler') || (role == 'manager'))
? selectedAgent
: userId,
"name": controllers["name"]?.text,
"mobile": controllers["mobile"]?.text,
"email": controllers["email"]?.text,
"reg_no": controllers["regNo"]?.text,
"vehicle_type_id": selectedVehicleType,
"is_data_created_by_handler": role == 'handler' ? '1' : '0',
"is_data_created_by_manager": role == 'manager' ? '1' : '0',
// "insurer_id": selectedInsurer,
// "rc_file_name": "rc_doc.pdf",
// "id_proof_file_name": "id_proof.pdf",
@ -517,11 +520,22 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
print('Im handler');
print('ROle - $role');
if (isUpdating) {
context.go(AppRoutes.enquiryHandlerLst);
context.go(AppRoutes.tabEnquiry);
// context.go(AppRoutes.enquiryHandlerLst);
} else {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryHandlerLst);
}
} else if (role == 'manager') {
print('Im manager');
print('ROle - $role');
if (isUpdating) {
context.go(AppRoutes.tabEnquiry);
// context.go(AppRoutes.enquiryHandlerLst);
} else {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryForStaff);
}
} else {
print('Im agent');
if (isUpdating) {
@ -624,32 +638,32 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
?(role == 'handler')
?((role == 'handler') || (role == 'manager'))
? _buildResponsiveRow(
context,
buildAgentName(context),
SizedBox.shrink(),
)
: null,
?(role == 'handler')
?((role == 'handler') || (role == 'manager'))
? isMobile
? SizedBox(height: 5)
: SizedBox(height: 15)
: null,
_buildResponsiveRow(context, buildName(context), buildEmail(context)),
_buildResponsiveRow(context, buildName(context), buildId(context)),
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
_buildResponsiveRow(
context,
buildPhNumber(context),
buildId(context),
),
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
_buildResponsiveRow(
context,
buildVehicleType(context),
buildEmail(context),
),
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
_buildResponsiveRow(
context,
buildPhNumber(context),
// buildInsurer(context),
buildUploadRCDocument(context),
),
@ -863,7 +877,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 250),
constraints: BoxConstraints(maxHeight: 200),
menuProps: MenuProps(
backgroundColor:
Colors.white, // 👈 sets dropdown background to white

View File

@ -284,7 +284,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
"id": selectedId,
"status": val,
"action_by": userId,
"action_user": (role == 'agent') ? 'agent' : 'handler',
// "action_user": (role == 'agent') ? 'agent' : 'handler',
"action_user": role,
};
// data['id'] = selectedId; // Add plan_id for update

View File

@ -234,6 +234,9 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
if (role == 'handler') {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryHandlerLst);
} else if (role == 'manager') {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryForStaff);
} else {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryLst);
@ -248,7 +251,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
),
// const SizedBox(width: 8),
Text(
"Enquiry",
"Enquiry ",
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w600,
@ -342,77 +345,6 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
);
}
Widget _buildMobileTabs1({
required bool shrinkWrap,
required NeverScrollableScrollPhysics physics,
}) {
return ListView.builder(
shrinkWrap: shrinkWrap, // Important
physics: physics,
itemCount: tabs.length,
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
final isExpanded = expandedIndex == index;
return Card(
margin: const EdgeInsets.only(bottom: 12),
color: isExpanded ? const Color(0xFFEDF6F5) : const Color(0xFF425B5B),
// color: Color(0xFFEDF6F5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(
color: isExpanded ? Color(0xFF425B5B) : Color(0xFF425B5B),
// color: isExpanded ? Color(0xFFEDF6F5) : Color(0xFFEDF6F5),
width: 1,
),
),
child: ExpansionTile(
collapsedIconColor: isExpanded ? Colors.black : Colors.white,
iconColor: isExpanded ? Colors.black : Colors.white,
initiallyExpanded: isExpanded,
onExpansionChanged: (expanded) {
setState(() {
if (expanded) {
expandedIndex = index;
// Scroll to make the expanded tile visible
WidgetsBinding.instance.addPostFrameCallback((_) {
RenderBox box = context.findRenderObject() as RenderBox;
double yPos = box.localToGlobal(Offset.zero).dy;
_scrollController.animateTo(
_scrollController.offset +
yPos -
100, // adjust 100 if needed
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
});
} else {
expandedIndex = null;
}
});
},
title: Text(
tabs[index].title,
style: GoogleFonts.inter(
fontSize: 14,
color: isExpanded ? Colors.black : Colors.white,
fontWeight: FontWeight.w600,
),
),
children: [
Container(
// padding: const EdgeInsets.all(12),
child: tabs[index].widget,
),
],
),
);
},
);
}
Widget _buildDesktopTabs() {
return Column(
children: [
@ -446,6 +378,9 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
if (role == 'handler') {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryHandlerLst);
} else if (role == 'manager') {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryForStaff);
} else {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryLst);

View File

@ -409,13 +409,13 @@ class ProfilePopUpState extends ConsumerState<ProfilePopUp> {
}
static final _dataBold = TextStyle(
fontSize: 14,
fontSize: 11.8,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
fontSize: 14,
fontSize: 12,
fontWeight: FontWeight.w500,
color: Color(0xFF000000),
);

View File

@ -55,6 +55,7 @@ class StaffState extends ConsumerState<Staff> {
List<Map<String, dynamic>> filteredRolesData = [];
List<Map<String, dynamic>> getRolesData = [];
List<dynamic>? selectedHandlerIds = [];
String? selectedHandler;
List<Map<String, dynamic>> filteredHandlersData = [];
List<Map<String, dynamic>> getHandlersData = [];
@ -71,8 +72,9 @@ class StaffState extends ConsumerState<Staff> {
"mobile": controllers["mobile"]?.text,
// "emp_id": controllers["code"]?.text,
"is_active": isActive,
"role_id": selectedRole, // By default role 2 Staff, No fields Required
"handler_id": selectedHandler,
"role_id": selectedRole,
// "handler_id": selectedHandler,
"handler_id": selectedHandlerIds,
"manager_id": userId,
};
return data;
@ -118,7 +120,23 @@ class StaffState extends ConsumerState<Staff> {
controllers['email']?.text = data['email'] ?? '';
controllers['mobile']?.text = data['mobile'] ?? '';
selectedRole = data['role_id'] ?? '';
selectedHandler = data['handler_id'] ?? '';
// selectedHandler = data['handler_id'] ?? '';
if (data['handler_id'] != null &&
data['handler_id'].toString().isNotEmpty) {
try {
// Decode only if it's a valid JSON array string
selectedHandlerIds = jsonDecode(data['handler_id']);
} catch (e) {
// Fallback: handle if it's not JSON (e.g., already a list)
if (data['handler_id'] is List) {
selectedHandlerIds = (data['handler_id'] as List)
.map((e) => e.toString())
.toList();
} else {
selectedHandlerIds = [];
}
}
}
// controllers['code']?.text = data['emp_id'] ?? '';
isActive = data["is_active"];
@ -546,6 +564,7 @@ class StaffState extends ConsumerState<Staff> {
selectedroleVal['role'] == 'Staff') {
showHandler = true;
} else {
selectedHandlerIds = [];
showHandler = false;
}
@ -676,11 +695,18 @@ class StaffState extends ConsumerState<Staff> {
// height: 40,
child: AbsorbPointer(
absorbing: isReadOnly,
child: DropdownSearch<Map<String, dynamic>>(
// child: DropdownSearch<Map<String, dynamic>>(
child: DropdownSearch<Map<String, dynamic>>.multiSelection(
key: dropDownKeyHandler,
selectedItem: selectedHandlered.isNotEmpty
? selectedHandlered
: null,
// selectedItem: selectedHandlered.isNotEmpty
// ? selectedHandlered
// : null,
selectedItems: filteredHandlersData
.where(
(item) => (selectedHandlerIds ?? []).contains(item['id']),
)
.toList(),
items: (filter, infiniteScrollProps) {
return filteredHandlersData;
},
@ -688,9 +714,15 @@ class StaffState extends ConsumerState<Staff> {
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;
// },
validator: (val) {
if (val == null) {
return "Required"; // error message
if (val == null || val.isEmpty) {
return "Required";
}
return null;
},
@ -704,45 +736,108 @@ class StaffState extends ConsumerState<Staff> {
Colors.white, // 👈 makes the dropdown input white
),
),
popupProps: PopupProps.menu(
popupProps: PopupPropsMultiSelection.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 250),
menuProps: MenuProps(
backgroundColor:
Colors.white, // 👈 sets dropdown background to white
),
showSearchBox: true,
menuProps: MenuProps(backgroundColor: Colors.white),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: "Search Handler...",
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
), // 👈 Normal border
borderSide: BorderSide(color: Colors.white),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
// color: Colors.blue,
color: Color(0xFFEDF6F5),
width: 1.5,
), // 👈 Focused border
),
),
),
),
// constraints: BoxConstraints(),
),
onChanged: (val) {
if (val != null) {
print("Selected Handler : ${val['name']}");
print("Id: ${val['id']}");
selectedHandler = val['id'];
// controllers['agentId']?.text = val['agent_code'];
// agentId = agent['id'];
}
// checkBoxBuilder: (context, item, isSelected, isDisabled) {
// return Icon(
// isSelected
// ? Icons.check_box
// : Icons.check_box_outline_blank,
// color: isSelected ? Color(0xFFE26728) : Colors.red,
// );
// },
// validationBuilder: (context, selectedItems) {
// return Padding(
// padding: const EdgeInsets.symmetric(
// vertical: 8.0,
// horizontal: 8.0,
// ),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: Color(0xFF425B5B),
// foregroundColor: Colors.white,
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// ),
// minimumSize: Size(70, 36),
// ),
// onPressed: () => Navigator.pop(context),
// child: const Text("OK"),
// ),
// ],
// ),
// );
// },
),
onChanged: (List<Map<String, dynamic>> selectedVals) {
selectedHandlerIds = selectedVals
.map((v) => v['id'].toString())
.toList();
print("Selected Handler IDs: $selectedHandlerIds");
},
// popupProps: PopupProps.menu(
// fit: FlexFit.loose,
// constraints: BoxConstraints(maxHeight: 250),
// menuProps: MenuProps(
// backgroundColor:
// Colors.white, // 👈 sets dropdown background to white
// ),
// showSearchBox: true,
// searchFieldProps: TextFieldProps(
// decoration: InputDecoration(
// filled: true,
// fillColor: Colors.white,
// hintText: "Search Handler...",
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color: Colors.white,
// ), // 👈 Normal border
// ),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color: Colors.white,
// width: 1.5,
// ), // 👈 Focused border
// ),
// ),
// ),
// // constraints: BoxConstraints(),
// ),
//
// onChanged: (val) {
// if (val != null) {
// print("Selected Handler : ${val['name']}");
// print("Id: ${val['id']}");
// selectedHandler = val['id'];
// // controllers['agentId']?.text = val['agent_code'];
// // agentId = agent['id'];
// }
// },
),
),
),

View File

@ -299,7 +299,7 @@ class StaffListState extends ConsumerState<StaffList> {
),
SizedBox(width: 10),
GestureDetector(
InkWell(
onTap: () {
context.go('/staff/create');
},

View File

@ -1211,16 +1211,16 @@ class othersPendings extends StatelessWidget {
// style: _headerStyle,
// ),
// ),
if (role == 'manager') ...[
Expanded(
flex: 2,
child: Text(
"Handler Name",
textAlign: TextAlign.center,
style: _headerStyle,
),
),
],
// if (role == 'manager') ...[
// Expanded(
// flex: 2,
// child: Text(
// "Handler Name",
// textAlign: TextAlign.center,
// style: _headerStyle,
// ),
// ),
// ],
Expanded(
flex: 2,
child: Text(
@ -1312,17 +1312,17 @@ class othersPendings extends StatelessWidget {
// style: _tableDataStyle,
// ),
// ),
if (role == 'manager') ...[
Expanded(
flex: 2,
child: Text(
row['handler_name'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
],
// if (role == 'manager') ...[
// Expanded(
// flex: 2,
// child: Text(
// row['handler_name'] ?? "",
//
// textAlign: TextAlign.center,
// style: _tableDataStyle,
// ),
// ),
// ],
Expanded(
flex: 2,
child: Text(

View File

@ -827,25 +827,6 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
fontSize: 14,
),
),
// GestureDetector(
// onTap: () {
// ref
// .read(
// enquiryIdProvider.notifier,
// )
// .state =
// null;
// context.go(AppRoutes.tabEnquiry);
// },
// child: Text(
// 'Create New Enquiry',
// style: GoogleFonts.inter(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
// ),
// ),
// ),
],
],
),

View File

@ -263,6 +263,10 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
final message = data['data']['message'];
// setState(() {
// enteredEmailOrMobile = true;
// });
if (verification == true) {
// if (switcherStatus == 1) {
// _verifyPhoneNumber();

View File

@ -697,6 +697,42 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
);
}
Future<void> handleStaff(
BuildContext context,
dynamic data,
id,
regNum,
) async {
showDialog(
context: context,
builder: (ctx) => AssignStaffDialog(
enquiryPrimaryId: id,
regNum: regNum,
userId: userId,
onSubmit: (value) {
debugPrint("New assignY: $value");
refresh();
},
),
);
}
Future<void> handleEdit(item) async {
// Navigator.pop(context);
print('EDITStaff - ${item['id']}');
final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId');
final id = item['id'].toString();
// Save the new id
await prefs.setString('enqAgentDataId', id.toString());
ref.read(enquiryIdProvider.notifier).state = id;
context.go(AppRoutes.tabEnquiry);
}
Widget _buildContent(BuildContext context) {
return Column(
children: [
@ -805,6 +841,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
// ],
// ),
// ),
// SizedBox(width: 10),
Spacer(),
],
@ -814,8 +851,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
onChanged: filterData,
controller: _searchStaffController,
txtwidth: ResponsiveLayout.isMobile(context)
? MediaQuery.of(context).size.width * 0.7
: MediaQuery.of(context).size.width * 0.2,
? MediaQuery.of(context).size.width * 0.4
: MediaQuery.of(context).size.width * 0.13,
),
ResponsiveLayout.isMobile(context)
@ -852,6 +889,45 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
"status",
],
),
if (roleId == 'manager') ...[
SizedBox(width: 10),
GestureDetector(
onTap: () async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId');
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.tabEnquiry);
// print('Export');
},
child: Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Color(0xFF425B5B),
borderRadius: BorderRadius.circular(8.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.add, color: Colors.white),
if (!ResponsiveLayout.isMobile(context)) ...[
SizedBox(width: 10),
Text(
'Raise Enquiry',
style: GoogleFonts.inter(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
],
],
),
),
),
],
],
),
),
@ -863,31 +939,43 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: const Row(
child: Row(
children: [
Expanded(
const Expanded(
flex: 2,
child: Text('Received Date', style: _headerStyle),
),
Expanded(flex: 2, child: Text('Partner ', style: _headerStyle)),
Expanded(
const Expanded(
flex: 2,
child: Text('Partner ', style: _headerStyle),
),
const Expanded(
flex: 2,
child: Text('Assigned To ', style: _headerStyle),
),
Expanded(flex: 4, child: Text('Insurer', style: _headerStyle)),
Expanded(
const Expanded(
flex: 4,
child: Text('Insurer', style: _headerStyle),
),
const Expanded(
flex: 3,
child: Text('Vehicle No', style: _headerStyle),
),
Expanded(
const Expanded(
flex: 3,
child: Text('Insured Name', style: _headerStyle),
),
Expanded(
const Expanded(
flex: 2,
child: Text('Assigned Date', style: _headerStyle),
),
Expanded(flex: 3, child: Text('Status', style: _headerStyle)),
const Expanded(
flex: 3,
child: Text('Status', style: _headerStyle),
),
if (roleId == 'manager') ...const [
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
],
],
),
),
@ -1110,6 +1198,52 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
),
),
),
if (roleId == 'manager') ...[
Expanded(
flex: 1,
child: Row(
children: [
if (item['status'] == 'Awaiting Proposal')
Tooltip(
message: "Assign Staff",
child: IconButton(
icon: Icon(Icons.assignment_ind_outlined, size: 15),
onPressed: () {
handleStaff(
context,
item,
item['id'],
item['reg_no'],
);
},
splashRadius: 5,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(),
),
),
Tooltip(
message: 'Edit Raised Enquiry',
child: IconButton(
icon: Image.asset(
"assets/miscellaneous/Edit.png",
height: 12,
width: 12,
),
onPressed: () {
handleEdit(item);
},
splashRadius: 5,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(),
),
),
],
),
),
],
],
),
);

View File

@ -542,7 +542,9 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
ToastHelper.showSuccessToast(context, 'Saved Policy');
print("Response: ${response.body}");
Navigator.pop(context);
if (isUpdating) {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryForStaff);
} else {
ref.read(enquiryIdProvider.notifier).state = null;
@ -730,7 +732,8 @@ class PolicyStaffTabState extends ConsumerState<PolicyStaffTab> {
color: Color(0xFF425B5B),
),
child: Text(
!hasPolicyData ? 'Submit' : 'Update',
// !hasPolicyData ? 'Submit' : 'Update',
'Submit',
style: TextStyle(
color: Colors.white,
fontSize: 12,

View File

@ -150,7 +150,11 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
});
try {
final response = await apiService.fetchStaffUserList(id, role);
// final response = await apiService.fetchStaffUserList(id, role);
final response = await apiService.fetchStaffListForEnquiryAssignDropDown(
id,
role,
);
if (response['status'] == 'success') {
print('getStaffDetails - ${response['data']}');

View File

@ -90,7 +90,7 @@ class ExportBtn extends HookWidget {
),
)
: null,
?txt! ? SizedBox(width: 20) : null,
?txt! ? SizedBox(width: 15) : null,
Image.asset(
"assets/miscellaneous/export.png",
height: 25,