/// News Remote DataSource /// /// Handles fetching news/blog data from the Frappe API. library; import 'package:dio/dio.dart'; import 'package:worker/core/constants/api_constants.dart'; import 'package:worker/core/network/dio_client.dart'; import 'package:worker/core/services/frappe_auth_service.dart'; import 'package:worker/features/news/data/models/blog_category_model.dart'; /// News Remote Data Source /// /// Provides methods to fetch news and blog content from the Frappe API. /// Uses FrappeAuthService for session management. class NewsRemoteDataSource { NewsRemoteDataSource(this._dioClient, this._frappeAuthService); final DioClient _dioClient; final FrappeAuthService _frappeAuthService; /// Get blog categories /// /// Fetches all published blog categories from Frappe. /// Returns a list of [BlogCategoryModel]. /// /// API endpoint: POST https://land.dbiz.com/api/method/frappe.client.get_list /// Request body: /// ```json /// { /// "doctype": "Blog Category", /// "fields": ["title","name"], /// "filters": {"published":1}, /// "order_by": "creation desc", /// "limit_page_length": 0 /// } /// ``` /// /// Response format: /// ```json /// { /// "message": [ /// {"title": "Tin tức", "name": "tin-tức"}, /// {"title": "Chuyên môn", "name": "chuyên-môn"}, /// ... /// ] /// } /// ``` Future> getBlogCategories() async { try { // Get Frappe session headers final headers = await _frappeAuthService.getHeaders(); // Build full API URL final url = '${ApiConstants.baseUrl}${ApiConstants.frappeApiMethod}${ApiConstants.frappeGetList}'; final response = await _dioClient.post>( url, data: { 'doctype': 'Blog Category', 'fields': ['title', 'name'], 'filters': {'published': 1}, 'order_by': 'creation desc', 'limit_page_length': 0, }, options: Options(headers: headers), ); if (response.data == null) { throw Exception('Empty response from server'); } // Parse the response using the wrapper model final categoriesResponse = BlogCategoriesResponse.fromJson(response.data!); return categoriesResponse.message; } on DioException catch (e) { if (e.response?.statusCode == 404) { throw Exception('Blog categories endpoint not found'); } else if (e.response?.statusCode == 500) { throw Exception('Server error while fetching blog categories'); } else if (e.type == DioExceptionType.connectionTimeout) { throw Exception('Connection timeout while fetching blog categories'); } else if (e.type == DioExceptionType.receiveTimeout) { throw Exception('Response timeout while fetching blog categories'); } else { throw Exception('Failed to fetch blog categories: ${e.message}'); } } catch (e) { throw Exception('Unexpected error fetching blog categories: $e'); } } }