marco.pms.mobileapp/lib/controller/document/user_document_controller.dart

174 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:marco/helpers/services/api_service.dart';
import 'package:marco/model/document/document_filter_model.dart';
import 'package:marco/model/document/documents_list_model.dart';
class DocumentController extends GetxController {
// ------------------ Observables ---------------------
var isLoading = false.obs;
var documents = <DocumentItem>[].obs;
var filters = Rxn<DocumentFiltersData>();
// Selected filters
var selectedFilter = "".obs;
var selectedUploadedBy = "".obs;
var selectedCategory = "".obs;
var selectedType = "".obs;
var selectedTag = "".obs;
// Pagination state
var pageNumber = 1.obs;
final int pageSize = 20;
var hasMore = true.obs;
// Error message
var errorMessage = "".obs;
// NEW: show inactive toggle
var showInactive = false.obs;
// NEW: search
var searchQuery = ''.obs;
var searchController = TextEditingController();
// ------------------ API Calls -----------------------
/// Fetch Document Filters for an Entity
Future<void> fetchFilters(String entityTypeId) async {
try {
isLoading.value = true;
final response = await ApiService.getDocumentFilters(entityTypeId);
if (response != null && response.success) {
filters.value = response.data;
} else {
errorMessage.value = response?.message ?? "Failed to fetch filters";
}
} catch (e) {
errorMessage.value = "Error fetching filters: $e";
} finally {
isLoading.value = false;
}
}
/// Toggle document active/inactive state
Future<bool> toggleDocumentActive(
String id, {
required bool isActive,
required String entityTypeId,
required String entityId,
}) async {
try {
isLoading.value = true;
final success =
await ApiService.deleteDocumentApi(id: id, isActive: isActive);
if (success) {
// 🔥 Always fetch fresh list after toggle
await fetchDocuments(
entityTypeId: entityTypeId,
entityId: entityId,
reset: true,
);
return true;
} else {
errorMessage.value = "Failed to update document state";
return false;
}
} catch (e) {
errorMessage.value = "Error updating document: $e";
return false;
} finally {
isLoading.value = false;
}
}
/// Permanently delete a document (or deactivate depending on API)
Future<bool> deleteDocument(String id, {bool isActive = false}) async {
try {
isLoading.value = true;
final success =
await ApiService.deleteDocumentApi(id: id, isActive: isActive);
if (success) {
// remove from local list immediately for better UX
documents.removeWhere((doc) => doc.id == id);
return true;
} else {
errorMessage.value = "Failed to delete document";
return false;
}
} catch (e) {
errorMessage.value = "Error deleting document: $e";
return false;
} finally {
isLoading.value = false;
}
}
/// Fetch Documents for an entity
Future<void> fetchDocuments({
required String entityTypeId,
required String entityId,
String? filter,
String? searchString,
bool reset = false,
}) async {
try {
if (reset) {
pageNumber.value = 1;
documents.clear();
hasMore.value = true;
}
if (!hasMore.value) return;
isLoading.value = true;
final response = await ApiService.getDocumentListApi(
entityTypeId: entityTypeId,
entityId: entityId,
filter: filter ?? "",
searchString: searchString ?? searchQuery.value,
pageNumber: pageNumber.value,
pageSize: pageSize,
isActive: !showInactive.value, // 👈 active or inactive
);
if (response != null && response.success) {
if (response.data.data.isNotEmpty) {
documents.addAll(response.data.data);
pageNumber.value++;
} else {
hasMore.value = false;
}
} else {
errorMessage.value = response?.message ?? "Failed to fetch documents";
}
} catch (e) {
errorMessage.value = "Error fetching documents: $e";
} finally {
isLoading.value = false;
}
}
// ------------------ Helpers -----------------------
/// Clear selected filters
void clearFilters() {
selectedUploadedBy.value = "";
selectedCategory.value = "";
selectedType.value = "";
selectedTag.value = "";
}
/// Check if any filters are active (for red dot indicator)
bool hasActiveFilters() {
return selectedUploadedBy.value.isNotEmpty ||
selectedCategory.value.isNotEmpty ||
selectedType.value.isNotEmpty ||
selectedTag.value.isNotEmpty;
}
}