policy ui changes

This commit is contained in:
venbaittech 2025-04-05 14:16:08 +05:30
parent 83d71279eb
commit 1f28816021
6 changed files with 2630 additions and 2232 deletions

View File

@ -7,74 +7,72 @@ import 'package:shared_preferences/shared_preferences.dart';
import '../../config/apiUrl.dart';
import '../../data/models/plan.dart';
class BusListWidget extends StatelessWidget{
class BusListWidget extends StatelessWidget {
final List<Map<String, dynamic>> busList;
final Function(bool, Map<String, dynamic>, String) onOpen;
final Function(Map<String,dynamic>) onDeleteBus;
const BusListWidget({super.key, required this.busList, required this.onOpen, required this.onDeleteBus});
final Function(Map<String, dynamic>) onDeleteBus;
const BusListWidget(
{super.key,
required this.busList,
required this.onOpen,
required this.onDeleteBus});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Bus Booking List",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Container(
// color: Colors.blueGrey,
width: double.infinity,
child: Center(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width ,
child: DataTable(
border: TableBorder(
bottom: BorderSide(color: Colors.black12),
horizontalInside: BorderSide(color: Colors.black12), // Only horizontal lines
),
columns: const [
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Bus Booking List",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Container(
// color: Colors.blueGrey,
width: double.infinity,
child: Center(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
// child: Expanded(
// DataColumn(label: Text('#')),
DataColumn(label: Text('From')),
DataColumn(label: Text('To')),
DataColumn(label: Text('Date')),
DataColumn(label: Text('Time')),
DataColumn(label: Text('Actions')),
],
rows: _buildDataRows(),
),
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: DataTable(
border: TableBorder(
bottom: BorderSide(color: Colors.black12),
horizontalInside: BorderSide(
color: Colors.black12), // Only horizontal lines
),
columns: const [
// DataColumn(label: Text('#')),
DataColumn(label: Text('From')),
DataColumn(label: Text('To')),
DataColumn(label: Text('Date')),
DataColumn(label: Text('Time')),
DataColumn(label: Text('Actions')),
],
rows: _buildDataRows(),
),
),
// )
),
),
],
),
),
],
),
);
}
List<DataRow> _buildDataRows() {
List<Map<String, dynamic>> filteredList = busList
.where((item) => item["is_active"] == "1")
.toList();
List<Map<String, dynamic>> filteredList =
busList.where((item) => item["is_active"] == "1").toList();
print("filteredList- $filteredList");
return filteredList.asMap().entries.map((entry) {
final Map<String, dynamic> item = entry.value;
return DataRow(cells: [

View File

@ -2,15 +2,18 @@ import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
class ForexListWidget extends StatelessWidget{
final List<Map<String,dynamic>> forexList;
final Function(bool, Map<String,dynamic>, String)onOpen;
final Function(Map<String,dynamic>) onDeleteForex;
class ForexListWidget extends StatelessWidget {
final List<Map<String, dynamic>> forexList;
final Function(bool, Map<String, dynamic>, String) onOpen;
final Function(Map<String, dynamic>) onDeleteForex;
final List<dynamic>? apiCountryData;
const ForexListWidget({super.key, required this.forexList, required this.onOpen,
required this.onDeleteForex,required this.apiCountryData});
const ForexListWidget(
{super.key,
required this.forexList,
required this.onOpen,
required this.onDeleteForex,
required this.apiCountryData});
@override
Widget build(BuildContext context) {
@ -30,66 +33,61 @@ class ForexListWidget extends StatelessWidget{
child: Center(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width ,
child: DataTable(
border: TableBorder(
bottom: BorderSide(color: Colors.black12),
horizontalInside: BorderSide(color: Colors.black12), // Only horizontal lines
),
columns: const [
// DataColumn(label: Text('#')),
DataColumn(label: Text('Forex Start Date')),
DataColumn(label: Text('Forex End Date')),
DataColumn(label: Text('Country')),
DataColumn(label: Text('Perdiem Amount')),
DataColumn(label: Text('Actions')),
],
rows: _buildDataRows(),
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: DataTable(
border: TableBorder(
bottom: BorderSide(color: Colors.black12),
horizontalInside: BorderSide(
color: Colors.black12), // Only horizontal lines
),
columns: const [
// DataColumn(label: Text('#')),
DataColumn(label: Text('Forex Start Date')),
DataColumn(label: Text('Forex End Date')),
DataColumn(label: Text('Country')),
DataColumn(label: Text('Perdiem Amount')),
DataColumn(label: Text('Actions')),
],
rows: _buildDataRows(),
),
),
//
),
),
),
],
),
);
}
List<DataRow> _buildDataRows() {
List<dynamic> countryList = apiCountryData ?? [];
List<dynamic> countryList = apiCountryData ?? [];
List<Map<String, dynamic>> filteredList = forexList
.where((item) => item["is_active"] == "1")
.toList();
List<Map<String, dynamic>> filteredList =
forexList.where((item) => item["is_active"] == "1").toList();
print("filteredList- $filteredList");
String getRequestForCountry(String? countryCode) {
if (countryCode == null) return "N/A";
return countryList
.firstWhere(
(element) => element["country_code"].toString() == countryCode,
orElse: () => {"country_name": "N/A"},
)["country_name"]
orElse: () => {"country_name": "N/A"},
)["country_name"]
.toString();
}
return filteredList.asMap().entries.map((entry) {
Map<String,dynamic> item = entry.value;
Map<String, dynamic> item = entry.value;
return DataRow(cells: [
// DataCell(Text(item["indx"]?.toString() ?? "N/A")), // Index column
DataCell(Text(item["start_date"] ?? "N/A")),
DataCell(Text(item["end_date"] ?? "N/A")),
DataCell( Text(getRequestForCountry( item["country_code"]!.toString()))),
DataCell(Text(getRequestForCountry(item["country_code"]!.toString()))),
// DataCell(Text(item["country_code"] ?? "N/A")),
DataCell(Text(item["perdiem_amount"] ?? "N/A")),
DataCell(Row(

View File

@ -45,106 +45,115 @@ class _PolicyState extends State<Policy> {
return Container(
margin: isDesktop
? EdgeInsets.all(20.0)
: EdgeInsets.only(left: 20.0, bottom: 20.0, top: 10.0, right: 10.0),
: EdgeInsets.only(left: 20.0, bottom: 20.0, top: 10.0, right: 20.0),
height: MediaQuery.of(context).size.height,
// color: Colors.grey,
decoration: BoxDecoration(
border: isDesktop
? Border.all(
width: 3,
color: Color(0xFFF7F7FB),
)
: null,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
// color: Color(0xFFF7F7FB),
color: Color(0xFFF7F7FB),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Container(
// color: Colors.amber,
// color: Color(0xFFF7F7FB),
padding: EdgeInsets.all(5),
alignment: Alignment.center,
child: Text(
"Choose Policy Type",
style: TextStyle(
fontSize: 18,
),
),
),
),
],
),
SizedBox(
height: 10,
),
Container(
padding: isDesktop ? EdgeInsets.all(6) : EdgeInsets.all(3),
// color: Colors.white, // Background to avoid overlapping
color: isDesktop ? Color(0xFFF7F7FB) : Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
policyType = "domestic";
});
},
child: Container(
padding: EdgeInsets.all(10),
color: policyType == "domestic"
? Colors.blueAccent.shade100
: Color(0xFFEBEBF7),
// color: Colors.blue.shade300,
child: Column(
children: [
Text(
"Domestic",
style: TextStyle(
color: policyType == "domestic"
? Colors.white
: Colors.black87,
fontSize: 15,
fontWeight: FontWeight.bold),
),
],
),
),
Text(
"Choose Policy Type",
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
policyType = "international";
});
},
child: Container(
padding: EdgeInsets.all(10),
// color: Color(0xFFEBEBF7),
color: policyType == "international"
? Colors.blueAccent.shade100
: Color(0xFFEBEBF7),
// color: Color(0xFFE3F2FD),
child: Column(
children: [
Text(
"International",
style: TextStyle(
color: policyType == "international"
? Colors.white
: Colors.black87,
fontSize: 15,
fontWeight: FontWeight.bold),
),
],
),
),
)),
],
),
),
// Container(
// child: Row(
// children: [
// Expanded(
// child: GestureDetector(
// onTap: () {
// setState(() {
// policyType = "domestic";
// });
// },
// child: Container(
// padding: EdgeInsets.all(10),
// color: policyType == "domestic"
// ? Colors.blueAccent.shade100
// : Color(0xFFEBEBF7),
// // color: Colors.blue.shade300,
// child: Column(
// children: [
// Text(
// "Domestic",
// style: TextStyle(
// color: policyType == "domestic"
// ? Colors.white
// : Colors.black87,
// fontSize: 15,
// fontWeight: FontWeight.bold),
// ),
// ],
// ),
// ),
// ),
// ),
// Expanded(
// child: GestureDetector(
// onTap: () {
// setState(() {
// policyType = "international";
// });
// },
// child: Container(
// padding: EdgeInsets.all(10),
// // color: Color(0xFFEBEBF7),
// color: policyType == "international"
// ? Colors.blueAccent.shade100
// : Color(0xFFEBEBF7),
// // color: Color(0xFFE3F2FD),
//
// child: Column(
// children: [
// Text(
// "International",
// style: TextStyle(
// color: policyType == "international"
// ? Colors.white
// : Colors.black87,
// fontSize: 15,
// fontWeight: FontWeight.bold),
// ),
// ],
// ),
// ),
// )),
// ],
// ),
// ),
//
],
),
),
SizedBox(
height: 10,
),
isDesktop
? Expanded(
child: Row(
@ -215,7 +224,7 @@ class _PolicyState extends State<Policy> {
return SizedBox(
width: isDesktop ? 180 : null,
height: isDesktop
? max((MediaQuery.of(context).size.height * 0.085), 10)
? max((MediaQuery.of(context).size.height * 0.09), 10)
: 45,
child: GestureDetector(
onTap: () {

View File

@ -23,6 +23,7 @@ class PolicyCriteria extends StatefulWidget {
class _PolicyCriteriaState extends State<PolicyCriteria> {
String? selectedFirstApprovarType;
String? selectedService;
String? _selectedTripType;
// bool isClass = true;
// bool isCost = true;
@ -42,12 +43,12 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: 15),
widget.isDesktop ? SizedBox(height: 10) : SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Selected Policy Criteria For ${widget.selectedTab} ",
" Policy Criteria For ${widget.selectedTab} ",
style: TextStyle(
fontSize: 13,
color: Color(0xFF9E9DBD),
@ -55,7 +56,17 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
)
],
),
if (widget.isClass!) SizedBox(height: 15),
widget.isDesktop ? SizedBox(height: 15) : SizedBox(height: 5),
Padding(
padding: widget.isDesktop
? const EdgeInsets.all(8.0)
: const EdgeInsets.all(1.0),
child: Row(
children: _buildTripType(widget.isDesktop),
),
),
if (widget.isClass!)
widget.isDesktop ? SizedBox(height: 15) : SizedBox(height: 5),
Row(
children: [
Expanded(
@ -171,21 +182,24 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
Expanded(
child: Container(
width: widget.isDesktop
? MediaQuery.of(context).size.width * 0.62
? MediaQuery.of(context).size.width * 0.63
: 600,
child: Column(
children: [
Container(
margin: const EdgeInsets.only(right: 20),
decoration: BoxDecoration(
color: Colors.grey.shade50,
border: Border.all(
color: Colors.grey.shade50,
),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(10),
padding: const EdgeInsets.only(
top: 10, bottom: 10, left: 35, right: 35),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
mainAxisAlignment: widget.isDesktop
? MainAxisAlignment.spaceAround
: MainAxisAlignment.spaceBetween,
children: [
Text(
"Approver Name",
@ -217,6 +231,7 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
scrollDirection: Axis.vertical,
child: Container(
// color: Colors.grey,
margin: const EdgeInsets.only(right: 20),
color: Colors.grey.shade50,
child: Column(children: [
Container(
@ -496,4 +511,57 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
],
);
}
List<Widget> _buildTripType(bool isMobile) {
return [
CustomTextFieldWrapper(
color: Color(0xFFF4F4FB),
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
width: 120,
isFocused: _selectedTripType == "1",
isDesktop: widget.isDesktop,
child: SizedBox(
height: 35,
child: Material(
color: Colors.transparent,
child: RadioListTile<String>(
activeColor: Colors.blueAccent,
contentPadding: EdgeInsets.zero,
visualDensity: VisualDensity.compact,
dense: true,
title: Text("Domestic"),
value: "1",
groupValue: _selectedTripType,
onChanged: (value) {
setState(() {
_selectedTripType = value!;
});
},
),
),
),
),
SizedBox(width: 20),
CustomTextFieldWrapper(
color: Color(0xFFF4F4FB),
width: 150,
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 2),
isFocused: _selectedTripType == "2",
isDesktop: widget.isDesktop,
child: RadioListTile<String>(
activeColor: Colors.blueAccent,
contentPadding: EdgeInsets.zero,
dense: true,
title: Text("International"),
value: "2",
groupValue: _selectedTripType,
onChanged: (value) {
setState(() {
_selectedTripType = value!;
});
},
),
),
];
}
}

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@ class _UserListScreenState extends State<UserListScreen> {
Future<String?> getToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('auth_token');
}
Future<List<dynamic>> fetchUsers() async {
@ -74,11 +73,12 @@ class _UserListScreenState extends State<UserListScreen> {
final data = json.decode(response.body);
print("Country - $data");
if (!data.containsKey('data') || data['data'] is!List) {
throw Exception("Invalid response format: 'data' field is missing or not a List");
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception(
"Invalid response format: 'data' field is missing or not a List");
}
List <dynamic> plansJson = data['data']; // 'data' is a Map, not a List
List<dynamic> plansJson = data['data']; // 'data' is a Map, not a List
if (data['data'] is List) {
List<dynamic> plansJson = data['data'];
@ -91,7 +91,6 @@ class _UserListScreenState extends State<UserListScreen> {
apiCountryData = plansJson; // Store API response in state
});
print('plansJSONContry - $plansJson');
} catch (e) {
throw Exception('Error parsing response: $e');
}
@ -100,7 +99,6 @@ class _UserListScreenState extends State<UserListScreen> {
}
}
@override
void initState() {
super.initState();
@ -108,15 +106,15 @@ class _UserListScreenState extends State<UserListScreen> {
fetchCountryList();
}
void handleDelete(userId){
void handleDelete(userId) {
print("handDel - $userId");
}
void handleToggleUserStatus(String userId, String currentStatus) async {
print("Toggling user status - $userId (Current: $currentStatus)");
final String apiUrlData = '$apiUrl/api/users/update/$userId'; // API for updating user
final String apiUrlData =
'$apiUrl/api/users/update/$userId'; // API for updating user
final String? token = await getToken();
if (token == null) {
@ -158,331 +156,412 @@ class _UserListScreenState extends State<UserListScreen> {
});
}
@override
Widget build(BuildContext context) {
return ResponsiveBuilder(builder: (context, sizingInfo) {
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
return Scaffold(
appBar: isDesktop ? null : const CustomAppBar(title:'User Management'),
appBar: isDesktop ? null : const CustomAppBar(title: 'User Management'),
drawer: isDesktop ? null : CustomDrawer(isDesktop: false),
body:
Container(
body: Container(
color: Colors.white,
child: Row(
children: [
if(isDesktop)
CustomDrawer(isDesktop: true),
if (isDesktop) CustomDrawer(isDesktop: true),
// const Expanded(child: Center(child: Text("User Page Content"))),
Expanded(child: buildUserTable(isDesktop)),
],
),
),
);
});
}
Widget buildUserTable(bool isDesktop) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
child:
Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
const Text('User List',
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.keyboard_arrow_down),
onPressed: () {
},
),
],
),
ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.blueAccent),
onPressed: () async {
List<dynamic> users = await futureUsers;
// Print the resolved value
print("CREATELIAS - $users");
context.go("/CreateUserDetails",
extra: {
// 'apiCountryData': apiCountryData,
'apiUserData' :users,
}
);
if (!isDesktop) Navigator.pop(context);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(Icons.add_circle,color: Colors.white,),
SizedBox(width: 5,),
Text('New User'),
const Text('User List',
style:
TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.keyboard_arrow_down),
onPressed: () {},
),
],
),
),
],
),
const SizedBox(height: 10),
ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: Colors.blueAccent),
onPressed: () async {
List<dynamic> users = await futureUsers;
FutureBuilder<List<dynamic>>(
future: futureUsers,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text("No users found"));
}
// Print the resolved value
print("CREATELIAS - $users");
List<dynamic> users = snapshot.data!;
Color borderColor = Color(0xFF9E9DBD);
context.go("/CreateUserDetails", extra: {
// 'apiCountryData': apiCountryData,
'apiUserData': users,
});
if (!isDesktop) Navigator.pop(context);
},
child: Row(
children: [
Icon(
Icons.add_circle,
color: Colors.white,
),
SizedBox(
width: 5,
),
Text('New User'),
],
),
),
],
),
const SizedBox(height: 10),
FutureBuilder<List<dynamic>>(
future: futureUsers,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text("Error: ${snapshot.error}"));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text("No users found"));
}
return Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
width: MediaQuery.of(context).size.width * 1.5,
child: SingleChildScrollView(
List<dynamic> users = snapshot.data!;
Color borderColor = Color(0xFF9E9DBD);
scrollDirection: Axis.horizontal, // Inner wrapper for vertical scrolling
return Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
width: MediaQuery.of(context).size.width * 1.5,
child: SingleChildScrollView(
scrollDirection: Axis
.horizontal, // Inner wrapper for vertical scrolling
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width),
// constraints: BoxConstraints(minWidth: 1300),
// width: MediaQuery.of(context).size.width ,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width * 0.8),
// constraints: BoxConstraints(minWidth: 1300),
// width: MediaQuery.of(context).size.width ,
child: Container(
// color: Colors.amber,
child: DataTable(
columnSpacing: 20.0, // Adjust spacing between columns
dividerThickness: 0.5,
dataRowMinHeight: 60.0, // Minimum row height
dataRowMaxHeight: 100.0,
border: TableBorder(
horizontalInside: BorderSide(width: 0.5, color: Colors.grey.shade200),
),
columns: const [
child: Container(
// color: Colors.grey,
// color: Colors.amber,
child: DataTable(
columnSpacing:
20.0, // Adjust spacing between columns
dividerThickness: 0.5,
dataRowMinHeight: 60.0, // Minimum row height
dataRowMaxHeight: 100.0,
border: TableBorder(
horizontalInside: BorderSide(
width: 0.5, color: Colors.grey.shade200),
),
columns: const [
DataColumn(
label: Text(
'User Details',
style: TextStyle(
color: Color(0xFF9E9DBD),
fontSize: 15,
fontWeight: FontWeight.bold),
)),
DataColumn(
label: Text(
'Role',
style: TextStyle(
color: Color(0xFF9E9DBD),
fontSize: 15,
fontWeight: FontWeight.bold),
)),
DataColumn(
label: Text(
'Level',
style: TextStyle(
color: Color(0xFF9E9DBD),
fontSize: 15,
fontWeight: FontWeight.bold),
)),
DataColumn(
label: Text(
'Status',
style: TextStyle(
color: Color(0xFF9E9DBD),
fontSize: 15,
fontWeight: FontWeight.bold),
)),
DataColumn(
label: Text(
'Actions',
style: TextStyle(
color: Color(0xFF9E9DBD),
fontSize: 15,
fontWeight: FontWeight.bold),
)),
],
DataColumn(label: Text('User Details',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)),
DataColumn(label: Text('Role',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)),
DataColumn(label: Text('Level',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)),
DataColumn(label: Text('Status',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)),
DataColumn(label: Text('Actions',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)),
rows: users.map((user) {
String userId =
user['user_id'].toString(); // Get user ID
bool isSelected = selectedUserId == userId;
],
return DataRow(cells: [
// DataCell(Text(user['user_id'].toString())),
DataCell(Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: () {
setState(() {
selectedUserId =
userId; // Store clicked user ID
});
},
child: Container(
width: 15, // Adjust size
height: 15,
decoration: BoxDecoration(
// Background color
shape: BoxShape.rectangle,
border: Border.all(
color: isSelected
? Colors.blueAccent
: Color(0xFF9E9DBD),
// color: Color(0xFF9E9DBD),
// color: Color.fromRGBO(128, 128, 128, 0.6),
width: isSelected
? 2
: 1), // Grey outline
),
),
),
),
SizedBox(
width: 50,
),
Align(
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Color(0xFF9E9DBD),
width: 1), // Grey outline
),
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: 40, // Adjust size
height: 40,
decoration: BoxDecoration(
color: Colors
.amber, // Inner circle background
shape: BoxShape.circle,
),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Text(
(user['first_name'] !=
null &&
user['first_name']!
.isNotEmpty)
? user['first_name']![0]
.toUpperCase()
: "?",
style: TextStyle(
fontSize: 18,
fontWeight:
FontWeight.bold,
color: Colors.white,
),
),
],
),
),
)),
),
SizedBox(
width: 20,
),
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
"${user['first_name'] ?? ''} ${user['last_name'] ?? ''}",
style: TextStyle(
color: Colors.blueAccent,
fontSize: 16),
),
],
),
SizedBox(height: 5),
Row(
children: [
Icon(Icons.mail_outline,
size: 15,
color: Color(0xFF9E9EBE)),
SizedBox(
width: 10,
),
Text(user['email'] ?? '')
],
),
SizedBox(height: 5),
Row(
children: [
Icon(Icons.account_tree_outlined,
size: 15,
color: Color(0xFF9E9EBE)),
SizedBox(
width: 10,
),
Text(user['user_type'] ?? '')
],
),
],
),
],
)),
rows: users.map((user) {
String userId = user['user_id'].toString(); // Get user ID
bool isSelected = selectedUserId == userId;
DataCell(Text(
user['role_id'] ?? 'N/A',
style: TextStyle(
color: user['is_active'] == "1"
? Colors.black
: Colors.grey,
fontWeight: FontWeight.bold),
)),
DataCell(Text(
user['level_id'] ?? 'N/A',
style: TextStyle(
color: user['is_active'] == "1"
? Colors.black
: Colors.grey,
fontWeight: FontWeight.bold),
)),
DataCell(GestureDetector(
onTap: () {
handleToggleUserStatus(
user['user_id'], user['is_active']);
},
child: Text(
user['is_active'] == "1"
? "Active"
: "Inactive",
style: TextStyle(
color: user['is_active'] == "1"
? Colors.lightGreen
: Colors.grey,
fontWeight: FontWeight.bold),
))),
return DataRow(cells: [
// DataCell(Text(user['user_id'].toString())),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(alignment: Alignment.center,
child: GestureDetector(
onTap: () {
setState(() {
selectedUserId = userId; // Store clicked user ID
});
},
child: Container(
width: 15, // Adjust size
height: 15,
decoration: BoxDecoration(
// Background color
shape: BoxShape.rectangle,
border: Border.all(
color: isSelected ? Colors.blueAccent : Color(0xFF9E9DBD),
// color: Color(0xFF9E9DBD),
// color: Color.fromRGBO(128, 128, 128, 0.6),
width: isSelected ?2:1), // Grey outline
),
),
),
),
SizedBox(width: 50,),
Align(
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Color(0xFF9E9DBD), width: 1), // Grey outline
),
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: 40, // Adjust size
height: 40,
decoration: BoxDecoration(
color: Colors.amber, // Inner circle background
shape: BoxShape.circle,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
(user['first_name'] != null && user['first_name']!.isNotEmpty)
? user['first_name']![0].toUpperCase()
: "?",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ),
),],
),
),
)),
),
SizedBox(width: 20,),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(children: [
Text("${user['first_name'] ?? ''} ${user['last_name'] ?? ''}",
style: TextStyle( color: Colors.blueAccent,fontSize: 16),),
],),
SizedBox(height: 5),
Row(children: [
Icon(Icons.mail_outline, size: 15,color: Color(0xFF9E9EBE)),
SizedBox(width: 10,),
Text(user['email'] ?? '')
],),
SizedBox(height: 5),
Row(children: [
Icon(Icons.account_tree_outlined, size: 15,color:Color(0xFF9E9EBE)),
SizedBox(width: 10,),
Text(user['user_type'] ?? '') ],),
],),
],
)
),
DataCell(Text(user['role_id'] ?? 'N/A',style: TextStyle(color: user['is_active'] == "1" ? Colors.black :Colors.grey, fontWeight: FontWeight.bold),)),
DataCell(Text(user['level_id'] ?? 'N/A',style: TextStyle(color: user['is_active'] == "1" ? Colors.black :Colors.grey, fontWeight: FontWeight.bold),)),
DataCell(
GestureDetector( onTap :(){
handleToggleUserStatus(user['user_id'], user['is_active']);
},
child: Text(
user['is_active'] == "1" ? "Active" : "Inactive",
style: TextStyle(color: user['is_active'] == "1" ? Colors.lightGreen :Colors.grey ,
fontWeight: FontWeight.bold),)
)
),
DataCell(
Row(
children: [
MouseRegion(
cursor: user['is_active'] == "0" ? SystemMouseCursors.forbidden : SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.remove_red_eye, color: user['is_active'] == "0" ? Colors.grey : Colors.blueAccent),
onPressed: user['is_active'] == "0"
? null
: () {
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": user,
"isViewMode": true
},
);
},
),
),
MouseRegion(
cursor: user['is_active'] == "0" ? SystemMouseCursors.forbidden : SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.edit, color: user['is_active'] == "0" ? Colors.grey : Colors.green),
onPressed: user['is_active'] == "0"
? null
: () {
print("USER: $user");
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": user,
"isViewMode": false
},
);
},
),
),
MouseRegion(
cursor: user['is_active'] == "0" ? SystemMouseCursors.forbidden : SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.delete, color: user['is_active'] == "0" ? Colors.grey : Colors.redAccent),
onPressed: user['is_active'] == "0"
? null
: () {
print("USER ID: ${user['user_id']}");
var userId = user['user_id'];
handleDelete(userId);
},
),
),
],
),
),
]);
}).toList(),
),
),
),
),
),
),
);
},
),
]));
DataCell(
Row(
children: [
MouseRegion(
cursor: user['is_active'] == "0"
? SystemMouseCursors.forbidden
: SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.remove_red_eye,
color: user['is_active'] == "0"
? Colors.grey
: Colors.blueAccent),
onPressed: user['is_active'] == "0"
? null
: () {
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": user,
"isViewMode": true
},
);
},
),
),
MouseRegion(
cursor: user['is_active'] == "0"
? SystemMouseCursors.forbidden
: SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.edit,
color: user['is_active'] == "0"
? Colors.grey
: Colors.green),
onPressed: user['is_active'] == "0"
? null
: () {
print("USER: $user");
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": user,
"isViewMode": false
},
);
},
),
),
MouseRegion(
cursor: user['is_active'] == "0"
? SystemMouseCursors.forbidden
: SystemMouseCursors.click,
child: IconButton(
icon: Icon(Icons.delete,
color: user['is_active'] == "0"
? Colors.grey
: Colors.redAccent),
onPressed: user['is_active'] == "0"
? null
: () {
print(
"USER ID: ${user['user_id']}");
var userId = user['user_id'];
handleDelete(userId);
},
),
),
],
),
),
]);
}).toList(),
),
),
),
),
),
),
);
},
),
]));
}
}