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) { if (_token == null) {
await _initializeToken(); 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 = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',

View File

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

View File

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

View File

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

View File

@ -105,7 +105,17 @@ class PolicyTabState extends ConsumerState<PolicyTab> {
// final response = await apiService.fetchQuotationList(managerId); // final response = await apiService.fetchQuotationList(managerId);
if (widget.data != null) { 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}'); print('policyListData - ${widget.data}');
setState(() { setState(() {

View File

@ -6,6 +6,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:nhance_partner/presentation/screens/Enquiry/enquiry/tabs.dart';
import '../../../../core/config/env.dart'; import '../../../../core/config/env.dart';
import '../../../../core/services/api_service.dart'; import '../../../../core/services/api_service.dart';
import '../../../../data/services/auth_service.dart'; import '../../../../data/services/auth_service.dart';
@ -23,7 +24,8 @@ class QuotationTab extends ConsumerStatefulWidget {
// final Map<String, dynamic>? data; // final Map<String, dynamic>? data;
final List<Map<String, dynamic>>? data; final List<Map<String, dynamic>>? data;
String? id; String? id;
QuotationTab({super.key, this.data, this.id}); final Future<void> Function()? onRefresh;
QuotationTab({super.key, this.data, this.id, this.onRefresh});
@override @override
ConsumerState<QuotationTab> createState() => QuotationTabState(); ConsumerState<QuotationTab> createState() => QuotationTabState();
} }
@ -41,6 +43,11 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey = final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<TabEnquiryListState> tabKey =
GlobalKey<TabEnquiryListState>();
bool blockKey = false;
List<String> tabHeader = [ List<String> tabHeader = [
'regNum', 'regNum',
'insurer', 'insurer',
@ -110,7 +117,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
managerId = ref.watch(managerIdProvider); managerId = ref.watch(managerIdProvider);
userId = ref.watch(userIdProvider); userId = ref.watch(userIdProvider);
getQuotationList(managerId); getQuotationList();
}); });
} }
@ -120,7 +127,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
} }
void refresh() { void refresh() {
getQuotationList(managerId); getQuotationList();
} }
@override @override
@ -132,8 +139,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
super.dispose(); super.dispose();
} }
Future<void> getQuotationList(managerId) async { Future<void> getQuotationList() async {
print('getClaimList called MagId - $managerId'); print('getClaimList called MagId - ');
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
@ -143,38 +150,48 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
if (widget.data != null && widget.id != null) { if (widget.data != null && widget.id != null) {
final data = List<Map<String, dynamic>>.from(widget.data as Iterable); 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}'); // print('quoationListData - ${widget.data}');
// setState(() { setState(() {
// getQuotationData = data; getQuotationData = data;
// // getQuotationData = List<Map<String, dynamic>>.from(response['data']); // getQuotationData = List<Map<String, dynamic>>.from(response['data']);
// originalData = getQuotationData; originalData = getQuotationData;
// filteredData = List.from(originalData); filteredData = List.from(originalData);
// // print('originalData - $getClaimPolicies'); print('quoationListData - $getQuotationData');
// });
if (response['status'] == 'success') { blockKey = getQuotationData.any((item) => item['status'] == 'Accepted');
final rawData = response['data']; print('blockKey- $blockKey');
print('quoationListData1 - ${response['data']}');
setState(() {
if (rawData is List) { // blockKey = getQuotationData.any(
// already a list // (item) => (item['status']?.toString().toLowerCase() ?? '') == 'approved',
getQuotationData = List<Map<String, dynamic>>.from(rawData); // );
} else if (rawData is Map) {
// single object, wrap into a list // print('originalData - $getClaimPolicies');
getQuotationData = [Map<String, dynamic>.from(rawData)]; });
} else {
getQuotationData = []; // if (response['status'] == 'success') {
} // final rawData = response['data'];
// getQuotationData = List<Map<String, dynamic>>.from(response['data']); // print('quoationListData1 - ${response['data']}');
originalData = getQuotationData; // setState(() {
filteredData = List.from(originalData); // if (rawData is List) {
// print('originalData - $getClaimPolicies'); // // already a list
}); // getQuotationData = List<Map<String, dynamic>>.from(rawData);
} else { // } else if (rawData is Map) {
getQuotationData = []; // // single object, wrap into a list
originalData = []; // 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 = [];
// }
} }
} catch (e) { } catch (e) {
print('Exception occurred: $e'); print('Exception occurred: $e');
@ -263,7 +280,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
// data['id'] = selectedId; // Add plan_id for update // data['id'] = selectedId; // Add plan_id for update
// data['status'] = val; // data['status'] = val;
print("data------- $data}"); print("data------- $data");
try { try {
final response = await http.post( final response = await http.post(
@ -280,11 +297,21 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
print("Response: ${response.body}"); print("Response: ${response.body}");
ToastHelper.showSuccessToast(context, 'Status Updated'); ToastHelper.showSuccessToast(context, 'Status Updated');
print("tre1");
selectedId = null; // just update field selectedId = null; // just update field
isquotation = false; 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); // context.go(AppRoutes.staffLst);
} else { } else {
final responseBody = jsonDecode(response.body); final responseBody = jsonDecode(response.body);
@ -368,6 +395,10 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
ToastHelper.showSuccessToast(context, 'Document Uploaded'); ToastHelper.showSuccessToast(context, 'Document Uploaded');
print("Response: ${response.body}"); print("Response: ${response.body}");
if (widget.onRefresh != null) {
await widget.onRefresh!();
}
// context.go(AppRoutes.agentLst); // context.go(AppRoutes.agentLst);
} else { } else {
final responseBody = jsonDecode(response.body); final responseBody = jsonDecode(response.body);
@ -383,6 +414,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
Color _getStatusColor(String? status) { Color _getStatusColor(String? status) {
switch (status) { switch (status) {
case 'Pending':
return Colors.yellow;
case 'Accepted': case 'Accepted':
return Colors.green; return Colors.green;
case 'Rejected': case 'Rejected':
@ -443,7 +476,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
const SizedBox(height: 20), const SizedBox(height: 20),
if (showAction) if (!blockKey)
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
@ -976,7 +1009,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w400, 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/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/routing/routes.dart'; import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart'; import '../../../../core/services/api_service.dart';
@ -26,11 +28,16 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
bool isLoading = true; bool isLoading = true;
late ApiService apiService; late ApiService apiService;
ScrollController _scrollController = ScrollController(); ScrollController _scrollController = ScrollController();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
apiService = ApiService(); apiService = ApiService();
if (kIsWeb) {
Future.microtask(() => _restoreId(ref));
}
Future.microtask(() { Future.microtask(() {
final id = ref.read(enquiryIdProvider); final id = ref.read(enquiryIdProvider);
@ -49,7 +56,21 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
// fetch immediately // 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'); print('Load Data');
setState(() => isLoading = true); setState(() => isLoading = true);
final response = await apiService.findEnqQuotePolicyView(id); final response = await apiService.findEnqQuotePolicyView(id);
@ -65,20 +86,37 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
TabItem( TabItem(
"Quotation", "Quotation",
QuotationTab( QuotationTab(
data: (enquiryData?["quotations"] as List<dynamic>?)! data:
.map((e) => Map<String, dynamic>.from(e as Map)) (enquiryData?["quotations"] as List<dynamic>?)
.toList(), ?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[],
id: id ?? "", id: id ?? "",
), ),
// QuotationTab(
// data: (enquiryData?["quotations"] as List<dynamic>?)!
// .map((e) => Map<String, dynamic>.from(e as Map))
// .toList(),
// id: id ?? "",
// ),
), ),
TabItem( TabItem(
"Policy", "Policy",
PolicyTab( PolicyTab(
data: (enquiryData?["policies"] as List<dynamic>?)! data:
.map((e) => Map<String, dynamic>.from(e as Map)) (enquiryData?["policies"] as List<dynamic>?)
.toList(), ?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[], // fallback to empty list
id: id ?? "", 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"])), // 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bool isMobile = MediaQuery.of(context).size.width < 600; final bool isMobile = MediaQuery.of(context).size.width < 600;
@ -94,12 +201,12 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
print("TABUPDID- $id"); print("TABUPDID- $id");
// When provider changes, re-fetch // // When provider changes, re-fetch
ref.listen<String?>(enquiryIdProvider, (prev, next) { // ref.listen<String?>(enquiryIdProvider, (prev, next) {
if (prev != next) { // if (prev != next) {
_loadData(id); // _loadData(id);
} // }
}); // });
print('ENQID: $id'); print('ENQID: $id');
@ -110,14 +217,130 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
child: isLoading child: isLoading
? const Center(child: CircularProgressIndicator()) ? const Center(child: CircularProgressIndicator())
: isMobile : 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(), : _buildDesktopTabs(),
), ),
); );
} }
Widget _buildMobileTabs() { Widget _buildMobileTabs({
required bool shrinkWrap,
required ScrollPhysics physics,
}) {
return ListView.builder( 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, itemCount: tabs.length,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -139,6 +362,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
collapsedIconColor: isExpanded ? Colors.black : Colors.white, collapsedIconColor: isExpanded ? Colors.black : Colors.white,
iconColor: isExpanded ? Colors.black : Colors.white, iconColor: isExpanded ? Colors.black : Colors.white,
initiallyExpanded: isExpanded, initiallyExpanded: isExpanded,
onExpansionChanged: (expanded) { onExpansionChanged: (expanded) {
setState(() { setState(() {
if (expanded) { if (expanded) {
@ -163,10 +387,12 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
title: Text( title: Text(
tabs[index].title, tabs[index].title,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 14,
color: isExpanded ? Colors.black : Colors.white, color: isExpanded ? Colors.black : Colors.white,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),
children: [ children: [
Container( Container(
// padding: const EdgeInsets.all(12), // padding: const EdgeInsets.all(12),

View File

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

View File

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

View File

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

View File

@ -180,6 +180,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
? Expanded( ? Expanded(
// take available space // take available space
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -236,12 +237,16 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
color: const Color(0xFF425B5B), color: const Color(0xFF425B5B),
borderRadius: BorderRadius.circular(25), borderRadius: BorderRadius.circular(25),
), ),
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(6),
child: Row( child: Row(
children: [ children: [
buildTab("Enquiries Pending", 0), Expanded(
child: buildTab("Enquiries Pending", 0),
),
const SizedBox(width: 10), const SizedBox(width: 10),
buildTab("Quotation Pending", 1), Expanded(
child: buildTab("Quotation Pending", 1),
),
], ],
), ),
), ),
@ -302,108 +307,224 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
), ),
), ),
) )
: Expanded( : Container(
child: Column( height: MediaQuery.of(context).size.height * 0.8,
children: [ child: SingleChildScrollView(
if (role != 'staff') scrollDirection: Axis.vertical,
Row( child: Column(
children: [ children: [
Expanded( if (role != 'staff')
child: StatCard( Row(
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: [ children: [
Expanded( Expanded(
child: Performance( child: StatCard(
title: "Top Agent Performance", title: "Policies Issued",
data: agentsPerformanceList, today: policiesIssuedToday ?? '',
month: policiesIssuedMonth ?? '',
year: policiesIssuedYear ?? '',
imagePath:
"assets/dashboard/Policy issue icon.png",
), ),
), ),
SizedBox(width: 16), SizedBox(width: 16),
Expanded( Expanded(
child: Performance( child: StatCard(
title: "Bottom Non-Performing Agents", title: "Premium Value",
data: nonAgentsPerformanceList, 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')
const SizedBox(height: 10), SizedBox(
Expanded( // replace Expanded
child: Row( height: 350, // adjust height as needed
children: [ child: Row(
Expanded( children: [
child: (role == 'agent') Expanded(
? agentPendings( child: Performance(
title: title: "Top Agent Performance",
"Enquiries Pending (${policiesPendingList.length})", data: agentsPerformanceList,
data: policiesPendingList, ),
) ),
: othersPendings( SizedBox(width: 16),
title: Expanded(
"Quotations Pending (${quotationsPendingList.length})", child: Performance(
data: quotationsPendingList, title: "Bottom Non-Performing Agents",
stringFlag: "Quotation", data: nonAgentsPerformanceList,
), ),
),
],
), ),
const SizedBox(width: 16), ),
Expanded( const SizedBox(height: 10),
child: (role == 'agent') SizedBox(
? agentPendings( // replace Expanded
title: height: (role == 'agent')
"Quotations Pending (${quotationsPendingList.length})", ? MediaQuery.of(context).size.height *
data: quotationsPendingList, 0.69 //400
) : MediaQuery.of(context).size.height *
: othersPendings( 0.5, // 350 adjust height as needed
title: child: Row(
"Policies Pending (${policiesPendingList.length})", children: [
data: policiesPendingList, Expanded(
stringFlag: "Policies", child: (role == 'agent')
), ? agentPendings(
// child: title:
// quotationsPendingList.isEmpty ? Center(child: Text("Loading quotations...")) : "Enquiries Pending (${policiesPendingList.length})",
// agentPendings( data: policiesPendingList,
// title: "Quotations Pending (${quotationsPendingList.length})", )
// data: quotationsPendingList, : 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",
),
),
],
),
), ),
), ],
], ),
), ),
), ),
// Expanded(
// child:
//
// 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,22 +543,22 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
}, },
child: SizedBox( child: SizedBox(
child: Container( child: Container(
padding: EdgeInsets.only( padding: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
top: 9.0,
bottom: 9.0,
left: 20.0,
right: 20.0,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isSelected ? const Color(0xFFFFFFFF) : Colors.transparent, color: isSelected ? const Color(0xFFFFFFFF) : Colors.transparent,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Text( child: Center(
title, child: Text(
style: GoogleFonts.poppins( title,
fontSize: 12, style: GoogleFonts.poppins(
color: isSelected ? Colors.black : Colors.white, fontSize: 12,
fontWeight: FontWeight.w500,
color: isSelected ? Colors.black : Colors.white,
fontWeight: FontWeight.w500,
),
maxLines: 2,
softWrap: true,
), ),
), ),
), ),
@ -483,7 +604,7 @@ class StatCard extends StatelessWidget {
title, title,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w700,
color: Color(0xFF425B5B), color: Color(0xFF425B5B),
), ),
), ),
@ -533,21 +654,21 @@ class StatCard extends StatelessWidget {
child: Text( child: Text(
"Today", "Today",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12), style: topHeaderStyle,
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"This Month", "This Month",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12), style: topHeaderStyle,
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"This Year", "This Year",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter(fontSize: 12), style: topHeaderStyle,
), ),
), ),
], ],
@ -731,19 +852,12 @@ class agentPendings extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Title // Title
Text( Text(title, style: _title),
title, const SizedBox(height: 10),
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
// Header row // Header row
Container( Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF3E5B56), color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
@ -754,33 +868,21 @@ class agentPendings extends StatelessWidget {
child: Text( child: Text(
"Date & Time", "Date & Time",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"Registration number", "Registration number",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"Insurer Company", "Insurer Company",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
], ],
@ -827,20 +929,8 @@ class agentPendings extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(date, style: _tableDataStyle),
date, Text(time, style: _tableDataStyle),
style: GoogleFonts.inter(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
Text(
time,
style: GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w400,
),
),
], ],
), ),
), ),
@ -850,10 +940,7 @@ class agentPendings extends StatelessWidget {
child: Text( child: Text(
row['reg_no'] ?? "", row['reg_no'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
@ -862,10 +949,7 @@ class agentPendings extends StatelessWidget {
child: Text( child: Text(
row['insurer_name'] ?? "", row['insurer_name'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
], ],
@ -907,19 +991,12 @@ class othersPendings extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Title // Title
Text( Text(title, style: _title),
title, const SizedBox(height: 10),
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
// Header row // Header row
Container( Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF3E5B56), color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
@ -927,48 +1004,36 @@ class othersPendings extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
flex: 1,
child: Text( child: Text(
"S.No", "S.No",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
flex: 2,
child: Text( child: Text(
"Staff Name", "Staff Name",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
flex: 2,
child: Text( child: Text(
stringFlag + " Issued", stringFlag + " Issued",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
(stringFlag == "Policies") (stringFlag == "Policies")
? Expanded( ? Expanded(
flex: 2,
child: Text( child: Text(
"Total Premium Value", "Total Premium Value",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
) )
: const SizedBox.shrink(), : const SizedBox.shrink(),
@ -1005,43 +1070,38 @@ class othersPendings extends StatelessWidget {
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
flex: 1,
child: Text( child: Text(
(index + 1).toString(), (index + 1).toString(),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
Expanded( Expanded(
flex: 2,
child: Text( child: Text(
row['staff_name'] ?? "", row['staff_name'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
Expanded( Expanded(
flex: 2,
child: Text( child: Text(
issuedCount, issuedCount,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
stringFlag == "Policies" stringFlag == "Policies"
? Expanded( ? Expanded(
flex: 2,
child: Text( child: Text(
formatToCroresLakhsAndThousands(permiumValue), formatToCroresLakhsAndThousands(permiumValue),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 16, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
@ -1079,19 +1139,12 @@ class Performance extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Title // Title
Text( Text(title, style: _title),
title, const SizedBox(height: 10),
style: GoogleFonts.inter(
fontWeight: FontWeight.bold,
fontSize: 20,
color: const Color(0xff425B5B),
),
),
const SizedBox(height: 20),
// Header row // Header row
Container( Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0xFF3E5B56), color: const Color(0xFF3E5B56),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
@ -1102,33 +1155,21 @@ class Performance extends StatelessWidget {
child: Text( child: Text(
"S.No", "S.No",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"Agent Name", "Agent Name",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
child: Text( child: Text(
"Policies Issued", "Policies Issued",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
Expanded( Expanded(
@ -1137,11 +1178,7 @@ class Performance extends StatelessWidget {
? "Premium Value" ? "Premium Value"
: "Status", : "Status",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _headerStyle,
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white,
),
), ),
), ),
], ],
@ -1157,6 +1194,7 @@ class Performance extends StatelessWidget {
final row = data[index]; final row = data[index];
return Container( return Container(
// height: 5200,
margin: const EdgeInsets.symmetric(vertical: 5), margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 5, vertical: 5,
@ -1172,10 +1210,7 @@ class Performance extends StatelessWidget {
child: Text( child: Text(
(index + 1).toString(), // convert int to string (index + 1).toString(), // convert int to string
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
@ -1183,10 +1218,7 @@ class Performance extends StatelessWidget {
child: Text( child: Text(
row['agent_name'] ?? "", row['agent_name'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
@ -1194,10 +1226,7 @@ class Performance extends StatelessWidget {
child: Text( child: Text(
row['total_policy_issued'] ?? "", row['total_policy_issued'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: _tableDataStyle,
fontSize: 16,
fontWeight: FontWeight.w500,
),
), ),
), ),
@ -1210,7 +1239,7 @@ class Performance extends StatelessWidget {
: (row['status']?.toString() ?? ""), : (row['status']?.toString() ?? ""),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 16, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: title == "Top Agent Performance" color: title == "Top Agent Performance"
? Colors.black ? 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 'dart:io';
import 'package:firebase_auth/firebase_auth.dart'; 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/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -46,6 +48,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
bool enteredEmailOrMobile = false; bool enteredEmailOrMobile = false;
dynamic clickedButtonName; dynamic clickedButtonName;
dynamic token; dynamic token;
dynamic fCMToken;
// Future<void> _handleLogin() async { // Future<void> _handleLogin() async {
// if (!_formKey.currentState!.validate()) return; // if (!_formKey.currentState!.validate()) return;
@ -104,6 +107,20 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
_countryController.text = "+91"; _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 { Future<void> _saveUserRole(String token) async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final decodedToken = Jwt.parseJwt(token); final decodedToken = Jwt.parseJwt(token);
@ -747,41 +764,41 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
const SizedBox(height: 30), const SizedBox(height: 15),
Image.asset( Image.asset(
"assets/login/nhance-partner-logo.png", "assets/login/nhance-partner-logo.png",
height: 45, height: 35,
), ),
const SizedBox(height: 30), const SizedBox(height: 10),
Text( Text(
"Welcome Back", "Welcome Back",
style: TextStyle( style: GoogleFonts.inter(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF425C5C), color: Color(0xFF425C5C),
), ),
), ),
const SizedBox(height: 20),
Image.asset("assets/login/login-content.png", height: 180),
const SizedBox(height: 10), const SizedBox(height: 10),
Image.asset("assets/login/login-content.png", height: 120),
// const SizedBox(height: 10),
Container( Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 50), padding: EdgeInsets.symmetric(vertical: 10, horizontal: 50),
child: Text( 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, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 14,
color: Color(0xFF000000), color: Color(0xFF000000),
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
), ),
const SizedBox(height: 20), const SizedBox(height: 10),
Container( Container(
width: double.infinity, width: double.infinity,
height: MediaQuery.of( height:
context, MediaQuery.of(context).size.height *
).size.height, // full screen height 0.8, // full screen height
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: const BoxDecoration( decoration: const BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
@ -816,7 +833,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
Text( Text(
"Login to your account", "Login to your account",
style: TextStyle( style: TextStyle(
fontSize: ResponsiveLayout.isMobile(context) ? 28 : 35, fontSize: ResponsiveLayout.isMobile(context) ? 20 : 35,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.white, color: Colors.white,
), ),
@ -826,7 +843,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
"Enter your email or mobile number to receive a one time password.", "Enter your email or mobile number to receive a one time password.",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: ResponsiveLayout.isMobile(context) ? 14 : 18, fontSize: ResponsiveLayout.isMobile(context) ? 12 : 18,
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
@ -1129,19 +1146,22 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Container( Container(
child: Text( child: Center(
'OTP', child: Text(
style: TextStyle( 'OTP',
fontSize: ResponsiveLayout.isMobile(context) style: TextStyle(
? 14 fontSize: ResponsiveLayout.isMobile(context)
: 18, ? 14
fontWeight: FontWeight.w600, : 18,
color: Colors.white, fontWeight: FontWeight.w600,
color: Colors.white,
),
), ),
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Container( Container(
alignment: Alignment.center,
child: Pinput( child: Pinput(
length: 6, length: 6,
defaultPinTheme: defaultPinTheme, defaultPinTheme: defaultPinTheme,
@ -1191,49 +1211,104 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
), ),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
SizedBox( Container(
width: 400, alignment: Alignment.center, // center the text
child: CommonButton( child: RichText(
text: "Continue", textAlign: TextAlign.center,
backgroundColor: Color(0xFF436462), text: TextSpan(
onPressed: () async { text: 'Didnt Receive Code? ', // normal text
if (switcherStatus == 1) { style: TextStyle(
await verifyFirebaseMobileOTP(); fontSize: ResponsiveLayout.isMobile(context)
} else { ? 12
await verifyMobileOrMailOTP( : 14,
_otpController.text, 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",
backgroundColor: Color(0xFF436462),
onPressed: () async {
if (switcherStatus == 1) {
await verifyFirebaseMobileOTP();
} else {
await verifyMobileOrMailOTP(
_otpController.text,
);
}
},
),
// ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: const Color(0xFF436462),
// padding: const EdgeInsets.symmetric(
// vertical: 16,
// ),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// ),
// ),
// onPressed: () {
// if (switcherStatus == 1) {
// verifyFirebaseMobileOTP();
// } else {
// verifyMobileOrMailOTP(_otpController.text);
// }
// },
// child: Text(
// 'Continue',
// style: TextStyle(
// fontSize: ResponsiveLayout.isMobile(context)
// ? 18
// : 20,
// fontWeight: FontWeight.w600,
// color: Colors.white,
// ),
// ),
// ),
), ),
// ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: const Color(0xFF436462),
// padding: const EdgeInsets.symmetric(
// vertical: 16,
// ),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// ),
// ),
// onPressed: () {
// if (switcherStatus == 1) {
// verifyFirebaseMobileOTP();
// } else {
// verifyMobileOrMailOTP(_otpController.text);
// }
// },
// child: Text(
// 'Continue',
// style: TextStyle(
// fontSize: ResponsiveLayout.isMobile(context)
// ? 18
// : 20,
// fontWeight: FontWeight.w600,
// color: Colors.white,
// ),
// ),
// ),
), ),
], ],
) )
@ -1258,12 +1333,16 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
_PhoneNumberController.text = ''; _PhoneNumberController.text = '';
_emailController.text = ''; _emailController.text = '';
_otpController.text = ''; _otpController.text = '';
_PhoneNumberController.clear();
_emailController.clear();
_otpController.clear();
if (selectedIndex == 2) { if (selectedIndex == 2) {
switcherStatus = 0; switcherStatus = 0;
} else { } else {
switcherStatus = 1; switcherStatus = 1;
} }
}); });
_formKey.currentState?.reset();
}, },
child: Container( child: Container(
padding: EdgeInsets.only( 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:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/config/env.dart'; import '../../../../core/config/env.dart';
import '../../../../core/routing/routes.dart'; import '../../../../core/routing/routes.dart';
@ -236,9 +237,23 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Material( Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () { onTap: () async {
Navigator.pop(context); 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; ref.read(quotationStaffIdProvider.notifier).state = id;
context.go(AppRoutes.quotation); context.go(AppRoutes.quotation);
}, },
hoverColor: Color(0xFFE3F1F0), hoverColor: Color(0xFFE3F1F0),
@ -271,8 +286,19 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Material( Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () { onTap: () async {
Navigator.pop(context); 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; ref.read(quotationStaffIdProvider.notifier).state = id;
context.go(AppRoutes.policy); context.go(AppRoutes.policy);
}, },
@ -372,13 +398,14 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
Spacer(), Spacer(),
ExportBtn( ExportBtn(
sheetName: "Policy", sheetName: "Enquiry",
fileName: "Policy_list", fileName: "Enquiry_list",
data: filteredData, data: filteredData,
txt: !ResponsiveLayout.isMobile(context) txt: !ResponsiveLayout.isMobile(context)
? true ? true
: false, : false,
headers: [ headers: [
"updated_on",
"reg_no", "reg_no",
"agent_name", "agent_name",
"assigned_to_name", "assigned_to_name",
@ -386,7 +413,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
"insured_name", "insured_name",
"premium_amount", "premium_amount",
"payment_mode", "payment_mode",
"updated_on", "policy_number",
"status", "status",
], ],
), ),
@ -446,7 +473,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: const Row( child: const Row(
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 3,
child: Text('Date', style: _headerStyle), child: Text('Date', style: _headerStyle),
), ),
@ -467,7 +494,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: Text('Insurer', style: _headerStyle), child: Text('Insurer', style: _headerStyle),
), ),
Expanded( Expanded(
flex: 2, flex: 3,
child: Text('Insured Name', style: _headerStyle), child: Text('Insured Name', style: _headerStyle),
), ),
Expanded( Expanded(
@ -579,7 +606,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
flex: 2, flex: 3,
child: Text( child: Text(
_formatDate(item['updated_on']) ?? '-', _formatDate(item['updated_on']) ?? '-',
style: _dataBold, style: _dataBold,
@ -613,7 +640,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
), ),
), ),
Expanded( Expanded(
flex: 2, flex: 3,
child: Text( child: Text(
item['insured_name'] ?? '-', item['insured_name'] ?? '-',
style: _dataBold, style: _dataBold,

View File

@ -1,4 +1,5 @@
// import 'dart:io' as html; // import 'dart:io' as html;
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.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:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/config/env.dart'; import '../../../../core/config/env.dart';
import '../../../../core/routing/routes.dart'; import '../../../../core/routing/routes.dart';
@ -149,6 +151,10 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
// getQuotationList(managerId); // getQuotationList(managerId);
// }); // });
if (kIsWeb) {
Future.microtask(() => _restoreManagerId(ref));
}
Future.microtask(() { Future.microtask(() {
managerId = ref.read(managerIdProvider); // use read managerId = ref.read(managerIdProvider); // use read
userId = ref.read(userIdProvider); // 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 @override
void dispose() { void dispose() {
// Dispose all TextEditingControllers // Dispose all TextEditingControllers
@ -510,7 +530,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
context.go(AppRoutes.policylist); context.go(AppRoutes.enquiryForStaff);
}, },
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@ -1215,12 +1235,13 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Widget buildUploadPolicyPdf(BuildContext context) { Widget buildUploadPolicyPdf(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text('Upload Policy PDF * ', style: _textStyle), Text('Upload Policy PDF * ', style: _textStyle),
const SizedBox(height: 10), const SizedBox(height: 10),
Column( Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ThemedUploadField( ThemedUploadField(
hintText: selectedPDFFileNames ?? "Upload Document", hintText: selectedPDFFileNames ?? "Upload Document",
@ -1241,6 +1262,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Container( Container(
// color: Colors.white, // color: Colors.white,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
GestureDetector( GestureDetector(
@ -1313,6 +1335,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
Container( Container(
// color: Colors.white, // color: Colors.white,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
GestureDetector( GestureDetector(

View File

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

View File

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

View File

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:excel/excel.dart'; import 'package:excel/excel.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -62,7 +63,12 @@ class ExportBtn extends HookWidget {
) )
: null, : null,
?txt! ? SizedBox(width: 20) : 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), // Image.asset("assets/miscellaneous/export", height: 15, width: 15),
], ],
), ),
@ -71,6 +77,8 @@ class ExportBtn extends HookWidget {
} }
} }
class ExcelExporter { class ExcelExporter {
static Future<void> exportToExcel({ static Future<void> exportToExcel({
required String sheetName, required String sheetName,
@ -79,14 +87,16 @@ class ExcelExporter {
required String fileName, required String fileName,
}) async { }) async {
try { try {
// Create Excel and delete default sheet // Create Excel
var excel = Excel.createExcel(); var excel = Excel.createExcel();
// Rename default sheet
if (excel.sheets.containsKey('Sheet1')) { if (excel.sheets.containsKey('Sheet1')) {
excel.delete('Sheet1'); excel.rename('Sheet1', sheetName);
} }
// Create your sheet // Get the sheet
Sheet sheetObject = excel[sheetName]; // now this is the only sheet Sheet sheetObject = excel[sheetName]!;
// Add headers // Add headers
sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList()); sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
@ -112,13 +122,12 @@ class ExcelExporter {
var bytes = excel.encode()!; var bytes = excel.encode()!;
if (kIsWeb) { if (kIsWeb) {
// Web: download // Web: base64 download instead of Blob
final blob = html.Blob([bytes]); final base64Str = base64Encode(bytes);
final url = html.Url.createObjectUrlFromBlob(blob); final dataUri = "data:application/octet-stream;base64,$base64Str";
final anchor = html.AnchorElement(href: url) final anchor = html.AnchorElement(href: dataUri)
..setAttribute("download", "$fileName.xlsx") ..setAttribute("download", "$fileName.xlsx")
..click(); ..click();
html.Url.revokeObjectUrl(url);
} else { } else {
// Mobile/Desktop: save file // Mobile/Desktop: save file
final dir = await getApplicationDocumentsDirectory(); 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 { // class ExcelExporter {
// static Future<void> exportToExcel({ // static Future<void> exportToExcel({
// required String sheetName, // required String sheetName,

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:google_fonts/google_fonts.dart';
// import 'package:uae_stat/config/my_theme.dart'; // import 'package:uae_stat/config/my_theme.dart';
@ -103,7 +104,13 @@ class ThemedFormField extends HookWidget {
// dynamic hint color // dynamic hint color
color: const Color(0xFFC3C6CB), 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( prefixIconConstraints: const BoxConstraints(
maxWidth: 25 + 16 + 10, maxWidth: 25 + 16 + 10,
maxHeight: 25 + (8 * 2), maxHeight: 25 + (8 * 2),
@ -139,6 +146,11 @@ class ThemedFormField extends HookWidget {
// allow multiline if user sets maxLines / minLines // allow multiline if user sets maxLines / minLines
minLines: (keyboardType == TextInputType.multiline) ? 3 : 1, minLines: (keyboardType == TextInputType.multiline) ? 3 : 1,
maxLines: (keyboardType == TextInputType.multiline) ? null : 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"), 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( DrawerContentWrapper(
child: Consumer( child: Consumer(
builder: (context, ref, _) { builder: (context, ref, _) {
@ -290,6 +267,30 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
), ),
DrawerLabel("User"), 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,28 +100,48 @@ class _MobileBottomMenuState extends ConsumerState<MobileBottomMenu> {
}, },
items: [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Image.asset( icon: _currentIndex == 0
"assets/drawer/drawerImg1.png", ? Image.asset(
height: 20, "assets/drawer/drawerImg1_light.png",
width: 20, height: 20,
), width: 20,
)
: Image.asset(
"assets/drawer/drawerImg1.png",
height: 20,
width: 20,
),
label: "Dashboard", label: "Dashboard",
), ),
BottomNavigationBarItem( BottomNavigationBarItem(
icon: Image.asset( icon: _currentIndex == 1
"assets/drawer/drawerImg2.png", ? Image.asset(
height: 20, "assets/drawer/drawerImg2_light.png",
width: 20, height: 20,
), width: 20,
)
: Image.asset(
"assets/drawer/drawerImg2.png",
height: 20,
width: 20,
),
label: "Reports", label: "Reports",
), ),
const BottomNavigationBarItem( BottomNavigationBarItem(
icon: Icon(Icons.list_alt_rounded, size: 24, color: Colors.black), icon: Icon(
Icons.list_alt_rounded,
size: 24,
color: _currentIndex == 2 ? Colors.white : Colors.black,
),
label: "Enquiry", label: "Enquiry",
), ),
const BottomNavigationBarItem( BottomNavigationBarItem(
icon: Icon(Icons.person_add_alt, size: 24, color: Colors.black), icon: Icon(
Icons.person_add_alt,
size: 24,
color: _currentIndex == 3 ? Colors.white : Colors.black,
),
label: "User", label: "User",
), ),
], ],

View File

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

BIN
lib_29_sep.zip Normal file

Binary file not shown.