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:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:nhance_partner/core/routing/routes.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/claims/claimsList.dart';
|
||||||
import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart';
|
import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart';
|
||||||
import '../../data/services/auth_service.dart';
|
import '../../data/services/auth_service.dart';
|
||||||
@ -32,6 +33,11 @@ final GoRouter appRouter = GoRouter(
|
|||||||
builder: (context, state) => const DashboardScreen(),
|
builder: (context, state) => const DashboardScreen(),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
GoRoute(
|
||||||
|
path: AppRoutes.profile,
|
||||||
|
builder: (context, state) => const ProfilePopUp(),
|
||||||
|
),
|
||||||
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: AppRoutes.agentLst,
|
path: AppRoutes.agentLst,
|
||||||
// builder: (context, state) => const Agent(),
|
// builder: (context, state) => const Agent(),
|
||||||
@ -70,7 +76,6 @@ final GoRouter appRouter = GoRouter(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
redirect: (context, state) async {
|
redirect: (context, state) async {
|
||||||
final loggedIn = await AuthService.isLoggedIn();
|
final loggedIn = await AuthService.isLoggedIn();
|
||||||
|
|||||||
@ -3,9 +3,9 @@ class AppRoutes {
|
|||||||
static const String home = '/home';
|
static const String home = '/home';
|
||||||
static const String dashboard = '/dashboard';
|
static const String dashboard = '/dashboard';
|
||||||
static const String login = '/login';
|
static const String login = '/login';
|
||||||
|
static const String profile = '/profile';
|
||||||
static const String agentLst = '/agentLst';
|
static const String agentLst = '/agentLst';
|
||||||
static const agent = '/agent/:id';
|
static const agent = '/agent/:id';
|
||||||
static const String staffLst = '/staffLst';
|
static const String staffLst = '/staffLst';
|
||||||
static const staff = '/staff/:id';
|
static const staff = '/staff/:id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,6 +98,27 @@ class ApiService {
|
|||||||
return response;
|
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 {
|
Future<Map<String, dynamic>> fetchAgentUserList(int managerId) async {
|
||||||
// print(_token);
|
// print(_token);
|
||||||
if (_token == null) {
|
if (_token == null) {
|
||||||
@ -212,7 +233,7 @@ class ApiService {
|
|||||||
// final url = Uri.parse(
|
// final url = Uri.parse(
|
||||||
// 'https://venbait.in/nhance/partner/dev/api/agent/downloadAgentCertificateFile?agent_id=1',
|
// '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();
|
// final token = await getToken();
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:nhance_partner/core/routing/routes.dart';
|
import 'package:nhance_partner/core/routing/routes.dart';
|
||||||
import 'package:nhance_partner/data/services/auth_service.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/topbar.dart';
|
||||||
import '../widgets/footer.dart';
|
import '../widgets/footer.dart';
|
||||||
import '../widgets/drawer_menu.dart';
|
import '../widgets/drawer_menu.dart';
|
||||||
@ -19,6 +21,7 @@ class MainLayout extends StatelessWidget {
|
|||||||
return ResponsiveLayout(
|
return ResponsiveLayout(
|
||||||
// Mobile Layout
|
// Mobile Layout
|
||||||
mobile: Scaffold(
|
mobile: Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
appBar: TopBar(
|
appBar: TopBar(
|
||||||
title: title,
|
title: title,
|
||||||
isMobile: true,
|
isMobile: true,
|
||||||
@ -34,6 +37,9 @@ class MainLayout extends StatelessWidget {
|
|||||||
bottomNavigationBar: MobileTabs(
|
bottomNavigationBar: MobileTabs(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
debugPrint("Mobile tab changed to $index");
|
debugPrint("Mobile tab changed to $index");
|
||||||
|
if (index == 1) {
|
||||||
|
context.go(AppRoutes.profile);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -50,9 +56,27 @@ class MainLayout extends StatelessWidget {
|
|||||||
AuthService.clearToken();
|
AuthService.clearToken();
|
||||||
context.go(AppRoutes.login);
|
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: () {
|
onNotifications: () {
|
||||||
debugPrint("Notifications tapped");
|
debugPrint("Notifications tapped");
|
||||||
},
|
},
|
||||||
@ -60,18 +84,14 @@ class MainLayout extends StatelessWidget {
|
|||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 80, // fixed width for drawer
|
width: 90, // fixed width for drawer
|
||||||
child: DrawerMenu(),
|
child: DrawerMenu(),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: Column(
|
child: Column(children: [Expanded(child: body)]),
|
||||||
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 'package:flutter/material.dart';
|
||||||
import '../../layouts/main_layout.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.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/manager_provider.dart';
|
||||||
import '../../providers/userRoleProvider.dart';
|
import '../../providers/userRoleProvider.dart';
|
||||||
|
|
||||||
@ -18,9 +18,345 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
final managerId = ref.watch(managerIdProvider);
|
final managerId = ref.watch(managerIdProvider);
|
||||||
final userId = ref.watch(userIdProvider);
|
final userId = ref.watch(userIdProvider);
|
||||||
final role = ref.watch(userRoleProvider);
|
final role = ref.watch(userRoleProvider);
|
||||||
|
|
||||||
return MainLayout(
|
return MainLayout(
|
||||||
title: "Home",
|
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) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 10),
|
||||||
Container(
|
Container(
|
||||||
height: 45,
|
height: 45,
|
||||||
width: 50,
|
width: 55,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
color: const Color(0xFFB2D8D3),
|
color: const Color(0xFFB2D8D3),
|
||||||
),
|
),
|
||||||
child: Center(child: child),
|
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> {
|
class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
||||||
OverlayEntry? _overlayEntry;
|
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
|
_hidePopup(); // clear old one before creating new
|
||||||
|
|
||||||
_overlayEntry = OverlayEntry(
|
_overlayEntry = OverlayEntry(
|
||||||
@ -39,33 +39,76 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
if (key == 'User') ...[
|
||||||
onTap: () {
|
GestureDetector(
|
||||||
print("Tappped Agent");
|
onTap: () {
|
||||||
context.go(AppRoutes.agentLst);
|
print("Tappped Agent");
|
||||||
},
|
context.go(AppRoutes.agentLst);
|
||||||
child: const Text(
|
},
|
||||||
"Agent",
|
child: const Text(
|
||||||
style: TextStyle(
|
"Agent",
|
||||||
fontSize: 16,
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w400,
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 5),
|
||||||
const SizedBox(height: 5),
|
GestureDetector(
|
||||||
GestureDetector(
|
onTap: () {
|
||||||
onTap: () {
|
print("Bf clicked");
|
||||||
print("Bf clicked");
|
context.go(AppRoutes.staffLst);
|
||||||
context.go(AppRoutes.staffLst);
|
},
|
||||||
},
|
child: const Text(
|
||||||
child: const Text(
|
"Staff",
|
||||||
"Staff",
|
style: TextStyle(
|
||||||
style: TextStyle(
|
fontSize: 16,
|
||||||
fontSize: 16,
|
fontWeight: FontWeight.w400,
|
||||||
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(
|
child: ListView(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
children: [
|
children: [
|
||||||
// ListTile(
|
SizedBox(height: 30),
|
||||||
// title: const Text("Home"),
|
|
||||||
// onTap: () {
|
|
||||||
// context.go(AppRoutes.home);
|
|
||||||
// Navigator.pop(context);
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
SizedBox(height: 50),
|
|
||||||
DrawerContentWrapper(
|
DrawerContentWrapper(
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
"assets/drawer/drawerImag1",
|
"assets/drawer/drawerImg1.png",
|
||||||
height: 50,
|
height: 25,
|
||||||
width: 50,
|
width: 25,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DrawerContentWrapper(
|
DrawerLabel("Dashboard"),
|
||||||
child: Image.asset(
|
|
||||||
"assets/drawer/drawerImag2",
|
Builder(
|
||||||
height: 50,
|
builder: (itemContext) {
|
||||||
width: 50,
|
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: Image.asset(
|
child: IconButton(
|
||||||
"assets/drawer/drawerImag3",
|
onPressed: () {},
|
||||||
height: 50,
|
icon: Icon(Icons.list_alt_rounded, size: 30, color: Colors.black),
|
||||||
width: 50,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
if (roleId == 'manager')
|
DrawerLabel("Enquiry"),
|
||||||
|
|
||||||
|
if (roleId == 'manager') ...[
|
||||||
Builder(
|
Builder(
|
||||||
builder: (itemContext) {
|
builder: (itemContext) {
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
@ -136,7 +192,8 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
|
|||||||
itemContext.findRenderObject() as RenderBox;
|
itemContext.findRenderObject() as RenderBox;
|
||||||
final offset = renderBox.localToGlobal(Offset.zero);
|
final offset = renderBox.localToGlobal(Offset.zero);
|
||||||
final size = renderBox.size;
|
final size = renderBox.size;
|
||||||
_showPopup(context, offset, size);
|
final key = 'User';
|
||||||
|
_showPopup(context, offset, size, key);
|
||||||
},
|
},
|
||||||
|
|
||||||
child: DrawerContentWrapper(
|
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? onBack;
|
||||||
final VoidCallback? onMenuPressed;
|
final VoidCallback? onMenuPressed;
|
||||||
final VoidCallback? onLogout;
|
final VoidCallback? onLogout;
|
||||||
final VoidCallback? onProfile;
|
// final VoidCallback? onProfile;
|
||||||
|
final void Function(TapDownDetails details)? onProfile;
|
||||||
final VoidCallback? onNotifications;
|
final VoidCallback? onNotifications;
|
||||||
final int notificationCount;
|
final int notificationCount;
|
||||||
|
|
||||||
@ -33,7 +34,11 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
children: [
|
children: [
|
||||||
if (isMobile)
|
if (isMobile)
|
||||||
IconButton(
|
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),
|
onPressed: onBack ?? () => Navigator.pop(context),
|
||||||
)
|
)
|
||||||
else if (onMenuPressed != null)
|
else if (onMenuPressed != null)
|
||||||
@ -56,10 +61,14 @@ class TopBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
onPressed: onNotifications,
|
onPressed: onNotifications,
|
||||||
),
|
),
|
||||||
if (!isMobile) ...[
|
if (!isMobile) ...[
|
||||||
IconButton(
|
GestureDetector(
|
||||||
icon: const Icon(Icons.person_outline, color: Colors.black87),
|
onTapDown: (details) => onProfile!(details),
|
||||||
onPressed: onProfile,
|
child: const Icon(Icons.person_outline, color: Colors.black87),
|
||||||
),
|
),
|
||||||
|
// IconButton(
|
||||||
|
// icon: const Icon(Icons.person_outline, color: Colors.black87),
|
||||||
|
// onPressed: onProfile,
|
||||||
|
// ),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.logout, color: Colors.black87),
|
icon: const Icon(Icons.logout, color: Colors.black87),
|
||||||
onPressed: onLogout,
|
onPressed: onLogout,
|
||||||
|
|||||||
@ -91,6 +91,7 @@ flutter:
|
|||||||
- assets/login/
|
- assets/login/
|
||||||
- assets/drawer/
|
- assets/drawer/
|
||||||
- assets/miscellaneous/
|
- assets/miscellaneous/
|
||||||
|
- assets/dashboard/
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
# assets:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user