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

383 lines
13 KiB
Dart

import 'dart:developer';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:onufitness/controller/update_acces_token_controller.dart';
import 'package:onufitness/screens/accounts/model/coach_service_offerings_response_model.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';
import 'package:url_launcher/url_launcher.dart';
import 'package:http/http.dart' as http;
class CoachServiceOfferingController extends GetxController {
@override
void onInit() {
fetchCoachTypes();
getServiceOfferings();
super.onInit();
}
var isServiceOfferingsLoading = false.obs;
var serviceOfferingsData = Rxn<ServiceOfferingsData>();
var apiCertificates = <Certificate>[].obs;
var isUpdatingServiceOffering = false.obs;
var isAddingCertificate = false.obs;
Future<void> pickFileForAdding() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['pdf', 'jpg', 'jpeg', 'png'],
);
if (result != null) {
String filePath = result.files.single.path!;
await addCertificateToServer(filePath);
}
}
void pickFileForEditing(int index) async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['pdf', 'jpg', 'jpeg', 'png'],
);
if (result != null) {
String filePath = result.files.single.path!;
Certificate cert = apiCertificates[index];
await updateCertificateOnServer(cert.certificateId!, filePath);
}
}
Future<void> downloadCertificate(String filePath) async {
final uri = Uri.parse(filePath);
if (!await launchUrl(uri, mode: LaunchMode.inAppBrowserView)) {
throw Exception('Could not launch $filePath');
}
}
String getShortText(String text, {int maxLength = 10}) {
if (text.length <= maxLength) return text;
return '${text.substring(0, maxLength)}...';
}
void removeCertificateWithConfirmation(int index) {
String fileName = apiCertificates[index].certificateName!;
Get.dialog(
AlertDialog(
title: Text("Remove Certificate"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Are you sure you want to remove this certificate?"),
SizedBox(height: 10),
Text(
"File: $fileName",
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 10),
],
),
actions: [
TextButton(onPressed: () => Get.back(), child: Text("Cancel")),
ElevatedButton(
onPressed: () {
Get.back();
_removeCertificateAtIndex(index);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
),
child: Text("Remove"),
),
],
),
);
}
void _removeCertificateAtIndex(int index) async {
Certificate cert = apiCertificates[index];
await deleteCertificateFromServer(cert.certificateId!);
}
//Update Service Offering ..............................................................................
Future<void> updateServiceOffering() async {
if (selectedCoachTypesId.value == 0) {
customSnackbar(title: "Error", message: "Please select a coach type");
return;
}
isUpdatingServiceOffering(true);
try {
var response = await ApiBase.putRequest(
extendedURL: ApiUrl.updateServiceOffering,
sendHeaders: true,
body: {"coachTypeID": selectedCoachTypesId.value},
);
if (response.statusCode == 200 || response.statusCode == 201) {
customSnackbar(
title: "Success",
message: "Service offering updated successfully",
duration: 1,
);
await getServiceOfferings();
} else {
customSnackbar(
title: "Error",
message: "Failed to update service offering",
duration: 1,
);
}
} catch (e) {
customSnackbar(
title: "Error",
message: "Failed to update service offering",
duration: 1,
);
} finally {
isUpdatingServiceOffering(false);
}
}
// Delete Certificate...............................................................................
RxList<int> deleteCertificateLoading = <int>[].obs;
Future<void> deleteCertificateFromServer(int certificateId) async {
deleteCertificateLoading.add(certificateId);
try {
var response = await ApiBase.deleteRequest(
extendedURL: "${ApiUrl.deleteCoachCertificate}/$certificateId",
sendHeaders: true,
body: {},
);
if (response.statusCode == 200 || response.statusCode == 204) {
await getServiceOfferings();
} else {
customSnackbar(title: "Error", message: "Failed to delete certificate");
}
} catch (e) {
log("Exception in deleteCertificateFromServer: $e");
customSnackbar(
title: "Error",
message: "Failed to delete certificate: ${e.toString()}",
);
} finally {
deleteCertificateLoading.remove(certificateId);
}
}
// Update Certificate.......................................................................................
RxList<int> updateCertificateLoading = <int>[].obs;
Future<void> updateCertificateOnServer(
int certificateId,
String filePath,
) async {
updateCertificateLoading.add(certificateId);
try {
var request = http.MultipartRequest(
'PUT',
Uri.parse("${ApiUrl.baseUrl}${ApiUrl.updateCoachCertificate}"),
);
String? token = SharedServices.userAuth();
request.headers['Authorization'] = 'Bearer $token';
request.headers['accept'] = 'text/plain';
request.fields['CertificateID'] = certificateId.toString();
var file = await http.MultipartFile.fromPath('Certificates', filePath);
request.files.add(file);
var response = await request.send();
var responseBody = await response.stream.bytesToString();
if (response.statusCode == 200 || response.statusCode == 201) {
customSnackbar(
title: "Success",
message: "Certificate updated successfully",
duration: 1,
);
await getServiceOfferings();
} else if (response.statusCode == 401) {
await UpdateAccesTokenController.updateAccessToken();
await updateCertificateOnServer(certificateId, filePath);
} else {
log("Update certificate error: ${response.statusCode} - $responseBody");
customSnackbar(
title: "Error",
message: "Failed to update certificate",
duration: 1,
);
}
} catch (e) {
log("Catch: Exception in updateCertificateOnServer");
customSnackbar(
title: "Error",
message: "Failed to update certificate",
duration: 1,
);
} finally {
updateCertificateLoading.remove(certificateId);
}
}
// Add Certificate.......................................................................................
Future<void> addCertificateToServer(String filePath) async {
isAddingCertificate(true);
try {
var request = http.MultipartRequest(
'POST',
Uri.parse(
"${ApiUrl.baseUrl}${ApiUrl.coachAddServiceOfferingCertificate}",
),
);
String? token = SharedServices.userAuth();
request.headers['Authorization'] = 'Bearer $token';
request.headers['accept'] = 'text/plain';
request.fields['CertificateType'] = 'string';
var file = await http.MultipartFile.fromPath('Certificates', filePath);
request.files.add(file);
var response = await request.send();
var responseBody = await response.stream.bytesToString();
log("Add certificate error: ${response.statusCode} - $responseBody");
if (response.statusCode == 200 || response.statusCode == 201) {
customSnackbar(
title: "Success",
message: "Certificate added successfully",
duration: 1,
);
await getServiceOfferings();
} else if (response.statusCode == 401) {
await UpdateAccesTokenController.updateAccessToken();
await addCertificateToServer(filePath);
} else {
log("Add certificate error: ${response.statusCode} - $responseBody");
customSnackbar(
title: "Error",
message: "Failed to add certificate",
duration: 1,
);
}
} catch (e) {
log("Exception in addCertificateToServer: $e");
customSnackbar(
title: "Error",
message: "Failed to add certificate: ${e.toString()}",
duration: 1,
);
} finally {
isAddingCertificate(false);
}
}
//...........Fetch Coach Types for Dropdown..............................................................................
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: true,
);
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);
}
}
//...........Get Service Offerings API Call..............................................................................
Future<void> getServiceOfferings() async {
isServiceOfferingsLoading(true);
try {
var response = await ApiBase.getRequest(
extendedURL: ApiUrl.getServiceOfferings,
sendHeaders: true,
);
log(response.body);
if (response.statusCode == 200 || response.statusCode == 201) {
var responseData = getServiceOfferingsResponseModelFromJson(
response.body,
);
if (responseData.isSuccess == true && responseData.data != null) {
serviceOfferingsData.value = responseData.data;
apiCertificates.assignAll(responseData.data?.certificates ?? []);
if (responseData.data?.coachTypeName != null) {
selectedCoachTypes.value = responseData.data!.coachTypeName!;
selectedCoachTypesId.value = responseData.data!.coachTypeId ?? 0;
}
log("Service Offerings loaded successfully");
} else {
customSnackbar(
title: "Error",
message: responseData.message ?? "Failed to get Service Offerings",
);
}
} else {
log("API Error: Status Code ${response.statusCode}");
log("Response Body: ${response.body}");
customSnackbar(
title: "Error",
message: "Failed to get Service Offerings",
);
}
} catch (e) {
log("Exception in getServiceOfferings: $e");
customSnackbar(
title: "Error",
message: "Failed to get Service Offerings}",
);
} finally {
isServiceOfferingsLoading(false);
}
}
// Method to refresh/reload service offerings........................................................................
Future<void> refreshServiceOfferings() async {
await getServiceOfferings();
}
}