377 lines
12 KiB
Dart
377 lines
12 KiB
Dart
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',
|
|
'app-signature': 'ts-traveltool-2025-signature-123456',
|
|
};
|
|
|
|
try {
|
|
final uri = Uri.parse(apiUrldata);
|
|
final headers = {
|
|
'Authorization': 'Bearer $token',
|
|
'Content-Type': 'application/json',
|
|
'app-signature': 'ts-traveltool-2025-signature-123456',
|
|
};
|
|
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 == 403) {
|
|
print("403-FORB");
|
|
await apiService.logout(context);
|
|
return null;
|
|
// throw Exception('Failed to load users');
|
|
} 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(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|