update news
This commit is contained in:
@@ -8,6 +8,7 @@ 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';
|
||||
import 'package:worker/features/news/data/models/blog_post_model.dart';
|
||||
|
||||
/// News Remote Data Source
|
||||
///
|
||||
@@ -90,4 +91,173 @@ class NewsRemoteDataSource {
|
||||
throw Exception('Unexpected error fetching blog categories: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get blog posts
|
||||
///
|
||||
/// Fetches all published blog posts from Frappe.
|
||||
/// Returns a list of [BlogPostModel].
|
||||
///
|
||||
/// API endpoint: POST https://land.dbiz.com/api/method/frappe.client.get_list
|
||||
/// Request body:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "doctype": "Blog Post",
|
||||
/// "fields": ["name","title","published_on","blogger","blog_intro","content","meta_image","meta_description","blog_category"],
|
||||
/// "filters": {"published":1},
|
||||
/// "order_by": "published_on desc",
|
||||
/// "limit_page_length": 0
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Response format:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "message": [
|
||||
/// {
|
||||
/// "name": "post-slug",
|
||||
/// "title": "Post Title",
|
||||
/// "published_on": "2024-01-01 10:00:00",
|
||||
/// "blogger": "Author Name",
|
||||
/// "blog_intro": "Short introduction...",
|
||||
/// "content": "<p>Full HTML content...</p>",
|
||||
/// "meta_image": "https://...",
|
||||
/// "meta_description": "SEO description",
|
||||
/// "blog_category": "tin-tức"
|
||||
/// },
|
||||
/// ...
|
||||
/// ]
|
||||
/// }
|
||||
/// ```
|
||||
Future<List<BlogPostModel>> getBlogPosts() async {
|
||||
try {
|
||||
// Get Frappe session headers
|
||||
final headers = await _frappeAuthService.getHeaders();
|
||||
|
||||
// Build full API URL
|
||||
const url =
|
||||
'${ApiConstants.baseUrl}${ApiConstants.frappeApiMethod}${ApiConstants.frappeGetList}';
|
||||
|
||||
final response = await _dioClient.post<Map<String, dynamic>>(
|
||||
url,
|
||||
data: {
|
||||
'doctype': 'Blog Post',
|
||||
'fields': [
|
||||
'name',
|
||||
'title',
|
||||
'published_on',
|
||||
'blogger',
|
||||
'blog_intro',
|
||||
'content',
|
||||
'meta_image',
|
||||
'meta_description',
|
||||
'blog_category',
|
||||
],
|
||||
'filters': {'published': 1},
|
||||
'order_by': 'published_on 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 postsResponse = BlogPostsResponse.fromJson(response.data!);
|
||||
|
||||
return postsResponse.message;
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 404) {
|
||||
throw Exception('Blog posts endpoint not found');
|
||||
} else if (e.response?.statusCode == 500) {
|
||||
throw Exception('Server error while fetching blog posts');
|
||||
} else if (e.type == DioExceptionType.connectionTimeout) {
|
||||
throw Exception('Connection timeout while fetching blog posts');
|
||||
} else if (e.type == DioExceptionType.receiveTimeout) {
|
||||
throw Exception('Response timeout while fetching blog posts');
|
||||
} else {
|
||||
throw Exception('Failed to fetch blog posts: ${e.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Unexpected error fetching blog posts: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get blog post detail by name
|
||||
///
|
||||
/// Fetches a single blog post by its unique name (slug) from Frappe.
|
||||
/// Returns a [BlogPostModel].
|
||||
///
|
||||
/// API endpoint: POST https://land.dbiz.com/api/method/frappe.client.get
|
||||
/// Request body:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "doctype": "Blog Post",
|
||||
/// "name": "post-slug"
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Response format:
|
||||
/// ```json
|
||||
/// {
|
||||
/// "message": {
|
||||
/// "name": "post-slug",
|
||||
/// "title": "Post Title",
|
||||
/// "published_on": "2024-01-01 10:00:00",
|
||||
/// "blogger": "Author Name",
|
||||
/// "blog_intro": "Short introduction...",
|
||||
/// "content": "<p>Full HTML content...</p>",
|
||||
/// "meta_image": "https://...",
|
||||
/// "meta_description": "SEO description",
|
||||
/// "blog_category": "tin-tức"
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
Future<BlogPostModel> getBlogPostDetail(String postName) async {
|
||||
try {
|
||||
// Get Frappe session headers
|
||||
final headers = await _frappeAuthService.getHeaders();
|
||||
|
||||
// Build full API URL for frappe.client.get
|
||||
const url =
|
||||
'${ApiConstants.baseUrl}${ApiConstants.frappeApiMethod}${ApiConstants.frappeGet}';
|
||||
|
||||
final response = await _dioClient.post<Map<String, dynamic>>(
|
||||
url,
|
||||
data: {
|
||||
'doctype': 'Blog Post',
|
||||
'name': postName,
|
||||
},
|
||||
options: Options(headers: headers),
|
||||
);
|
||||
|
||||
if (response.data == null) {
|
||||
throw Exception('Empty response from server');
|
||||
}
|
||||
|
||||
// The response has the blog post data directly in "message" field
|
||||
final messageData = response.data!['message'];
|
||||
if (messageData == null) {
|
||||
throw Exception('Blog post not found: $postName');
|
||||
}
|
||||
|
||||
// Parse the blog post from the message field
|
||||
return BlogPostModel.fromJson(messageData as Map<String, dynamic>);
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 404) {
|
||||
throw Exception('Blog post not found: $postName');
|
||||
} else if (e.response?.statusCode == 500) {
|
||||
throw Exception('Server error while fetching blog post detail');
|
||||
} else if (e.type == DioExceptionType.connectionTimeout) {
|
||||
throw Exception('Connection timeout while fetching blog post detail');
|
||||
} else if (e.type == DioExceptionType.receiveTimeout) {
|
||||
throw Exception('Response timeout while fetching blog post detail');
|
||||
} else {
|
||||
throw Exception('Failed to fetch blog post detail: ${e.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Unexpected error fetching blog post detail: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user