Files
authsec_flutter/lib/screens/profileManagement/Profilesettings.dart
T
2026-09-15 09:09:11 +05:30

525 lines
19 KiB
Dart

import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../resources/api_constants.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_text_form_field.dart';
import '../Login Screen/login_screen.dart';
import '../LogoutService/Logoutservice.dart';
import 'apiserviceprofilemanagement.dart';
import 'package:http/http.dart' as http;
import 'changepassword.dart';
class ProfileSettingsScreen extends StatefulWidget {
final Map<String, dynamic> userData;
ProfileSettingsScreen({required this.userData});
@override
_ProfileSettingsScreenState createState() => _ProfileSettingsScreenState();
}
class _ProfileSettingsScreenState extends State<ProfileSettingsScreen> {
ApiServiceProfileManagement apiService = ApiServiceProfileManagement();
String? fetchedimageurl =
'http://43.205.154.152:30165/assets/images/profile-icon.png';
Uint8List? _imageBytes; // Uint8List to store the image data
String? _imageFileName;
final _formKey = GlobalKey<FormState>();
TextEditingController fullNameController = TextEditingController();
TextEditingController pronounsController = TextEditingController();
TextEditingController roleController = TextEditingController();
TextEditingController departmentController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController aboutMeController = TextEditingController();
@override
void initState() {
super.initState();
//fetchProfileImageData();
fetchUserProfileData();
}
Future<void> _uploadImageFile() async {
final imagePicker = ImagePicker();
try {
final pickedImage =
await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
final imageBytes = await pickedImage.readAsBytes();
setState(() {
_imageBytes = imageBytes;
_imageFileName = pickedImage.name; // Store the file name
});
}
} catch (e) {
print(e);
}
}
//api/user-profile
Future<void> fetchUserProfileData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
setState(() {
fullNameController.text =
jsonData['fullName'] != null ? jsonData['fullName'] : '';
pronounsController.text =
jsonData['pronouns'] != null ? jsonData['pronouns'] : '';
roleController.text =
jsonData['role'] != null ? jsonData['role'] : '';
departmentController.text =
jsonData['department'] != null ? jsonData['department'] : '';
emailController.text =
jsonData['email'] != null ? jsonData['email'] : '';
aboutMeController.text =
jsonData['about'] != null ? jsonData['about'] : '';
});
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> fetchProfileImageData() async {
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/retrieve-image';
try {
final response = await http.get(
Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode >= 200 && response.statusCode <= 209) {
final Map<String, dynamic> jsonData = json.decode(response.body);
final trustedImageUrl = Uri.dataFromString(jsonData['image'],
mimeType: 'image/*', encoding: Encoding.getByName('utf-8'))
.toString();
fetchedimageurl = trustedImageUrl;
} else {
throw Exception('Failed to load data: ${response.statusCode}');
}
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
Future<void> _submitImage() async {
if (_imageBytes == null) {
// Show an error message if no image is selected
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Please select an image.'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
return;
}
if (_imageFileName == null) {
// Handle the case where _imageFileName is null (no file name provided)
print('File name is missing.');
return;
}
try {
final token = await TokenManager.getToken();
await apiService.createFile(_imageBytes!, _imageFileName!, token!);
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to upload image: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
Future<void> _updateProfile() async {
if (_formKey.currentState!.validate()) {
// Create a JSON object with the form data
final profileData = {
'fullName': fullNameController.text,
'pronouns': pronounsController.text,
'role': roleController.text,
'department': departmentController.text,
'email': emailController.text,
'aboutMe': aboutMeController.text,
};
//api/user-profile
final token = await TokenManager.getToken();
final String baseUrl = ApiConstants.baseUrl;
final String apiUrl = '$baseUrl/api/user-profile';
try {
final response = await http.put(Uri.parse(apiUrl),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: json.encode(profileData));
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode <= 209) {
print("success");
Navigator.of(context).pop();
} else {
print(response.statusCode);
}
} catch (e) {
throw Exception('Failed to Update: $e');
}
}
}
Future<void> _logoutUser() async {
try {
String logouturl = "${ApiConstants.baseUrl}/token/logout";
var response = await http.get(Uri.parse(logouturl));
if (response.statusCode <= 209) {
// ignore: use_build_context_synchronously
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginScreen()),
(route) => false, // Remove all routes from the stack
);
} else {
const Text('failed to logout');
}
} catch (error) {
print('Error occurred during logout: $error');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "My Profile Settings")),
body: SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
// Section: Show Profile Photo
Center(
child: Column(
children: [
CircleAvatar(
radius: 70, // Adjust as needed
backgroundImage: NetworkImage(
"$fetchedimageurl"), // Replace with your API URL
),
SizedBox(height: 10),
CustomButton(
height: getVerticalSize(50),
text: _imageBytes == null
? "Pick a Profile Photo"
: 'Upload Success',
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
if (_imageBytes != null) {
_submitImage();
} else {
_uploadImageFile();
}
},
),
],
),
),
SizedBox(height: 20),
// Section: Profile Form
Text(
'Your Profile Information',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Your Full Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
controller: fullNameController,
hintText: "Enter Full Name",
validator: (value) {
if (value!.isEmpty) {
return 'Please enter your full name';
}
return null;
},
onChanged: (value) {
fullNameController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Pronouns",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Pronouns",
controller: pronounsController,
onChanged: (value) {
pronounsController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Role",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Role",
controller: roleController,
onChanged: (value) {
roleController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Department or Team",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Department or Team",
controller: departmentController,
onChanged: (value) {
departmentController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Email",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Email",
controller: emailController,
validator: (value) {
if (value!.isEmpty || !value!.contains('@')) {
return 'Please enter a valid email address';
}
return null;
},
onChanged: (value) {
emailController.text = value;
},
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("About Me",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "About Me",
controller: aboutMeController,
maxLines: 3,
onChanged: (value) {
aboutMeController.text = value;
},
margin: getMargin(top: 6))
])),
CustomButton(
height: getVerticalSize(50),
text: "Update Profile",
margin: getMargin(top: 24, bottom: 5),
onTap: _updateProfile,
),
],
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResetPasswordScreen(
userData: widget.userData,
userEmail: emailController.text,
), //go to get all entity
),
);
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
"Password:Change Password for your account Change password",
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
print("change password");
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Security:Logout of all sessions except this current browser Logout other sessions',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
GestureDetector(
onTap: () {
_logoutUser();
},
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'Deactivation:Remove access to all organizations and workspace in cloudnsure Deactivate account',
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.blue,
),
),
],
),
),
),
SizedBox(height: 20),
],
),
),
);
}
}