user management - remarks list
This commit is contained in:
parent
75592f9879
commit
db7df6b7de
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:core';
|
||||
import 'package:frontend/Screens/allTrips/remarks_list.dart';
|
||||
import 'package:frontend/data/models/plan.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -782,12 +783,14 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Admin"),
|
||||
builder: (context) =>
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId:
|
||||
plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Admin"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
@ -869,7 +872,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) =>
|
||||
CommentModal(
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId
|
||||
.toString(),
|
||||
|
||||
197
lib/Screens/allTrips/remarks_list.dart
Normal file
197
lib/Screens/allTrips/remarks_list.dart
Normal file
@ -0,0 +1,197 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../config/apiUrl.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
|
||||
class CommentModalList extends StatefulWidget {
|
||||
final String planId;
|
||||
final Color layoutColorForUser;
|
||||
final String role;
|
||||
|
||||
const CommentModalList({
|
||||
Key? key,
|
||||
required this.planId,
|
||||
required this.layoutColorForUser,
|
||||
required this.role,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CommentModalListState createState() => _CommentModalListState();
|
||||
}
|
||||
|
||||
class _CommentModalListState extends State<CommentModalList> {
|
||||
late Future<List<Map<String, dynamic>>> _commentsFuture;
|
||||
|
||||
Future<List<Map<String, dynamic>>> fetchComments1() async {
|
||||
final response = await http.get(
|
||||
Uri.parse(
|
||||
'$apiUrl/api/plans/getRemarksByPlanId?plan_id=${widget.planId}'),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final jsonData = json.decode(response.body);
|
||||
final List<dynamic> dataList = jsonData['data'];
|
||||
return dataList.cast<Map<String, dynamic>>();
|
||||
} else {
|
||||
throw Exception('Failed to load comments');
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> fetchComments() async {
|
||||
// final String apiUrldata =
|
||||
// '$apiUrl/getRemarksByPlanId?plan_id=${widget.planId}&user_id=$userId';
|
||||
|
||||
final String apiUrldata =
|
||||
'$apiUrl/api/plans/getRemarksByPlanId?plan_id=${widget.planId}';
|
||||
|
||||
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) {
|
||||
final jsonData = json.decode(response.body);
|
||||
final List<dynamic> dataList = jsonData['data'];
|
||||
return dataList.cast<Map<String, dynamic>>();
|
||||
} else {
|
||||
throw Exception('Failed to load comments');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_commentsFuture = fetchComments();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
title: Text(
|
||||
'Comments',
|
||||
style: GoogleFonts.poppins(color: Colors.black),
|
||||
),
|
||||
content: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: 500, // ✅ You can adjust this width
|
||||
maxHeight:
|
||||
400, // ✅ Optional: limit height to make it scrollable vertically
|
||||
),
|
||||
child: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: _commentsFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
if (snapshot.hasError) {
|
||||
return Text(
|
||||
'No Comments For This Plan',
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
}
|
||||
|
||||
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Text(
|
||||
'No comments found.',
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
}
|
||||
|
||||
final comments = snapshot.data!;
|
||||
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: DataTable(
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Name',
|
||||
style:
|
||||
GoogleFonts.poppins(fontSize: 11, color: Colors.black),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Comment',
|
||||
style:
|
||||
GoogleFonts.poppins(fontSize: 11, color: Colors.black),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Updated On',
|
||||
style:
|
||||
GoogleFonts.poppins(fontSize: 11, color: Colors.black),
|
||||
)),
|
||||
],
|
||||
rows: comments.map((comment) {
|
||||
final name = comment['created_by_name'] ?? 'Unknown';
|
||||
final remark = comment['remarks'] ?? '';
|
||||
final rawDateStr = comment['updated_on'];
|
||||
String updatedOn = '';
|
||||
|
||||
if (rawDateStr != null && rawDateStr.isNotEmpty) {
|
||||
try {
|
||||
final parsedDate = DateTime.parse(rawDateStr);
|
||||
updatedOn = DateFormat('d MMM yyyy')
|
||||
.format(parsedDate); // e.g., 15 May 2025
|
||||
} catch (e) {
|
||||
updatedOn = rawDateStr.split(' ').first; // fallback
|
||||
}
|
||||
}
|
||||
|
||||
return DataRow(cells: [
|
||||
DataCell(Text(
|
||||
name,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500),
|
||||
)),
|
||||
DataCell(Text(
|
||||
remark,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500),
|
||||
)),
|
||||
DataCell(Text(
|
||||
updatedOn,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w500),
|
||||
)),
|
||||
]);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text('Close',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: widget.layoutColorForUser)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@ import '../../utils/pagination.dart';
|
||||
import '../../utils/travelAgent_remarks.dart';
|
||||
import '../../widgets/custom_popup.dart';
|
||||
import '../../widgets/popup_listPlan_action.dart';
|
||||
import '../allTrips/remarks_list.dart';
|
||||
|
||||
class ApprovalList extends StatefulWidget {
|
||||
const ApprovalList({super.key});
|
||||
@ -756,12 +757,14 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Approver"),
|
||||
builder: (context) =>
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId:
|
||||
plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Approver"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
@ -946,12 +949,14 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Approver"),
|
||||
builder: (context) =>
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId:
|
||||
plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "Approver"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
|
||||
@ -13,13 +13,15 @@ class AccomodationScreen extends StatefulWidget {
|
||||
final Function(Map<String, dynamic>) onSaveAccomadation;
|
||||
final Map<String, dynamic>? selectedItem;
|
||||
final String? loginUser;
|
||||
final String? tripType;
|
||||
|
||||
AccomodationScreen(
|
||||
{required this.onClose,
|
||||
required this.onSaveAccomadation,
|
||||
required this.selectedItem,
|
||||
required this.loginUser,
|
||||
required this.flightData});
|
||||
required this.flightData,
|
||||
this.tripType});
|
||||
|
||||
@override
|
||||
_AccomodationScreenState createState() => _AccomodationScreenState();
|
||||
@ -293,7 +295,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
}
|
||||
|
||||
Future<void> loadCountryList() async {
|
||||
final result = await apiService.fetchFlightsCountryList();
|
||||
final result = await apiService.fetchFlightsCountryList(widget.tripType);
|
||||
|
||||
print("ResultCountry : $result");
|
||||
|
||||
|
||||
@ -84,6 +84,8 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
print("TripType - ${widget.tripType}");
|
||||
|
||||
// _initializeRows();
|
||||
// List<dynamic> purposeList = widget.apiData?['flight_trip_type'] ?? [];
|
||||
// selectedTripType ??= purposeList.isNotEmpty ? purposeList.first['dropdown_value'] : null;
|
||||
@ -206,7 +208,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
isCountryLoading = true;
|
||||
});
|
||||
|
||||
final result = await apiService.fetchFlightsCountryList();
|
||||
final result = await apiService.fetchFlightsCountryList(widget.tripType);
|
||||
|
||||
print("ResultCountry : $result");
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ class TrainScreen extends StatefulWidget {
|
||||
final Function(bool) onClose;
|
||||
final Map<String, dynamic>? selectedItem;
|
||||
final String? loginUser;
|
||||
final String? tripType;
|
||||
|
||||
TrainScreen(
|
||||
{required this.onClose,
|
||||
@ -22,7 +23,8 @@ class TrainScreen extends StatefulWidget {
|
||||
required this.onSavetrain,
|
||||
required this.selectedItem,
|
||||
required this.loginUser,
|
||||
this.apiDataForClass});
|
||||
this.apiDataForClass,
|
||||
this.tripType});
|
||||
|
||||
@override
|
||||
_TrainScreenState createState() => _TrainScreenState();
|
||||
|
||||
@ -43,7 +43,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
}
|
||||
|
||||
Future<void> loadCountryList() async {
|
||||
final result = await apiService.fetchFlightsCountryList();
|
||||
final result = await apiService.fetchFlightsCountryList(widget.tripType);
|
||||
|
||||
print("ResultCountry : $result");
|
||||
|
||||
|
||||
@ -616,6 +616,7 @@ class DynamicItineraryState extends State<DynamicItinerary> {
|
||||
apiDataForClass: widget.apiDataForClass,
|
||||
loginUser: widget.loginUser,
|
||||
onSavetrain: (data) => handleItineraryUpdate("Train", data),
|
||||
tripType: widget.tripType,
|
||||
selectedItem: selectedItem);
|
||||
break;
|
||||
case "Taxi":
|
||||
|
||||
@ -18,6 +18,7 @@ import '../../utils/pagination.dart';
|
||||
import '../../utils/travelAgent_remarks.dart';
|
||||
import '../../widgets/custom_popup.dart';
|
||||
import '../../widgets/popup_listPlan_action.dart';
|
||||
import '../allTrips/remarks_list.dart';
|
||||
|
||||
class ListPlans extends StatefulWidget {
|
||||
const ListPlans({super.key});
|
||||
@ -822,12 +823,14 @@ class _ListPlansState extends State<ListPlans> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "User"),
|
||||
builder: (context) =>
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId:
|
||||
plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "User"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
@ -942,12 +945,14 @@ class _ListPlansState extends State<ListPlans> {
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => CommentModal(
|
||||
// planId: plan.planId,
|
||||
planId: plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "User"),
|
||||
builder: (context) =>
|
||||
CommentModalList(
|
||||
// planId: plan.planId,
|
||||
planId:
|
||||
plan.planId.toString(),
|
||||
layoutColorForUser:
|
||||
layoutColor!,
|
||||
role: "User"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
|
||||
@ -31,6 +31,8 @@ import '../../../widgets/custom_text_forex.dart';
|
||||
import '../../../widgets/custom_user_form.dart';
|
||||
import 'office_details.dart';
|
||||
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
class CreateUserFormDetials extends StatefulWidget {
|
||||
@override
|
||||
_CreateUserFormDetialsState createState() => _CreateUserFormDetialsState();
|
||||
@ -44,7 +46,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
final GlobalKey<TravellerDetailsState> travellerDetailsKey =
|
||||
GlobalKey<TravellerDetailsState>();
|
||||
|
||||
// late List<Map<String, dynamic>?> travelDetailsData;
|
||||
Map<String, dynamic>? travelDetailsData;
|
||||
Map<String, dynamic>? travelDetailsDataFromAPI;
|
||||
|
||||
late TabController _tabController;
|
||||
|
||||
@ -172,6 +176,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
}
|
||||
|
||||
void handleUserTypeChange(bool isTravelAgent) {
|
||||
print("handleUserTypeChange- $isTravelAgent");
|
||||
|
||||
setState(() {
|
||||
setSelectesUserType = isTravelAgent;
|
||||
});
|
||||
@ -186,6 +192,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
if (apiselectedUser != null && apiselectedUser!.isNotEmpty) {
|
||||
isapiselectedUser = true;
|
||||
|
||||
print("API Selected User Has Data - $apiselectedUser");
|
||||
}
|
||||
|
||||
controllers["Fname"]?.text = apiselectedUser?["first_name"] ?? "";
|
||||
@ -265,18 +273,17 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
print("Updated selectedGender: $selectedGender"); // Debugging
|
||||
|
||||
// ✅ Load passport document from API
|
||||
String? apiDocPath = apiselectedUser?["passport_document"];
|
||||
if (apiDocPath != null && apiDocPath.isNotEmpty) {
|
||||
passportFileUrlFromApi = apiDocPath;
|
||||
selectedFileNames =
|
||||
apiDocPath.split('/').last; // Extract filename from path
|
||||
passportFile = null; // No local file selected yet
|
||||
} else {
|
||||
passportFileUrlFromApi = null;
|
||||
selectedFileNames = null;
|
||||
passportFile = null;
|
||||
}
|
||||
travelDetailsDataFromAPI = apiselectedUser?["travel_details"];
|
||||
|
||||
print("travelDetailsDataFromAPI00 - $travelDetailsDataFromAPI");
|
||||
// if (travelDetails != null) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// // Safe to call updateTravel now
|
||||
// travellerDetailsKey.currentState?.updateTravel();
|
||||
// });
|
||||
// }
|
||||
|
||||
// Optionally load other travel-related fields like meal/seat preferences, etc.
|
||||
});
|
||||
} else {
|
||||
print("API Selected User Has Data - No data available yet");
|
||||
@ -288,15 +295,13 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
super.initState();
|
||||
selectedTab = "personal";
|
||||
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
// WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Step 1: Set 'reloaded' flag before page unload
|
||||
html.window.onBeforeUnload.listen((event) {
|
||||
html.window.localStorage['reloaded'] = 'true';
|
||||
});
|
||||
// html.window.onBeforeUnload.listen((event) {
|
||||
// html.window.localStorage['reloaded'] = 'true';
|
||||
// });
|
||||
|
||||
// apiCountryData = extraData['apiCountryData']; // Extract apiCountryData
|
||||
// futureUsers = extraData['apiUserData']; // Extract futureUsers (Future<List<dynamic>>)
|
||||
apiCountryData = null;
|
||||
apiUserData = null;
|
||||
// apiselectedUser = null;
|
||||
@ -306,12 +311,12 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
// Initialize controllers for each field
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
final wasReloaded = html.window.localStorage['reloaded'] == 'true';
|
||||
|
||||
if (wasReloaded) {
|
||||
html.window.localStorage.remove('reloaded'); // Clear it
|
||||
context.go('/listUser'); // Navigate using go_router
|
||||
}
|
||||
// final wasReloaded = html.window.localStorage['reloaded'] == 'true';
|
||||
//
|
||||
// if (wasReloaded) {
|
||||
// html.window.localStorage.remove('reloaded'); // Clear it
|
||||
// context.go('/listUser'); // Navigate using go_router
|
||||
// }
|
||||
|
||||
final extraData =
|
||||
GoRouterState.of(context).extra as Map<String, dynamic>?;
|
||||
@ -484,9 +489,11 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
}
|
||||
|
||||
void handleNext() async {
|
||||
print("USR Detail Submit");
|
||||
print("USR Detail Next");
|
||||
printFormData();
|
||||
|
||||
// travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials];
|
||||
|
||||
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
||||
|
||||
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
||||
@ -528,11 +535,15 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
void handleSubmit() async {
|
||||
print("USR Detail Submit");
|
||||
printFormData();
|
||||
|
||||
// printFormData();
|
||||
travelDetailsData = travellerDetailsKey.currentState?.travel_Detials;
|
||||
|
||||
print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
||||
print("TRAVEL DETAILS FROM CHILD");
|
||||
// print("TRAVEL DETAILS FROM CHILD: $travelDetailsData");
|
||||
|
||||
passportFile = travellerDetailsKey.currentState?.passportFile;
|
||||
|
||||
print("passportFile : $passportFile");
|
||||
|
||||
Map<String, dynamic> data = userDetials;
|
||||
|
||||
@ -665,9 +676,21 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
}
|
||||
|
||||
// Add all non-null and non-empty user data fields
|
||||
// userData.forEach((key, value) {
|
||||
// if (value != null && value.toString().trim().isNotEmpty) {
|
||||
// request.fields[key] = value.toString();
|
||||
// }
|
||||
// });
|
||||
|
||||
userData.forEach((key, value) {
|
||||
if (value != null && value.toString().trim().isNotEmpty) {
|
||||
request.fields[key] = value.toString();
|
||||
if (key == 'travel_details' && value is Map<String, dynamic>) {
|
||||
// ✅ Encode travel_details as a proper JSON string
|
||||
request.fields[key] = jsonEncode(value);
|
||||
print("✅ Encoded travel_details: ${request.fields[key]}");
|
||||
} else {
|
||||
request.fields[key] = value.toString();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -801,6 +824,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: (selectedTab == "travel" ||
|
||||
selectedRole == "5" ||
|
||||
isEditProfile ||
|
||||
setSelectesUserType == true)
|
||||
? _buildSubmit(isDesktop, layoutColor!)
|
||||
: _buildNext(isDesktop, layoutColor!),
|
||||
@ -808,6 +833,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: (selectedTab == "travel" ||
|
||||
selectedRole == "5" ||
|
||||
setSelectesUserType == true)
|
||||
? _buildSubmit(isDesktop, layoutColor!)
|
||||
: _buildNext(isDesktop, layoutColor!),
|
||||
@ -827,16 +853,32 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
apiselectedUser != null ? "Profile" : "Create New User",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
apiselectedUser != null ? "Profile" : "Create New User",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
if (isEditProfile)
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.edit,
|
||||
color: Color(0xFF114D8B),
|
||||
size: 14,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
isViewMode = !isViewMode;
|
||||
});
|
||||
})
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
height: 18,
|
||||
),
|
||||
isDesktop
|
||||
? buildTabsForUser()
|
||||
@ -935,6 +977,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
isViewMode: isViewMode,
|
||||
controllers: controllers,
|
||||
errorMessages: errorMessages,
|
||||
travelDetails: travelDetailsDataFromAPI, // 👈 Pass this down
|
||||
passportFileUrlFromApi: passportFileUrlFromApi,
|
||||
);
|
||||
default:
|
||||
return PersonalDetails(
|
||||
@ -952,12 +996,30 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
}
|
||||
|
||||
Widget buildTabsForUser() {
|
||||
final tabs = {
|
||||
// final tabs = {
|
||||
// "personal": "Personal Details",
|
||||
// "office": "Office Details",
|
||||
// "travel": "Travel Details",
|
||||
// };
|
||||
|
||||
final Map<String, String> allTabs = {
|
||||
"personal": "Personal Details",
|
||||
"office": "Office Details",
|
||||
"travel": "Travel Details",
|
||||
};
|
||||
|
||||
Map<String, String> getTabs(bool setSelectesUserType) {
|
||||
if (setSelectesUserType || selectedRole == "5") {
|
||||
return {
|
||||
"personal": "Personal Details",
|
||||
};
|
||||
} else {
|
||||
return allTabs;
|
||||
}
|
||||
}
|
||||
|
||||
final tabs = getTabs(setSelectesUserType);
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end, // important
|
||||
children: tabs.entries.map((entry) {
|
||||
@ -1042,7 +1104,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
onPressed: () {
|
||||
isEditProfile ? context.go('/listPlan') : context.go('/listUser');
|
||||
},
|
||||
child: isViewMode ? Text("Back") : Text("Cancel")),
|
||||
child: Text("Cancel")),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
|
||||
@ -150,6 +150,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
|
||||
if (response is Map<String, dynamic> && response.containsKey("role")) {
|
||||
List<dynamic> roleList = response["role"]; // Extract the list
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
apiRoleData = roleList;
|
||||
});
|
||||
@ -1109,7 +1111,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
child: SizedBox(
|
||||
height: 45, // Set appropriate height
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: widget.isViewMode ? null : selectedRole,
|
||||
// value: widget.isViewMode ? null : selectedRole,
|
||||
value: selectedRole,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
@ -1121,7 +1124,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
: (newValue) {
|
||||
setState(() {
|
||||
selectedRole = newValue;
|
||||
isTravelAgent = selectedRole == "Travel Agent";
|
||||
isTravelAgent = selectedRole == "5";
|
||||
// Pass the result back to parent
|
||||
widget.onUserTypeChanged?.call(isTravelAgent);
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart'; // don't forget
|
||||
import '../services/apiService.dart';
|
||||
import '../utils/auth_utils.dart';
|
||||
|
||||
enum TabSelection { allTrips, myTrips, myApprovals }
|
||||
|
||||
@ -481,7 +482,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
extra: {
|
||||
"selectedUser": userDetails,
|
||||
"isEditProfile": true,
|
||||
"isViewMode": true
|
||||
"isEditProfile": true,
|
||||
"isViewMode": false,
|
||||
},
|
||||
);
|
||||
case '/logout':
|
||||
|
||||
@ -489,9 +489,11 @@ class ApiService {
|
||||
|
||||
// Flight From - To
|
||||
|
||||
Future<List<dynamic>> fetchFlightsCountryList() async {
|
||||
Future<List<dynamic>> fetchFlightsCountryList(String? tripType) async {
|
||||
print("FlightTripType- $tripType");
|
||||
|
||||
final String apiUrldata =
|
||||
'$apiUrl/api/getAirportCodeMaster?limit=1000&offset=0';
|
||||
'$apiUrl/api/getAirportCodeMaster?trip_type=$tripType';
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ Future<String?> getRoleUser() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String? userDataString = prefs.getString('user_data');
|
||||
|
||||
// print("UserDataSTr - $userDataString");
|
||||
|
||||
if (userDataString != null) {
|
||||
try {
|
||||
final Map<String, dynamic> userData = jsonDecode(userDataString);
|
||||
|
||||
@ -26,23 +26,35 @@ class CommentModalState extends State<CommentModal> {
|
||||
Map<String, dynamic>? remarksData;
|
||||
int? remarksId;
|
||||
dynamic userId;
|
||||
late final role;
|
||||
bool isLoading = true;
|
||||
String? errorMessage;
|
||||
bool editRemarks = false;
|
||||
TextEditingController commentController = TextEditingController();
|
||||
|
||||
Map<String, dynamic> getData() {
|
||||
// Map<String, dynamic> getData() {
|
||||
// final map = {
|
||||
// "plan_id": int.parse(widget.planId),
|
||||
// "remarks": commentController.text,
|
||||
// "created_by": userId,
|
||||
// "is_active": 1,
|
||||
// };
|
||||
//
|
||||
// if (remarksId != null) {
|
||||
// map["id"] = remarksId; // Add 'id' only if available
|
||||
// }
|
||||
//
|
||||
// return map;
|
||||
// }
|
||||
|
||||
Map<String, dynamic> getData({int isActive = 1}) {
|
||||
final map = {
|
||||
"plan_id": int.parse(widget.planId),
|
||||
"remarks": commentController.text,
|
||||
"created_by": userId,
|
||||
"is_active": 1,
|
||||
// "created_by": userId,
|
||||
"is_active": isActive,
|
||||
};
|
||||
|
||||
if (remarksId != null) {
|
||||
map["id"] = remarksId; // Add 'id' only if available
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -59,6 +71,10 @@ class CommentModalState extends State<CommentModal> {
|
||||
throw Exception('User ID not found.');
|
||||
}
|
||||
|
||||
role = await getRoleUser();
|
||||
|
||||
print("Role - $role");
|
||||
|
||||
userId = int.tryParse(userIdString);
|
||||
if (userId == null) {
|
||||
throw Exception('Invalid user ID format.');
|
||||
@ -85,8 +101,15 @@ class CommentModalState extends State<CommentModal> {
|
||||
// final String apiUrldata =
|
||||
// '$apiUrl/getRemarksByPlanId?plan_id=${widget.planId}&user_id=$userId';
|
||||
|
||||
final String apiUrldata =
|
||||
'$apiUrl/api/plans/getRemarksByPlanId?plan_id=${widget.planId}&user_id=$userId';
|
||||
final String apiUrldata;
|
||||
|
||||
if (role == "Travel Agent") {
|
||||
apiUrldata =
|
||||
'$apiUrl/api/plans/getRemarksByPlanId?plan_id=${widget.planId}&user_id=$userId';
|
||||
} else {
|
||||
apiUrldata =
|
||||
'$apiUrl/api/plans/getRemarksByPlanId?plan_id=${widget.planId}';
|
||||
}
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
@ -128,8 +151,19 @@ class CommentModalState extends State<CommentModal> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> postRemarksData() async {
|
||||
final remarksData = getData();
|
||||
Future<void> postRemarksData({int isActive = 1}) async {
|
||||
// final remarksData = getData();
|
||||
|
||||
final remarksData = getData(isActive: isActive);
|
||||
|
||||
print("remarksId - $remarksId");
|
||||
|
||||
if (remarksId != null) {
|
||||
remarksData["id"] = remarksId;
|
||||
remarksData["updated_by"] = userId;
|
||||
} else {
|
||||
remarksData["created_by"] = userId;
|
||||
}
|
||||
|
||||
print("Remarks Data - remarksData");
|
||||
|
||||
@ -172,12 +206,16 @@ class CommentModalState extends State<CommentModal> {
|
||||
if (data['data'] != null && data['data'].isNotEmpty) {
|
||||
final remarksData = data['data'][0]; // Take the first item from the list
|
||||
|
||||
print("remarksData - $remarksData");
|
||||
// Now update your local fields
|
||||
commentController.text = remarksData['remarks'] ?? '';
|
||||
|
||||
// If you need to update other fields like created_by, you can do that too
|
||||
userId = remarksData['created_by'] ?? userId;
|
||||
remarksId = remarksData['id'];
|
||||
// remarksId = remarksData['id'];
|
||||
remarksId = int.tryParse(remarksData['id'].toString());
|
||||
|
||||
print("remarksId1- $remarksId");
|
||||
// If plan_id needs to be updated (usually it doesn't change), you can do it too
|
||||
// widget.planId = remarksData['plan_id'].toString(); // If widget.planId is mutable
|
||||
|
||||
@ -211,12 +249,15 @@ class CommentModalState extends State<CommentModal> {
|
||||
});
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete, size: 20),
|
||||
onPressed: () {
|
||||
// Handle delete pressed
|
||||
},
|
||||
),
|
||||
if (widget.role == "Travel Agent")
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete, size: 20),
|
||||
onPressed: () async {
|
||||
await postRemarksData(
|
||||
isActive: 0); // Marks the remark as deleted
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
@ -32,7 +32,7 @@ class _CustomTextFieldUserTravellerWrapperState
|
||||
return Container(
|
||||
width: widget.width ?? // Use custom width if provided, else default
|
||||
(widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.24
|
||||
? MediaQuery.of(context).size.width * 0.22
|
||||
: MediaQuery.of(context).size.width * 0.8),
|
||||
padding: widget.padding,
|
||||
decoration: BoxDecoration(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user