onufitness_mobile/lib/screens/accounts/become_a_coach_controller.dart
2026-01-13 11:36:24 +05:30

264 lines
8.5 KiB
Dart

import 'dart:convert';
import 'dart:developer';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:onufitness/constants/api_endpoints.dart';
import 'package:onufitness/models/master_dropdowns/coach_types_dropdown_response_model.dart';
import 'package:onufitness/services/api_services/base_api_services.dart';
import 'package:onufitness/services/local_storage_services/shared_services.dart';
import 'package:onufitness/utils/custom_sneakbar.dart';
class BecomeACoachController extends GetxController {
@override
void onInit() async {
super.onInit();
fetchCoachTypes();
certificateTypeController = TextEditingController();
socialMediaController = TextEditingController();
selectedExperienceCount = TextEditingController();
}
//...............................................................................................................
var certificateFile = Rx<XFile?>(null);
Future<void> pickCertificate() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg', 'png', 'pdf'],
);
if (result != null && result.files.single.path != null) {
final file = result.files.single;
final filePath = file.path!;
final fileSize = file.size; // in bytes
final fileExtension = file.extension?.toLowerCase();
const maxFileSize = 5 * 1024 * 1024; // 5MB
if (!['jpg', 'jpeg', 'png', 'pdf'].contains(fileExtension)) {
customSnackbar(
title: "Invalid File",
message: "Only PDF, PNG, JPG, JPEG files are allowed.",
);
return;
}
if (fileSize > maxFileSize) {
customSnackbar(
title: "File Too Large",
message:
"File size too large. PDF, PNG, JPG, and JPEG files must be 5MB or smaller.",
);
return;
}
certificateFile.value = XFile(filePath);
}
}
//............................................................................................................
Rx<DateTime?> selectedDate = Rx<DateTime?>(null);
void pickDate(BuildContext context) async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: selectedDate.value ?? DateTime.now(),
firstDate: DateTime(1900),
lastDate: DateTime.now(),
);
if (pickedDate != null) {
selectedDate.value = pickedDate;
}
}
//............................................................................................................
var isCoachTypesLoading = false.obs;
var apiCoachTypeList = <CoachTypes>[].obs;
var selectedCoachTypes = "".obs;
RxList<String> localCoachTypesNameList = <String>[].obs;
RxInt selectedCoachTypesId = 0.obs;
Future<void> fetchCoachTypes() async {
isCoachTypesLoading(true);
try {
var response = await ApiBase.getRequest(
extendedURL: ApiUrl.fetchCoachTypes,
sendHeaders: false,
);
if (response.statusCode == 200 || response.statusCode == 201) {
var responseData = coachTypesResponseModelFromJson(response.body);
if (responseData.isSuccess == true) {
apiCoachTypeList.assignAll(responseData.data ?? []);
localCoachTypesNameList.clear();
for (var coach in responseData.data!) {
localCoachTypesNameList.add(coach.typeName.toString());
}
} else {
var responseData = coachTypesResponseModelFromJson(response.body);
customSnackbar(
title: "Error",
message: responseData.message ?? "Failed to get Coach Types",
);
}
} else {
var responseData = coachTypesResponseModelFromJson(response.body);
customSnackbar(
title: "Error",
message: responseData.message ?? "Failed to get Coach Types",
);
}
} catch (e) {
log("Exception: $e");
customSnackbar(title: "Error", message: "Failed to get Coach Types");
} finally {
isCoachTypesLoading(false);
}
}
//............................................................................................................
TextEditingController certificateTypeController = TextEditingController();
TextEditingController socialMediaController = TextEditingController();
TextEditingController selectedExperienceCount = TextEditingController();
RxBool isBecomeCoachLoading = false.obs;
Future<bool> becomeCoach() async {
isBecomeCoachLoading(true);
bool ret = false;
try {
if (certificateFile.value == null) {
customSnackbar(
title: "Error",
message: "Please select a certificate file.",
);
isBecomeCoachLoading(false);
return false;
}
var response = await ApiBase.postMultipleFiles(
extendedURL: ApiUrl.becomeACoach,
body: {
"UserID": SharedServices.getLoginDetails()?.data?.userId.toString(),
"YearOfExperience": selectedExperienceCount.text,
"CertificateType": certificateTypeController.text,
"SocialMediaLinks": "",
"CoachTypeID": selectedCoachTypesId.value,
},
files: [certificateFile.value!],
fileNameKey: 'Certificates',
);
log(certificateFile.value!.path.toString());
if (response.statusCode == 200 || response.statusCode == 201) {
Future.delayed(Duration(milliseconds: 300), () {
customSnackbar(
title: "Success",
message: "Coach registration successful.",
);
});
certificateTypeController.clear();
socialMediaController.clear();
selectedCoachTypesId.value = 0;
selectedExperienceCount.text = "";
certificateFile.value = null;
ret = true;
} else {
log("Error: ${response.body}");
Map<String, dynamic> responseData = json.decode(response.body);
String message = responseData['message'] ?? 'Unknown error occurred';
Future.delayed(Duration(milliseconds: 300), () {
customSnackbar(title: "Failed", message: message);
});
}
} catch (e) {
log("Exception: $e");
customSnackbar(
title: "Failure",
message: "Unexpected error occurred. Please try again later.",
);
}
isBecomeCoachLoading(false);
return ret;
}
// Upload Profile Picture.................................................................................
var profileImage = Rx<XFile?>(null);
final ImagePicker _picker = ImagePicker();
Future<void> pickImage() async {
final XFile? result = await _picker.pickImage(source: ImageSource.gallery);
if (result != null) {
final fileBytes = await result.readAsBytes();
final fileSize = fileBytes.length;
const maxFileSize = 5 * 1024 * 1024; // 5MB
if (fileSize > maxFileSize) {
customSnackbar(
title: "File Too Large",
message:
"Profile image must be 5MB or smaller. Please select a smaller file.",
);
return;
}
profileImage.value = result;
update();
await uploadProfilePicture();
}
}
//.........................................................................................................
var isUploadingImage = false.obs;
Future<void> uploadProfilePicture() async {
if (profileImage.value == null) {
log("No image selected");
customSnackbar(title: "Error", message: "No image selected");
return;
}
isUploadingImage(true);
try {
var userId = SharedServices.getUserDetails()?.data?.userId.toString();
var response = await ApiBase.postSingleFileRequest(
extendedURL: "${ApiUrl.uploadProfileImage}/$userId",
sendHeaders: false,
file: profileImage.value!,
fileNameKey: 'file',
);
log(response.statusCode.toString());
log(response.body.toString());
if (response.statusCode == 200 || response.statusCode == 201) {
log("Image uploaded successfully");
customSnackbar(
title: "Success",
message: "Image uploaded successfully",
duration: 1,
);
} else {
customSnackbar(
title: "Error",
message: jsonDecode(response.body)["message"],
);
}
} catch (e) {
log("Error uploading image: \$e");
customSnackbar(title: "Error", message: "Failed to upload image");
} finally {
isUploadingImage(false);
}
}
}