This commit is contained in:
venbaittech 2025-09-30 10:50:05 +05:30
parent 4acdbca2b2
commit fc08f0a2d4
25 changed files with 1278 additions and 575 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

View File

@ -543,7 +543,7 @@ class ApiService {
if (_token == null) {
await _initializeToken();
}
final url = Uri.parse('${Env.apiUrl}/quotation/findQuotation?id=1=$id');
final url = Uri.parse('${Env.apiUrl}quotation/findQuotation?id=$id');
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',

View File

@ -1,4 +1,5 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AuthService {
static const _tokenKey = 'auth_token';
@ -18,6 +19,8 @@ class AuthService {
// Delete token (logout)
static Future<void> clearToken() async {
print('ClearToken');
final prefs = await SharedPreferences.getInstance();
prefs.clear();
await _storage.delete(key: _tokenKey);
}

View File

@ -33,6 +33,12 @@ class MainLayout extends StatelessWidget {
onNotifications: () {
debugPrint("Notifications tapped");
},
onLogout: () {
debugPrint("Logout tapped");
AuthService.clearToken();
context.go(AppRoutes.login);
},
),
drawer: const DrawerMenu(),
body: body,

View File

@ -699,7 +699,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
label: "Vehicle Type *",
field: Container(
decoration: BoxDecoration(
color: Colors.white,
// color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
width: ResponsiveLayout.isMobile(context)
@ -732,6 +732,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
),
),
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 250),
@ -784,7 +785,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
label: "Insurer *",
field: Container(
decoration: BoxDecoration(
color: Colors.white,
// color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
width: ResponsiveLayout.isMobile(context)

View File

@ -105,7 +105,17 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// final response = await apiService.fetchQuotationList(managerId);
if (widget.data != null) {
final data = List<Map<String, dynamic>>.from(widget.data as Iterable);
// final data = List<Map<String, dynamic>>.from(widget.data as Iterable);
List<Map<String, dynamic>> data;
if (widget.data is List) {
data = List<Map<String, dynamic>>.from(widget.data as List);
} else if (widget.data is Map) {
data = [Map<String, dynamic>.from(widget.data as Map)];
} else {
data = [];
}
print('policyListData - ${widget.data}');
setState(() {

View File

@ -6,6 +6,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:nhance_partner/presentation/screens/Enquiry/enquiry/tabs.dart';
import '../../../../core/config/env.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/services/auth_service.dart';
@ -23,7 +24,8 @@ class QuotationTab extends ConsumerStatefulWidget {
// final Map<String, dynamic>? data;
final List<Map<String, dynamic>>? data;
String? id;
QuotationTab({super.key, this.data, this.id});
final Future<void> Function()? onRefresh;
QuotationTab({super.key, this.data, this.id, this.onRefresh});
@override
ConsumerState<QuotationTab> createState() => QuotationTabState();
}
@ -41,6 +43,11 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<TabEnquiryListState> tabKey =
GlobalKey<TabEnquiryListState>();
bool blockKey = false;
List<String> tabHeader = [
'regNum',
'insurer',
@ -110,7 +117,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
managerId = ref.watch(managerIdProvider);
userId = ref.watch(userIdProvider);
getQuotationList(managerId);
getQuotationList();
});
}
@ -120,7 +127,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
}
void refresh() {
getQuotationList(managerId);
getQuotationList();
}
@override
@ -132,8 +139,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
super.dispose();
}
Future<void> getQuotationList(managerId) async {
print('getClaimList called MagId - $managerId');
Future<void> getQuotationList() async {
print('getClaimList called MagId - ');
setState(() {
isLoading = true;
});
@ -143,38 +150,48 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
if (widget.data != null && widget.id != null) {
final data = List<Map<String, dynamic>>.from(widget.data as Iterable);
response = await apiService.findSingleQuotationData(widget.id);
// response = await apiService.findSingleQuotationData(widget.id);
// print('quoationListData - ${widget.data}');
setState(() {
getQuotationData = data;
// getQuotationData = List<Map<String, dynamic>>.from(response['data']);
originalData = getQuotationData;
filteredData = List.from(originalData);
print('quoationListData - $getQuotationData');
blockKey = getQuotationData.any((item) => item['status'] == 'Accepted');
print('blockKey- $blockKey');
// blockKey = getQuotationData.any(
// (item) => (item['status']?.toString().toLowerCase() ?? '') == 'approved',
// );
// print('originalData - $getClaimPolicies');
});
// if (response['status'] == 'success') {
// final rawData = response['data'];
// print('quoationListData1 - ${response['data']}');
// setState(() {
// getQuotationData = data;
// if (rawData is List) {
// // already a list
// getQuotationData = List<Map<String, dynamic>>.from(rawData);
// } else if (rawData is Map) {
// // single object, wrap into a list
// getQuotationData = [Map<String, dynamic>.from(rawData)];
// } else {
// getQuotationData = [];
// }
// // getQuotationData = List<Map<String, dynamic>>.from(response['data']);
// originalData = getQuotationData;
// filteredData = List.from(originalData);
// // print('originalData - $getClaimPolicies');
// });
if (response['status'] == 'success') {
final rawData = response['data'];
print('quoationListData1 - ${response['data']}');
setState(() {
if (rawData is List) {
// already a list
getQuotationData = List<Map<String, dynamic>>.from(rawData);
} else if (rawData is Map) {
// single object, wrap into a list
getQuotationData = [Map<String, dynamic>.from(rawData)];
} else {
getQuotationData = [];
}
// getQuotationData = List<Map<String, dynamic>>.from(response['data']);
originalData = getQuotationData;
filteredData = List.from(originalData);
// print('originalData - $getClaimPolicies');
});
} else {
getQuotationData = [];
originalData = [];
}
// } else {
// getQuotationData = [];
// originalData = [];
// }
}
} catch (e) {
print('Exception occurred: $e');
@ -263,7 +280,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
// data['id'] = selectedId; // Add plan_id for update
// data['status'] = val;
print("data------- $data}");
print("data------- $data");
try {
final response = await http.post(
@ -280,11 +297,21 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
print("Response: ${response.body}");
ToastHelper.showSuccessToast(context, 'Status Updated');
print("tre1");
selectedId = null; // just update field
isquotation = false;
refresh();
print("tre11");
// 🔄 Refresh parent
if (widget.onRefresh != null) {
await widget.onRefresh!();
}
// refresh();
// WidgetsBinding.instance.addPostFrameCallback((_) {
// tabKey.currentState?.loadQuotationTab(widget.id ?? "");
// });
// context.go(AppRoutes.staffLst);
} else {
final responseBody = jsonDecode(response.body);
@ -368,6 +395,10 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
ToastHelper.showSuccessToast(context, 'Document Uploaded');
print("Response: ${response.body}");
if (widget.onRefresh != null) {
await widget.onRefresh!();
}
// context.go(AppRoutes.agentLst);
} else {
final responseBody = jsonDecode(response.body);
@ -383,6 +414,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
Color _getStatusColor(String? status) {
switch (status) {
case 'Pending':
return Colors.yellow;
case 'Accepted':
return Colors.green;
case 'Rejected':
@ -443,7 +476,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
const SizedBox(height: 20),
if (showAction)
if (!blockKey)
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
@ -976,7 +1009,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
fontSize: 14,
fontWeight: FontWeight.w400,
color: item['status'] == 'Accepted' ? Colors.green : Colors.red,
color: _getStatusColor(item['status']),
// color: item['status'] == 'Accepted' ? Colors.green : Colors.red,
),
),
),

View File

@ -1,7 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
@ -26,11 +28,16 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
bool isLoading = true;
late ApiService apiService;
ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
apiService = ApiService();
if (kIsWeb) {
Future.microtask(() => _restoreId(ref));
}
Future.microtask(() {
final id = ref.read(enquiryIdProvider);
@ -49,7 +56,21 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
// fetch immediately
}
Future<void> _loadData(id) async {
Future<void> _restoreId(WidgetRef ref) async {
final prefs = await SharedPreferences.getInstance();
final String? savedId = prefs.getString(
'enqAgentDataId',
); // already a string
if (savedId != null) {
ref.read(enquiryIdProvider.notifier).state = savedId;
print("savedenqStaffDataId ID restored: $savedId");
_loadData(savedId);
}
}
Future<void> _loadData1(id) async {
print('Load Data');
setState(() => isLoading = true);
final response = await apiService.findEnqQuotePolicyView(id);
@ -65,20 +86,37 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
TabItem(
"Quotation",
QuotationTab(
data: (enquiryData?["quotations"] as List<dynamic>?)!
.map((e) => Map<String, dynamic>.from(e as Map))
.toList(),
data:
(enquiryData?["quotations"] as List<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[],
id: id ?? "",
),
// QuotationTab(
// data: (enquiryData?["quotations"] as List<dynamic>?)!
// .map((e) => Map<String, dynamic>.from(e as Map))
// .toList(),
// id: id ?? "",
// ),
),
TabItem(
"Policy",
PolicyTab(
data: (enquiryData?["policies"] as List<dynamic>?)!
.map((e) => Map<String, dynamic>.from(e as Map))
.toList(),
data:
(enquiryData?["policies"] as List<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[], // fallback to empty list
id: id ?? "",
),
// PolicyTab(
// data: (enquiryData?["policies"] as List<dynamic>?)!
// .map((e) => Map<String, dynamic>.from(e as Map))
// .toList(),
// id: id ?? "",
// ),
),
// TabItem("Quotation", QuotationTab(data: enquiryData?["quotations"])),
@ -87,6 +125,75 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
});
}
Future<void> _loadData(id, {int? tabIndex}) async {
print('loadQuotationTab 2');
setState(() => isLoading = true);
final response = await apiService.findEnqQuotePolicyView(id);
setState(() {
enquiryData = response["data"];
isLoading = false;
tabs = [
TabItem(
"Enquiry",
EnquiryTab(data: enquiryData?["enquiry"], id: id ?? ""),
),
TabItem(
"Quotation",
QuotationTab(
data:
(enquiryData?["quotations"] as List<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[],
id: id ?? "",
onRefresh: () async {
await _loadData(id); // refresh parent data
},
),
),
TabItem(
"Policy",
PolicyTab(
data: enquiryData?["policies"] is List
? List<Map<String, dynamic>>.from(
(enquiryData?["policies"] as List).map(
(e) => Map<String, dynamic>.from(e as Map),
),
)
: enquiryData?["policies"] is Map
? [Map<String, dynamic>.from(enquiryData?["policies"] as Map)]
: [],
id: id ?? "",
),
),
// TabItem(
// "Policy",
// PolicyTab(
// data:
// (enquiryData?["policies"] as List<dynamic>?)
// ?.map((e) => Map<String, dynamic>.from(e as Map))
// .toList() ??
// [],
// id: id ?? "",
// ),
// ),
];
if (tabIndex != null) {
selectedIndex = tabIndex;
expandedIndex = tabIndex;
}
});
}
/// Public method to load data and select a tab
Future<void> loadQuotationTab(String id) async {
print('loadQuotationTab 1');
await _loadData(id, tabIndex: 2); // now _loadData will set the selected tab
}
@override
Widget build(BuildContext context) {
final bool isMobile = MediaQuery.of(context).size.width < 600;
@ -94,12 +201,12 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
print("TABUPDID- $id");
// When provider changes, re-fetch
ref.listen<String?>(enquiryIdProvider, (prev, next) {
if (prev != next) {
_loadData(id);
}
});
// // When provider changes, re-fetch
// ref.listen<String?>(enquiryIdProvider, (prev, next) {
// if (prev != next) {
// _loadData(id);
// }
// });
print('ENQID: $id');
@ -110,14 +217,130 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
child: isLoading
? const Center(child: CircularProgressIndicator())
: isMobile
? _buildMobileTabs()
? SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
child: GestureDetector(
onTap: () {
// context.go(AppRoutes.dashboard);
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryLst);
},
child: Row(
children: [
const Icon(
Icons.arrow_left_sharp,
size: 25,
color: Color(0xFF425B5B),
),
// const SizedBox(width: 8),
Text(
"Enquiry",
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
],
),
),
),
_buildMobileTabs(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
),
],
),
)
: _buildDesktopTabs(),
),
);
}
Widget _buildMobileTabs() {
Widget _buildMobileTabs({
required bool shrinkWrap,
required ScrollPhysics physics,
}) {
return ListView.builder(
shrinkWrap: shrinkWrap,
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),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: const BorderSide(color: Color(0xFF425B5B), width: 1),
),
child: Theme(
// removes top & bottom dividers inside ExpansionTile
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
child: ExpansionTile(
key: ValueKey(index),
collapsedIconColor: isExpanded ? Colors.black : Colors.white,
iconColor: isExpanded ? Colors.black : Colors.white,
initiallyExpanded: isExpanded,
tilePadding: const EdgeInsets.symmetric(horizontal: 16.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
collapsedShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
onExpansionChanged: (expanded) {
setState(() {
expandedIndex = expanded ? index : null;
if (expanded) {
WidgetsBinding.instance.addPostFrameCallback((_) {
RenderBox box = context.findRenderObject() as RenderBox;
double yPos = box.localToGlobal(Offset.zero).dy;
_scrollController.animateTo(
_scrollController.offset + yPos - 100,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
});
}
});
},
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 _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) {
@ -139,6 +362,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
collapsedIconColor: isExpanded ? Colors.black : Colors.white,
iconColor: isExpanded ? Colors.black : Colors.white,
initiallyExpanded: isExpanded,
onExpansionChanged: (expanded) {
setState(() {
if (expanded) {
@ -163,10 +387,12 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
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),

View File

@ -2,9 +2,11 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart';
import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/utils/Pagination.dart';
@ -100,6 +102,29 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
return sortedData.sublist(startIndex, endIndex);
}
Future<void> handleEdit(item) async {
// Navigator.pop(context);
print('EDITStaff - ${item['id']}');
// dynamic id = data['id'];
// context.go('/tabEnquiry/$id');
final prefs = await SharedPreferences.getInstance();
// Remove old value (if any)
await prefs.remove('enqAgentDataId');
// setState(() {
final id = item['id'].toString();
// Save the new id
await prefs.setString('enqAgentDataId', id.toString());
ref.read(enquiryIdProvider.notifier).state = id;
// });
// update provider
context.go(AppRoutes.tabEnquiry);
}
void filterData(String query) {
print("FilterDAta - $query");
setState(() {
@ -186,13 +211,13 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
children: [
Icon(
Icons.arrow_left_sharp,
size: 35,
size: ResponsiveLayout.isMobile(context) ? 25 : 35,
color: Color(0xFF425B5B),
),
Text(
"Enquiries",
style: TextStyle(
fontSize: 18,
style: GoogleFonts.inter(
fontSize: ResponsiveLayout.isMobile(context) ? 14 : 18,
fontWeight: FontWeight.w600,
),
),
@ -201,7 +226,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
),
),
SizedBox(height: 10),
SizedBox(height: ResponsiveLayout.isMobile(context) ? 5 : 10),
Expanded(
child: Container(
@ -250,8 +275,10 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
SizedBox(width: 10),
GestureDetector(
onTap: () {
ref.read(enquiryIdProvider.notifier).state = null;
onTap: () async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('enqAgentDataId');
context.go(AppRoutes.tabEnquiry);
// print('Export');
},
@ -270,7 +297,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
SizedBox(width: 10),
Text(
'Create New Enquiry',
style: TextStyle(
style: GoogleFonts.inter(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 14,
@ -288,7 +315,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
// },
// child: Text(
// 'Create New Enquiry',
// style: TextStyle(
// style: GoogleFonts.inter(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
@ -315,7 +342,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
vertical: 12,
horizontal: 16,
),
child: const Row(
child: Row(
children: [
Expanded(
flex: 1,
@ -341,7 +368,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
child: Text('Status', style: _headerStyle),
),
Expanded(
flex: 1,
flex: 2,
child: Text('Remarks', style: _headerStyle),
),
Expanded(
@ -423,7 +450,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
Widget _buildDataRow(Map<String, dynamic> item, sno) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
// margin: const EdgeInsets.only(top: 10),
decoration: BoxDecoration(
color: Colors.white,
@ -462,7 +489,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
child: Text(item['status'] ?? '-', style: _dataBold),
),
Expanded(
flex: 1,
flex: 2,
child: Text(
item['remarks'] ?? '-',
style: _dataBold,
@ -473,36 +500,70 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
PopupMenuButton<int>(
color: Colors.white,
padding: EdgeInsets.zero,
offset: Offset(0, 30),
icon: Icon(
Icons.more_vert,
color: Color(0xFF475569),
size: 14,
),
itemBuilder: (context) => [
CustomPopupMenuEntry(
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 8,
vertical: 8,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: _buildPopupMenuActions(context, item),
),
GestureDetector(
// onTap: () {
// Navigator.pop(context);
// print('EDITStaff - ${item['id']}');
// // dynamic id = data['id'];
// // context.go('/tabEnquiry/$id');
// setState(() {
// final id = item['id'].toString();
// ref.read(enquiryIdProvider.notifier).state = id;
// });
// // update provider
//
// context.go(AppRoutes.tabEnquiry);
// },
onTap: () {
handleEdit(item);
},
child: Image.asset(
"assets/miscellaneous/Edit.png",
height: 15,
width: 15,
),
),
],
),
],
),
),
// Expanded(
// flex: 1,
// child: Row(
// children: [
// PopupMenuButton<int>(
// color: Colors.white,
// padding: EdgeInsets.zero,
// offset: Offset(0, 30),
// icon: Icon(
// Icons.more_vert,
// color: Color(0xFF475569),
// size: 14,
// ),
// itemBuilder: (context) => [
// CustomPopupMenuEntry(
// child: Container(
// padding: EdgeInsets.symmetric(
// horizontal: 8,
// vertical: 8,
// ),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// mainAxisAlignment: MainAxisAlignment.center,
// children: _buildPopupMenuActions(context, item),
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
],
),
);
@ -524,24 +585,47 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(item['reg_no'] ?? '-', style: _headerStyle),
PopupMenuButton<int>(
color: Colors.white,
padding: EdgeInsets.zero,
offset: Offset(0, 30),
icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14),
itemBuilder: (context) => [
CustomPopupMenuEntry(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: _buildPopupMenuActions(context, item),
GestureDetector(
// onTap: () {
// Navigator.pop(context);
// print('EDITStaff - ${item['id']}');
// // dynamic id = data['id'];
// // context.go('/tabEnquiry/$id');
// setState(() {
// final id = item['id'].toString();
// ref.read(enquiryIdProvider.notifier).state = id;
// });
// // update provider
//
// context.go(AppRoutes.tabEnquiry);
// },
onTap: () {
handleEdit(item);
},
child: Image.asset(
"assets/miscellaneous/Edit.png",
height: 15,
width: 15,
),
),
),
],
),
// PopupMenuButton<int>(
// color: Colors.white,
// padding: EdgeInsets.zero,
// offset: Offset(0, 30),
// icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14),
// itemBuilder: (context) => [
// CustomPopupMenuEntry(
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// mainAxisAlignment: MainAxisAlignment.center,
// children: _buildPopupMenuActions(context, item),
// ),
// ),
// ),
// ],
// ),
],
),
const Divider(color: Color(0xffD9EBE8), thickness: 0.8),
@ -557,7 +641,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text("Company", style: _cardheaderStyle),
Text("Company", style: _cardheaderStyle),
Text(
item['insurer_name'] ?? '-',
style: _cardBodyStyle,
@ -573,7 +657,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Text("Status", style: _cardheaderStyle),
Text("Status", style: _cardheaderStyle),
Text(
item['status'] ?? '-',
style: _cardBodyStyle,
@ -595,7 +679,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Received Date & Time", style: _cardheaderStyle),
Text("Received Date & Time", style: _cardheaderStyle),
Text(
_formatDate(item['created_on']) ?? '-',
style: _cardBodyStyle,
@ -608,7 +692,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Remarks", style: _cardheaderStyle),
Text("Remarks", style: _cardheaderStyle),
Text(
item['remarks'] ?? '-',
style: _cardBodyStyle,
@ -625,30 +709,34 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
);
}
static final _dataBold = TextStyle(
static final _dataBold = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static const _headerStyle = TextStyle(
// static const _headerStyle = GoogleFonts.inter(
// color: Colors.black,
// fontWeight: FontWeight.bold,
// );
static final _headerStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.bold,
);
static const _cardheaderStyle = TextStyle(
static final _cardheaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12,
);
static const _cardBodyStyle = TextStyle(
static final _cardBodyStyle = GoogleFonts.inter(
color: Color(0xFF545454),
fontWeight: FontWeight.w400,
fontSize: 12,

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import '../../../../core/routing/routes.dart';
@ -188,7 +189,7 @@ class claimListState extends ConsumerState<claimList> {
),
Text(
"Claims",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.w600,
),
@ -271,7 +272,7 @@ class claimListState extends ConsumerState<claimList> {
// },
// child: Text(
// 'Create New Staff',
// style: TextStyle(
// style: GoogleFonts.inter(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
@ -297,7 +298,7 @@ class claimListState extends ConsumerState<claimList> {
vertical: 12,
horizontal: 16,
),
child: const Row(
child: Row(
children: [
Expanded(
flex: 2,
@ -556,7 +557,7 @@ class claimListState extends ConsumerState<claimList> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
//company
const Text("Company", style: _cardheaderStyle),
Text("Company", style: _cardheaderStyle),
Text(
item['policy_end_date'] != null
? _formatDate(item['policy_end_date'])
@ -575,7 +576,7 @@ class claimListState extends ConsumerState<claimList> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
//status
const Text("Claim Type", style: _cardheaderStyle),
Text("Claim Type", style: _cardheaderStyle),
Text(
item['claim_type_value'] ?? '-',
style: _cardBodyStyle,
@ -598,7 +599,7 @@ class claimListState extends ConsumerState<claimList> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//date and time
const Text("policy Number", style: _cardheaderStyle),
Text("policy Number", style: _cardheaderStyle),
Text(item['policy_no'] ?? '-', style: _cardBodyStyle),
],
),
@ -609,7 +610,7 @@ class claimListState extends ConsumerState<claimList> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//remarks
const Text("Claim Number", style: _cardheaderStyle),
Text("Claim Number", style: _cardheaderStyle),
Text(
item['claim_number'] ?? '-',
style: _cardBodyStyle,
@ -626,31 +627,31 @@ class claimListState extends ConsumerState<claimList> {
);
}
static final _dataBold = TextStyle(
static final _dataBold = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static const _headerStyle = TextStyle(
static final _headerStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.bold,
);
static const _cardheaderStyle = TextStyle(
static final _cardheaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12,
);
static const _cardBodyStyle = TextStyle(
color: Color(0xFF545454),
static final _cardBodyStyle = GoogleFonts.inter(
color: const Color(0xFF545454),
fontWeight: FontWeight.w400,
fontSize: 12,
);

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import '../../../../core/routing/routes.dart';
@ -185,7 +186,7 @@ class endosementState extends ConsumerState<endosement> {
),
Text(
"Endorsement",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.w600,
),
@ -267,7 +268,7 @@ class endosementState extends ConsumerState<endosement> {
// },
// child: Text(
// 'Create New Staff',
// style: TextStyle(
// style: GoogleFonts.inter(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
@ -293,7 +294,7 @@ class endosementState extends ConsumerState<endosement> {
vertical: 12,
horizontal: 16,
),
child: const Row(
child: Row(
children: [
Expanded(
flex: 2,
@ -535,7 +536,7 @@ class endosementState extends ConsumerState<endosement> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
//company
const Text("Company", style: _cardheaderStyle),
Text("Company", style: _cardheaderStyle),
Text(
item['insurer_name'] ?? '-',
style: _cardBodyStyle,
@ -552,7 +553,7 @@ class endosementState extends ConsumerState<endosement> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
//status
const Text("Endorsement Type", style: _cardheaderStyle),
Text("Endorsement Type", style: _cardheaderStyle),
Text(
item['endorsement_type_value'] ?? '-',
style: _cardBodyStyle,
@ -575,7 +576,7 @@ class endosementState extends ConsumerState<endosement> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//date and time
const Text("policy Number", style: _cardheaderStyle),
Text("policy Number", style: _cardheaderStyle),
Text(
_formatDate(item['policy_number']) ?? '-',
style: _cardBodyStyle,
@ -589,7 +590,7 @@ class endosementState extends ConsumerState<endosement> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//remarks
const Text("Endorsement Number", style: _cardheaderStyle),
Text("Endorsement Number", style: _cardheaderStyle),
Text(
item['endorsement_no'] ?? '-',
style: _cardBodyStyle,
@ -606,31 +607,31 @@ class endosementState extends ConsumerState<endosement> {
);
}
static final _dataBold = TextStyle(
static final _dataBold = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static const _headerStyle = TextStyle(
static final _headerStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.bold,
);
static const _cardheaderStyle = TextStyle(
static final _cardheaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12,
);
static const _cardBodyStyle = TextStyle(
color: Color(0xFF545454),
static final _cardBodyStyle = GoogleFonts.inter(
color: const Color(0xFF545454),
fontWeight: FontWeight.w400,
fontSize: 12,
);

View File

@ -180,6 +180,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
? Expanded(
// take available space
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -236,12 +237,16 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
color: const Color(0xFF425B5B),
borderRadius: BorderRadius.circular(25),
),
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(6),
child: Row(
children: [
buildTab("Enquiries Pending", 0),
Expanded(
child: buildTab("Enquiries Pending", 0),
),
const SizedBox(width: 10),
buildTab("Quotation Pending", 1),
Expanded(
child: buildTab("Quotation Pending", 1),
),
],
),
),
@ -302,7 +307,10 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
),
),
)
: Expanded(
: Container(
height: MediaQuery.of(context).size.height * 0.8,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
if (role != 'staff')
@ -314,7 +322,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
today: policiesIssuedToday ?? '',
month: policiesIssuedMonth ?? '',
year: policiesIssuedYear ?? '',
imagePath: "assets/dashboard/Policy issue icon.png",
imagePath:
"assets/dashboard/Policy issue icon.png",
),
),
SizedBox(width: 16),
@ -340,7 +349,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
],
),
if (role == 'manager')
Expanded(
SizedBox(
// replace Expanded
height: 350, // adjust height as needed
child: Row(
children: [
Expanded(
@ -360,7 +371,13 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
),
),
const SizedBox(height: 10),
Expanded(
SizedBox(
// replace Expanded
height: (role == 'agent')
? MediaQuery.of(context).size.height *
0.69 //400
: MediaQuery.of(context).size.height *
0.5, // 350 adjust height as needed
child: Row(
children: [
Expanded(
@ -391,19 +408,123 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
data: policiesPendingList,
stringFlag: "Policies",
),
),
],
),
),
],
),
),
),
// Expanded(
// child:
// quotationsPendingList.isEmpty ? Center(child: Text("Loading quotations...")) :
// agentPendings(
// title: "Quotations Pending (${quotationsPendingList.length})",
// data: quotationsPendingList,
//
// SingleChildScrollView(
// scrollDirection: Axis.vertical,
// child: Column(
// children: [
// if (role != 'staff')
// Row(
// children: [
// Expanded(
// child: StatCard(
// title: "Policies Issued",
// today: policiesIssuedToday ?? '',
// month: policiesIssuedMonth ?? '',
// year: policiesIssuedYear ?? '',
// imagePath:
// "assets/dashboard/Policy issue icon.png",
// ),
// ),
// SizedBox(width: 16),
// Expanded(
// child: StatCard(
// title: "Premium Value",
// today: premiumValueToday ?? '',
// month: premiumValueMonth ?? '',
// year: premiumValueYear ?? '',
// imagePath: "assets/dashboard/Premium value.png",
// ),
// ),
// SizedBox(width: 16),
// Expanded(
// child: StatCard(
// title: "Earnings",
// today: earningsToday ?? '',
// month: earningsMonth ?? '',
// year: earningsYear ?? '',
// imagePath: "assets/dashboard/Earnings.png",
// ),
// ),
// ],
// ),
// if (role == 'manager')
// Expanded(
// child: Row(
// children: [
// Expanded(
// child: Performance(
// title: "Top Agent Performance",
// data: agentsPerformanceList,
// ),
// ),
// SizedBox(width: 16),
// Expanded(
// child: Performance(
// title: "Bottom Non-Performing Agents",
// data: nonAgentsPerformanceList,
// ),
// ),
// ],
// ),
// ),
// const SizedBox(height: 10),
// Expanded(
// child: Row(
// children: [
// Expanded(
// child: (role == 'agent')
// ? agentPendings(
// title:
// "Enquiries Pending (${policiesPendingList.length})",
// data: policiesPendingList,
// )
// : othersPendings(
// title:
// "Quotations Pending (${quotationsPendingList.length})",
// data: quotationsPendingList,
// stringFlag: "Quotation",
// ),
// ),
// const SizedBox(width: 16),
// Expanded(
// child: (role == 'agent')
// ? agentPendings(
// title:
// "Quotations Pending (${quotationsPendingList.length})",
// data: quotationsPendingList,
// )
// : othersPendings(
// title:
// "Policies Pending (${policiesPendingList.length})",
// data: policiesPendingList,
// stringFlag: "Policies",
// ),
// // child:
// // quotationsPendingList.isEmpty ? Center(child: Text("Loading quotations...")) :
// // agentPendings(
// // title: "Quotations Pending (${quotationsPendingList.length})",
// // data: quotationsPendingList,
// // ),
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
),
],
),
),
],
),
),
);
}
@ -422,23 +543,23 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
},
child: SizedBox(
child: Container(
padding: EdgeInsets.only(
top: 9.0,
bottom: 9.0,
left: 20.0,
right: 20.0,
),
padding: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
decoration: BoxDecoration(
color: isSelected ? const Color(0xFFFFFFFF) : Colors.transparent,
borderRadius: BorderRadius.circular(16),
),
child: Center(
child: Text(
title,
style: GoogleFonts.poppins(
fontSize: 12,
color: isSelected ? Colors.black : Colors.white,
fontWeight: FontWeight.w500,
),
maxLines: 2,
softWrap: true,
),
),
),
),
@ -483,7 +604,7 @@ class StatCard extends StatelessWidget {
title,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
color: Color(0xFF425B5B),
),
),
@ -533,21 +654,21 @@ class StatCard extends StatelessWidget {
child: Text(
"Today",
textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12),
style: topHeaderStyle,
),
),
Expanded(
child: Text(
"This Month",
textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12),
style: topHeaderStyle,
),
),
Expanded(
child: Text(
"This Year",
textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12),
style: topHeaderStyle,
),
),
],
@ -731,19 +852,12 @@ class agentPendings extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(
title,
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
Text(title, style: _title),
const SizedBox(height: 10),
// Header row
Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration(
color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10),
@ -754,33 +868,21 @@ class agentPendings extends StatelessWidget {
child: Text(
"Date & Time",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
child: Text(
"Registration number",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
child: Text(
"Insurer Company",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
],
@ -827,20 +929,8 @@ class agentPendings extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
date,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
Text(
time,
style: GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w400,
),
),
Text(date, style: _tableDataStyle),
Text(time, style: _tableDataStyle),
],
),
),
@ -850,10 +940,7 @@ class agentPendings extends StatelessWidget {
child: Text(
row['reg_no'] ?? "",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
@ -862,10 +949,7 @@ class agentPendings extends StatelessWidget {
child: Text(
row['insurer_name'] ?? "",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
],
@ -907,19 +991,12 @@ class othersPendings extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(
title,
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
Text(title, style: _title),
const SizedBox(height: 10),
// Header row
Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration(
color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10),
@ -927,48 +1004,36 @@ class othersPendings extends StatelessWidget {
child: Row(
children: [
Expanded(
flex: 1,
child: Text(
"S.No",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
"Staff Name",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
stringFlag + " Issued",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
(stringFlag == "Policies")
? Expanded(
flex: 2,
child: Text(
"Total Premium Value",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
)
: const SizedBox.shrink(),
@ -1005,43 +1070,38 @@ class othersPendings extends StatelessWidget {
child: Row(
children: [
Expanded(
flex: 1,
child: Text(
(index + 1).toString(),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
row['staff_name'] ?? "",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
issuedCount,
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
stringFlag == "Policies"
? Expanded(
flex: 2,
child: Text(
formatToCroresLakhsAndThousands(permiumValue),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
@ -1079,19 +1139,12 @@ class Performance extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(
title,
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
Text(title, style: _title),
const SizedBox(height: 10),
// Header row
Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration(
color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10),
@ -1102,33 +1155,21 @@ class Performance extends StatelessWidget {
child: Text(
"S.No",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
child: Text(
"Agent Name",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
child: Text(
"Policies Issued",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
Expanded(
@ -1137,11 +1178,7 @@ class Performance extends StatelessWidget {
? "Premium Value"
: "Status",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
style: _headerStyle,
),
),
],
@ -1157,6 +1194,7 @@ class Performance extends StatelessWidget {
final row = data[index];
return Container(
// height: 5200,
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
vertical: 5,
@ -1172,10 +1210,7 @@ class Performance extends StatelessWidget {
child: Text(
(index + 1).toString(), // convert int to string
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
@ -1183,10 +1218,7 @@ class Performance extends StatelessWidget {
child: Text(
row['agent_name'] ?? "",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
@ -1194,10 +1226,7 @@ class Performance extends StatelessWidget {
child: Text(
row['total_policy_issued'] ?? "",
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
style: _tableDataStyle,
),
),
@ -1210,7 +1239,7 @@ class Performance extends StatelessWidget {
: (row['status']?.toString() ?? ""),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
fontSize: 14,
fontWeight: FontWeight.w500,
color: title == "Top Agent Performance"
? Colors.black
@ -1233,3 +1262,27 @@ class Performance extends StatelessWidget {
);
}
}
final _headerStyle = GoogleFonts.inter(
fontWeight: FontWeight.w600,
fontSize: 14,
color: Colors.white,
);
final _title = GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 16,
// color: Colors.red,
color: const Color(0xff425B5B),
);
final _tableDataStyle = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
);
final topHeaderStyle = GoogleFonts.inter(
fontSize: 12,
color: Colors.black,
fontWeight: FontWeight.w500,
);

View File

@ -2,6 +2,8 @@ import 'dart:convert';
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
@ -46,6 +48,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
bool enteredEmailOrMobile = false;
dynamic clickedButtonName;
dynamic token;
dynamic fCMToken;
// Future<void> _handleLogin() async {
// if (!_formKey.currentState!.validate()) return;
@ -104,6 +107,20 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
_countryController.text = "+91";
}
Future<void> initNotification() async {
try {
// await _firebaseMessaging.requestPermission();
fCMToken = await FirebaseMessaging.instance.getToken();
print('Token : $fCMToken');
if (fCMToken != null) {
// await sendDeviceToken(fCMToken);
}
} catch (e) {
print("Error getting FCM Token: $e");
}
}
Future<void> _saveUserRole(String token) async {
final prefs = await SharedPreferences.getInstance();
final decodedToken = Jwt.parseJwt(token);
@ -747,41 +764,41 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 30),
const SizedBox(height: 15),
Image.asset(
"assets/login/nhance-partner-logo.png",
height: 45,
height: 35,
),
const SizedBox(height: 30),
const SizedBox(height: 10),
Text(
"Welcome Back",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 24,
fontWeight: FontWeight.w600,
color: Color(0xFF425C5C),
),
),
const SizedBox(height: 20),
Image.asset("assets/login/login-content.png", height: 180),
const SizedBox(height: 10),
Image.asset("assets/login/login-content.png", height: 120),
// const SizedBox(height: 10),
Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 50),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 50),
child: Text(
'${'"'}Manage vsdv your policies, track quotations, and grow your business all in one place.${'"'}',
'${'"'}Manage your policies, track quotations, and grow your business all in one place.${'"'}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 11,
fontSize: 14,
color: Color(0xFF000000),
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(height: 20),
const SizedBox(height: 10),
Container(
width: double.infinity,
height: MediaQuery.of(
context,
).size.height, // full screen height
height:
MediaQuery.of(context).size.height *
0.8, // full screen height
padding: const EdgeInsets.all(20),
decoration: const BoxDecoration(
gradient: LinearGradient(
@ -816,7 +833,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
Text(
"Login to your account",
style: TextStyle(
fontSize: ResponsiveLayout.isMobile(context) ? 28 : 35,
fontSize: ResponsiveLayout.isMobile(context) ? 20 : 35,
fontWeight: FontWeight.w600,
color: Colors.white,
),
@ -826,7 +843,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
"Enter your email or mobile number to receive a one time password.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: ResponsiveLayout.isMobile(context) ? 14 : 18,
fontSize: ResponsiveLayout.isMobile(context) ? 12 : 18,
color: Colors.white,
fontWeight: FontWeight.w600,
),
@ -1129,6 +1146,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: Center(
child: Text(
'OTP',
style: TextStyle(
@ -1140,8 +1158,10 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
),
),
),
),
const SizedBox(height: 10),
Container(
alignment: Alignment.center,
child: Pinput(
length: 6,
defaultPinTheme: defaultPinTheme,
@ -1191,7 +1211,61 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
),
),
const SizedBox(height: 20),
SizedBox(
Container(
alignment: Alignment.center, // center the text
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'Didnt Receive Code? ', // normal text
style: TextStyle(
fontSize: ResponsiveLayout.isMobile(context)
? 12
: 14,
fontWeight: FontWeight.normal,
color: Colors.white,
),
children: [
TextSpan(
text: 'Resend', // bold clickable part
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
decoration: TextDecoration
.underline, // optional
),
recognizer: TapGestureRecognizer()
..onTap = () {
print('Resend clicked');
print(enteredEmailOrMobile);
print(clickedButtonName);
if (_PhoneNumberController
.text
.isNotEmpty) {
print('1224');
_resendCode(
_PhoneNumberController.text,
_resendToken,
);
} else if (_PhoneNumberController
.text
.isEmpty) {
print('1227');
sendMobileOrEmailVerify(
clickedButtonName,
);
} else {
print('data not found');
}
},
),
],
),
),
),
const SizedBox(height: 20),
Center(
child: SizedBox(
width: 400,
child: CommonButton(
text: "Continue",
@ -1235,6 +1309,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
// ),
// ),
),
),
],
)
: const SizedBox.shrink(), // Empty widget when false
@ -1258,12 +1333,16 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
_PhoneNumberController.text = '';
_emailController.text = '';
_otpController.text = '';
_PhoneNumberController.clear();
_emailController.clear();
_otpController.clear();
if (selectedIndex == 2) {
switcherStatus = 0;
} else {
switcherStatus = 1;
}
});
_formKey.currentState?.reset();
},
child: Container(
padding: EdgeInsets.only(

View File

@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/config/env.dart';
import '../../../../core/routing/routes.dart';
@ -236,9 +237,23 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
onTap: () async {
Navigator.pop(context);
final prefs = await SharedPreferences.getInstance();
// Remove old value (if any)
await prefs.remove('enqStaffDataId');
// Save the new id
await prefs.setString('enqStaffDataId', id.toString());
// Read it back if needed
// final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId');
// Update provider too
// ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId;
ref.read(quotationStaffIdProvider.notifier).state = id;
context.go(AppRoutes.quotation);
},
hoverColor: Color(0xFFE3F1F0),
@ -271,8 +286,19 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
onTap: () async {
Navigator.pop(context);
final prefs = await SharedPreferences.getInstance();
// Remove old value (if any)
await prefs.remove('enqStaffDataId');
// Save the new id
await prefs.setString('enqStaffDataId', id.toString());
// Update provider too
ref.read(quotationStaffIdProvider.notifier).state = id;
context.go(AppRoutes.policy);
},
@ -372,13 +398,14 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Spacer(),
ExportBtn(
sheetName: "Policy",
fileName: "Policy_list",
sheetName: "Enquiry",
fileName: "Enquiry_list",
data: filteredData,
txt: !ResponsiveLayout.isMobile(context)
? true
: false,
headers: [
"updated_on",
"reg_no",
"agent_name",
"assigned_to_name",
@ -386,7 +413,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
"insured_name",
"premium_amount",
"payment_mode",
"updated_on",
"policy_number",
"status",
],
),
@ -446,7 +473,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: const Row(
children: [
Expanded(
flex: 2,
flex: 3,
child: Text('Date', style: _headerStyle),
),
@ -467,7 +494,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: Text('Insurer', style: _headerStyle),
),
Expanded(
flex: 2,
flex: 3,
child: Text('Insured Name', style: _headerStyle),
),
Expanded(
@ -579,7 +606,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: Row(
children: [
Expanded(
flex: 2,
flex: 3,
child: Text(
_formatDate(item['updated_on']) ?? '-',
style: _dataBold,
@ -613,7 +640,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
),
),
Expanded(
flex: 2,
flex: 3,
child: Text(
item['insured_name'] ?? '-',
style: _dataBold,

View File

@ -1,4 +1,5 @@
// import 'dart:io' as html;
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.dart';
@ -7,6 +8,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/config/env.dart';
import '../../../../core/routing/routes.dart';
@ -149,6 +151,10 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
// getQuotationList(managerId);
// });
if (kIsWeb) {
Future.microtask(() => _restoreManagerId(ref));
}
Future.microtask(() {
managerId = ref.read(managerIdProvider); // use read
userId = ref.read(userIdProvider); // use read
@ -162,6 +168,20 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
});
}
Future<void> _restoreManagerId(WidgetRef ref) async {
final prefs = await SharedPreferences.getInstance();
final String? savedId = prefs.getString(
'enqStaffDataId',
); // already a string
if (savedId != null) {
ref.read(quotationStaffIdProvider.notifier).state = savedId;
print("savedenqStaffDataId ID restored: $savedId");
_loadData(savedId);
}
}
@override
void dispose() {
// Dispose all TextEditingControllers
@ -510,7 +530,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
width: MediaQuery.of(context).size.width,
child: GestureDetector(
onTap: () {
context.go(AppRoutes.policylist);
context.go(AppRoutes.enquiryForStaff);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
@ -1215,12 +1235,13 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Widget buildUploadPolicyPdf(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('Upload Policy PDF * ', style: _textStyle),
const SizedBox(height: 10),
Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ThemedUploadField(
hintText: selectedPDFFileNames ?? "Upload Document",
@ -1241,6 +1262,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Container(
// color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
@ -1313,6 +1335,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Container(
// color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/screens/staff/assignStaff.dart';
@ -312,7 +313,7 @@ class policylistState extends ConsumerState<policylist> {
),
Text(
"Policy",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.w600,
),
@ -398,7 +399,7 @@ class policylistState extends ConsumerState<policylist> {
// },
// child: Text(
// 'Create New Staff',
// style: TextStyle(
// style: GoogleFonts.inter(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
@ -424,10 +425,10 @@ class policylistState extends ConsumerState<policylist> {
vertical: 12,
horizontal: 16,
),
child: const Row(
child: Row(
children: [
Expanded(
flex: 2,
flex: 3,
child: Text('Date', style: _headerStyle),
),
Expanded(
@ -559,7 +560,7 @@ class policylistState extends ConsumerState<policylist> {
child: Row(
children: [
Expanded(
flex: 2,
flex: 3,
child: Text(
_formatDate(item['updated_on']) ?? '-',
style: _dataBold,
@ -726,7 +727,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Company", style: _cardheaderStyle),
Text("Company", style: _cardheaderStyle),
Text(item['insurer_name'] ?? '-', style: _cardBodyStyle),
],
),
@ -736,7 +737,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Status", style: _cardheaderStyle),
Text("Status", style: _cardheaderStyle),
Text(item['status'] ?? '-', style: _cardBodyStyle),
],
),
@ -752,7 +753,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Agent", style: _cardheaderStyle),
Text("Agent", style: _cardheaderStyle),
Text(item['agent_name'] ?? '-', style: _cardBodyStyle),
],
),
@ -762,7 +763,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Assigned To", style: _cardheaderStyle),
Text("Assigned To", style: _cardheaderStyle),
Text(
item['assigned_to_name'] ?? '-',
style: _cardBodyStyle,
@ -781,7 +782,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Insured Name", style: _cardheaderStyle),
Text("Insured Name", style: _cardheaderStyle),
Text(item['insured_name'] ?? '-', style: _cardBodyStyle),
],
),
@ -791,7 +792,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Premium", style: _cardheaderStyle),
Text("Premium", style: _cardheaderStyle),
Text(item['premium_amount'] ?? '-', style: _cardBodyStyle),
],
),
@ -807,7 +808,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Payment Mode", style: _cardheaderStyle),
Text("Payment Mode", style: _cardheaderStyle),
Text(item['payment_mode'] ?? '-', style: _cardBodyStyle),
],
),
@ -817,7 +818,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Policy Number", style: _cardheaderStyle),
Text("Policy Number", style: _cardheaderStyle),
Text(item['policy_number'] ?? '-', style: _cardBodyStyle),
],
),
@ -833,7 +834,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Date", style: _cardheaderStyle),
Text("Date", style: _cardheaderStyle),
Text(
_formatDate(item['updated_on']) ?? '-',
style: _cardBodyStyle,
@ -846,7 +847,7 @@ class policylistState extends ConsumerState<policylist> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Remarks", style: _cardheaderStyle),
Text("Remarks", style: _cardheaderStyle),
Text(
item['remarks'] ?? '-',
style: _cardBodyStyle,
@ -862,31 +863,31 @@ class policylistState extends ConsumerState<policylist> {
);
}
static final _dataBold = TextStyle(
static final _dataBold = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static const _headerStyle = TextStyle(
static final _headerStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.bold,
);
static const _cardheaderStyle = TextStyle(
static final _cardheaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12,
);
static const _cardBodyStyle = TextStyle(
color: Color(0xFF545454),
static final _cardBodyStyle = GoogleFonts.inter(
color: const Color(0xFF545454),
fontWeight: FontWeight.w400,
fontSize: 12,
);

View File

@ -3,10 +3,12 @@ import 'dart:io' as html;
import 'package:dropdown_search/dropdown_search.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
@ -32,6 +34,8 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
int currentPage = 0;
int itemsPerPage = 10;
bool blockKey = false;
List<Map<String, dynamic>> dataVal = [];
final TextEditingController _searchController = TextEditingController();
@ -94,11 +98,29 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
List<Map<String, dynamic>> filteredData = [];
// bool isLoading = false;
Future<void> _restoreManagerId(WidgetRef ref) async {
final prefs = await SharedPreferences.getInstance();
final String? savedId = prefs.getString(
'enqStaffDataId',
); // already a string
if (savedId != null) {
ref.read(quotationStaffIdProvider.notifier).state = savedId;
print("savedenqStaffDataId ID restored: $savedId");
_loadData(savedId);
}
}
@override
void initState() {
super.initState();
apiService = ApiService();
if (kIsWeb) {
Future.microtask(() => _restoreManagerId(ref));
}
for (String field in tabHeader) {
controllers[field] = TextEditingController();
}
@ -137,7 +159,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
selectedEnquiryId = enquiryData['id'];
print('selectedEnquiryId- $selectedEnquiryId');
controllers["regNum"]?.text = enquiryData['reg_no'];
controllers["insurer"]?.text = enquiryData['insurer_id'];
controllers["insurer"]?.text = enquiryData['insurer_name'];
});
}
@ -171,6 +193,9 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
);
originalData = getQuotationData;
filteredData = List.from(originalData);
blockKey = getQuotationData.any((item) => item['status'] == 'Accepted');
print('blockKey- $blockKey');
// print('originalData - $getClaimPolicies');
});
} else {
@ -188,12 +213,12 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
Color _getStatusColor(String? status) {
switch (status) {
case 'Pending':
return Colors.yellow;
case 'Accepted':
return Colors.green;
case 'Rejected':
return Colors.red;
case 'Pending':
return Colors.yellow;
default:
return Colors.grey;
}
@ -261,7 +286,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
width: MediaQuery.of(context).size.width,
child: GestureDetector(
onTap: () {
context.go(AppRoutes.policylist);
context.go(AppRoutes.enquiryForStaff);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
@ -274,7 +299,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
),
Text(
"Quotation",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 18,
fontWeight: FontWeight.w600,
),
@ -360,6 +385,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
],
const SizedBox(height: 20),
if(!blockKey)...[
Container(
padding: EdgeInsets.only(right: 10),
child: Row(
@ -368,6 +394,10 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
GestureDetector(
onTap: () {
// print('Export');
setState(() {
selectedQuotationFrmListId = null;
selectedQuotationFrmListData = null;
});
showDialog(
context: context,
@ -420,7 +450,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
),
),
const SizedBox(height: 20),
const SizedBox(height: 20),],
//3RD SECTION (TABLE)
Container(
@ -503,11 +533,11 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
Text(
"Download RC",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w200,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
@ -546,9 +576,9 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
children: [
Text(
"Download ID Proof",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w200,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
@ -583,9 +613,9 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
children: [
Text(
"Download Previous Policy",
style: TextStyle(
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.w200,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
@ -719,7 +749,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
child: const Row(
child: Row(
children: [
// Expanded(flex: 3, child: Text(' ', style: _headerStyle)),
Expanded(
@ -779,7 +809,11 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
flex: 2,
child: Text(
item['status'] ?? '-',
style: _dataBold.copyWith(color: _getStatusColor(item['status'])),
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: _getStatusColor(item['status']),
),
),
),
@ -905,7 +939,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
children: [
TextSpan(
text: 'Status : ', // key
style: TextStyle(
style: GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 11,
@ -913,7 +947,7 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
),
TextSpan(
text: '${item['status'] ?? '-'}', // value
style: TextStyle(
style: GoogleFonts.inter(
color: _getStatusColor(item['status']),
fontWeight: FontWeight.w600,
fontSize: 11,
@ -937,49 +971,49 @@ class QuotationScreenState extends ConsumerState<QuotationScreen> {
);
}
static final _dataBold = TextStyle(
static final _dataBold = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _dataSub = TextStyle(
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static const _headerStyle = TextStyle(
static final _headerStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.bold,
);
static const _textStyle = TextStyle(
static final _textStyle = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w600,
);
static const _cardheaderStyle = TextStyle(
static final _cardheaderStyle = GoogleFonts.inter(
color: Colors.black,
fontWeight: FontWeight.w600,
fontSize: 12,
);
static const _cardBodyStyle = TextStyle(
static final _cardBodyStyle = GoogleFonts.inter(
color: Color(0xFF545454),
fontWeight: FontWeight.w400,
fontSize: 12,
);
static const _cardRow1BodyStyle = TextStyle(
static final _cardRow1BodyStyle = GoogleFonts.inter(
// color: Color(0xFF545454),
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 12,
);
static const _cardRow2BodyStyle = TextStyle(
color: Color(0xFF545454),
static final _cardRow2BodyStyle = GoogleFonts.inter(
color: const Color(0xFF545454),
// color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 12,

View File

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io';
import 'package:excel/excel.dart';
import 'package:flutter/material.dart';
@ -62,7 +63,12 @@ class ExportBtn extends HookWidget {
)
: null,
?txt! ? SizedBox(width: 20) : null,
Icon(Icons.input_sharp, color: Colors.white),
Image.asset(
"assets/miscellaneous/export.png",
height: 25,
width: 25,
),
// Icon(Icons.input_sharp, color: Colors.white),
// Image.asset("assets/miscellaneous/export", height: 15, width: 15),
],
),
@ -71,6 +77,8 @@ class ExportBtn extends HookWidget {
}
}
class ExcelExporter {
static Future<void> exportToExcel({
required String sheetName,
@ -79,14 +87,16 @@ class ExcelExporter {
required String fileName,
}) async {
try {
// Create Excel and delete default sheet
// Create Excel
var excel = Excel.createExcel();
// Rename default sheet
if (excel.sheets.containsKey('Sheet1')) {
excel.delete('Sheet1');
excel.rename('Sheet1', sheetName);
}
// Create your sheet
Sheet sheetObject = excel[sheetName]; // now this is the only sheet
// Get the sheet
Sheet sheetObject = excel[sheetName]!;
// Add headers
sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
@ -112,13 +122,12 @@ class ExcelExporter {
var bytes = excel.encode()!;
if (kIsWeb) {
// Web: download
final blob = html.Blob([bytes]);
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor = html.AnchorElement(href: url)
// Web: base64 download instead of Blob
final base64Str = base64Encode(bytes);
final dataUri = "data:application/octet-stream;base64,$base64Str";
final anchor = html.AnchorElement(href: dataUri)
..setAttribute("download", "$fileName.xlsx")
..click();
html.Url.revokeObjectUrl(url);
} else {
// Mobile/Desktop: save file
final dir = await getApplicationDocumentsDirectory();
@ -132,6 +141,71 @@ class ExcelExporter {
}
}
// class ExcelExporter {
// static Future<void> exportToExcel({
// required String sheetName,
// required List<Map<String, dynamic>> data,
// required List<String> headers,
// required String fileName,
// }) async {
// try {
// // Create Excel and delete default sheet
// var excel = Excel.createExcel();
// if (excel.sheets.containsKey('Sheet1')) {
// excel.delete('Sheet1');
// }
//
// // Create your sheet
// Sheet sheetObject = excel[sheetName]; // now this is the only sheet
//
// // Add headers
// sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
//
// // Add data
// for (var rowData in data) {
// var row = <CellValue?>[];
// for (var key in headers) {
// final value = rowData[key];
// if (value == null) {
// row.add(TextCellValue('-'));
// } else if (value is int) {
// row.add(IntCellValue(value));
// } else if (value is double) {
// row.add(DoubleCellValue(value));
// } else {
// row.add(TextCellValue(value.toString()));
// }
// }
// sheetObject.appendRow(row);
// }
//
// var bytes = excel.encode()!;
//
// if (kIsWeb) {
// // Web: download
// final blob = html.Blob([bytes]);
// final url = html.Url.createObjectUrlFromBlob(blob);
// final anchor = html.AnchorElement(href: url)
// ..setAttribute("download", "$fileName.xlsx")
// ..click();
// html.Url.revokeObjectUrl(url);
// } else {
// // Mobile/Desktop: save file
// final dir = await getApplicationDocumentsDirectory();
// final file = File('${dir.path}/$fileName.xlsx');
// await file.writeAsBytes(bytes);
// await OpenFile.open(file.path);
// }
// } catch (e) {
// print("Error exporting Excel: $e");
// }
// }
// }
//---------------------------------------------------------------------------
// class ExcelExporter {
// static Future<void> exportToExcel({
// required String sheetName,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:google_fonts/google_fonts.dart';
// import 'package:uae_stat/config/my_theme.dart';
@ -103,7 +104,13 @@ class ThemedFormField extends HookWidget {
// dynamic hint color
color: const Color(0xFFC3C6CB),
),
labelStyle: TextStyle(fontSize: 12),
// labelText: hintText,
// labelStyle: GoogleFonts.inter(
// fontSize: 10,
// // color: Colors.black, // customize here
// color: Colors.red, // customize here
// fontWeight: FontWeight.w400,
// ),
prefixIconConstraints: const BoxConstraints(
maxWidth: 25 + 16 + 10,
maxHeight: 25 + (8 * 2),
@ -139,6 +146,11 @@ class ThemedFormField extends HookWidget {
// allow multiline if user sets maxLines / minLines
minLines: (keyboardType == TextInputType.multiline) ? 3 : 1,
maxLines: (keyboardType == TextInputType.multiline) ? null : 1,
style: GoogleFonts.inter(
fontSize: 14, // 👈 Change this to your desired size
fontWeight: FontWeight.w400, // optional
color: Colors.black, // optional
),
),
),
);

View File

@ -219,29 +219,6 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
),
DrawerLabel("Dashboard"),
Builder(
builder: (itemContext) {
return MouseRegion(
// onEnter: (_) => _showPopup(itemContext),
onEnter: (_) {
final renderBox = itemContext.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
final key = "Reports";
_showPopup(context, offset, size, key);
},
child: DrawerContentWrapper(
child: Image.asset(
"assets/drawer/drawerImg2.png",
height: 25,
width: 25,
),
),
);
},
),
DrawerLabel("Reports"),
DrawerContentWrapper(
child: Consumer(
builder: (context, ref, _) {
@ -290,6 +267,30 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
),
DrawerLabel("User"),
],
Builder(
builder: (itemContext) {
return MouseRegion(
// onEnter: (_) => _showPopup(itemContext),
onEnter: (_) {
final renderBox = itemContext.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
final key = "Reports";
_showPopup(context, offset, size, key);
},
child: DrawerContentWrapper(
child: Image.asset(
"assets/drawer/drawerImg2.png",
height: 25,
width: 25,
),
),
);
},
),
DrawerLabel("Reports"),
],
),
);

View File

@ -100,7 +100,13 @@ class _MobileBottomMenuState extends ConsumerState<MobileBottomMenu> {
},
items: [
BottomNavigationBarItem(
icon: Image.asset(
icon: _currentIndex == 0
? Image.asset(
"assets/drawer/drawerImg1_light.png",
height: 20,
width: 20,
)
: Image.asset(
"assets/drawer/drawerImg1.png",
height: 20,
width: 20,
@ -108,20 +114,34 @@ class _MobileBottomMenuState extends ConsumerState<MobileBottomMenu> {
label: "Dashboard",
),
BottomNavigationBarItem(
icon: Image.asset(
icon: _currentIndex == 1
? Image.asset(
"assets/drawer/drawerImg2_light.png",
height: 20,
width: 20,
)
: Image.asset(
"assets/drawer/drawerImg2.png",
height: 20,
width: 20,
),
label: "Reports",
),
const BottomNavigationBarItem(
icon: Icon(Icons.list_alt_rounded, size: 24, color: Colors.black),
BottomNavigationBarItem(
icon: Icon(
Icons.list_alt_rounded,
size: 24,
color: _currentIndex == 2 ? Colors.white : Colors.black,
),
label: "Enquiry",
),
const BottomNavigationBarItem(
icon: Icon(Icons.person_add_alt, size: 24, color: Colors.black),
BottomNavigationBarItem(
icon: Icon(
Icons.person_add_alt,
size: 24,
color: _currentIndex == 3 ? Colors.white : Colors.black,
),
label: "User",
),
],

View File

@ -39,6 +39,14 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
width: 120,
),
if (isMobile) ...[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"assets/login/nhance-partner-logo.png",
height: 40,
width: 90,
),
),
// IconButton(
// icon: const Icon(
// Icons.arrow_back_ios,
@ -47,17 +55,17 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
// ),
// onPressed: onBack ?? () => Navigator.pop(context),
// ),
SizedBox(width: 5),
Expanded(
child: Text(
title,
style: const TextStyle(
color: Colors.black87,
fontWeight: FontWeight.w500,
fontSize: 16,
),
),
),
// SizedBox(width: 5),
// Expanded(
// child: Text(
// title,
// style: const TextStyle(
// color: Colors.black87,
// fontWeight: FontWeight.w500,
// fontSize: 16,
// ),
// ),
// ),
],
Spacer(),
@ -98,6 +106,7 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
// icon: const Icon(Icons.person_outline, color: Colors.black87),
// onPressed: onProfile,
// ),
],
SizedBox(width: 10),
Container(
width: 40,
@ -111,7 +120,7 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
onPressed: onLogout,
),
),
],
],
),
);

BIN
lib_29_sep.zip Normal file

Binary file not shown.