Files
worker/lib/features/news/data/datasources/news_remote_datasource.dart
Phuoc Nguyen 36bdf6613b add auth
2025-11-10 14:21:27 +07:00

94 lines
3.0 KiB
Dart

/// 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<List<BlogCategoryModel>> 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<Map<String, dynamic>>(
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');
}
}
}