146 lines
4.0 KiB
Dart
146 lines
4.0 KiB
Dart
import 'package:get/get.dart';
|
|
import 'package:marco/helpers/services/api_service.dart';
|
|
import 'package:marco/model/service_project/service_projects_details_model.dart';
|
|
import 'package:marco/model/service_project/job_list_model.dart';
|
|
import 'package:marco/model/service_project/service_project_job_detail_model.dart';
|
|
|
|
class ServiceProjectDetailsController extends GetxController {
|
|
// -------------------- Observables --------------------
|
|
var projectId = ''.obs;
|
|
var projectDetail = Rxn<ProjectDetail>();
|
|
var jobList = <JobEntity>[].obs;
|
|
var jobDetail = Rxn<JobDetailsResponse>();
|
|
|
|
// Loading states
|
|
var isLoading = false.obs;
|
|
var isJobLoading = false.obs;
|
|
var isJobDetailLoading = false.obs;
|
|
|
|
// Error messages
|
|
var errorMessage = ''.obs;
|
|
var jobErrorMessage = ''.obs;
|
|
var jobDetailErrorMessage = ''.obs;
|
|
|
|
// Pagination
|
|
var pageNumber = 1;
|
|
final int pageSize = 20;
|
|
var hasMoreJobs = true.obs;
|
|
|
|
// -------------------- Lifecycle --------------------
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
fetchProjectJobs(initialLoad: true); // fetch job list initially
|
|
}
|
|
|
|
// -------------------- Project --------------------
|
|
void setProjectId(String id) {
|
|
projectId.value = id;
|
|
fetchProjectDetail();
|
|
pageNumber = 1;
|
|
hasMoreJobs.value = true;
|
|
fetchProjectJobs(initialLoad: true);
|
|
}
|
|
|
|
Future<void> fetchProjectDetail() async {
|
|
if (projectId.value.isEmpty) {
|
|
errorMessage.value = "Invalid project ID";
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
errorMessage.value = '';
|
|
|
|
try {
|
|
final result =
|
|
await ApiService.getServiceProjectDetailApi(projectId.value);
|
|
|
|
if (result != null && result.data != null) {
|
|
projectDetail.value = result.data!;
|
|
} else {
|
|
errorMessage.value =
|
|
result?.message ?? "Failed to fetch project details";
|
|
}
|
|
} catch (e) {
|
|
errorMessage.value = "Error: $e";
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
// -------------------- Job List --------------------
|
|
Future<void> fetchProjectJobs({bool initialLoad = false}) async {
|
|
if (projectId.value.isEmpty && !initialLoad) {
|
|
jobErrorMessage.value = "Invalid project ID";
|
|
return;
|
|
}
|
|
|
|
if (!hasMoreJobs.value && !initialLoad) return;
|
|
|
|
isJobLoading.value = true;
|
|
jobErrorMessage.value = '';
|
|
|
|
try {
|
|
final result = await ApiService.getServiceProjectJobListApi(
|
|
projectId: projectId.value,
|
|
pageNumber: pageNumber,
|
|
pageSize: pageSize,
|
|
isActive: true,
|
|
);
|
|
|
|
if (result != null && result.data != null) {
|
|
if (initialLoad) {
|
|
jobList.value = result.data?.data ?? [];
|
|
} else {
|
|
jobList.addAll(result.data?.data ?? []);
|
|
}
|
|
|
|
hasMoreJobs.value = (result.data?.data?.length ?? 0) == pageSize;
|
|
if (hasMoreJobs.value) pageNumber++;
|
|
} else {
|
|
jobErrorMessage.value = result?.message ?? "Failed to fetch job list";
|
|
}
|
|
} catch (e) {
|
|
jobErrorMessage.value = "Error fetching jobs: $e";
|
|
} finally {
|
|
isJobLoading.value = false;
|
|
}
|
|
}
|
|
|
|
Future<void> fetchMoreJobs() async => fetchProjectJobs();
|
|
|
|
// -------------------- Manual Refresh --------------------
|
|
Future<void> refresh() async {
|
|
pageNumber = 1;
|
|
hasMoreJobs.value = true;
|
|
await Future.wait([
|
|
fetchProjectDetail(),
|
|
fetchProjectJobs(initialLoad: true),
|
|
]);
|
|
}
|
|
|
|
// -------------------- Job Detail --------------------
|
|
Future<void> fetchJobDetail(String jobId) async {
|
|
if (jobId.isEmpty) {
|
|
jobDetailErrorMessage.value = "Invalid job ID";
|
|
return;
|
|
}
|
|
|
|
isJobDetailLoading.value = true;
|
|
jobDetailErrorMessage.value = '';
|
|
|
|
try {
|
|
final result = await ApiService.getServiceProjectJobDetailApi(jobId);
|
|
if (result != null) {
|
|
jobDetail.value = result;
|
|
} else {
|
|
jobDetailErrorMessage.value = "Failed to fetch job details";
|
|
}
|
|
} catch (e) {
|
|
jobDetailErrorMessage.value = "Error fetching job details: $e";
|
|
} finally {
|
|
isJobDetailLoading.value = false;
|
|
}
|
|
}
|
|
}
|