group changes
This commit is contained in:
parent
b630ac35b7
commit
2891e93d8d
645
lib/Screens/group/groupDetails.dart
Normal file
645
lib/Screens/group/groupDetails.dart
Normal file
@ -0,0 +1,645 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../config/apiUrl.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../widgets/custom_text_forex.dart';
|
||||
import 'groupList.dart';
|
||||
|
||||
class GroupData extends StatefulWidget {
|
||||
final Future<void> Function() fetchGetGroup;
|
||||
final bool isDesktop;
|
||||
final Color? layoutColor;
|
||||
|
||||
final int? groupId; // <-- Add this
|
||||
final Map<String, dynamic>? groupData;
|
||||
|
||||
const GroupData(
|
||||
{super.key,
|
||||
required this.isDesktop,
|
||||
this.layoutColor,
|
||||
required this.fetchGetGroup,
|
||||
this.groupId,
|
||||
this.groupData});
|
||||
|
||||
@override
|
||||
GroupDataState createState() => GroupDataState();
|
||||
}
|
||||
|
||||
class GroupDataState extends State<GroupData> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
Map<String, String> DomesticMap = {};
|
||||
Map<String, String> InternationalMap = {};
|
||||
|
||||
late List<dynamic>? apiForDomestic;
|
||||
late List<dynamic>? apiForInternational;
|
||||
|
||||
Map<String, dynamic>? apiData;
|
||||
final Map<String, TextEditingController> controllers = {};
|
||||
Map<String, String> errorMessages = {};
|
||||
|
||||
|
||||
List<dynamic> domesticList = [];
|
||||
List<dynamic> internationalList = [];
|
||||
|
||||
String? selectedName;
|
||||
String? selectedDescription;
|
||||
|
||||
String? selectedInternationalPolicyID;
|
||||
String? selectedInternationalPolicyName;
|
||||
|
||||
String? selectedDomesticPolicyID;
|
||||
String? selectedDomesticPolicyName;
|
||||
|
||||
String? userId;
|
||||
int? groupDataId;
|
||||
|
||||
late String isActive = "1";
|
||||
|
||||
List<String> dataHeader = [
|
||||
"name",
|
||||
"description",
|
||||
"domestic_policy_id",
|
||||
"domestic_policy_name",
|
||||
"international_policy_id",
|
||||
"international_policy_name",
|
||||
];
|
||||
|
||||
Map<String, dynamic> group_Detials() {
|
||||
final data = {
|
||||
"name":controllers["name"]?.text,
|
||||
"description":controllers["description"]?.text,
|
||||
"domestic_policy_id":selectedDomesticPolicyID,
|
||||
"international_policy_id":selectedInternationalPolicyID,
|
||||
"domestic_policy_name":selectedDomesticPolicyName,
|
||||
"international_policy_name":selectedInternationalPolicyName,
|
||||
"is_active": isActive,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadAllServices();
|
||||
});
|
||||
|
||||
apiForDomestic = null;
|
||||
apiForInternational = null;
|
||||
|
||||
apiData = null;
|
||||
for (var field in dataHeader) {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
|
||||
if (widget.groupId != null) {
|
||||
print('Editing group ID: ${widget.groupId}');
|
||||
updateGroupDetails();
|
||||
}
|
||||
_clearError();
|
||||
}
|
||||
|
||||
void _clearError() {
|
||||
setState(() {
|
||||
errorMessages.clear();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
for (var controller in controllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void updateGroupDetails() {
|
||||
print("Update - ${widget.groupData}");
|
||||
|
||||
final data = widget.groupData;
|
||||
|
||||
if (data == null) return;
|
||||
setState(() {
|
||||
selectedDomesticPolicyID = data['domestic_policy_id']; // For dropdown
|
||||
selectedDomesticPolicyName = "";
|
||||
selectedInternationalPolicyID = data['international_policy_id'];
|
||||
selectedInternationalPolicyName = ""; // Optional if used elsewhere
|
||||
controllers['name']?.text = data['name'] ?? '';
|
||||
controllers['description']?.text = data['description'] ?? '';
|
||||
isActive = data["is_active"];
|
||||
final groupId = int.tryParse(data['group_id'].toString());
|
||||
groupDataId = groupId;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> loadAllServices() async {
|
||||
try {
|
||||
final result = await apiService.fetchAllPolicy();
|
||||
|
||||
userId = await getUserId();
|
||||
|
||||
setState(() {
|
||||
apiForDomestic =
|
||||
result.where((policy) => policy["domestic"] == "1").toList();
|
||||
apiForInternational =
|
||||
result.where((policy) => policy["international"] == "1").toList();
|
||||
});
|
||||
print("Domestic policies: $apiForDomestic");
|
||||
print("International policies: $apiForInternational");
|
||||
} catch (e) {
|
||||
print('Error fetching role list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void toggleStatus() {
|
||||
setState(() {
|
||||
isActive = isActive == "1" ? "0" : "1";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool validateData() {
|
||||
errorMessages.clear();
|
||||
|
||||
final data = {
|
||||
"name":controllers["name"]?.text,
|
||||
"description":controllers["description"]?.text,
|
||||
"domestic_policy_id":selectedDomesticPolicyID,
|
||||
"international_policy_id":selectedInternationalPolicyID,
|
||||
"domestic_policy_name":selectedDomesticPolicyName,
|
||||
"international_policy_name":selectedInternationalPolicyName,
|
||||
};
|
||||
|
||||
final requiredFields = [
|
||||
"name",
|
||||
"description",
|
||||
];
|
||||
|
||||
// Check validation for each field
|
||||
for (String field in requiredFields) {
|
||||
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
||||
errorMessages[field] = "Required";
|
||||
}
|
||||
}
|
||||
|
||||
return errorMessages.isEmpty;
|
||||
}
|
||||
|
||||
Future<void> handleSubmit() async {
|
||||
userId = await getUserId();
|
||||
|
||||
setState(() {
|
||||
// This triggers UI rebuild with error messages
|
||||
if (validateData()) {
|
||||
postGroupData();
|
||||
}
|
||||
});
|
||||
|
||||
final groupData1 = group_Detials();
|
||||
print("GroupDAta - $groupData1");
|
||||
}
|
||||
|
||||
Future<void> postGroupData({int isActive = 1}) async {
|
||||
final orgId = await getOrgId();
|
||||
final groupData = group_Detials();
|
||||
final String apiUrlData;
|
||||
|
||||
// static here
|
||||
groupData["org_id"] = orgId;
|
||||
|
||||
// dynamic here
|
||||
if (groupDataId != null) {
|
||||
apiUrlData = '$apiUrl/api/groups/update/$groupDataId';
|
||||
groupData["group_id"] = groupDataId.toString();
|
||||
groupData["updated_by"] = userId;
|
||||
} else {
|
||||
apiUrlData = '$apiUrl/api/groups/create';
|
||||
groupData["created_by"] = userId;
|
||||
}
|
||||
|
||||
final token = await getToken(); // Fetch token
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
try {
|
||||
final uri = Uri.parse(apiUrlData);
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
final body = jsonEncode(groupData);
|
||||
|
||||
final response = groupDataId != null
|
||||
? await http.put(uri, headers: headers, body: body)
|
||||
: await http.post(uri, headers: headers, body: body);
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
print("Group Details Created successfully!");
|
||||
print("Response: ${response.body}");
|
||||
// _clearError();
|
||||
_clearError();
|
||||
await widget.fetchGetGroup();
|
||||
|
||||
// dispose();
|
||||
Navigator.of(context).pop();
|
||||
} else if (response.statusCode == 404) {
|
||||
Navigator.of(context).pop();
|
||||
final message = jsonDecode(response.body)['message'] ?? 'Unknown error';
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
backgroundColor: Colors.redAccent,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
print("Failed to submit plan. Status: ${response.statusCode}");
|
||||
print("Error: ${response.body}");
|
||||
}
|
||||
} catch (e) {
|
||||
print(" Error submitting plan: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
late Map<String, String> DomesticMap;
|
||||
late List<String> DomesticID;
|
||||
late Map<String, String> InternationalMap;
|
||||
late List<String> InternationalID;
|
||||
|
||||
domesticList = apiForDomestic ?? [];
|
||||
internationalList = apiForInternational ?? [];
|
||||
|
||||
// print("domesticListFromAPI--$domesticList");
|
||||
|
||||
// Map id to names
|
||||
DomesticMap = {
|
||||
for (var object in domesticList)
|
||||
object['policy_id'] as String: object['name'] as String
|
||||
};
|
||||
|
||||
// print("domestic -- map--$DomesticMap");
|
||||
|
||||
// Extract only id for processing
|
||||
DomesticID = DomesticMap.keys.toList();
|
||||
|
||||
// print("domestic -- id--$DomesticID");
|
||||
|
||||
// print("domestic -- selected --$selectedDomesticPolicyID");
|
||||
|
||||
InternationalMap = {
|
||||
for (var item in internationalList)
|
||||
item['policy_id'] as String: item['name'] as String
|
||||
};
|
||||
|
||||
// Extract only id for processing
|
||||
InternationalID = InternationalMap.keys.toList();
|
||||
|
||||
selectedInternationalPolicyID ??= null;
|
||||
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
// contentPadding: const EdgeInsets.fromLTRB(44, 40, 44, 40),
|
||||
contentPadding: const EdgeInsets.fromLTRB(34, 30, 34, 30),
|
||||
// contentPadding: const EdgeInsets.fromLTRB(24, 20, 24, 10),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Row 1: Title + Edit + Delete buttons
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
(groupDataId != null) ? 'Edit Group' : 'Create Group',
|
||||
style: GoogleFonts.poppins(fontSize: 15, color: Colors.black),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Divider(
|
||||
thickness: 0.2,
|
||||
color: Colors.blueGrey.shade100,
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["name"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Name",
|
||||
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
)),
|
||||
),
|
||||
if (errorMessages["name"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["name"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select Policy For International",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: InternationalMap[selectedInternationalPolicyID],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
menuProps: const MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
itemBuilder: (context, item, isSelected) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0, vertical: 6.0),
|
||||
child: Text(
|
||||
item,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
),
|
||||
),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Select Policy For International",
|
||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: InternationalMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Policy For International",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
// Find the country_code based on selected country_name
|
||||
selectedInternationalPolicyID = InternationalMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
selectedInternationalPolicyName = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Select Policy For Domestic",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: DomesticMap[selectedDomesticPolicyID],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
menuProps: const MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
itemBuilder: (context, object, isSelected) => Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0, vertical: 6.0),
|
||||
child: Text(
|
||||
object,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
),
|
||||
),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Select Policy For Domestic...",
|
||||
hintStyle: GoogleFonts.poppins(fontSize: 11),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: DomesticMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Policy For Domestic",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
// Find the country_code based on selected country_name
|
||||
selectedDomesticPolicyID = DomesticMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
selectedDomesticPolicyName = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Description",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
child: TextField(
|
||||
controller: controllers["description"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Description",
|
||||
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["description"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
errorMessages["description"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
if (groupDataId != null)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Change Status ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
Tooltip(
|
||||
message:
|
||||
isActive == "1" ? "Tap to deactivate" : "Tap to activate",
|
||||
child: GestureDetector(
|
||||
onTap: toggleStatus,
|
||||
child: Text(
|
||||
isActive == "1" ? "Active" : "Inactive",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
color: isActive == "1" ? Colors.green : Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
if (groupDataId != null)
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
// SizedBox(
|
||||
// child: ElevatedButton(
|
||||
// onPressed: () {
|
||||
// // You can get text from commentController.text
|
||||
// Navigator.of(context).pop(); // Close the modal
|
||||
// },
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: widget.layoutColor,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// ),
|
||||
// ),
|
||||
// child: Text('Cancel',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 13, color: Colors.white)),
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width: 10,
|
||||
// ),
|
||||
SizedBox(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
handleSubmit();
|
||||
// You can get text from commentController.text
|
||||
// Navigator.of(context).pop(); // Close the modal
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: widget.layoutColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Text('Save',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11, color: Colors.white)),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
// : SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ import '../../routes/custom_appBar.dart';
|
||||
import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import 'groupDetails.dart';
|
||||
|
||||
class GroupList extends StatefulWidget {
|
||||
@override
|
||||
@ -117,6 +118,10 @@ class _GroupListState extends State<GroupList> {
|
||||
handleActiveStatus(groupdata, groupId.toString(), status.toString());
|
||||
}
|
||||
|
||||
Future<void> refreshData() async {
|
||||
loadAllGroups();
|
||||
}
|
||||
|
||||
// Future<void> deleteGroupFromApi(int groupId) async {
|
||||
// try {
|
||||
// await apiService.deleteGroup(groupId); // your delete API call
|
||||
@ -236,7 +241,18 @@ class _GroupListState extends State<GroupList> {
|
||||
),
|
||||
onPressed: () async {
|
||||
// List<dynamic> users = await futureUsers;
|
||||
context.go('/CreateGroup');
|
||||
// context.go('/CreateGroup');
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => GroupData(
|
||||
isDesktop: isDesktop,
|
||||
groupId: null,
|
||||
layoutColor: layoutColor!,
|
||||
fetchGetGroup: refreshData
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
@ -355,9 +371,35 @@ class _GroupListState extends State<GroupList> {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
context.go("/CreateGroup", extra: group);
|
||||
onTap: () async {
|
||||
|
||||
if (group['group_id'] != null) {
|
||||
final newGroupID = int.tryParse(group['group_id'].toString());
|
||||
if (newGroupID != null) {
|
||||
final data = await apiService.getGroupDetailsFind(newGroupID); // ✅ Always an int
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => GroupData(
|
||||
isDesktop: isDesktop,
|
||||
groupId: newGroupID, // Pass the ID
|
||||
groupData: data,
|
||||
layoutColor: layoutColor!,
|
||||
fetchGetGroup: refreshData
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
print("something went wrong check properly");
|
||||
}
|
||||
},
|
||||
|
||||
// onTap: () {
|
||||
// context.go("/CreateGroup", extra: group);
|
||||
// },
|
||||
child: Image.asset('assets/images/IconsImg/edit.png',
|
||||
width: 20, height: 15),
|
||||
),
|
||||
|
||||
@ -96,7 +96,7 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
},
|
||||
{
|
||||
'value': '/hotels',
|
||||
'icon': Icons.cabin_sharp,
|
||||
'icon': Icons.add_business,
|
||||
'label': 'Hotels',
|
||||
'description': 'Create and Edit Hotels'
|
||||
},
|
||||
@ -126,6 +126,7 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
case '/templateList':
|
||||
case '/costcenter':
|
||||
case '/hotels':
|
||||
case '/groupDetails' :
|
||||
context.go(route);
|
||||
break;
|
||||
default:
|
||||
|
||||
@ -1048,4 +1048,87 @@ class ApiService {
|
||||
throw Exception('Failed to load CostCenter details');
|
||||
}
|
||||
}
|
||||
Future<Map<String, dynamic>> getHotelsDetailsFind(int id) async {
|
||||
final String apiUrldata = '$apiUrl/api/findHotels?hotel_id=$id';
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(apiUrldata),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
try {
|
||||
final data = json.decode(response.body);
|
||||
// print('findout the result');
|
||||
// print(data.runtimeType);
|
||||
// print(data);
|
||||
|
||||
if (!data.containsKey('data') || data['data'] is! List) {
|
||||
throw Exception(
|
||||
"Invalid response format: 'data' field is missing or not a List");
|
||||
}
|
||||
|
||||
final List<Map<String, dynamic>> listData =
|
||||
List<Map<String, dynamic>>.from(data['data']);
|
||||
|
||||
if (listData.isEmpty) {
|
||||
throw Exception("No Hotel data found with ID $id");
|
||||
}
|
||||
|
||||
return listData[0];
|
||||
} catch (e) {
|
||||
throw Exception('Error parsing response: $e');
|
||||
}
|
||||
} else {
|
||||
throw Exception('Failed to load Hotel details');
|
||||
}
|
||||
}
|
||||
Future<Map<String, dynamic>> getGroupDetailsFind(int id) async {
|
||||
final String apiUrldata = '$apiUrl/api/groups/find/$id';
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(apiUrldata),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
try {
|
||||
final data = json.decode(response.body);
|
||||
print(data);
|
||||
if (!data.containsKey('data') || data['data'] is! Map) {
|
||||
throw Exception(
|
||||
"Invalid response format: 'data' field is missing or not a Map");
|
||||
}
|
||||
print('Single USer 1');
|
||||
|
||||
Map<String, dynamic> plansJson =
|
||||
data['data']; // 'data' is a Map, not a List
|
||||
|
||||
print('Single USer 2');
|
||||
return plansJson;
|
||||
} catch (e) {
|
||||
throw Exception('Error parsing response: $e');
|
||||
}
|
||||
} else {
|
||||
throw Exception('Failed to load plans');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user