feat(reports,settings,docs): server-side PDF export, cutoff date picker, and UI refinements
- Reports: Migrate DepEd Transparency Board PDF export to backend Puppeteer service with enlarged layout and per-section downloads - Settings: Replace dynamic grace period days input with cutoff date picker and calculated days preview; separate schedule date pickers - Documents: Default requirements section to collapsed/closed state in upload OCR modal with pulsing border container - Fix contrast on Auto-Graduation trigger button and ensure desktop responsiveness across report buttons
This commit is contained in:
1 parent
2376e99217
commit
7faade70a9
28 files changed
+2500
-1800
No files matched your search
@@ -748,6 +748,25 @@ class DocumentRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> mergePrintQueuePdf({List<int>? documentIds}) async {
|
||||
try {
|
||||
final options = await _getAuthOptions();
|
||||
options.responseType = ResponseType.bytes;
|
||||
final res = await _dio.post<List<int>>(
|
||||
'/documents/print-queue/merge-pdf',
|
||||
data: documentIds != null && documentIds.isNotEmpty
|
||||
? {'documentIds': documentIds}
|
||||
: null,
|
||||
options: options,
|
||||
);
|
||||
return Uint8List.fromList(res.data!);
|
||||
} on DioException catch (e) {
|
||||
final msg =
|
||||
e.response?.data?['message'] ?? 'Failed to merge print queue PDF.';
|
||||
throw Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Recycle Bin / Trash
|
||||
Future<List<TrashDocumentModel>> getTrashDocuments() async {
|
||||
try {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import '../../core/network/api_constants.dart';
|
||||
@@ -122,5 +123,43 @@ class ReportRepository {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> downloadTransparencyBoardPdf({
|
||||
int? academicYearId,
|
||||
List<int>? yearIds,
|
||||
String? schoolName,
|
||||
String? divisionName,
|
||||
String? regionName,
|
||||
String? category,
|
||||
}) async {
|
||||
try {
|
||||
final queryParams = <String, dynamic>{};
|
||||
if (academicYearId != null) queryParams['academicYearId'] = academicYearId;
|
||||
if (yearIds != null && yearIds.isNotEmpty) {
|
||||
queryParams['yearIds'] = yearIds.join(',');
|
||||
}
|
||||
if (schoolName != null) queryParams['schoolName'] = schoolName;
|
||||
if (divisionName != null) queryParams['divisionName'] = divisionName;
|
||||
if (regionName != null) queryParams['regionName'] = regionName;
|
||||
if (category != null && category.isNotEmpty && category != 'all') {
|
||||
queryParams['category'] = category;
|
||||
}
|
||||
|
||||
final options = await _authOptions();
|
||||
options.responseType = ResponseType.bytes;
|
||||
|
||||
final res = await _dio.get<List<int>>(
|
||||
'/reports/transparency-board/pdf',
|
||||
queryParameters: queryParams.isNotEmpty ? queryParams : null,
|
||||
options: options,
|
||||
);
|
||||
return Uint8List.fromList(res.data!);
|
||||
} on DioException catch (e) {
|
||||
throw Exception(
|
||||
e.response?.data?['message'] ??
|
||||
'Failed to generate transparency board PDF.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +100,21 @@ class SetupRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> checkAutoArchive() async {
|
||||
try {
|
||||
final options = await _getAuthOptions();
|
||||
final res = await _dio.post(
|
||||
'/setup/academic-years/check-auto-archive',
|
||||
options: options,
|
||||
);
|
||||
return res.data as Map<String, dynamic>;
|
||||
} on DioException catch (e) {
|
||||
throw Exception(
|
||||
e.response?.data?['message'] ?? 'Failed to check auto-archive.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteAcademicYear(int id) async {
|
||||
try {
|
||||
final options = await _getAuthOptions();
|
||||
|
||||
Reference in new issue
Block a user