issues fixes
This commit is contained in:
parent
3b24228080
commit
ac303e666f
383
lib/Screens/userManagement/create_user/change_password.dart
Normal file
383
lib/Screens/userManagement/create_user/change_password.dart
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
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_user_form.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class ChangePasswordDialogData extends StatefulWidget {
|
||||||
|
|
||||||
|
final dynamic isDesktop;
|
||||||
|
final dynamic layoutColor;
|
||||||
|
final dynamic updaterUserId;
|
||||||
|
final dynamic updaterEmail;
|
||||||
|
|
||||||
|
const ChangePasswordDialogData({
|
||||||
|
super.key,
|
||||||
|
this.isDesktop,
|
||||||
|
this.layoutColor,
|
||||||
|
this.updaterUserId,
|
||||||
|
this.updaterEmail
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
ChangePasswordDialogDataState createState() => ChangePasswordDialogDataState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangePasswordDialogDataState extends State<ChangePasswordDialogData> {
|
||||||
|
|
||||||
|
final ApiService apiService = ApiService();
|
||||||
|
|
||||||
|
final Map<String, TextEditingController> controllers = {};
|
||||||
|
Map<String, String> errorMessages = {};
|
||||||
|
|
||||||
|
|
||||||
|
String? loggeduserId;
|
||||||
|
String? updaterUserIdForAPI;
|
||||||
|
|
||||||
|
List<String> dataHeader = [
|
||||||
|
"email",
|
||||||
|
"changePassword",
|
||||||
|
"confirmPassword"
|
||||||
|
];
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
//
|
||||||
|
// for (var field in dataHeader) {
|
||||||
|
// controllers[field] = TextEditingController();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// setState(() {
|
||||||
|
// controllers['email']?.text = widget.updaterEmail ?? '';
|
||||||
|
// controllers['changePassword']?.text = '';
|
||||||
|
// controllers['confirmPassword']?.text = '';
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
print("widget.updaterEmail: ${widget.updaterEmail}");
|
||||||
|
|
||||||
|
for (var field in dataHeader) {
|
||||||
|
controllers[field] = TextEditingController();
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
controllers['email']?.text = widget.updaterEmail ;
|
||||||
|
controllers['changePassword']?.text = '';
|
||||||
|
controllers['confirmPassword']?.text = '';
|
||||||
|
updaterUserIdForAPI = widget.updaterUserId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _clearError() {
|
||||||
|
setState(() {
|
||||||
|
errorMessages.clear();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
for (var controller in controllers.values) {
|
||||||
|
controller.dispose();
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool validateData() {
|
||||||
|
errorMessages.clear();
|
||||||
|
|
||||||
|
final String? email = controllers["email"]?.text;
|
||||||
|
final String? changePassword = controllers["changePassword"]?.text;
|
||||||
|
final String? confirmPassword = controllers["confirmPassword"]?.text;
|
||||||
|
|
||||||
|
// Required fields check
|
||||||
|
if (email == null || email.trim().isEmpty) {
|
||||||
|
errorMessages["email"] = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changePassword == null || changePassword.trim().isEmpty) {
|
||||||
|
errorMessages["changePassword"] = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirmPassword == null || confirmPassword.trim().isEmpty) {
|
||||||
|
errorMessages["confirmPassword"] = "Required";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Password match check
|
||||||
|
if ((changePassword?.isNotEmpty ?? false) &&
|
||||||
|
(confirmPassword?.isNotEmpty ?? false) &&
|
||||||
|
changePassword != confirmPassword) {
|
||||||
|
errorMessages["changePassword"] = "Passwords do not match";
|
||||||
|
errorMessages["confirmPassword"] = "Passwords do not match";
|
||||||
|
}
|
||||||
|
|
||||||
|
// setState(() {}); // Update UI with any error messages
|
||||||
|
return errorMessages.isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> handleSubmit() async {
|
||||||
|
loggeduserId = await getUserId();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
// This triggers UI rebuild with error messages
|
||||||
|
if (validateData()) {
|
||||||
|
postData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> postData() async {
|
||||||
|
// final remarksData = getData();
|
||||||
|
print('sss$updaterUserIdForAPI');
|
||||||
|
final loggedInUserId = await getUserId();
|
||||||
|
|
||||||
|
final password = controllers["changePassword"]?.text ?? '';
|
||||||
|
final confirmPassword = controllers["confirmPassword"]?.text ?? '';
|
||||||
|
final String apiUrldata = '$apiUrl/api/user/user-password/$updaterUserIdForAPI';
|
||||||
|
|
||||||
|
final token = await getToken();
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
final uri = Uri.parse(apiUrldata);
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
};
|
||||||
|
final body = jsonEncode({
|
||||||
|
"password": password,
|
||||||
|
"updated_by": loggedInUserId,
|
||||||
|
});
|
||||||
|
|
||||||
|
final response = await http.put(uri, headers: headers, body: body);
|
||||||
|
|
||||||
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||||
|
print("Forex Details Created successfully!");
|
||||||
|
print("Response: ${response.body}");
|
||||||
|
_clearError();
|
||||||
|
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) {
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
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(
|
||||||
|
'Change Password',
|
||||||
|
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(
|
||||||
|
"Email",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF575A74)),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: widget.isDesktop,
|
||||||
|
color: Colors.transparent,
|
||||||
|
// width: isDesktop
|
||||||
|
// ? MediaQuery.of(context).size.width * 0.330
|
||||||
|
// : MediaQuery.of(context).size.width * 0.66,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
controller: controllers["email"],
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Email",
|
||||||
|
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
if (errorMessages["email"] != null) ...[
|
||||||
|
SizedBox(height: 5), // Space before error message
|
||||||
|
Text(
|
||||||
|
errorMessages["email"]!,
|
||||||
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Change Password",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF575A74)),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: widget.isDesktop,
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
controller: controllers["changePassword"],
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Change Password",
|
||||||
|
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
if (errorMessages["changePassword"] != null) ...[
|
||||||
|
SizedBox(height: 5), // Space before error message
|
||||||
|
Text(
|
||||||
|
errorMessages["changePassword"]!,
|
||||||
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Confirm Password",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF575A74)),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserWrapper(
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: widget.isDesktop,
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
controller: controllers["confirmPassword"],
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: "Confirm Password",
|
||||||
|
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
if (errorMessages["confirmPassword"] != null) ...[
|
||||||
|
SizedBox(height: 5), // Space before error message
|
||||||
|
Text(
|
||||||
|
errorMessages["confirmPassword"]!,
|
||||||
|
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 15,
|
||||||
|
),
|
||||||
|
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
handleSubmit();
|
||||||
|
},
|
||||||
|
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(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -54,6 +54,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
String? userId;
|
String? userId;
|
||||||
String? orgId;
|
String? orgId;
|
||||||
|
String? userIdApi;
|
||||||
|
|
||||||
String? token;
|
String? token;
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
print("API Selected User Has Data - $apiselectedUser");
|
print("API Selected User Has Data - $apiselectedUser");
|
||||||
}
|
}
|
||||||
|
userIdApi = apiselectedUser?["user_id"] ?? "";
|
||||||
controllers["Fname"]?.text = apiselectedUser?["first_name"] ?? "";
|
controllers["Fname"]?.text = apiselectedUser?["first_name"] ?? "";
|
||||||
controllers["Lname"]?.text = apiselectedUser?["last_name"] ?? "";
|
controllers["Lname"]?.text = apiselectedUser?["last_name"] ?? "";
|
||||||
controllers["email"]?.text = apiselectedUser?["email"] ?? "";
|
controllers["email"]?.text = apiselectedUser?["email"] ?? "";
|
||||||
@ -976,6 +977,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
personalDetailsKey: personalDetailsKey,
|
personalDetailsKey: personalDetailsKey,
|
||||||
isDesktop: isDesktop, // pass isDesktop as a named argument
|
isDesktop: isDesktop, // pass isDesktop as a named argument
|
||||||
isViewMode: isViewMode,
|
isViewMode: isViewMode,
|
||||||
|
userIdApi:userIdApi,
|
||||||
controllers: controllers,
|
controllers: controllers,
|
||||||
errorMessages: errorMessages,
|
errorMessages: errorMessages,
|
||||||
selectedGender: selectedGender,
|
selectedGender: selectedGender,
|
||||||
|
|||||||
@ -1108,6 +1108,12 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
_selectedCheckOutDate = pickedDate;
|
_selectedCheckOutDate = pickedDate;
|
||||||
widget.controllers["delegationStartDate"]?.text =
|
widget.controllers["delegationStartDate"]?.text =
|
||||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||||
|
|
||||||
|
if (_selectedEndDate != null &&
|
||||||
|
_selectedEndDate!.isBefore(_selectedCheckOutDate!)) {
|
||||||
|
_selectedEndDate = null;
|
||||||
|
widget.controllers["delegationEndDate"]?.text = '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1173,6 +1179,10 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
DateTime today = DateTime(now.year, now.month, now.day);
|
DateTime today = DateTime(now.year, now.month, now.day);
|
||||||
|
|
||||||
|
DateTime minDate = _selectedCheckOutDate != null
|
||||||
|
? _selectedCheckOutDate!
|
||||||
|
: today;
|
||||||
|
|
||||||
// Parse date from notifier if available, else use today
|
// Parse date from notifier if available, else use today
|
||||||
DateTime initialDate;
|
DateTime initialDate;
|
||||||
|
|
||||||
@ -1188,11 +1198,11 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
|
|
||||||
DateTime? pickedDate = await showDatePicker(
|
DateTime? pickedDate = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialDate:
|
initialDate: _selectedEndDate != null &&
|
||||||
_selectedEndDate != null && _selectedEndDate!.isAfter(today)
|
_selectedEndDate!.isAfter(minDate)
|
||||||
? _selectedEndDate!
|
? _selectedEndDate!
|
||||||
: today,
|
: minDate,
|
||||||
firstDate: today,
|
firstDate: minDate,
|
||||||
lastDate: DateTime(2100),
|
lastDate: DateTime(2100),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1201,8 +1211,6 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
|||||||
_selectedEndDate = pickedDate;
|
_selectedEndDate = pickedDate;
|
||||||
widget.controllers["delegationEndDate"]?.text =
|
widget.controllers["delegationEndDate"]?.text =
|
||||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||||
// textControllers["_forexEndDate"]?.text =
|
|
||||||
// DateFormat('dd-MM-yyyy').format(initialDate);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,14 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import '../../../services/apiService.dart';
|
import '../../../services/apiService.dart';
|
||||||
import '../../../utils/auth_utils.dart';
|
import '../../../utils/auth_utils.dart';
|
||||||
import '../../../widgets/custom_user_form.dart';
|
import '../../../widgets/custom_user_form.dart';
|
||||||
|
import '../../../config/apiUrl.dart';
|
||||||
|
import 'change_password.dart';
|
||||||
|
|
||||||
class PersonalDetails extends StatefulWidget {
|
class PersonalDetails extends StatefulWidget {
|
||||||
final GlobalKey<PersonalDetailsState> personalDetailsKey;
|
final GlobalKey<PersonalDetailsState> personalDetailsKey;
|
||||||
@ -31,6 +34,7 @@ class PersonalDetails extends StatefulWidget {
|
|||||||
final String? selectedGender;
|
final String? selectedGender;
|
||||||
final String? selectedCountry;
|
final String? selectedCountry;
|
||||||
final String? selectedRole;
|
final String? selectedRole;
|
||||||
|
final String? userIdApi;
|
||||||
|
|
||||||
// const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},);
|
// const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},);
|
||||||
const PersonalDetails(
|
const PersonalDetails(
|
||||||
@ -49,7 +53,7 @@ class PersonalDetails extends StatefulWidget {
|
|||||||
this.onGenderChanged,
|
this.onGenderChanged,
|
||||||
this.onCountryChanged,
|
this.onCountryChanged,
|
||||||
this.onRoleChanged,
|
this.onRoleChanged,
|
||||||
this.onUserTypeChanged})
|
this.onUserTypeChanged, this.userIdApi})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -124,8 +128,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
Color? layoutColor;
|
Color? layoutColor;
|
||||||
Color? bodyColor;
|
Color? bodyColor;
|
||||||
|
|
||||||
|
final Map<String, TextEditingController> controllers = {};
|
||||||
|
Map<String, String> errorMessages2 = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
apiCountryData = null;
|
apiCountryData = null;
|
||||||
@ -144,6 +154,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
loadAllServices();
|
loadAllServices();
|
||||||
getOrganizationData();
|
getOrganizationData();
|
||||||
|
loadInitialData();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +164,21 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadInitialData() async {
|
||||||
|
String? layoutString = await getLayoutColor();
|
||||||
|
String? bodyStringColor = await getBodyColor();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
layoutColor = layoutString != null
|
||||||
|
? Color(int.parse(layoutString))
|
||||||
|
: Colors.redAccent;
|
||||||
|
|
||||||
|
bodyColor = bodyStringColor != null
|
||||||
|
? Color(int.parse(bodyStringColor))
|
||||||
|
: Colors.white;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> fetchRoles() async {
|
Future<void> fetchRoles() async {
|
||||||
try {
|
try {
|
||||||
final response = await apiService.fetchMasterDropdown();
|
final response = await apiService.fetchMasterDropdown();
|
||||||
@ -526,6 +552,24 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildThirdRow(bool isDesktop) {
|
Widget _buildThirdRow(bool isDesktop) {
|
||||||
|
|
||||||
|
void _openPopup() {
|
||||||
|
final emailValue = widget.controllers["email"]?.text ?? "";
|
||||||
|
final updaterUserId = widget.userIdApi ?? "";
|
||||||
|
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return ChangePasswordDialogData(
|
||||||
|
updaterEmail: emailValue,
|
||||||
|
updaterUserId: updaterUserId,
|
||||||
|
layoutColor: layoutColor,
|
||||||
|
isDesktop: widget.isDesktop,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: isDesktop
|
child: isDesktop
|
||||||
@ -535,8 +579,16 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
if (!widget.apiselectedUser) ...[
|
if (!widget.apiselectedUser) ...[
|
||||||
buildPassword(),
|
buildPassword(),
|
||||||
SizedBox(width: 15),
|
SizedBox(width: 15),
|
||||||
],
|
|
||||||
buildRole()
|
buildRole()
|
||||||
|
]
|
||||||
|
else ...[
|
||||||
|
buildRole(),
|
||||||
|
SizedBox(height: 8, width: 15),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => _openPopup(),
|
||||||
|
child: Text("Change Password"),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Column(
|
: Column(
|
||||||
@ -544,9 +596,15 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
children: [
|
children: [
|
||||||
if (!widget.apiselectedUser) ...[
|
if (!widget.apiselectedUser) ...[
|
||||||
buildPassword(),
|
buildPassword(),
|
||||||
SizedBox(height: 8)], //
|
SizedBox(height: 8),buildRole()
|
||||||
buildRole()
|
] else ...[
|
||||||
|
buildRole(),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => _openPopup(),
|
||||||
|
child: Text("Change Password"),
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -1282,3 +1340,4 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
// apiselectedUser != null
|
// apiselectedUser != null
|
||||||
// ? SizedBox()
|
// ? SizedBox()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3093,6 +3093,109 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildVisaType2(entry) {
|
||||||
|
late Map<String, String> visaTypeMap; // Mapping country_code -> country_name
|
||||||
|
late List<String> visaTypeCodes; // List of country codes
|
||||||
|
|
||||||
|
// List<dynamic> purposeList = apiData?['visa_type_of_visa'];
|
||||||
|
|
||||||
|
List<dynamic> purposeList = apiData?['visa_type_of_visa'];
|
||||||
|
|
||||||
|
print("purposeList - $purposeList");
|
||||||
|
|
||||||
|
|
||||||
|
visaTypeMap = {
|
||||||
|
for (var item in purposeList)
|
||||||
|
item['visa_type_id'] as String: item['visa_type_of_visa'] as String
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract only country codes for processing
|
||||||
|
visaTypeCodes = visaTypeMap.keys.toList();
|
||||||
|
|
||||||
|
// selectedPurpose ??= null;
|
||||||
|
|
||||||
|
String? selectedPurpose = entry['visa_type_of_visa'];
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Visa Type",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF575A74))
|
||||||
|
),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
CustomTextFieldUserTravellerWrapper(
|
||||||
|
width: widget.isDesktop
|
||||||
|
? MediaQuery.of(context).size.width * 0.17
|
||||||
|
: null,
|
||||||
|
isFocused: false,
|
||||||
|
isDesktop: widget.isDesktop,
|
||||||
|
child: SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: DropdownSearch<String>(
|
||||||
|
selectedItem: visaTypeMap[selectedPurpose],
|
||||||
|
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: "Search Visa Type...",
|
||||||
|
hintStyle: GoogleFonts.poppins(fontSize: 11.5),
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
items: visaTypeMap.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 Visa Type",
|
||||||
|
style: TextStyle(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
// Find the country_code based on selected country_name
|
||||||
|
// selectedCountry = countryMap.entries
|
||||||
|
// .firstWhere((entry) => entry.value == newValue)
|
||||||
|
// .key;
|
||||||
|
|
||||||
|
final selectedPurpose = visaTypeMap.entries
|
||||||
|
.firstWhere((entry) => entry.value == newValue)
|
||||||
|
.key;
|
||||||
|
entry['visa_type_of_visa'] = selectedPurpose;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildVisaValidFrom(Map<String, dynamic> entry) {
|
Widget buildVisaValidFrom(Map<String, dynamic> entry) {
|
||||||
DateTime? _selectedCheckOutDate;
|
DateTime? _selectedCheckOutDate;
|
||||||
TimeOfDay? _selectedCheckOutTime;
|
TimeOfDay? _selectedCheckOutTime;
|
||||||
@ -3132,7 +3235,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"ValidFrom",
|
"Valid From",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
@ -3214,7 +3317,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Valid UpTo",
|
"Valid To",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user