diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index 02f0e24..295bd62 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -609,7 +609,12 @@ class ApiService { // ----------------------------------- POLICY ------------------------------------------------- - Future> fetchPolicyList(int id, role) async { + Future> fetchPolicyList( + int id, + role, { + String? fromDate, + String? toDate, + }) async { // print(_token); if (_token == null) { await _initializeToken(); @@ -618,11 +623,25 @@ class ApiService { final userId = '1'; final url; + final String query; + if (role == 'manager') { - url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?manager_id=$id'); + query = 'manager_id=$id'; + } else if (role == 'staff') { + query = 'staff_id=$id'; } else { - url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?staff_id=$id'); + query = 'agent_id=$id'; } + + url = Uri.parse( + '${Env.apiUrl}enquiry/enquiryList?$query&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + ); + + // if (role == 'manager') { + // url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?manager_id=$id'); + // } else { + // url = Uri.parse('${Env.apiUrl}enquiry/enquiryList?staff_id=$id'); + // } // else { // url = Uri.parse('${Env.apiUrl}endorsement/endorsementList?agent_id=$id'); // } @@ -637,28 +656,47 @@ class ApiService { return response; } - Future> fetchPolicyDataOnlyList(int id, role) async { + Future> fetchPolicyDataOnlyList( + int id, + role, { + String? fromDate, + String? toDate, + }) async { // print(_token); if (_token == null) { await _initializeToken(); } final userId = '1'; - final url; + + final String query; if (role == 'manager') { - url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?manager_id=$id&only_policy_data=true', - ); + query = 'manager_id=$id'; } else if (role == 'staff') { - url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?staff_id=$id&only_policy_data=true', - ); + query = 'staff_id=$id'; } else { - url = Uri.parse( - '${Env.apiUrl}enquiry/enquiryList?agent_id=$id&only_policy_data=true', - ); + query = 'agent_id=$id'; } + + final url = Uri.parse( + '${Env.apiUrl}enquiry/enquiryList?$query&only_policy_data=true&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}', + ); + + // if (role == 'manager') { + // url = Uri.parse( + // '${Env.apiUrl}enquiry/enquiryList?manager_id=$id&only_policy_data=true', + // ); + // } else if (role == 'staff') { + // url = Uri.parse( + // '${Env.apiUrl}enquiry/enquiryList?staff_id=$id&only_policy_data=true', + // ); + // } else { + // url = Uri.parse( + // '${Env.apiUrl}enquiry/enquiryList?agent_id=$id&only_policy_data=true', + // ); + // } + // final url = Uri.parse( // 'https://venbait.in/nhance/partner/dev/api/agent/agentList?manager_id=${managerId}', // ); diff --git a/lib/presentation/layouts/main_layout.dart b/lib/presentation/layouts/main_layout.dart index 75639b8..0947f5a 100644 --- a/lib/presentation/layouts/main_layout.dart +++ b/lib/presentation/layouts/main_layout.dart @@ -27,9 +27,9 @@ class MainLayout extends StatelessWidget { appBar: TopBar( title: title, isMobile: true, - onBack: () { - // Navigator.pop(context); - }, + // onBack: () { + // // Navigator.pop(context); + // }, onNotifications: () { debugPrint("Notifications tapped"); }, diff --git a/lib/presentation/screens/Enquiry/enquiryList.dart b/lib/presentation/screens/Enquiry/enquiryList.dart index c336083..813d910 100644 --- a/lib/presentation/screens/Enquiry/enquiryList.dart +++ b/lib/presentation/screens/Enquiry/enquiryList.dart @@ -38,9 +38,9 @@ class EnquiryListState extends ConsumerState { List> getStaffData = []; List> originalData = []; List> filteredData = []; - Map controllers = {}; - bool isLoading = false; + bool isLoading = false; + Map controllers = {}; List tabHeader = ['startDate', 'endDate']; @override @@ -378,240 +378,23 @@ class EnquiryListState extends ConsumerState { ), SizedBox(height: ResponsiveLayout.isMobile(context) ? 5 : 10), - - Expanded( - child: Container( - // color: Colors.green, - // color: Colors.green.shade50, - width: MediaQuery.of(context).size.width, - - padding: EdgeInsets.all(8.0), - child: Column( - children: [ - if (ResponsiveLayout.isMobile(context)) ...[ - Container( - padding: EdgeInsets.all(8.0), - color: Color(0xffD9EBE8), - child: DateFilterRow( - startController: controllers['startDate']!, - endController: controllers['endDate']!, - formKey: _formKey, - isMobile: ResponsiveLayout.isMobile(context), - onFilter: () { - // call your filter logic - filterDateRange(); - }, - onRefresh: () { - // call your refresh logic - refrshfilterDateRange(); - }, - ), - ), - ], - - Container( - // height: 40, - // color: Colors.pink, - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (!ResponsiveLayout.isMobile(context)) ...[ - DateFilterRow( - startController: controllers['startDate']!, - endController: controllers['endDate']!, - formKey: _formKey, - isMobile: ResponsiveLayout.isMobile(context), - onFilter: () { - // call your filter logic - filterDateRange(); - }, - onRefresh: () { - // call your refresh logic - refrshfilterDateRange(); - }, - ), - - // Form( - // key: _formKey, - // child: Row( - // mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.end, - // children: [ - // buildStartDate(context), - // SizedBox(width: 10), - // buildEndDate(context), - // SizedBox(width: 10), - // - // Padding( - // padding: const EdgeInsets.symmetric( - // vertical: 8.0, - // ), - // child: GestureDetector( - // // onTap: filterDateRange, - // onTap: () { - // if (_formKey.currentState!.validate()) { - // filterDateRange(); // only runs if valid - // } - // }, - // child: Icon(Icons.filter_alt_outlined), - // ), - // ), - // - // Padding( - // padding: const EdgeInsets.all(8.0), - // child: GestureDetector( - // onTap: refrshfilterDateRange, - // child: Icon(Icons.refresh), - // ), - // ), - // ], - // ), - // ), - Spacer(), - ], - ThemedSearchField( - hintText: 'Search', - backgroundColor: Color(0xFFF6F8F8), - onChanged: filterData, - controller: _searchStaffController, - txtwidth: ResponsiveLayout.isMobile(context) - ? MediaQuery.of(context).size.width * 0.6 - : MediaQuery.of(context).size.width * 0.2, - ), - - SizedBox(width: 10), - - ExportBtn( - sheetName: "Enquiry", - fileName: "enquiry_list", - data: filteredData, - txt: !ResponsiveLayout.isMobile(context) - ? true - : false, - headers: [ - "id", - "created_on", - "updated_on", - "reg_no", - "insurer_name", - "status", - "remarks", - ], - ), - - SizedBox(width: 10), - GestureDetector( - onTap: () async { - final prefs = - await SharedPreferences.getInstance(); - - await prefs.remove('enqAgentDataId'); - 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( - 'Create New Enquiry', - style: GoogleFonts.inter( - color: Colors.white, - fontWeight: FontWeight.w600, - 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, - // ), - // ), - // ), - ], - ], - ), - ), - ), - ], + ResponsiveLayout.isMobile(context) + ? Container( + height: MediaQuery.of(context).size.height * 0.7, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(8), + child: _buildContent(context), ), ), - SizedBox(height: 10), - - if (!ResponsiveLayout.isMobile(context)) - Container( - decoration: BoxDecoration( - color: Color(0xFFEDF6F5), - borderRadius: BorderRadius.circular(6), - ), - padding: const EdgeInsets.symmetric( - vertical: 12, - horizontal: 16, - ), - child: Row( - children: [ - Expanded( - flex: 1, - child: Text('S.No.', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Created Date', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Updated Date', style: _headerStyle), - ), - Expanded( - flex: 1, - child: Text('Reg.No.', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Company', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Status', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Remarks', style: _headerStyle), - ), - Expanded( - flex: 1, - child: Text('Action', style: _headerStyle), - ), - ], - ), - ), - Expanded(child: _buildDataTable(context)), - ], - ), - ), - ), + ) + : Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(8.0), + child: _buildContent(context), + ), + ), Container( // height: 20, @@ -642,6 +425,243 @@ class EnquiryListState extends ConsumerState { ); } + Widget _buildContent(BuildContext context) { + return Column( + children: [ + if (ResponsiveLayout.isMobile(context)) ...[ + Container( + padding: EdgeInsets.all(8.0), + color: Color(0xffD9EBE8), + child: DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + ), + ], + + Container( + // height: 40, + // color: Colors.pink, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!ResponsiveLayout.isMobile(context)) ...[ + DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + + // Form( + // key: _formKey, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // buildStartDate(context), + // SizedBox(width: 10), + // buildEndDate(context), + // SizedBox(width: 10), + // + // Padding( + // padding: const EdgeInsets.symmetric( + // vertical: 8.0, + // ), + // child: GestureDetector( + // // onTap: filterDateRange, + // onTap: () { + // if (_formKey.currentState!.validate()) { + // filterDateRange(); // only runs if valid + // } + // }, + // child: Icon(Icons.filter_alt_outlined), + // ), + // ), + // + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: refrshfilterDateRange, + // child: Icon(Icons.refresh), + // ), + // ), + // ], + // ), + // ), + Spacer(), + ], + ThemedSearchField( + hintText: 'Search', + backgroundColor: Color(0xFFF6F8F8), + onChanged: filterData, + controller: _searchStaffController, + txtwidth: ResponsiveLayout.isMobile(context) + ? MediaQuery.of(context).size.width * 0.6 + : MediaQuery.of(context).size.width * 0.2, + ), + + SizedBox(width: 10), + + ExportBtn( + sheetName: "Enquiry", + fileName: "enquiry_list", + data: filteredData, + txt: !ResponsiveLayout.isMobile(context) ? true : false, + headers: [ + "id", + "created_on", + "updated_on", + "reg_no", + "insurer_name", + "status", + "remarks", + ], + ), + + SizedBox(width: 10), + GestureDetector( + onTap: () async { + final prefs = await SharedPreferences.getInstance(); + + await prefs.remove('enqAgentDataId'); + 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, + ), + ), + // 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, + // ), + // ), + // ), + ], + ], + ), + ), + ), + ], + ), + ), + SizedBox(height: 10), + + if (!ResponsiveLayout.isMobile(context)) + Container( + decoration: BoxDecoration( + color: Color(0xFFEDF6F5), + borderRadius: BorderRadius.circular(6), + ), + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Row( + children: [ + Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)), + Expanded( + flex: 2, + child: Text('Created Date', style: _headerStyle), + ), + Expanded( + flex: 2, + child: Text('Updated Date', style: _headerStyle), + ), + Expanded(flex: 1, child: Text('Reg.No.', style: _headerStyle)), + Expanded(flex: 3, child: Text('Company', style: _headerStyle)), + Expanded(flex: 2, child: Text('Status', style: _headerStyle)), + Expanded(flex: 2, child: Text('Remarks', style: _headerStyle)), + Expanded(flex: 1, child: Text('Action', style: _headerStyle)), + ], + ), + ), + + ResponsiveLayout.isMobile(context) + ? _buildDataTable(context) + : Expanded(child: _buildDataTable(context)), + ], + ); + } + + // Widget _buildDataTable1(BuildContext context) { + // if (filteredData.isEmpty) { + // return const SizedBox( + // height: 50, + // child: Center(child: Text('No available data')), + // ); + // } + // + // final sortedData = [..._paginatedData]; + // 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) { if (filteredData.isEmpty) { return const SizedBox( @@ -651,24 +671,28 @@ class EnquiryListState extends ConsumerState { } final sortedData = [..._paginatedData]; + + if (ResponsiveLayout.isMobile(context)) { + // Use Column instead of ListView + return Column( + children: List.generate(sortedData.length, (index) { + final startIndex = (currentPage - 1) * itemsPerPage; + final item = sortedData[index]; + final sno = startIndex + index; + return _buildDataCard(item, sno); + }), + ); + } + + // Desktop: keep ListView.builder return ListView.builder( - itemCount: ResponsiveLayout.isMobile(context) - ? sortedData - .length // only cards for mobile - : sortedData.length + 1, // +1 for header in desktop + itemCount: sortedData.length + 1, itemBuilder: (context, index) { - if (!ResponsiveLayout.isMobile(context) && index == 0) { - return _buildHeader(); - } - + if (index == 0) return _buildHeader(); final startIndex = (currentPage - 1) * itemsPerPage; - final item = - sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; + final item = sortedData[index - 1]; final sno = startIndex + index; - - return !ResponsiveLayout.isMobile(context) - ? _buildDataRow(item, sno) - : _buildDataCard(item, sno); + return _buildDataRow(item, sno); }, ); } diff --git a/lib/presentation/screens/login/login_screen.dart b/lib/presentation/screens/login/login_screen.dart index 2fa35dd..73bd9e4 100644 --- a/lib/presentation/screens/login/login_screen.dart +++ b/lib/presentation/screens/login/login_screen.dart @@ -251,10 +251,10 @@ class _LoginScreenState extends ConsumerState { // if (switcherStatus == 1) { // _verifyPhoneNumber(); // } else { - setState(() { - enteredEmailOrMobile = true; - }); - ToastHelper.showSuccessToast(context, 'OTP sent successfully'); + setState(() { + enteredEmailOrMobile = true; + }); + ToastHelper.showSuccessToast(context, 'OTP sent successfully'); // } return true; // ✅ success } else { @@ -1308,9 +1308,9 @@ class _LoginScreenState extends ConsumerState { // if (switcherStatus == 1) { // await verifyFirebaseMobileOTP(); // } else { - await verifyMobileOrMailOTP( - _otpController.text, - ); + await verifyMobileOrMailOTP( + _otpController.text, + ); // } }, ), diff --git a/lib/presentation/screens/staff/Enquiry/enquiry_list.dart b/lib/presentation/screens/staff/Enquiry/enquiry_list.dart index 076c8d4..8103052 100644 --- a/lib/presentation/screens/staff/Enquiry/enquiry_list.dart +++ b/lib/presentation/screens/staff/Enquiry/enquiry_list.dart @@ -37,6 +37,7 @@ import '../../../themes/indicators/text_field_theme.dart'; import 'package:file_picker/file_picker.dart'; +import '../../../widgets/custom_Stdate_EnDate_Filter.dart'; import '../../../widgets/custom_action_popup.dart'; import '../assignStaff.dart'; @@ -50,6 +51,8 @@ class EnquiryStaffState extends ConsumerState { int currentPage = 1; int itemsPerPage = 10; late ApiService apiService; + dynamic userId; + final _formKey = GlobalKey(); // List> dataVal = []; List> getStaffData = []; @@ -58,19 +61,28 @@ class EnquiryStaffState extends ConsumerState { bool isLoading = false; dynamic roleId; + Map controllers = {}; + List tabHeader = ['startDate', 'endDate']; + @override void initState() { super.initState(); apiService = ApiService(); + for (String field in tabHeader) { + controllers[field] = TextEditingController(); + } + Future.microtask(() { final id = ref.read(managerIdProvider); roleId = ref.read(userRoleProvider); - final userId = ref.read(userIdProvider); + userId = ref.read(userIdProvider); print("C72 => r : $roleId | mId: $id | uId: $userId "); - if (userId != null) { getStaffList(userId, roleId); } + if (userId != null) { + getStaffList(userId, roleId); + } }); } @@ -80,24 +92,84 @@ class EnquiryStaffState extends ConsumerState { final userId = ref.read(userIdProvider); print("C82 => r : $roleId | mId: $id | uId: $userId "); - if (userId != null) { getStaffList(userId, roleId); } - + if (userId != null) { + getStaffList(userId, roleId); + } } - Future getStaffList(int managerId, role) async { + void filterDateRange() { + // ✅ Validate the form first + if (!_formKey.currentState!.validate()) { + // stop execution if validation fails + return; + } + final fromDateText = controllers['startDate']?.text ?? ''; + final toDateText = controllers['endDate']?.text ?? ''; + + // Optional: double-check End >= Start + final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + + if (toDate.isBefore(fromDate)) { + // This is already caught by the validator, but extra safety + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("End Date cannot be earlier than Start Date")), + ); + return; + } + + // ✅ Call your API + getStaffList(userId, roleId); + } + + void refrshfilterDateRange() { + setState(() { + controllers['startDate']!.clear(); + controllers['endDate']!.clear(); + + controllers['startDate']?.text = ''; + controllers['endDate']?.text = ''; + // Reset the FormField validation + _formKey.currentState?.reset(); + }); + getStaffList(userId, roleId); + } + + Future getStaffList( + int managerId, + role, { + String fromDate = '', + String toDate = '', + }) async { print('C89 => Fns called => $managerId | $role'); setState(() { isLoading = true; }); try { - final response = await apiService.fetchPolicyList(managerId, role); + final response = await apiService.fetchPolicyList( + managerId, + role, + fromDate: controllers['startDate']?.text ?? '', + toDate: controllers['endDate']?.text ?? '', + ); + + print('FromDate : $fromDate'); + print('ToDate : $toDate'); if (response['status'] == 'success') { final data = response['data']; print('C99 => getStaffListData => ${response['data']}'); + final fromDate = response['from_date'] ?? ''; + final toDate = response['to_date'] ?? ''; + + print('FromDate : $fromDate'); + print('ToDate : $toDate'); setState(() { + controllers['startDate']?.text = fromDate; + controllers['endDate']?.text = toDate; + if (data is List) { // Already a list of maps getStaffData = List>.from(data); @@ -391,175 +463,34 @@ class EnquiryStaffState extends ConsumerState { ), SizedBox(height: 10), - - Expanded( - child: Container( - // color: Colors.green, - // color: Colors.green.shade50, - width: MediaQuery.of(context).size.width, - - padding: EdgeInsets.all(8.0), - child: Column( - children: [ - Container( - // height: 40, - // color: Colors.pink, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ThemedSearchField( - hintText: 'Search', - backgroundColor: Color(0xFFF6F8F8), - onChanged: filterData, - controller: _searchStaffController, - txtwidth: ResponsiveLayout.isMobile(context) - ? MediaQuery.of(context).size.width * 0.6 - : MediaQuery.of(context).size.width * 0.2, - ), - - Spacer(), - - ExportBtn( - sheetName: "Enquiry", - fileName: "Enquiry_list", - data: filteredData, - txt: !ResponsiveLayout.isMobile(context) - ? true - : false, - headers: [ - "created_on", - "updated_on", - "reg_no", - "agent_name", - "assigned_to_name", - "insurer_name", - "insured_name", - "premium_amount", - "payment_mode", - "policy_number", - "status", - ], - ), - - // SizedBox(width: 10), - // GestureDetector( - // onTap: () { - // // 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), - // - // GestureDetector( - // onTap: () { - // // context.go(AppRoutes.agent / create); - // context.go('/staff/create'); - // }, - // child: Text( - // 'Create New Staff', - // style: TextStyle( - // color: Colors.white, - // fontWeight: FontWeight.w600, - // fontSize: 14, - // ), - // ), - // ), - // ], - // ], - // ), - // ), - // ), - ], + ResponsiveLayout.isMobile(context) + ? Container( + height: MediaQuery.of(context).size.height * 0.69, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(8), + child: _buildContent(context), ), ), - SizedBox(height: 10), - if (!ResponsiveLayout.isMobile(context)) - Container( - decoration: BoxDecoration( - color: Color(0xFFEDF6F5), - borderRadius: BorderRadius.circular(6), - ), - padding: const EdgeInsets.symmetric( - vertical: 12, - horizontal: 16, - ), - child: const Row( - children: [ - Expanded( - flex: 3, - child: Text('Created Date', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Updated Date', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Reg.No', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Agents', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Assigned To', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Insurer', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Padding( - padding: EdgeInsets.only(left: 8.0), - child: Text( - 'Insured Name', - style: _headerStyle, - ), - ), - ), - Expanded( - flex: 2, - child: Text('Premium', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Payment Mode', style: _headerStyle), - ), - Expanded( - flex: 2, - child: Text('Policy Number', style: _headerStyle), - ), - - Expanded( - flex: 3, - child: Text('Status', style: _headerStyle), - ), - Expanded( - flex: 1, - child: Text('Action', style: _headerStyle), - ), - ], - ), - ), - Expanded(child: _buildDataTable(context)), - ], - ), - ), - ), + ) + : Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(8.0), + child: _buildContent(context), + ), + ), + // Expanded( + // child: Container( + // // color: Colors.green, + // // color: Colors.green.shade50, + // width: MediaQuery.of(context).size.width, + // + // padding: EdgeInsets.all(8.0), + // child: + // ), + // ), Container( // height: 20, width: MediaQuery.of(context).size.width, @@ -589,6 +520,221 @@ class EnquiryStaffState extends ConsumerState { ); } + Widget _buildContent(BuildContext context) { + return Column( + children: [ + if (ResponsiveLayout.isMobile(context)) ...[ + Container( + padding: EdgeInsets.all(8.0), + color: Color(0xffD9EBE8), + child: DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + ), + ], + + Container( + // height: 40, + // color: Colors.pink, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!ResponsiveLayout.isMobile(context)) ...[ + DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + + // Form( + // key: _formKey, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // buildStartDate(context), + // SizedBox(width: 10), + // buildEndDate(context), + // SizedBox(width: 10), + // + // Padding( + // padding: const EdgeInsets.symmetric( + // vertical: 8.0, + // ), + // child: GestureDetector( + // // onTap: filterDateRange, + // onTap: () { + // if (_formKey.currentState!.validate()) { + // filterDateRange(); // only runs if valid + // } + // }, + // child: Icon(Icons.filter_alt_outlined), + // ), + // ), + // + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: refrshfilterDateRange, + // child: Icon(Icons.refresh), + // ), + // ), + // ], + // ), + // ), + Spacer(), + ], + + ThemedSearchField( + hintText: 'Search', + backgroundColor: Color(0xFFF6F8F8), + onChanged: filterData, + controller: _searchStaffController, + txtwidth: ResponsiveLayout.isMobile(context) + ? MediaQuery.of(context).size.width * 0.7 + : MediaQuery.of(context).size.width * 0.2, + ), + + ResponsiveLayout.isMobile(context) + ? Spacer() + : SizedBox(width: 10), + + ExportBtn( + sheetName: "Enquiry", + fileName: "Enquiry_list", + data: filteredData, + txt: !ResponsiveLayout.isMobile(context) ? true : false, + headers: [ + "created_on", + "updated_on", + "reg_no", + "agent_name", + "assigned_to_name", + "insurer_name", + "insured_name", + "premium_amount", + "payment_mode", + "policy_number", + "status", + ], + ), + + // SizedBox(width: 10), + // GestureDetector( + // onTap: () { + // // 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), + // + // GestureDetector( + // onTap: () { + // // context.go(AppRoutes.agent / create); + // context.go('/staff/create'); + // }, + // child: Text( + // 'Create New Staff', + // style: TextStyle( + // color: Colors.white, + // fontWeight: FontWeight.w600, + // fontSize: 14, + // ), + // ), + // ), + // ], + // ], + // ), + // ), + // ), + ], + ), + ), + SizedBox(height: 10), + if (!ResponsiveLayout.isMobile(context)) + Container( + decoration: BoxDecoration( + color: Color(0xFFEDF6F5), + borderRadius: BorderRadius.circular(6), + ), + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: const Row( + children: [ + Expanded( + flex: 3, + child: Text('Created Date', style: _headerStyle), + ), + Expanded( + flex: 3, + child: Text('Updated Date', style: _headerStyle), + ), + Expanded(flex: 2, child: Text('Reg.No', style: _headerStyle)), + Expanded(flex: 2, child: Text('Agents', style: _headerStyle)), + Expanded( + flex: 2, + child: Text('Assigned To', style: _headerStyle), + ), + Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), + Expanded( + flex: 3, + child: Padding( + padding: EdgeInsets.only(left: 8.0), + child: Text('Insured Name', style: _headerStyle), + ), + ), + Expanded(flex: 2, child: Text('Premium', style: _headerStyle)), + Expanded( + flex: 2, + child: Text('Payment Mode', style: _headerStyle), + ), + Expanded( + flex: 2, + child: Text('Policy Number', style: _headerStyle), + ), + + Expanded(flex: 3, child: Text('Status', style: _headerStyle)), + Expanded(flex: 1, child: Text('Action', style: _headerStyle)), + ], + ), + ), + ResponsiveLayout.isMobile(context) + ? _buildDataTable(context) + : Expanded(child: _buildDataTable(context)), + ], + ); + } + Widget _buildDataTable(BuildContext context) { if (filteredData.isEmpty) { return const SizedBox( @@ -598,28 +744,63 @@ class EnquiryStaffState extends ConsumerState { } final sortedData = [..._paginatedData]; + + if (ResponsiveLayout.isMobile(context)) { + // Use Column instead of ListView + return Column( + children: List.generate(sortedData.length, (index) { + final startIndex = (currentPage - 1) * itemsPerPage; + final item = sortedData[index]; + final sno = startIndex + index; + return _buildDataCard(item, sno); + }), + ); + } + + // Desktop: keep ListView.builder return ListView.builder( - itemCount: ResponsiveLayout.isMobile(context) - ? sortedData - .length // only cards for mobile - : sortedData.length + 1, // +1 for header in desktop + itemCount: sortedData.length + 1, itemBuilder: (context, index) { - if (!ResponsiveLayout.isMobile(context) && index == 0) { - return _buildHeader(); - } - + if (index == 0) return _buildHeader(); final startIndex = (currentPage - 1) * itemsPerPage; - final item = - sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; + final item = sortedData[index - 1]; final sno = startIndex + index; - - return !ResponsiveLayout.isMobile(context) - ? _buildDataRow(item, sno) - : _buildDataCard(item, sno); + return _buildDataRow(item, sno); }, ); } + // Widget _buildDataTable(BuildContext context) { + // if (filteredData.isEmpty) { + // return const SizedBox( + // height: 50, + // child: Center(child: Text('No available data')), + // ); + // } + // + // final sortedData = [..._paginatedData]; + // 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 _buildHeader() { return SizedBox.shrink(); } diff --git a/lib/presentation/screens/staff/policy/policy_list.dart b/lib/presentation/screens/staff/policy/policy_list.dart index fb6ff39..41b4a3d 100644 --- a/lib/presentation/screens/staff/policy/policy_list.dart +++ b/lib/presentation/screens/staff/policy/policy_list.dart @@ -15,6 +15,7 @@ import '../../../providers/manager_provider.dart'; import '../../../providers/quotation_staff_proivder.dart'; import '../../../themes/indicators/export_btn.dart'; import '../../../themes/indicators/search_field_theme.dart'; +import '../../../widgets/custom_Stdate_EnDate_Filter.dart'; import '../../../widgets/custom_action_popup.dart'; class policylist extends ConsumerStatefulWidget { @@ -27,13 +28,16 @@ class policylistState extends ConsumerState { int currentPage = 1; int itemsPerPage = 10; late ApiService apiService; - + dynamic userId; // List> dataVal = []; List> getStaffData = []; List> originalData = []; List> filteredData = []; bool isLoading = false; dynamic roleId; + final _formKey = GlobalKey(); + Map controllers = {}; + List tabHeader = ['startDate', 'endDate']; @override void initState() { @@ -41,10 +45,14 @@ class policylistState extends ConsumerState { apiService = ApiService(); + for (String field in tabHeader) { + controllers[field] = TextEditingController(); + } + Future.microtask(() { final id = ref.read(managerIdProvider); roleId = ref.read(userRoleProvider); - final userId = ref.read(userIdProvider); + userId = ref.read(userIdProvider); print("D49 => r : $roleId | mId: $id | uId: $userId "); if (userId != null) { @@ -64,7 +72,12 @@ class policylistState extends ConsumerState { } } - Future getStaffList(int managerId, role) async { + Future getStaffList( + int managerId, + role, { + String fromDate = '', + String toDate = '', + }) async { print('D68 => Fns called => $managerId | $role'); setState(() { isLoading = true; @@ -74,12 +87,22 @@ class policylistState extends ConsumerState { final response = await apiService.fetchPolicyDataOnlyList( managerId, role, + fromDate: controllers['startDate']?.text ?? '', + toDate: controllers['endDate']?.text ?? '', ); if (response['status'] == 'success') { final data = response['data']; print('D81 => getStaffListData => ${response['data']}'); + + final fromDate = response['from_date'] ?? ''; + final toDate = response['to_date'] ?? ''; + + print('FromDate : $fromDate'); + print('ToDate : $toDate'); setState(() { + controllers['startDate']?.text = fromDate; + controllers['endDate']?.text = toDate; if (data is List) { // Already a list of maps getStaffData = List>.from(data); @@ -124,6 +147,45 @@ class policylistState extends ConsumerState { return sortedData.sublist(startIndex, endIndex); } + void filterDateRange() { + // ✅ Validate the form first + if (!_formKey.currentState!.validate()) { + // stop execution if validation fails + return; + } + + final fromDateText = controllers['startDate']?.text ?? ''; + final toDateText = controllers['endDate']?.text ?? ''; + + // Optional: double-check End >= Start + final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText); + final toDate = DateFormat('dd-MM-yyyy').parse(toDateText); + + if (toDate.isBefore(fromDate)) { + // This is already caught by the validator, but extra safety + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("End Date cannot be earlier than Start Date")), + ); + return; + } + + // ✅ Call your API + getStaffList(userId, roleId); + } + + void refrshfilterDateRange() { + setState(() { + controllers['startDate']!.clear(); + controllers['endDate']!.clear(); + + controllers['startDate']?.text = ''; + controllers['endDate']?.text = ''; + // Reset the FormField validation + _formKey.currentState?.reset(); + }); + getStaffList(userId, roleId); + } + void filterData(String query) { print("FilterDAta - $query"); setState(() { @@ -334,157 +396,23 @@ class policylistState extends ConsumerState { SizedBox(height: 10), - Expanded( - child: Container( - // color: Colors.green, - // color: Colors.green.shade50, - width: MediaQuery.of(context).size.width, - - padding: EdgeInsets.all(8.0), - child: Column( - children: [ - Container( - // height: 40, - // color: Colors.pink, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ThemedSearchField( - hintText: 'Search', - backgroundColor: Color(0xFFF6F8F8), - onChanged: filterData, - controller: _searchStaffController, - txtwidth: ResponsiveLayout.isMobile(context) - ? MediaQuery.of(context).size.width * 0.6 - : MediaQuery.of(context).size.width * 0.2, - ), - - Spacer(), - - ExportBtn( - sheetName: "Policy", - fileName: "Policy_list", - data: filteredData, - txt: !ResponsiveLayout.isMobile(context) - ? true - : false, - headers: [ - "reg_no", - "agent_name", - "assigned_to_name", - "insurer_name", - "insured_name", - "premium_amount", - "payment_mode", - "updated_on", - "policy_number", - ], - ), - - // SizedBox(width: 10), - // GestureDetector( - // onTap: () { - // // 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), - // - // GestureDetector( - // onTap: () { - // // context.go(AppRoutes.agent / create); - // context.go('/staff/create'); - // }, - // child: Text( - // 'Create New Staff', - // style: GoogleFonts.inter( - // color: Colors.white, - // fontWeight: FontWeight.w600, - // fontSize: 14, - // ), - // ), - // ), - // ], - // ], - // ), - // ), - // ), - ], + ResponsiveLayout.isMobile(context) + ? Container( + height: MediaQuery.of(context).size.height * 0.69, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.all(8), + child: _buildContent(context), ), ), - SizedBox(height: 10), - if (!ResponsiveLayout.isMobile(context)) - Container( - decoration: BoxDecoration( - color: Color(0xFFEDF6F5), - borderRadius: BorderRadius.circular(6), - ), - padding: const EdgeInsets.symmetric( - vertical: 12, - horizontal: 16, - ), - child: Row( - children: [ - Expanded( - flex: 4, - child: Text('Date', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Reg.No', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Agents', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Assigned To', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Insurer', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Insured Name', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Premium', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Payment Mode', style: _headerStyle), - ), - Expanded( - flex: 3, - child: Text('Policy Number', style: _headerStyle), - ), - - // Expanded( - // flex: 1, - // child: Text('Action', style: _headerStyle), - // ), - ], - ), - ), - Expanded(child: _buildDataTable(context)), - ], - ), - ), - ), + ) + : Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(8.0), + child: _buildContent(context), + ), + ), Container( // height: 20, @@ -515,6 +443,244 @@ class policylistState extends ConsumerState { ); } + Widget _buildContent(BuildContext context) { + return Column( + children: [ + if (ResponsiveLayout.isMobile(context)) ...[ + Container( + padding: EdgeInsets.all(8.0), + color: Color(0xffD9EBE8), + child: DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + ), + ], + + Container( + // height: 40, + // color: Colors.pink, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (!ResponsiveLayout.isMobile(context)) ...[ + DateFilterRow( + startController: controllers['startDate']!, + endController: controllers['endDate']!, + formKey: _formKey, + isMobile: ResponsiveLayout.isMobile(context), + onFilter: () { + // call your filter logic + filterDateRange(); + }, + onRefresh: () { + // call your refresh logic + refrshfilterDateRange(); + }, + ), + + // Form( + // key: _formKey, + // child: Row( + // mainAxisAlignment: MainAxisAlignment.start, + // crossAxisAlignment: CrossAxisAlignment.end, + // children: [ + // buildStartDate(context), + // SizedBox(width: 10), + // buildEndDate(context), + // SizedBox(width: 10), + // + // Padding( + // padding: const EdgeInsets.symmetric( + // vertical: 8.0, + // ), + // child: GestureDetector( + // // onTap: filterDateRange, + // onTap: () { + // if (_formKey.currentState!.validate()) { + // filterDateRange(); // only runs if valid + // } + // }, + // child: Icon(Icons.filter_alt_outlined), + // ), + // ), + // + // Padding( + // padding: const EdgeInsets.all(8.0), + // child: GestureDetector( + // onTap: refrshfilterDateRange, + // child: Icon(Icons.refresh), + // ), + // ), + // ], + // ), + // ), + Spacer(), + ], + ResponsiveLayout.isMobile(context) + ? SizedBox(height: 10) + : SizedBox.shrink(), + ThemedSearchField( + hintText: 'Search', + backgroundColor: Color(0xFFF6F8F8), + onChanged: filterData, + controller: _searchStaffController, + txtwidth: ResponsiveLayout.isMobile(context) + ? MediaQuery.of(context).size.width * 0.7 + : MediaQuery.of(context).size.width * 0.2, + ), + ResponsiveLayout.isMobile(context) + ? Spacer() + : SizedBox(width: 10), + ExportBtn( + sheetName: "Policy", + fileName: "Policy_list", + data: filteredData, + txt: !ResponsiveLayout.isMobile(context) ? true : false, + headers: [ + "reg_no", + "agent_name", + "assigned_to_name", + "insurer_name", + "insured_name", + "premium_amount", + "payment_mode", + "updated_on", + "policy_number", + ], + ), + + // SizedBox(width: 10), + // GestureDetector( + // onTap: () { + // // 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), + // + // GestureDetector( + // onTap: () { + // // context.go(AppRoutes.agent / create); + // context.go('/staff/create'); + // }, + // child: Text( + // 'Create New Staff', + // style: GoogleFonts.inter( + // color: Colors.white, + // fontWeight: FontWeight.w600, + // fontSize: 14, + // ), + // ), + // ), + // ], + // ], + // ), + // ), + // ), + ], + ), + ), + SizedBox(height: 10), + if (!ResponsiveLayout.isMobile(context)) + Container( + decoration: BoxDecoration( + color: Color(0xFFEDF6F5), + borderRadius: BorderRadius.circular(6), + ), + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), + child: Row( + children: [ + Expanded(flex: 4, child: Text('Date', style: _headerStyle)), + Expanded(flex: 3, child: Text('Reg.No', style: _headerStyle)), + Expanded(flex: 3, child: Text('Agents', style: _headerStyle)), + Expanded( + flex: 3, + child: Text('Assigned To', style: _headerStyle), + ), + Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), + Expanded( + flex: 3, + child: Text('Insured Name', style: _headerStyle), + ), + Expanded(flex: 3, child: Text('Premium', style: _headerStyle)), + Expanded( + flex: 3, + child: Text('Payment Mode', style: _headerStyle), + ), + Expanded( + flex: 3, + child: Text('Policy Number', style: _headerStyle), + ), + + // Expanded( + // flex: 1, + // child: Text('Action', style: _headerStyle), + // ), + ], + ), + ), + + // Expanded(child: _buildDataTable(context)), + ResponsiveLayout.isMobile(context) + ? _buildDataTable(context) + : Expanded(child: _buildDataTable(context)), + ], + ); + } + + // Widget _buildDataTable(BuildContext context) { + // if (filteredData.isEmpty) { + // return const SizedBox( + // height: 50, + // child: Center(child: Text('No available data')), + // ); + // } + // + // final sortedData = [..._paginatedData]; + // 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) { if (filteredData.isEmpty) { return const SizedBox( @@ -524,24 +690,28 @@ class policylistState extends ConsumerState { } final sortedData = [..._paginatedData]; + + if (ResponsiveLayout.isMobile(context)) { + // Use Column instead of ListView + return Column( + children: List.generate(sortedData.length, (index) { + final startIndex = (currentPage - 1) * itemsPerPage; + final item = sortedData[index]; + final sno = startIndex + index; + return _buildDataCard(item, sno); + }), + ); + } + + // Desktop: keep ListView.builder return ListView.builder( - itemCount: ResponsiveLayout.isMobile(context) - ? sortedData - .length // only cards for mobile - : sortedData.length + 1, // +1 for header in desktop + itemCount: sortedData.length + 1, itemBuilder: (context, index) { - if (!ResponsiveLayout.isMobile(context) && index == 0) { - return _buildHeader(); - } - + if (index == 0) return _buildHeader(); final startIndex = (currentPage - 1) * itemsPerPage; - final item = - sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; + final item = sortedData[index - 1]; final sno = startIndex + index; - - return !ResponsiveLayout.isMobile(context) - ? _buildDataRow(item, sno) - : _buildDataCard(item, sno); + return _buildDataRow(item, sno); }, ); } diff --git a/lib/presentation/widgets/topbar.dart b/lib/presentation/widgets/topbar.dart index 8096849..13e3827 100644 --- a/lib/presentation/widgets/topbar.dart +++ b/lib/presentation/widgets/topbar.dart @@ -1,44 +1,72 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:http/http.dart' as ref; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; -class TopBar extends StatelessWidget implements PreferredSizeWidget { +import '../../core/routing/routes.dart'; +import '../layouts/responsive_layout.dart'; +import '../providers/userRoleProvider.dart'; + +class TopBar extends StatefulWidget implements PreferredSizeWidget { final String title; final bool isMobile; - final VoidCallback? onBack; - final VoidCallback? onMenuPressed; final VoidCallback? onLogout; - // final VoidCallback? onProfile; final void Function(TapDownDetails details)? onProfile; + final VoidCallback? onMenuPressed; final VoidCallback? onNotifications; - final int notificationCount; const TopBar({ super.key, required this.title, this.isMobile = false, - this.onBack, - this.onMenuPressed, this.onLogout, this.onProfile, this.onNotifications, - this.notificationCount = 0, + this.onMenuPressed, }); + @override + State createState() => _TopBarState(); + + @override + Size get preferredSize => const Size.fromHeight(kToolbarHeight); +} + +class _TopBarState extends State { + String? role; + + @override + void initState() { + super.initState(); + _loadUser(); + } + + Future _loadUser() async { + final prefs = await SharedPreferences.getInstance(); + setState(() { + role = prefs.getString('userRole') ?? "Guest"; + }); + print('Tpbn - $role'); + } + @override Widget build(BuildContext context) { return AppBar( backgroundColor: const Color(0xFFD6F6F4), // light cyan elevation: 0, automaticallyImplyLeading: false, - titleSpacing: isMobile ? 0 : 30, + titleSpacing: widget.isMobile ? 0 : 30, title: Row( children: [ - if (!isMobile) + if (!widget.isMobile) Image.asset( "assets/login/nhance-partner-logo.png", height: 60, width: 120, ), - if (isMobile) ...[ + if (widget.isMobile) ...[ Padding( padding: const EdgeInsets.all(8.0), child: Image.asset( @@ -75,6 +103,38 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget { // icon: const Icon(Icons.menu, color: Colors.black87), // onPressed: onMenuPressed, // ), + if (role == 'agent') ...[ + GestureDetector( + onTap: () async { + final prefs = await SharedPreferences.getInstance(); + + await prefs.remove('enqAgentDataId'); + 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: [ + Text( + 'Raise Enquiry', + style: GoogleFonts.inter( + color: Colors.white, + fontWeight: FontWeight.w600, + fontSize: 14, + ), + ), + ], + ), + ), + ), + ], + SizedBox(width: 10), Container( width: 40, height: 40, @@ -84,10 +144,10 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget { ), child: IconButton( icon: const Icon(Icons.notifications_none, color: Colors.black87), - onPressed: onNotifications, + onPressed: widget.onNotifications, ), ), - if (!isMobile) ...[ + if (!widget.isMobile) ...[ SizedBox(width: 10), Container( width: 40, @@ -97,7 +157,7 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget { borderRadius: BorderRadius.circular(50.0), ), child: GestureDetector( - onTapDown: (details) => onProfile!(details), + onTapDown: (details) => widget.onProfile!(details), child: const Icon(Icons.person_outline, color: Colors.black87), ), ), @@ -106,21 +166,20 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget { // icon: const Icon(Icons.person_outline, color: Colors.black87), // onPressed: onProfile, // ), - ], - SizedBox(width: 10), - Container( - 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, - ), + ], + SizedBox(width: 10), + Container( + 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: widget.onLogout, + ), + ), ], ), );