Files
GNX-WEB/gnx-react/lib/api/blogService.ts
Iliyan Angelov 5ad9cbe3a6 update
2025-10-13 01:49:06 +03:00

423 lines
10 KiB
TypeScript

import { API_CONFIG } from '../config/api';
// Types for Blog API
export interface BlogAuthor {
id: number;
name: string;
email?: string;
bio?: string;
avatar?: string;
}
export interface BlogCategory {
id: number;
title: string;
slug: string;
description?: string;
display_order: number;
posts_count?: number;
}
export interface BlogTag {
id: number;
name: string;
slug: string;
}
export interface BlogPost {
id: number;
title: string;
slug: string;
content?: string;
excerpt: string;
thumbnail?: string;
featured_image?: string;
author?: BlogAuthor;
author_name?: string;
category?: BlogCategory;
category_title?: string;
category_slug?: string;
tags?: BlogTag[];
meta_description?: string;
meta_keywords?: string;
published: boolean;
featured: boolean;
views_count: number;
reading_time: number;
published_at: string;
created_at: string;
updated_at: string;
related_posts?: BlogPost[];
}
export interface BlogPostListResponse {
count: number;
next: string | null;
previous: string | null;
results: BlogPost[];
}
export interface BlogComment {
id: number;
post: number;
name: string;
email: string;
content: string;
parent?: number;
is_approved: boolean;
created_at: string;
updated_at: string;
replies?: BlogComment[];
}
export interface BlogCommentCreateData {
post: number;
name: string;
email: string;
content: string;
parent?: number;
}
// Helper function to build query string
const buildQueryString = (params: Record<string, any>): string => {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
searchParams.append(key, value.toString());
}
});
return searchParams.toString();
};
// Blog API functions
export const blogService = {
// Get all blog posts with optional filtering
getPosts: async (params?: {
category?: string;
tag?: string;
author?: number;
search?: string;
featured?: boolean;
ordering?: string;
page?: number;
page_size?: number;
}): Promise<BlogPostListResponse> => {
try {
const queryString = params ? buildQueryString(params) : '';
const url = `${API_CONFIG.BASE_URL}/api/blog/posts/${queryString ? `?${queryString}` : ''}`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get a single blog post by slug
getPostBySlug: async (slug: string): Promise<BlogPost> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/posts/${slug}/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get featured blog posts
getFeaturedPosts: async (): Promise<BlogPost[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/posts/featured/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get latest blog posts
getLatestPosts: async (limit: number = 5): Promise<BlogPost[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/posts/latest/?limit=${limit}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get popular blog posts
getPopularPosts: async (limit: number = 5): Promise<BlogPost[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/posts/popular/?limit=${limit}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get related posts for a specific post
getRelatedPosts: async (postSlug: string): Promise<BlogPost[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/posts/${postSlug}/related/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get all blog categories
getCategories: async (): Promise<BlogCategory[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/categories/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return Array.isArray(data) ? data : data.results || [];
} catch (error) {
throw error;
}
},
// Get categories with posts
getCategoriesWithPosts: async (): Promise<BlogCategory[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/categories/with_posts/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get a single category by slug
getCategoryBySlug: async (slug: string): Promise<BlogCategory> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/categories/${slug}/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get all blog tags
getTags: async (): Promise<BlogTag[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/tags/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return Array.isArray(data) ? data : data.results || [];
} catch (error) {
throw error;
}
},
// Get posts by tag
getPostsByTag: async (tagSlug: string): Promise<BlogPostListResponse> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/tags/${tagSlug}/posts/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get all blog authors
getAuthors: async (): Promise<BlogAuthor[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/authors/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return Array.isArray(data) ? data : data.results || [];
} catch (error) {
throw error;
}
},
// Get posts by author
getPostsByAuthor: async (authorId: number): Promise<BlogPostListResponse> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/authors/${authorId}/posts/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
// Get comments for a post
getComments: async (postId: number): Promise<BlogComment[]> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/comments/?post=${postId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return Array.isArray(data) ? data : data.results || [];
} catch (error) {
throw error;
}
},
// Create a new comment
createComment: async (commentData: BlogCommentCreateData): Promise<{ message: string; data: BlogComment }> => {
try {
const response = await fetch(`${API_CONFIG.BASE_URL}/api/blog/comments/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(commentData),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
throw error;
}
},
};