343 lines
9.5 KiB
Dart
343 lines
9.5 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
import '../../core/network/api_constants.dart';
|
|
import '../entities/setup_models.dart';
|
|
|
|
class SetupRepository {
|
|
final Dio _dio = ApiConstants.createDio();
|
|
final FlutterSecureStorage _storage = const FlutterSecureStorage();
|
|
|
|
Future<Options> _getAuthOptions() async {
|
|
final token = await _storage.read(key: 'jwt_token');
|
|
return Options(headers: {'Authorization': 'Bearer $token'});
|
|
}
|
|
|
|
// ==========================================
|
|
// ACADEMIC YEARS
|
|
// ==========================================
|
|
Future<List<AcademicYearModel>> getAcademicYears() async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.get(
|
|
'/setup/academic-years',
|
|
options: options,
|
|
);
|
|
return (response.data as List)
|
|
.map(
|
|
(item) => AcademicYearModel.fromJson(item as Map<String, dynamic>),
|
|
)
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to fetch academic years.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> createAcademicYear({
|
|
required String yearRange,
|
|
required String status,
|
|
String? startDate,
|
|
String? endDate,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.post(
|
|
'/setup/academic-years',
|
|
options: options,
|
|
data: {
|
|
'yearRange': yearRange,
|
|
'status': status,
|
|
if (startDate != null) 'startDate': startDate,
|
|
if (endDate != null) 'endDate': endDate,
|
|
},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to create academic year.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateAcademicYear({
|
|
required int id,
|
|
required String yearRange,
|
|
required String status,
|
|
String? startDate,
|
|
String? endDate,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.put(
|
|
'/setup/academic-years/$id',
|
|
options: options,
|
|
data: {
|
|
'yearRange': yearRange,
|
|
'status': status,
|
|
if (startDate != null) 'startDate': startDate,
|
|
if (endDate != null) 'endDate': endDate,
|
|
},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to update academic year.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> checkAutoGraduation() async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final res = await _dio.post(
|
|
'/setup/academic-years/check-auto-graduation',
|
|
options: options,
|
|
);
|
|
return res.data as Map<String, dynamic>;
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to check auto-graduation.',
|
|
);
|
|
}
|
|
}
|
|
|
|
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();
|
|
await _dio.delete('/setup/academic-years/$id', options: options);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to delete academic year.',
|
|
);
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// SECTIONS
|
|
// ==========================================
|
|
Future<List<SectionModel>> getAllSections() async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.get('/setup/sections', options: options);
|
|
return (response.data as List)
|
|
.map((item) => SectionModel.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to fetch sections.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<List<SectionModel>> getSectionsByYear(int yearId) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.get(
|
|
'/setup/academic-years/$yearId/sections',
|
|
options: options,
|
|
);
|
|
return (response.data as List)
|
|
.map((item) => SectionModel.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ??
|
|
'Failed to fetch sections for academic year.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> createSection({
|
|
required String name,
|
|
required int gradeLevel,
|
|
required int academicYearId,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.post(
|
|
'/setup/sections',
|
|
options: options,
|
|
data: {
|
|
'name': name,
|
|
'gradeLevel': gradeLevel,
|
|
'academicYearId': academicYearId,
|
|
},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to create section.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> bulkCreateAcademicStructure(
|
|
List<Map<String, dynamic>> rows,
|
|
) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.post(
|
|
'/setup/bulk-academic-structure',
|
|
options: options,
|
|
data: {'rows': rows},
|
|
);
|
|
return Map<String, dynamic>.from(response.data as Map);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to import academic structure.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateSection({
|
|
required int id,
|
|
required String name,
|
|
required int gradeLevel,
|
|
required int academicYearId,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.put(
|
|
'/setup/sections/$id',
|
|
options: options,
|
|
data: {
|
|
'name': name,
|
|
'gradeLevel': gradeLevel,
|
|
'academicYearId': academicYearId,
|
|
},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to update section.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> deleteSection(int id) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.delete('/setup/sections/$id', options: options);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to delete section.',
|
|
);
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// GRADE LEVELS
|
|
// ==========================================
|
|
Future<List<GradeLevelModel>> getGradeLevels() async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.get('/setup/grade-levels', options: options);
|
|
return (response.data as List)
|
|
.map((item) => GradeLevelModel.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to fetch grade levels.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> createGradeLevel({
|
|
required int level,
|
|
required String name,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.post(
|
|
'/setup/grade-levels',
|
|
options: options,
|
|
data: {'level': level, 'name': name},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to create grade level.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateGradeLevel({
|
|
required int id,
|
|
required int level,
|
|
required String name,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.put(
|
|
'/setup/grade-levels/$id',
|
|
options: options,
|
|
data: {'level': level, 'name': name},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to update grade level.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> deleteGradeLevel(int id) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.delete('/setup/grade-levels/$id', options: options);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to delete grade level.',
|
|
);
|
|
}
|
|
}
|
|
|
|
// ==========================================
|
|
// TEACHER SECTIONS
|
|
// ==========================================
|
|
Future<List<SectionModel>> getTeacherSections(int teacherId) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
final response = await _dio.get(
|
|
'/users/$teacherId/sections',
|
|
options: options,
|
|
);
|
|
return (response.data as List)
|
|
.map((item) => SectionModel.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to fetch teacher sections.',
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateTeacherSections({
|
|
required int teacherId,
|
|
required List<int> sectionIds,
|
|
}) async {
|
|
try {
|
|
final options = await _getAuthOptions();
|
|
await _dio.post(
|
|
'/users/$teacherId/sections',
|
|
options: options,
|
|
data: {'sectionIds': sectionIds},
|
|
);
|
|
} on DioException catch (e) {
|
|
throw Exception(
|
|
e.response?.data?['message'] ?? 'Failed to update teacher sections.',
|
|
);
|
|
}
|
|
}
|
|
}
|