import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; import 'package:intl_phone_field/intl_phone_field.dart'; import 'package:onufitness/constants/color_constant.dart'; import 'package:onufitness/constants/constant.dart'; import 'package:onufitness/constants/string_constant.dart'; import 'package:onufitness/constants/text_constant.dart'; import 'package:onufitness/screens/accounts/Controllers/edit_account_controller.dart'; import 'package:onufitness/utils/custom_sneakbar.dart'; import 'package:onufitness/utils/helper_function.dart'; import 'package:onufitness/widgets/Dropdowns/custom_lebel_dropdown.dart'; import 'package:onufitness/widgets/bottomsheet/common_upload_option_bottomsheet.dart' show CommonUploadBottomSheet; import 'package:onufitness/widgets/pickers/custom_date_picker.dart'; import 'package:onufitness/widgets/TextFields/custom_textfield_with_inside_container_label_text.dart'; class TraineeCoachEditProfileScreen extends StatefulWidget { const TraineeCoachEditProfileScreen({super.key}); @override State createState() => _TraineeCoachEditProfileScreenState(); } class _TraineeCoachEditProfileScreenState extends State { final controller = Get.find(); @override void initState() { WidgetsBinding.instance.addPostFrameCallback((_) { apicall(); }); super.initState(); } apicall() async { await controller.fetchUserDetails(); } // Simple age validation bool _isOver18(DateTime birthDate) { final now = DateTime.now(); final age = now.year - birthDate.year; if (now.month < birthDate.month || (now.month == birthDate.month && now.day < birthDate.day)) { return (age - 1) >= 18; } return age >= 18; } void pickBirthDate() async { final DateTime? pickedDate = await showDatePicker( context: context, initialDate: DateTime.now().subtract(Duration(days: 18 * 365)), firstDate: DateTime(1900), lastDate: DateTime.now(), ); if (pickedDate != null) { if (_isOver18(pickedDate)) { controller.selectedDate.value = "${pickedDate.day}/${pickedDate.month}/${pickedDate.year}"; } else { customSnackbar( title: "Age Restriction", message: "You must be at least 18 years old to proceed.", duration: 3, ); } } } void handleDoneButtonPress() async { if (controller.validateForm()) { try { await controller.updateUserProfile(); customSnackbar( title: "Success", message: "Profile updated successfully!", duration: 2, ); } catch (e) { customSnackbar( title: "Failed", message: "Failed to update profile. Please try again.", duration: 2, ); } } } Widget buildProfileImage(bool isTablet) { return Obx(() { if (controller.isLoading.value) { return Container( width: isTablet ? 150.r : 100.r, height: isTablet ? 150.r : 100.r, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey[300], ), child: Center( child: CircularProgressIndicator( color: Colors.black, strokeWidth: 2, ), ), ); } if (controller.profileImage.value != null) { return CircleAvatar( backgroundImage: FileImage(File(controller.profileImage.value!.path)), radius: isTablet ? 60.r : 50.r, ); } if (controller.hasNetworkImage) { return CircleAvatar( radius: isTablet ? 60.r : 50.r, backgroundColor: lightGreyColor.withValues(alpha: 0.5), child: ClipOval( child: Image.network( controller.userProfileImageUrl!, width: isTablet ? 120.r : 100.r, height: isTablet ? 120.r : 100.r, fit: BoxFit.cover, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) return child; return Container( width: isTablet ? 120.r : 100.r, height: isTablet ? 120.r : 100.r, decoration: BoxDecoration( color: lightGreyColor.withValues(alpha: 0.5), shape: BoxShape.circle, ), child: Center( child: CircularProgressIndicator( color: Colors.black, strokeWidth: 2, ), ), ); }, errorBuilder: (context, error, stackTrace) { return buildDefaultAvatar(isTablet); }, ), ), ); } return buildDefaultAvatar(isTablet); }); } Widget buildDefaultAvatar(bool isTablet) { return Container( width: isTablet ? 150.r : 100.r, height: isTablet ? 150.r : 100.r, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( colors: [ becomeACoachGradient2, becomeACoachGradient1.withValues(alpha: 0.3), ], begin: Alignment.topCenter, end: Alignment.bottomRight, ), ), child: Icon( Icons.person, size: isTablet ? 90.sp : 50.sp, color: Colors.white, ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( backgroundColor: Colors.white, leading: IconButton( icon: const Icon(Icons.arrow_back_ios), onPressed: () => Get.back(), ), title: Text( editProfile, style: customTextStyle.copyWith( color: appbarTextColor, fontWeight: FontWeight.w600, fontSize: isTablet ? 24.sp : 20.sp, ), ), actions: [ Obx( () => TextButton( onPressed: controller.isUpdating.value ? null : handleDoneButtonPress, child: controller.isUpdating.value ? SizedBox( height: 20.h, width: 20.w, child: CircularProgressIndicator( color: Colors.black, strokeWidth: 2, ), ) : Text( doneText, style: TextStyle( fontSize: isTablet ? 25.sp : 20.sp, fontWeight: FontWeight.w600, color: appbarTextColor, ), ), ), ), ], ), body: LayoutBuilder( builder: (context, constraints) { bool isTablet = constraints.maxWidth >= 600; return Obx(() { if (controller.fetchUserDetailsLoading.value) { return Center( child: CircularProgressIndicator(color: Colors.black), ); } return SingleChildScrollView( padding: EdgeInsets.symmetric( horizontal: isTablet ? 20.w : 15.w, vertical: 16.h, ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Stack( alignment: Alignment.bottomRight, children: [ CircleAvatar( radius: isTablet ? 60.r : 50.r, backgroundColor: Colors.grey[300], child: buildProfileImage(isTablet), ), Positioned( bottom: 5, right: 5, child: CircleAvatar( radius: 15.r, backgroundColor: Colors.white, child: controller.isUploadingImage.value ? SizedBox( width: 15.r, height: 15.r, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.black, ), ) : IconButton( icon: Icon( Icons.edit, size: isTablet ? 20.sp : 15.sp, color: Colors.black, ), onPressed: () { CommonUploadBottomSheet.show( context: context, title: "Upload Photo From", allowedFileTypes: [ 'jpg', 'jpeg', 'png', ], maxFileSizeMB: 5.0, showCamera: true, showGallery: true, showDocument: true, onFileSelected: ( String filePath, String fileName, String fileExtension, ) async { controller.profileImage.value = XFile( filePath, ); await controller .uploadProfilePictureAPIcall(); }, onError: (String errorMessage) { // Show error message customSnackbar( title: "Error", message: errorMessage, ); }, ); }, ), ), ), ], ), SizedBox(height: 20.h), // Form Fields with validation indicators CustomTextFieldContainerInsideLabel( label: "First Name*", controller: controller.firstNameController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), CustomTextFieldContainerInsideLabel( label: "Last name*", controller: controller.lastNameController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), CustomTextFieldContainerInsideLabel( label: "About me", controller: controller.aboutMeController, maxLine: 4, borderColor: lightGreyColor, topContentPadding: 25.h, ), SizedBox(height: 20.h), Obx( () => IntlPhoneField( controller: controller.phoneNumberController, initialCountryCode: controller.selectedCountryCode.value, style: TextStyle(fontSize: regularSizeText), decoration: InputDecoration( fillColor: textFieldFillColor, filled: true, labelText: "Phone Number*", labelStyle: TextStyle( color: greyTextColor1, fontSize: regularSizeText, ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: lightGreyColor, width: 1, ), borderRadius: BorderRadius.circular(10.r), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: lightGreyColor, width: 1, ), borderRadius: BorderRadius.circular(10.r), ), errorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 1), borderRadius: BorderRadius.circular(10.r), ), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.red, width: 1), borderRadius: BorderRadius.circular(10.r), ), ), dropdownTextStyle: TextStyle(fontSize: regularSizeText), onChanged: (value) { controller.selectedCountryCode.value = value.countryISOCode; }, ), ), SizedBox(height: 20.h), // Date Picker Obx( () => CustomDatePicker( label: "Date of birth", selectedDate: controller.selectedDate.value, onDatePicked: controller.pickDate, borderColor: lightGreyColor, ), ), SizedBox(height: 20.h), // Gender Dropdown Obx( () => EnhancedLebelTextDropdown( title: 'Gender', items: const ["Male", "Female", "Other"], selectedItem: controller.selectedGender.value, onChanged: (value) { if (value != null) { controller.selectedGender.value = value; } }, borderColor: lightGreyColor, ), ), SizedBox(height: 20.h), // Social Media Links CustomTextFieldContainerInsideLabel( label: "Facebook Profile Link", controller: controller.facebookController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), CustomTextFieldContainerInsideLabel( label: "Instagram Profile Link", controller: controller.instagramController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), CustomTextFieldContainerInsideLabel( label: "LinkedIn Profile Link", controller: controller.linkedInController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), CustomTextFieldContainerInsideLabel( label: "Twitter Profile Link", controller: controller.twitterController, borderColor: lightGreyColor, ), SizedBox(height: 20.h), ], ), ); }); }, ), ); } }