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

View File

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

View File

@ -45,106 +45,115 @@ class _PolicyState extends State<Policy> {
return Container( return Container(
margin: isDesktop margin: isDesktop
? EdgeInsets.all(20.0) ? 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, height: MediaQuery.of(context).size.height,
// color: Colors.grey, decoration: BoxDecoration(
border: isDesktop
? Border.all(
width: 3,
color: Color(0xFFF7F7FB),
)
: null,
),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Container( Container(
// color: Color(0xFFF7F7FB), color: Color(0xFFF7F7FB),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ 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( Container(
padding: isDesktop ? EdgeInsets.all(6) : EdgeInsets.all(3),
// color: Colors.white, // Background to avoid overlapping
color: isDesktop ? Color(0xFFF7F7FB) : Colors.white,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Expanded( Text(
child: GestureDetector( "Choose Policy Type",
onTap: () { style: TextStyle(
setState(() { fontSize: 18,
policyType = "domestic"; color: Colors.black,
});
},
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),
),
],
),
),
)),
], ],
), ),
), ),
// 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 isDesktop
? Expanded( ? Expanded(
child: Row( child: Row(
@ -215,7 +224,7 @@ class _PolicyState extends State<Policy> {
return SizedBox( return SizedBox(
width: isDesktop ? 180 : null, width: isDesktop ? 180 : null,
height: isDesktop height: isDesktop
? max((MediaQuery.of(context).size.height * 0.085), 10) ? max((MediaQuery.of(context).size.height * 0.09), 10)
: 45, : 45,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {

View File

@ -23,6 +23,7 @@ class PolicyCriteria extends StatefulWidget {
class _PolicyCriteriaState extends State<PolicyCriteria> { class _PolicyCriteriaState extends State<PolicyCriteria> {
String? selectedFirstApprovarType; String? selectedFirstApprovarType;
String? selectedService; String? selectedService;
String? _selectedTripType;
// bool isClass = true; // bool isClass = true;
// bool isCost = true; // bool isCost = true;
@ -42,12 +43,12 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
SizedBox(height: 15), widget.isDesktop ? SizedBox(height: 10) : SizedBox(height: 5),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Text(
"Selected Policy Criteria For ${widget.selectedTab} ", " Policy Criteria For ${widget.selectedTab} ",
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
color: Color(0xFF9E9DBD), 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( Row(
children: [ children: [
Expanded( Expanded(
@ -171,21 +182,24 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
Expanded( Expanded(
child: Container( child: Container(
width: widget.isDesktop width: widget.isDesktop
? MediaQuery.of(context).size.width * 0.62 ? MediaQuery.of(context).size.width * 0.63
: 600, : 600,
child: Column( child: Column(
children: [ children: [
Container( Container(
margin: const EdgeInsets.only(right: 20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.grey.shade50, color: Colors.grey.shade50,
border: Border.all( border: Border.all(
color: Colors.grey.shade50, color: Colors.grey.shade50,
), ),
borderRadius: BorderRadius.circular(8)), borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(10), padding: const EdgeInsets.only(
top: 10, bottom: 10, left: 35, right: 35),
child: Row( child: Row(
mainAxisAlignment: mainAxisAlignment: widget.isDesktop
MainAxisAlignment.spaceAround, ? MainAxisAlignment.spaceAround
: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Approver Name", "Approver Name",
@ -217,6 +231,7 @@ class _PolicyCriteriaState extends State<PolicyCriteria> {
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Container( child: Container(
// color: Colors.grey, // color: Colors.grey,
margin: const EdgeInsets.only(right: 20),
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column(children: [ child: Column(children: [
Container( 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 { Future<String?> getToken() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
return prefs.getString('auth_token'); return prefs.getString('auth_token');
} }
Future<List<dynamic>> fetchUsers() async { Future<List<dynamic>> fetchUsers() async {
@ -74,11 +73,12 @@ class _UserListScreenState extends State<UserListScreen> {
final data = json.decode(response.body); final data = json.decode(response.body);
print("Country - $data"); print("Country - $data");
if (!data.containsKey('data') || data['data'] is!List) { if (!data.containsKey('data') || data['data'] is! List) {
throw Exception("Invalid response format: 'data' field is missing or not a 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) { if (data['data'] is List) {
List<dynamic> plansJson = data['data']; List<dynamic> plansJson = data['data'];
@ -91,7 +91,6 @@ class _UserListScreenState extends State<UserListScreen> {
apiCountryData = plansJson; // Store API response in state apiCountryData = plansJson; // Store API response in state
}); });
print('plansJSONContry - $plansJson'); print('plansJSONContry - $plansJson');
} catch (e) { } catch (e) {
throw Exception('Error parsing response: $e'); throw Exception('Error parsing response: $e');
} }
@ -100,7 +99,6 @@ class _UserListScreenState extends State<UserListScreen> {
} }
} }
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -108,15 +106,15 @@ class _UserListScreenState extends State<UserListScreen> {
fetchCountryList(); fetchCountryList();
} }
void handleDelete(userId){ void handleDelete(userId) {
print("handDel - $userId"); print("handDel - $userId");
} }
void handleToggleUserStatus(String userId, String currentStatus) async { void handleToggleUserStatus(String userId, String currentStatus) async {
print("Toggling user status - $userId (Current: $currentStatus)"); 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(); final String? token = await getToken();
if (token == null) { if (token == null) {
@ -158,331 +156,412 @@ class _UserListScreenState extends State<UserListScreen> {
}); });
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ResponsiveBuilder(builder: (context, sizingInfo) { return ResponsiveBuilder(builder: (context, sizingInfo) {
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
return Scaffold( return Scaffold(
appBar: isDesktop ? null : const CustomAppBar(title:'User Management'), appBar: isDesktop ? null : const CustomAppBar(title: 'User Management'),
drawer: isDesktop ? null : CustomDrawer(isDesktop: false), drawer: isDesktop ? null : CustomDrawer(isDesktop: false),
body: body: Container(
Container(
color: Colors.white, color: Colors.white,
child: Row( child: Row(
children: [ children: [
if(isDesktop) if (isDesktop) CustomDrawer(isDesktop: true),
CustomDrawer(isDesktop: true),
// const Expanded(child: Center(child: Text("User Page Content"))), // const Expanded(child: Center(child: Text("User Page Content"))),
Expanded(child: buildUserTable(isDesktop)), Expanded(child: buildUserTable(isDesktop)),
], ],
), ),
), ),
); );
}); });
} }
Widget buildUserTable(bool isDesktop) { Widget buildUserTable(bool isDesktop) {
return Padding( return Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Column( child:
crossAxisAlignment: CrossAxisAlignment.stretch, Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Row( 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(
children: [ children: [
Icon(Icons.add_circle,color: Colors.white,), const Text('User List',
SizedBox(width: 5,), style:
Text('New User'), TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
IconButton(
icon: const Icon(Icons.keyboard_arrow_down),
onPressed: () {},
),
], ],
), ),
), ElevatedButton(
], style: ElevatedButton.styleFrom(
), foregroundColor: Colors.white,
const SizedBox(height: 10), backgroundColor: Colors.blueAccent),
onPressed: () async {
List<dynamic> users = await futureUsers;
FutureBuilder<List<dynamic>>( // Print the resolved value
future: futureUsers, print("CREATELIAS - $users");
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"));
}
List<dynamic> users = snapshot.data!; context.go("/CreateUserDetails", extra: {
Color borderColor = Color(0xFF9E9DBD); // '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( List<dynamic> users = snapshot.data!;
child: SingleChildScrollView( Color borderColor = Color(0xFF9E9DBD);
scrollDirection: Axis.vertical,
child: SizedBox(
width: MediaQuery.of(context).size.width * 1.5,
child: SingleChildScrollView(
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( child: ConstrainedBox(
constraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width), constraints: BoxConstraints(
// constraints: BoxConstraints(minWidth: 1300), minWidth: MediaQuery.of(context).size.width * 0.8),
// width: MediaQuery.of(context).size.width , // constraints: BoxConstraints(minWidth: 1300),
// width: MediaQuery.of(context).size.width ,
child: Container( child: Container(
// color: Colors.amber, // color: Colors.grey,
child: DataTable( // color: Colors.amber,
columnSpacing: 20.0, // Adjust spacing between columns child: DataTable(
dividerThickness: 0.5, columnSpacing:
dataRowMinHeight: 60.0, // Minimum row height 20.0, // Adjust spacing between columns
dataRowMaxHeight: 100.0, dividerThickness: 0.5,
border: TableBorder( dataRowMinHeight: 60.0, // Minimum row height
horizontalInside: BorderSide(width: 0.5, color: Colors.grey.shade200), dataRowMaxHeight: 100.0,
), border: TableBorder(
columns: const [ 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),)), rows: users.map((user) {
DataColumn(label: Text('Role',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)), String userId =
DataColumn(label: Text('Level',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)), user['user_id'].toString(); // Get user ID
DataColumn(label: Text('Status',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, fontWeight: FontWeight.bold),)), bool isSelected = selectedUserId == userId;
DataColumn(label: Text('Actions',style: TextStyle(color: Color(0xFF9E9DBD),fontSize: 15, 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'] ?? '')
],
),
],
),
],
)),
rows: users.map((user) { DataCell(Text(
String userId = user['user_id'].toString(); // Get user ID user['role_id'] ?? 'N/A',
bool isSelected = selectedUserId == userId; 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(
// DataCell(Text(user['user_id'].toString())), Row(
DataCell( children: [
Row( MouseRegion(
mainAxisAlignment: MainAxisAlignment.start, cursor: user['is_active'] == "0"
crossAxisAlignment: CrossAxisAlignment.start, ? SystemMouseCursors.forbidden
children: [ : SystemMouseCursors.click,
child: IconButton(
Align(alignment: Alignment.center, icon: Icon(Icons.remove_red_eye,
child: GestureDetector( color: user['is_active'] == "0"
onTap: () { ? Colors.grey
setState(() { : Colors.blueAccent),
selectedUserId = userId; // Store clicked user ID onPressed: user['is_active'] == "0"
}); ? null
}, : () {
child: Container( context.go(
width: 15, // Adjust size "/CreateUserDetails",
height: 15, extra: {
decoration: BoxDecoration( "selectedUser": user,
// Background color "isViewMode": true
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 MouseRegion(
), cursor: user['is_active'] == "0"
), ? SystemMouseCursors.forbidden
), : SystemMouseCursors.click,
), child: IconButton(
icon: Icon(Icons.edit,
color: user['is_active'] == "0"
? Colors.grey
SizedBox(width: 50,), : Colors.green),
Align( onPressed: user['is_active'] == "0"
alignment: Alignment.center, ? null
child: Container( : () {
print("USER: $user");
decoration: BoxDecoration( context.go(
shape: BoxShape.circle, "/CreateUserDetails",
border: Border.all(color: Color(0xFF9E9DBD), width: 1), // Grey outline extra: {
), "selectedUser": user,
"isViewMode": false
child: Padding( },
padding: const EdgeInsets.all(2.0), );
child: Container( },
),
width: 40, // Adjust size ),
height: 40, MouseRegion(
decoration: BoxDecoration( cursor: user['is_active'] == "0"
color: Colors.amber, // Inner circle background ? SystemMouseCursors.forbidden
shape: BoxShape.circle, : SystemMouseCursors.click,
), child: IconButton(
child: Column( icon: Icon(Icons.delete,
mainAxisAlignment: MainAxisAlignment.center, color: user['is_active'] == "0"
crossAxisAlignment: CrossAxisAlignment.center, ? Colors.grey
children: [ : Colors.redAccent),
Text( onPressed: user['is_active'] == "0"
(user['first_name'] != null && user['first_name']!.isNotEmpty) ? null
? user['first_name']![0].toUpperCase() : () {
: "?", print(
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), "USER ID: ${user['user_id']}");
),], var userId = user['user_id'];
handleDelete(userId);
},
), ),
), ),
)), ],
), ),
SizedBox(width: 20,), ),
]);
Column( }).toList(),
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(),
),
),
),
),
),
),
);
},
),
]));
} }
} }