UI_USER_PROFILE
This commit is contained in:
parent
cd06b555ac
commit
fa484bc00e
File diff suppressed because one or more lines are too long
BIN
assets/dashboard/Earnings.png
Normal file
BIN
assets/dashboard/Earnings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/dashboard/Policy issue icon.png
Normal file
BIN
assets/dashboard/Policy issue icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/dashboard/Premium value.png
Normal file
BIN
assets/dashboard/Premium value.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 957 B |
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:nhance_partner/core/routing/routes.dart';
|
||||
import 'package:nhance_partner/presentation/screens/UserManagement/Profile/profile_web.dart';
|
||||
import 'package:nhance_partner/presentation/screens/claims/claimsList.dart';
|
||||
import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart';
|
||||
import '../../data/services/auth_service.dart';
|
||||
@ -32,6 +33,11 @@ final GoRouter appRouter = GoRouter(
|
||||
builder: (context, state) => const DashboardScreen(),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.profile,
|
||||
builder: (context, state) => const ProfilePopUp(),
|
||||
),
|
||||
|
||||
GoRoute(
|
||||
path: AppRoutes.agentLst,
|
||||
// builder: (context, state) => const Agent(),
|
||||
@ -70,7 +76,6 @@ final GoRouter appRouter = GoRouter(
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
],
|
||||
redirect: (context, state) async {
|
||||
final loggedIn = await AuthService.isLoggedIn();
|
||||
|
||||
@ -3,9 +3,9 @@ class AppRoutes {
|
||||
static const String home = '/home';
|
||||
static const String dashboard = '/dashboard';
|
||||
static const String login = '/login';
|
||||
static const String profile = '/profile';
|
||||
static const String agentLst = '/agentLst';
|
||||
static const agent = '/agent/:id';
|
||||
static const String staffLst = '/staffLst';
|
||||
static const staff = '/staff/:id';
|
||||
}
|
||||
|
||||
|
||||
@ -98,6 +98,27 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchManagerIncentiveList(mangerId) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
|
||||
final url = Uri.parse(
|
||||
'${Env.apiUrl}staff/managerIncentiveFileList?manager_id=$mangerId',
|
||||
);
|
||||
|
||||
// final url = Uri.parse(
|
||||
// 'https://venbait.in/nhance/partner/dev/api/agent/agentIncentiveFileList?agent_id=${agentId}',
|
||||
// );
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
|
||||
};
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchAgentUserList(int managerId) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
@ -212,7 +233,7 @@ class ApiService {
|
||||
// final url = Uri.parse(
|
||||
// 'https://venbait.in/nhance/partner/dev/api/agent/downloadAgentCertificateFile?agent_id=1',
|
||||
// );
|
||||
final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path}');
|
||||
final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
|
||||
|
||||
// final token = await getToken();
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:nhance_partner/core/routing/routes.dart';
|
||||
import 'package:nhance_partner/data/services/auth_service.dart';
|
||||
import '../screens/UserManagement/Profile/profile_web.dart';
|
||||
import '../widgets/custom_action_popup.dart';
|
||||
import '../widgets/topbar.dart';
|
||||
import '../widgets/footer.dart';
|
||||
import '../widgets/drawer_menu.dart';
|
||||
@ -19,6 +21,7 @@ class MainLayout extends StatelessWidget {
|
||||
return ResponsiveLayout(
|
||||
// Mobile Layout
|
||||
mobile: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
appBar: TopBar(
|
||||
title: title,
|
||||
isMobile: true,
|
||||
@ -34,6 +37,9 @@ class MainLayout extends StatelessWidget {
|
||||
bottomNavigationBar: MobileTabs(
|
||||
onTabChanged: (index) {
|
||||
debugPrint("Mobile tab changed to $index");
|
||||
if (index == 1) {
|
||||
context.go(AppRoutes.profile);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -50,9 +56,27 @@ class MainLayout extends StatelessWidget {
|
||||
AuthService.clearToken();
|
||||
context.go(AppRoutes.login);
|
||||
},
|
||||
onProfile: () {
|
||||
debugPrint("Profile tapped");
|
||||
|
||||
onProfile: (TapDownDetails details) {
|
||||
final RenderBox overlay =
|
||||
Overlay.of(context).context.findRenderObject() as RenderBox;
|
||||
|
||||
showMenu(
|
||||
context: context,
|
||||
color: Colors.white,
|
||||
position: RelativeRect.fromRect(
|
||||
details.globalPosition & const Size(40, 40),
|
||||
Offset.zero & overlay.size,
|
||||
),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
enabled: false,
|
||||
child: SizedBox(width: 500, child: ProfilePopUp()),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
||||
onNotifications: () {
|
||||
debugPrint("Notifications tapped");
|
||||
},
|
||||
@ -60,18 +84,14 @@ class MainLayout extends StatelessWidget {
|
||||
body: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 80, // fixed width for drawer
|
||||
width: 90, // fixed width for drawer
|
||||
child: DrawerMenu(),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: body),
|
||||
],
|
||||
),
|
||||
child: Column(children: [Expanded(child: body)]),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
435
lib/presentation/screens/Enquiry/enquiryList.dart
Normal file
435
lib/presentation/screens/Enquiry/enquiryList.dart
Normal file
@ -0,0 +1,435 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../../../../core/routing/routes.dart';
|
||||
import '../../../../core/services/api_service.dart';
|
||||
import '../../../../data/utils/Pagination.dart';
|
||||
import '../../layouts/main_layout.dart';
|
||||
import '../../themes/indicators/export_btn.dart';
|
||||
import '../../themes/indicators/search_field_theme.dart';
|
||||
import '../../widgets/custom_action_popup.dart';
|
||||
|
||||
class enquiryList extends StatefulWidget {
|
||||
const enquiryList({super.key});
|
||||
@override
|
||||
enquiryListState createState() => enquiryListState();
|
||||
}
|
||||
|
||||
class enquiryListState extends State<enquiryList> {
|
||||
int currentPage = 1;
|
||||
int itemsPerPage = 10;
|
||||
late ApiService apiService;
|
||||
|
||||
// List<Map<String, dynamic>> dataVal = [];
|
||||
List<Map<String, dynamic>> getStaffData = [];
|
||||
List<Map<String, dynamic>> originalData = [];
|
||||
List<Map<String, dynamic>> filteredData = [];
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
apiService = ApiService();
|
||||
// getStaffList();
|
||||
}
|
||||
|
||||
List<dynamic> get _paginatedData {
|
||||
final startIndex = (currentPage - 1) * itemsPerPage;
|
||||
final endIndex = (currentPage * itemsPerPage).clamp(0, filteredData.length);
|
||||
return filteredData.sublist(startIndex, endIndex);
|
||||
}
|
||||
|
||||
void filterData(String query) {
|
||||
print("FilterDAta - $query");
|
||||
setState(() {
|
||||
filteredData = getStaffData.where((item) {
|
||||
final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
|
||||
|
||||
return (item['name'] ?? '').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['email'] ?? '').toLowerCase().contains(query.toLowerCase()) ||
|
||||
(item['mobile'] ?? '').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['address'] ?? '').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['emp_id'] ?? item['agent_code'] ?? '').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
isActiveStatus.contains(query.toLowerCase());
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
|
||||
final TextEditingController _searchStaffController = TextEditingController();
|
||||
|
||||
// Future<void> getStaffList() async {
|
||||
// print('getClaimList called');
|
||||
// setState(() {
|
||||
// isLoading = true;
|
||||
// });
|
||||
//
|
||||
// try {
|
||||
// final response = await apiService.fetchStaffUserList();
|
||||
//
|
||||
// if (response['status'] == 'success') {
|
||||
// print('getStaffListData - ${response['data']}');
|
||||
// setState(() {
|
||||
// getStaffData = List<Map<String, dynamic>>.from(response['data']);
|
||||
// originalData = getStaffData;
|
||||
// filteredData = List.from(originalData);
|
||||
// // print('originalData - $getClaimPolicies');
|
||||
// });
|
||||
// } else {
|
||||
// getStaffData = [];
|
||||
// originalData = [];
|
||||
// }
|
||||
// } catch (e) {
|
||||
// print('Exception occurred: $e');
|
||||
// } finally {
|
||||
// setState(() {
|
||||
// isLoading = false;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
List<Widget> _buildPopupMenuActions(BuildContext context, dynamic data) {
|
||||
return [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
print('EDITStaff - ${data['id']}');
|
||||
dynamic id = data['id'];
|
||||
context.go('/staff/$id');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
|
||||
SizedBox(width: 10),
|
||||
Text('Edit'),
|
||||
],
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MainLayout(
|
||||
title: "Enquiry",
|
||||
body: Container(
|
||||
// color: Colors.yellow.shade50,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.go(AppRoutes.dashboard);
|
||||
},
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.arrow_left_sharp,
|
||||
size: 35,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
Text(
|
||||
"Enquries",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 10),
|
||||
|
||||
Expanded(
|
||||
child: Container(
|
||||
// color: Colors.green,
|
||||
// color: Colors.green.shade50,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
// height: 40,
|
||||
// color: Colors.pink,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
ThemedSearchField(
|
||||
hintText: 'Search',
|
||||
backgroundColor: Color(0xFFF6F8F8),
|
||||
onChanged: filterData,
|
||||
controller: _searchStaffController,
|
||||
txtwidth: MediaQuery.of(context).size.width * 0.2,
|
||||
),
|
||||
|
||||
Spacer(),
|
||||
|
||||
ExportBtn(
|
||||
sheetName: "Staff",
|
||||
fileName: "staff_list",
|
||||
data: filteredData,
|
||||
headers: [
|
||||
"id",
|
||||
"name",
|
||||
"email",
|
||||
"mobile",
|
||||
"emp_id",
|
||||
"is_active",
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print('Export');
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF425B5B),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, color: Colors.white),
|
||||
|
||||
SizedBox(width: 10),
|
||||
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
// context.go(AppRoutes.agent / create);
|
||||
context.go('/staff/create');
|
||||
},
|
||||
child: Text(
|
||||
'Create New Staff',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Expanded(child: _buildDataTable(context)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Container(
|
||||
// height: 20,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
// color: Colors.green.shade50,
|
||||
child: PaginationControls(
|
||||
currentPage: currentPage,
|
||||
itemsPerPage: itemsPerPage,
|
||||
// totalItems: dataVal.length,
|
||||
totalItems: filteredData.length,
|
||||
// activeColor: layoutColor, // your theme color
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
});
|
||||
},
|
||||
onItemsPerPageChanged: (items) {
|
||||
setState(() {
|
||||
itemsPerPage = items;
|
||||
currentPage = 1;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDataTable(BuildContext context) {
|
||||
if (filteredData.isEmpty) {
|
||||
return const SizedBox(
|
||||
height: 50,
|
||||
child: Center(child: Text('No available data')),
|
||||
);
|
||||
}
|
||||
|
||||
final sortedData = [...filteredData]
|
||||
..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));
|
||||
|
||||
return ListView.builder(
|
||||
// itemCount: filteredData.length + 1, // +1 for header, +1 for pagination
|
||||
itemCount: sortedData.length + 1, // +1 for header, +1 for pagination
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) return _buildHeader();
|
||||
// if (index == dataVal.length + 1)
|
||||
// return _buildPagination(context);
|
||||
final startIndex = ((currentPage - 1) * itemsPerPage);
|
||||
// final item = filteredData[index - 1];
|
||||
final item = sortedData[index - 1];
|
||||
final sno = startIndex + index;
|
||||
return _buildDataRow(item, sno);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader() {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFEDF6F5),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
child: const Row(
|
||||
children: [
|
||||
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Received Date & Time', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 3, child: Text('Reg.No.', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Company', style: _headerStyle)),
|
||||
Expanded(flex: 1, child: Text('Status', style: _headerStyle)),
|
||||
Expanded(flex: 1, child: Text('Remarks', style: _headerStyle)),
|
||||
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDataRow(Map<String, dynamic> item, sno) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
// margin: const EdgeInsets.only(top: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// color: Color(0xFFE0F7F9),
|
||||
border: const Border(
|
||||
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
|
||||
Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(item['email'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item['mobile'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Text(item['emp_id'] ?? '-', style: _dataBold),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Transform.scale(
|
||||
scale: 0.6, // reduce size (0.7–0.9 works well)
|
||||
child: Switch(
|
||||
value: item['is_active'] == "1",
|
||||
onChanged: (val) {
|
||||
setState(() {
|
||||
item['is_active'] = val ? "1" : "0";
|
||||
});
|
||||
final response = apiService.updateStatus(
|
||||
item['id'],
|
||||
val ? "1" : "0",
|
||||
'staff',
|
||||
);
|
||||
print("Response - $response");
|
||||
},
|
||||
activeColor: Color(0xFF425B5B), // thumb when active
|
||||
activeTrackColor: Color(0xFFB2D8D3), // track when active
|
||||
inactiveThumbColor: Colors.grey.shade400, // thumb when inactive
|
||||
inactiveTrackColor: Colors.grey.shade300, // track when inactive
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final _dataBold = TextStyle(
|
||||
fontSize: 14,
|
||||
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
);
|
||||
|
||||
static final _dataSub = TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w300,
|
||||
color: Color(0xFF585757),
|
||||
);
|
||||
|
||||
static const _headerStyle = TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
}
|
||||
498
lib/presentation/screens/UserManagement/Profile/profile_web.dart
Normal file
498
lib/presentation/screens/UserManagement/Profile/profile_web.dart
Normal file
@ -0,0 +1,498 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
|
||||
import '../../../../core/services/api_service.dart';
|
||||
import '../../../../data/services/auth_service.dart';
|
||||
import '../../../layouts/main_layout.dart';
|
||||
import '../../../layouts/responsive_layout.dart';
|
||||
import '../../../providers/manager_provider.dart';
|
||||
|
||||
class ProfilePopUp extends ConsumerStatefulWidget {
|
||||
const ProfilePopUp({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<ProfilePopUp> createState() => ProfilePopUpState();
|
||||
}
|
||||
|
||||
class ProfilePopUpState extends ConsumerState<ProfilePopUp> {
|
||||
late ApiService apiService;
|
||||
|
||||
List<Map<String, dynamic>> filteredIncentiveData = [];
|
||||
List<Map<String, dynamic>> getAgentIncentiveFileData = [];
|
||||
Map<String, dynamic>? profileData;
|
||||
|
||||
dynamic roleIdRaw;
|
||||
dynamic roleId;
|
||||
|
||||
bool isProfile = true;
|
||||
bool isLoading = false;
|
||||
String? _token;
|
||||
dynamic latestId;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
apiService = ApiService();
|
||||
// getAgentList();
|
||||
_initializeToken();
|
||||
// Future.microtask(() {
|
||||
// final id = ref.read(managerIdProvider);
|
||||
// if (id != null) {
|
||||
// getAgentList(id);
|
||||
//
|
||||
// // api/staff/managerIncentiveFileList?manager_id=1
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
Future<void> _initializeToken() async {
|
||||
_token = await AuthService.getToken();
|
||||
print("APISERTOKEN - $_token");
|
||||
final Map<String, dynamic> decodedToken = Jwt.parseJwt(_token!);
|
||||
setState(() {
|
||||
profileData = decodedToken['data'];
|
||||
});
|
||||
print('decodedTokenProfile : $decodedToken');
|
||||
print('decodedTokenProfile : $profileData');
|
||||
|
||||
await getList();
|
||||
}
|
||||
|
||||
Future<void> getList() async {
|
||||
roleIdRaw = profileData?['role_id'];
|
||||
roleId = roleIdRaw is String ? int.tryParse(roleIdRaw) : roleIdRaw as int?;
|
||||
|
||||
if (roleId == 1) {
|
||||
final managerIdRaw = profileData?['manager_id'];
|
||||
final managerId = managerIdRaw is String
|
||||
? int.tryParse(managerIdRaw)
|
||||
: managerIdRaw as int?;
|
||||
if (managerId != null) {
|
||||
getIncenctiveFileList(managerId);
|
||||
}
|
||||
} else if (roleId != 1 && roleId != 2) {
|
||||
final agentIdRaw = profileData?['id'];
|
||||
final agentId = agentIdRaw is String
|
||||
? int.tryParse(agentIdRaw)
|
||||
: agentIdRaw as int?;
|
||||
if (agentId != null) {
|
||||
getIncenctiveFileList(agentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getIncenctiveFileList(id) async {
|
||||
// print('getClaimList agentId - $agentId');
|
||||
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response;
|
||||
|
||||
final roleIdRaw = profileData?['role_id'];
|
||||
final roleId = roleIdRaw is String
|
||||
? int.tryParse(roleIdRaw)
|
||||
: roleIdRaw as int?;
|
||||
if (roleId == 1) {
|
||||
response = await apiService.fetchManagerIncentiveList(id);
|
||||
} else {
|
||||
response = await apiService.fetchAgentIncentiveList(id);
|
||||
}
|
||||
|
||||
if (response['status'] == 'success') {
|
||||
print('AgentIncentive - ${response['data']}');
|
||||
setState(() {
|
||||
getAgentIncentiveFileData = List<Map<String, dynamic>>.from(
|
||||
response['data'],
|
||||
);
|
||||
print('API AgentIncentive - $getAgentIncentiveFileData');
|
||||
|
||||
filteredIncentiveData = List.from(getAgentIncentiveFileData);
|
||||
print('originalData - $filteredIncentiveData');
|
||||
|
||||
// Sort descending by created_on
|
||||
filteredIncentiveData.sort((a, b) {
|
||||
final dateA =
|
||||
DateTime.tryParse(a['created_on'].toString()) ?? DateTime(1970);
|
||||
final dateB =
|
||||
DateTime.tryParse(b['created_on'].toString()) ?? DateTime(1970);
|
||||
return dateB.compareTo(dateA); // newest first
|
||||
});
|
||||
|
||||
// Get the latest ID (from the first element after sorting)
|
||||
if (filteredIncentiveData.isNotEmpty) {
|
||||
latestId = filteredIncentiveData.first['id'];
|
||||
print("Latest incentive id: $latestId");
|
||||
}
|
||||
|
||||
print('sortedData - $filteredIncentiveData');
|
||||
});
|
||||
} else {
|
||||
getAgentIncentiveFileData = [];
|
||||
}
|
||||
} catch (e) {
|
||||
print('Exception occurred: $e');
|
||||
} finally {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MainLayout(
|
||||
title: 'Profile',
|
||||
body: Container(
|
||||
// color: Colors.white,
|
||||
padding: const EdgeInsets.all(6),
|
||||
width: 450,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (!ResponsiveLayout.isMobile(context))
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
isProfile ? 'My Profile' : 'Incentive Files',
|
||||
style: _topheaderStyle,
|
||||
),
|
||||
Spacer(),
|
||||
Container(
|
||||
width: 25,
|
||||
height: 25,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF1F1F1),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(); // closes the popup
|
||||
},
|
||||
child: const Icon(Icons.close, size: 18),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (ResponsiveLayout.isMobile(context))
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
isProfile ? '' : 'Incentive Files',
|
||||
style: _topheaderStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
isProfile
|
||||
? Container(
|
||||
color: Colors.white,
|
||||
padding: ResponsiveLayout.isMobile(context)
|
||||
? EdgeInsets.all(16.0)
|
||||
: null,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 25),
|
||||
Container(
|
||||
width: 70,
|
||||
height: 70,
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFD9D9D9),
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.person_outline,
|
||||
size: 50,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(profileData?['name'] ?? '-', style: _headerStyle),
|
||||
Text(
|
||||
profileData?['emp_id'] ?? '-',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 26),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.phone_outlined,
|
||||
size: 20,
|
||||
color: Colors.black,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
profileData?['mobile'] ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.email_outlined,
|
||||
size: 18,
|
||||
color: Colors.black,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
profileData?['email'] ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (profileData?['role_id'] != '1' &&
|
||||
profileData?['role_id'] != '2') ...[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.location_on_outlined,
|
||||
size: 18,
|
||||
color: Colors.black,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
|
||||
Expanded(
|
||||
child: Text(
|
||||
profileData?['address'] ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
|
||||
if (profileData?['role_id'] != 2) ...[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6),
|
||||
color: Color(0xffEDF6F5),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
print("Download - $latestId");
|
||||
dynamic path;
|
||||
|
||||
if (roleId == 1) {
|
||||
path =
|
||||
'api/agent/downloadManagerIncentiveFile?id=$latestId';
|
||||
} else if (roleId != 1 && roleId != 2) {
|
||||
path =
|
||||
'api/agent/downloadAgentIncentiveFile?id=$latestId';
|
||||
}
|
||||
apiService.getPdfDownload(path, latestId);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.download),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
"Download Incentive file",
|
||||
style: _dataSub,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
isProfile = false;
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
"View Previous Files",
|
||||
style: TextStyle(
|
||||
color: Color(0xff425B5B),
|
||||
decoration:
|
||||
TextDecoration.underline, // 👈 underline
|
||||
decorationThickness: 1.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
color: Colors.white,
|
||||
padding: ResponsiveLayout.isMobile(context)
|
||||
? EdgeInsets.all(16.0)
|
||||
: null,
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: filteredIncentiveData.isEmpty
|
||||
? const Center(
|
||||
child: Text("No incentive files found"),
|
||||
)
|
||||
: SizedBox(
|
||||
height: ResponsiveLayout.isMobile(context)
|
||||
? MediaQuery.of(context).size.height * 0.4
|
||||
: 450,
|
||||
child: ListView.builder(
|
||||
// padding: const EdgeInsets.all(8),
|
||||
itemCount: filteredIncentiveData.length,
|
||||
itemBuilder: (context, index) {
|
||||
final file = filteredIncentiveData[index];
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 2.0,
|
||||
),
|
||||
child: IncentiveFileRow(
|
||||
fileName:
|
||||
file['incentive_file_name'] ??
|
||||
"Unknown",
|
||||
date: file['incentive_month'] ?? "-",
|
||||
onUpload: () {
|
||||
print("Upload ${file['id']}");
|
||||
final selectedId = file['id'];
|
||||
|
||||
dynamic path;
|
||||
|
||||
if (roleId == 1) {
|
||||
path =
|
||||
'api/agent/downloadManagerIncentiveFile?id=$selectedId';
|
||||
} else if (roleId != 1 &&
|
||||
roleId != 2) {
|
||||
path =
|
||||
'api/agent/downloadAgentIncentiveFile?id=$selectedId';
|
||||
}
|
||||
apiService.getPdfDownload(
|
||||
path,
|
||||
selectedId,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final _dataBold = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
);
|
||||
|
||||
static final _dataSub = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF000000),
|
||||
);
|
||||
|
||||
static const _headerStyle = TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 20,
|
||||
);
|
||||
|
||||
static const _topheaderStyle = TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 19,
|
||||
);
|
||||
}
|
||||
|
||||
class IncentiveFileRow extends StatelessWidget {
|
||||
final String fileName;
|
||||
final String date;
|
||||
final VoidCallback? onUpload;
|
||||
// final VoidCallback? onDelete;
|
||||
|
||||
const IncentiveFileRow({
|
||||
super.key,
|
||||
required this.fileName,
|
||||
required this.date,
|
||||
this.onUpload,
|
||||
// this.onDelete,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 7.0),
|
||||
// margin: const EdgeInsets.only(bottom: 5), // spacing between rows
|
||||
decoration: BoxDecoration(
|
||||
// color: Colors.amber.shade50,
|
||||
border: Border(
|
||||
bottom: BorderSide(width: 0.6, color: const Color(0xFFE3E3E3)),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF4F6F8),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
border: Border.all(color: const Color(0xFFE3E3E3)),
|
||||
),
|
||||
child: const Icon(Icons.file_present, color: Color(0xFF838587)),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Text(
|
||||
fileName,
|
||||
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF1D1B20),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
Text(date, style: const TextStyle(color: Color(0xFF6E6E6E))),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
GestureDetector(
|
||||
onTap: onUpload,
|
||||
child: const Icon(
|
||||
Icons.file_download_outlined,
|
||||
color: Color(0xFF6E6E6E),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../layouts/main_layout.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../layouts/main_layout.dart';
|
||||
import '../../providers/manager_provider.dart';
|
||||
import '../../providers/userRoleProvider.dart';
|
||||
|
||||
@ -18,9 +18,345 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
final managerId = ref.watch(managerIdProvider);
|
||||
final userId = ref.watch(userIdProvider);
|
||||
final role = ref.watch(userRoleProvider);
|
||||
|
||||
return MainLayout(
|
||||
title: "Home",
|
||||
body: Center(child: Text("Dashboard Page Content $managerId $userId $role")),
|
||||
body: Row(
|
||||
children: [
|
||||
// Main content
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
// Stats cards
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Row(
|
||||
children: const [
|
||||
Expanded(
|
||||
child: StatCard(
|
||||
title: "Policies Issued",
|
||||
today: "20",
|
||||
month: "600",
|
||||
year: "219000",
|
||||
imagePath: "assets/dashboard/Policy issue icon.png",
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: StatCard(
|
||||
title: "Premium Value",
|
||||
today: "₹21000",
|
||||
month: "₹630000",
|
||||
year: "₹239950000",
|
||||
imagePath: "assets/dashboard/Premium value.png",
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: StatCard(
|
||||
title: "Earnings",
|
||||
today: "₹2100",
|
||||
month: "₹63000",
|
||||
year: "₹23995000",
|
||||
imagePath:
|
||||
"assets/dashboard/Earnings.png", // uses image
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Tables
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(
|
||||
children: const [
|
||||
Expanded(
|
||||
child: DataSection(title: "Enquiries Pending (15)"),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: DataSection(title: "Quotations Pending (10)"),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Stats card widget
|
||||
class StatCard extends StatelessWidget {
|
||||
final String title;
|
||||
final String today;
|
||||
final String month;
|
||||
final String year;
|
||||
final String? imagePath;
|
||||
|
||||
const StatCard({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.today,
|
||||
required this.month,
|
||||
required this.year,
|
||||
this.imagePath,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
color: Color(0xFFEAF6F4),
|
||||
elevation: 1,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Image.asset(imagePath!, width: 28, height: 28),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
today,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
month,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
year,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Today",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(fontSize: 12),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"This Month",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(fontSize: 12),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"This Year",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(fontSize: 12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Table section widget
|
||||
class DataSection extends StatelessWidget {
|
||||
final String title;
|
||||
const DataSection({super.key, required this.title});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final data = List.generate(
|
||||
10,
|
||||
(i) => {
|
||||
"date": "12/09/2025 11:00 AM",
|
||||
"reg": "TN64V4387",
|
||||
"company": "New India",
|
||||
},
|
||||
);
|
||||
|
||||
return Card(
|
||||
color: const Color(0xFFEAF6F4), // light mint background
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20,
|
||||
color: Color(0xff425B5B),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF3E5B56),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Date & Time",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Registration number",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Insurer Company",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
|
||||
...data.map(
|
||||
(row) => Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 5),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5,
|
||||
horizontal: 12,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'2025-05-31',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'11:11 pm',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: Text(
|
||||
row["reg"]!,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
row["company"]!,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,16 +9,17 @@ class DrawerContentWrapper extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
Container(
|
||||
height: 45,
|
||||
width: 50,
|
||||
width: 55,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: const Color(0xFFB2D8D3),
|
||||
),
|
||||
child: Center(child: child),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
const SizedBox(height: 5),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ class DrawerMenu extends ConsumerStatefulWidget {
|
||||
class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||
OverlayEntry? _overlayEntry;
|
||||
|
||||
void _showPopup(BuildContext context, Offset offset, Size size) {
|
||||
void _showPopup(BuildContext context, Offset offset, Size size, String key) {
|
||||
_hidePopup(); // clear old one before creating new
|
||||
|
||||
_overlayEntry = OverlayEntry(
|
||||
@ -39,33 +39,76 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Tappped Agent");
|
||||
context.go(AppRoutes.agentLst);
|
||||
},
|
||||
child: const Text(
|
||||
"Agent",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
if (key == 'User') ...[
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Tappped Agent");
|
||||
context.go(AppRoutes.agentLst);
|
||||
},
|
||||
child: const Text(
|
||||
"Agent",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Bf clicked");
|
||||
context.go(AppRoutes.staffLst);
|
||||
},
|
||||
child: const Text(
|
||||
"Staff",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
const SizedBox(height: 5),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Bf clicked");
|
||||
context.go(AppRoutes.staffLst);
|
||||
},
|
||||
child: const Text(
|
||||
"Staff",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
if (key == 'Reports') ...[
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Tappped Agent");
|
||||
},
|
||||
child: const Text(
|
||||
"Enquiries",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Bf clicked");
|
||||
},
|
||||
child: const Text(
|
||||
"Claims",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
print("Bf clicked");
|
||||
},
|
||||
child: const Text(
|
||||
"Endorsement",
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -96,37 +139,50 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||
child: ListView(
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
// ListTile(
|
||||
// title: const Text("Home"),
|
||||
// onTap: () {
|
||||
// context.go(AppRoutes.home);
|
||||
// Navigator.pop(context);
|
||||
// },
|
||||
// ),
|
||||
SizedBox(height: 50),
|
||||
SizedBox(height: 30),
|
||||
DrawerContentWrapper(
|
||||
child: Image.asset(
|
||||
"assets/drawer/drawerImag1",
|
||||
height: 50,
|
||||
width: 50,
|
||||
"assets/drawer/drawerImg1.png",
|
||||
height: 25,
|
||||
width: 25,
|
||||
),
|
||||
),
|
||||
DrawerContentWrapper(
|
||||
child: Image.asset(
|
||||
"assets/drawer/drawerImag2",
|
||||
height: 50,
|
||||
width: 50,
|
||||
),
|
||||
DrawerLabel("Dashboard"),
|
||||
|
||||
Builder(
|
||||
builder: (itemContext) {
|
||||
return MouseRegion(
|
||||
// onEnter: (_) => _showPopup(itemContext),
|
||||
onEnter: (_) {
|
||||
final renderBox = itemContext.findRenderObject() as RenderBox;
|
||||
final offset = renderBox.localToGlobal(Offset.zero);
|
||||
final size = renderBox.size;
|
||||
final key = "Reports";
|
||||
_showPopup(context, offset, size, key);
|
||||
},
|
||||
|
||||
child: DrawerContentWrapper(
|
||||
child: Image.asset(
|
||||
"assets/drawer/drawerImg2.png",
|
||||
height: 25,
|
||||
width: 25,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
DrawerLabel("Reports"),
|
||||
|
||||
DrawerContentWrapper(
|
||||
child: Image.asset(
|
||||
"assets/drawer/drawerImag3",
|
||||
height: 50,
|
||||
width: 50,
|
||||
child: IconButton(
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.list_alt_rounded, size: 30, color: Colors.black),
|
||||
),
|
||||
),
|
||||
|
||||
if (roleId == 'manager')
|
||||
DrawerLabel("Enquiry"),
|
||||
|
||||
if (roleId == 'manager') ...[
|
||||
Builder(
|
||||
builder: (itemContext) {
|
||||
return MouseRegion(
|
||||
@ -136,7 +192,8 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||
itemContext.findRenderObject() as RenderBox;
|
||||
final offset = renderBox.localToGlobal(Offset.zero);
|
||||
final size = renderBox.size;
|
||||
_showPopup(context, offset, size);
|
||||
final key = 'User';
|
||||
_showPopup(context, offset, size, key);
|
||||
},
|
||||
|
||||
child: DrawerContentWrapper(
|
||||
@ -145,8 +202,26 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||
);
|
||||
},
|
||||
),
|
||||
DrawerLabel("User"),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DrawerLabel extends StatelessWidget {
|
||||
final String text;
|
||||
const DrawerLabel(this.text, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(text, style: const TextStyle(color: Colors.white, fontSize: 11.5)),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,8 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
final VoidCallback? onBack;
|
||||
final VoidCallback? onMenuPressed;
|
||||
final VoidCallback? onLogout;
|
||||
final VoidCallback? onProfile;
|
||||
// final VoidCallback? onProfile;
|
||||
final void Function(TapDownDetails details)? onProfile;
|
||||
final VoidCallback? onNotifications;
|
||||
final int notificationCount;
|
||||
|
||||
@ -33,7 +34,11 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
children: [
|
||||
if (isMobile)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black87, size: 18),
|
||||
icon: const Icon(
|
||||
Icons.arrow_back_ios,
|
||||
color: Colors.black87,
|
||||
size: 18,
|
||||
),
|
||||
onPressed: onBack ?? () => Navigator.pop(context),
|
||||
)
|
||||
else if (onMenuPressed != null)
|
||||
@ -56,10 +61,14 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
onPressed: onNotifications,
|
||||
),
|
||||
if (!isMobile) ...[
|
||||
IconButton(
|
||||
icon: const Icon(Icons.person_outline, color: Colors.black87),
|
||||
onPressed: onProfile,
|
||||
GestureDetector(
|
||||
onTapDown: (details) => onProfile!(details),
|
||||
child: const Icon(Icons.person_outline, color: Colors.black87),
|
||||
),
|
||||
// IconButton(
|
||||
// icon: const Icon(Icons.person_outline, color: Colors.black87),
|
||||
// onPressed: onProfile,
|
||||
// ),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.logout, color: Colors.black87),
|
||||
onPressed: onLogout,
|
||||
|
||||
@ -91,6 +91,7 @@ flutter:
|
||||
- assets/login/
|
||||
- assets/drawer/
|
||||
- assets/miscellaneous/
|
||||
- assets/dashboard/
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user