Blog Application Service güncellemeleri

This commit is contained in:
Sedat ÖZTÜRK 2025-08-20 09:22:04 +03:00
parent 7386ff91fa
commit d891ae3f85
9 changed files with 426 additions and 340 deletions

View file

@ -0,0 +1,10 @@
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;
namespace Kurs.Platform.Blog;
public class BlogPostAndCategoriesDto
{
public PagedResultDto<BlogPostListDto> Posts { get; set; }
public List<BlogCategoryDto> Categories { get; set; }
}

View file

@ -9,7 +9,7 @@ namespace Kurs.Platform.Blog;
public interface IBlogAppService : IApplicationService
{
// Blog Post methods
Task<PagedResultDto<BlogPostListDto>> GetPostsAsync(GetBlogPostsInput input);
Task<BlogPostAndCategoriesDto> GetPostListAsync(GetBlogPostsInput input);
Task<BlogPostDto> GetPostAsync(Guid id);
Task<BlogPostDto> GetPostBySlugAsync(string slug);
Task<BlogPostDto> CreatePostAsync(CreateUpdateBlogPostDto input);
@ -19,7 +19,7 @@ public interface IBlogAppService : IApplicationService
Task<BlogPostDto> UnpublishPostAsync(Guid id);
// Blog Category methods
Task<List<BlogCategoryDto>> GetCategoriesAsync();
// Task<List<BlogCategoryDto>> GetCategoriesAsync();
Task<BlogCategoryDto> GetCategoryAsync(Guid id);
Task<BlogCategoryDto> CreateCategoryAsync(CreateUpdateBlogCategoryDto input);
Task<BlogCategoryDto> UpdateCategoryAsync(Guid id, CreateUpdateBlogCategoryDto input);

View file

@ -11,302 +11,370 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Users;
namespace Kurs.Platform.Blog
namespace Kurs.Platform.Blog;
[Authorize]
public class BlogAppService : PlatformAppService, IBlogAppService
{
[Authorize]
public class BlogAppService : PlatformAppService, IBlogAppService
private readonly IRepository<BlogPost, Guid> _postRepository;
private readonly IRepository<BlogCategory, Guid> _categoryRepository;
private readonly ICurrentUser _currentUser;
private readonly IStringLocalizer<PlatformResource> _localizer;
public BlogAppService(
IRepository<BlogPost, Guid> postRepository,
IRepository<BlogCategory, Guid> categoryRepository,
ICurrentUser currentUser,
IStringLocalizer<PlatformResource> localizer)
{
private readonly IRepository<BlogPost, Guid> _postRepository;
private readonly IRepository<BlogCategory, Guid> _categoryRepository;
private readonly ICurrentUser _currentUser;
private readonly IStringLocalizer<PlatformResource> _localizer;
public BlogAppService(
IRepository<BlogPost, Guid> postRepository,
IRepository<BlogCategory, Guid> categoryRepository,
ICurrentUser currentUser,
IStringLocalizer<PlatformResource> localizer)
{
_postRepository = postRepository;
_categoryRepository = categoryRepository;
_currentUser = currentUser;
_localizer = localizer;
}
// Blog Post methods
[AllowAnonymous]
public async Task<PagedResultDto<BlogPostListDto>> GetPostsAsync(GetBlogPostsInput input)
{
var allPosts = await _postRepository.GetListAsync(); // Tüm kayıtlar memory'ye alınır
var filtered = allPosts.Where(post =>
{
var searchMatch = string.IsNullOrWhiteSpace(input.Search) ||
post.ContentTr.Contains(input.Search, StringComparison.OrdinalIgnoreCase) ||
post.ContentEn.Contains(input.Search, StringComparison.OrdinalIgnoreCase);
var categoryMatch = !input.CategoryId.HasValue || post.CategoryId == input.CategoryId.Value;
return searchMatch && categoryMatch;
}).ToList();
var totalCount = filtered.Count;
var pagedPosts = filtered
.OrderByDescending(x => x.CreationTime)
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToList();
var categoryIds = pagedPosts.Select(x => x.CategoryId).Distinct().ToList();
var categories = await _categoryRepository.GetListAsync(x => categoryIds.Contains(x.Id));
var categoryDict = categories.ToDictionary(x => x.Id, x => x);
var postIds = pagedPosts.Select(x => x.Id).ToList();
var postDtos = pagedPosts.Select(post =>
{
var dto = ObjectMapper.Map<BlogPost, BlogPostListDto>(post);
if (categoryDict.TryGetValue(post.CategoryId, out var category))
{
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
dto.Author = new AuthorDto
{
Id = post.AuthorId,
Name = "User"
};
return dto;
}).ToList();
return new PagedResultDto<BlogPostListDto>(totalCount, postDtos);
}
[AllowAnonymous]
public async Task<BlogPostDto> GetPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
var dto = ObjectMapper.Map<BlogPost, BlogPostDto>(post);
// Get category
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(
await _categoryRepository.GetAsync(post.CategoryId)
);
// Get author info
dto.Author = new AuthorDto
{
Id = post.AuthorId,
Name = "User"
};
return dto;
}
[AllowAnonymous]
public async Task<BlogPostDto> GetPostBySlugAsync(string slug)
{
var post = await _postRepository.FirstOrDefaultAsync(x => x.Slug == slug);
if (post == null)
{
throw new EntityNotFoundException(typeof(BlogPost));
}
return await GetPostAsync(post.Id);
}
public async Task<BlogPostDto> CreatePostAsync(CreateUpdateBlogPostDto input)
{
var post = new BlogPost(
GuidGenerator.Create(),
input.Title,
input.Slug,
input.ContentTr,
input.ContentEn,
input.Summary,
input.ReadTime,
input.CoverImage,
input.CategoryId,
_currentUser.Id.Value,
true,
DateTime.UtcNow,
(Guid?)CurrentTenant.Id
);
await _postRepository.InsertAsync(post, autoSave: true);
return await GetPostAsync(post.Id);
}
public async Task<BlogPostDto> UpdatePostAsync(Guid id, CreateUpdateBlogPostDto input)
{
var post = await _postRepository.GetAsync(id);
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Update"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Title = input.Title;
post.Slug = input.Slug;
post.Summary = input.Summary;
post.CoverImage = input.CoverImage;
post.ContentTr = input.ContentTr;
post.ContentEn = input.ContentEn;
if (input.IsPublished) post.Publish(); else post.Unpublish();
if (post.CategoryId != input.CategoryId)
{
var oldCategory = await _categoryRepository.GetAsync(post.CategoryId);
oldCategory.DecrementPostCount();
await _categoryRepository.UpdateAsync(oldCategory);
var newCategory = await _categoryRepository.GetAsync(input.CategoryId);
newCategory.IncrementPostCount();
await _categoryRepository.UpdateAsync(newCategory);
post.CategoryId = input.CategoryId;
}
await _postRepository.UpdateAsync(post);
return await GetPostAsync(post.Id); // ✅ DTO dönülüyor
}
public async Task DeletePostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Delete"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
// Update category post count
var category = await _categoryRepository.GetAsync(post.CategoryId);
category.DecrementPostCount();
await _categoryRepository.UpdateAsync(category);
await _postRepository.DeleteAsync(id);
}
public async Task<BlogPostDto> PublishPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Publish"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Publish();
await _postRepository.UpdateAsync(post);
return await GetPostAsync(id);
}
public async Task<BlogPostDto> UnpublishPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Publish"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Unpublish();
await _postRepository.UpdateAsync(post);
return await GetPostAsync(id);
}
// Blog Category methods
[AllowAnonymous]
public async Task<List<BlogCategoryDto>> GetCategoriesAsync()
{
var categories = await _categoryRepository.GetListAsync();
var postQuery = await _postRepository.GetQueryableAsync();
var groupedCounts = postQuery
.Where(p => p.IsPublished) // sadece yayınlanmış yazılar
.GroupBy(p => p.CategoryId)
.Select(g => new { CategoryId = g.Key, Count = g.Count() })
.ToList();
var dtoList = ObjectMapper.Map<List<BlogCategory>, List<BlogCategoryDto>>(categories);
foreach (var dto in dtoList)
{
dto.PostCount = groupedCounts
.FirstOrDefault(x => x.CategoryId == dto.Id)?.Count ?? 0;
}
return dtoList;
}
public async Task<BlogCategoryDto> GetCategoryAsync(Guid id)
{
var category = await _categoryRepository.GetAsync(id);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Create")]
public async Task<BlogCategoryDto> CreateCategoryAsync(CreateUpdateBlogCategoryDto input)
{
var category = new BlogCategory(
GuidGenerator.Create(),
input.Name,
input.Slug,
input.Description,
CurrentTenant.Id
);
category.Icon = input.Icon;
category.DisplayOrder = input.DisplayOrder;
category.IsActive = input.IsActive;
await _categoryRepository.InsertAsync(category);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Update")]
public async Task<BlogCategoryDto> UpdateCategoryAsync(Guid id, CreateUpdateBlogCategoryDto input)
{
var category = await _categoryRepository.GetAsync(id);
category.Name = input.Name;
category.Slug = input.Slug;
category.Description = input.Description;
category.Icon = input.Icon;
category.DisplayOrder = input.DisplayOrder;
category.IsActive = input.IsActive;
await _categoryRepository.UpdateAsync(category);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Delete")]
public async Task DeleteCategoryAsync(Guid id)
{
// Check if category has posts
var hasPost = await _postRepository.AnyAsync(x => x.CategoryId == id);
if (hasPost)
{
throw new Volo.Abp.BusinessException("Cannot delete category with posts");
}
await _categoryRepository.DeleteAsync(id);
}
_postRepository = postRepository;
_categoryRepository = categoryRepository;
_currentUser = currentUser;
_localizer = localizer;
}
// Blog Post methods
[AllowAnonymous]
public async Task<BlogPostAndCategoriesDto> GetPostListAsync(GetBlogPostsInput input)
{
// IQueryable
var postQuery = await _postRepository.GetQueryableAsync();
// 🔎 Arama
if (!input.Search.IsNullOrWhiteSpace())
{
postQuery = postQuery.Where(p =>
p.ContentTr.Contains(input.Search) ||
p.ContentEn.Contains(input.Search));
}
// 📁 Kategori filtresi
if (input.CategoryId.HasValue)
{
postQuery = postQuery.Where(p => p.CategoryId == input.CategoryId.Value);
}
// Toplam adet (sayfalama öncesi)
var totalCount = await AsyncExecuter.CountAsync(postQuery);
// Sayfalama + sıralama
var pagedPosts = await AsyncExecuter.ToListAsync(
postQuery
.OrderByDescending(p => p.CreationTime)
.PageBy(input)
);
// Sayfadaki kategori kayıtları
var categoryIds = pagedPosts.Select(x => x.CategoryId).Distinct().ToList();
var pageCategories = await _categoryRepository.GetListAsync(x => categoryIds.Contains(x.Id));
var categoryDict = pageCategories.ToDictionary(x => x.Id, x => x);
// Post DTO mapping
var postDtos = pagedPosts.Select(post =>
{
var dto = ObjectMapper.Map<BlogPost, BlogPostListDto>(post);
if (categoryDict.TryGetValue(post.CategoryId, out var c))
{
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(c);
}
dto.Author = new AuthorDto { Id = post.AuthorId, Name = "User" };
return dto;
}).ToList();
// ----------- KATEGORİLER (PostCount ile) -----------
var allCategories = await _categoryRepository.GetListAsync();
var allPostQuery = await _postRepository.GetQueryableAsync();
var counts = await AsyncExecuter.ToListAsync(
allPostQuery
.Where(p => p.IsPublished)
.GroupBy(p => p.CategoryId)
.Select(g => new { g.Key, Count = g.Count() })
);
var countDict = counts.ToDictionary(x => x.Key, x => x.Count);
var categoryDtos = ObjectMapper.Map<List<BlogCategory>, List<BlogCategoryDto>>(allCategories);
foreach (var dto in categoryDtos)
{
dto.PostCount = countDict.GetOrDefault(dto.Id);
}
return new BlogPostAndCategoriesDto
{
Posts = new PagedResultDto<BlogPostListDto>(totalCount, postDtos),
Categories = categoryDtos
};
}
// public async Task<PagedResultDto<BlogPostListDto>> GetPostsAsync(GetBlogPostsInput input)
// {
// var allPosts = await _postRepository.GetListAsync(); // Tüm kayıtlar memory'ye alınır
// var filtered = allPosts.Where(post =>
// {
// var searchMatch = string.IsNullOrWhiteSpace(input.Search) ||
// post.ContentTr.Contains(input.Search, StringComparison.OrdinalIgnoreCase) ||
// post.ContentEn.Contains(input.Search, StringComparison.OrdinalIgnoreCase);
// var categoryMatch = !input.CategoryId.HasValue || post.CategoryId == input.CategoryId.Value;
// return searchMatch && categoryMatch;
// }).ToList();
// var totalCount = filtered.Count;
// var pagedPosts = filtered
// .OrderByDescending(x => x.CreationTime)
// .Skip(input.SkipCount)
// .Take(input.MaxResultCount)
// .ToList();
// var categoryIds = pagedPosts.Select(x => x.CategoryId).Distinct().ToList();
// var categories = await _categoryRepository.GetListAsync(x => categoryIds.Contains(x.Id));
// var categoryDict = categories.ToDictionary(x => x.Id, x => x);
// var postIds = pagedPosts.Select(x => x.Id).ToList();
// var postDtos = pagedPosts.Select(post =>
// {
// var dto = ObjectMapper.Map<BlogPost, BlogPostListDto>(post);
// if (categoryDict.TryGetValue(post.CategoryId, out var category))
// {
// dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
// }
// dto.Author = new AuthorDto
// {
// Id = post.AuthorId,
// Name = "User"
// };
// return dto;
// }).ToList();
// return new PagedResultDto<BlogPostListDto>(totalCount, postDtos);
// }
[AllowAnonymous]
public async Task<BlogPostDto> GetPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
var dto = ObjectMapper.Map<BlogPost, BlogPostDto>(post);
// Get category
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(
await _categoryRepository.GetAsync(post.CategoryId)
);
// Get author info
dto.Author = new AuthorDto
{
Id = post.AuthorId,
Name = "User"
};
return dto;
}
[AllowAnonymous]
public async Task<BlogPostDto> GetPostBySlugAsync(string slug)
{
var post = await _postRepository.FirstOrDefaultAsync(x => x.Slug == slug);
if (post == null)
{
throw new EntityNotFoundException(typeof(BlogPost));
}
return await GetPostAsync(post.Id);
}
public async Task<BlogPostDto> CreatePostAsync(CreateUpdateBlogPostDto input)
{
var post = new BlogPost(
GuidGenerator.Create(),
input.Title,
input.Slug,
input.ContentTr,
input.ContentEn,
input.Summary,
input.ReadTime,
input.CoverImage,
input.CategoryId,
_currentUser.Id.Value,
true,
DateTime.UtcNow,
(Guid?)CurrentTenant.Id
);
await _postRepository.InsertAsync(post, autoSave: true);
return await GetPostAsync(post.Id);
}
public async Task<BlogPostDto> UpdatePostAsync(Guid id, CreateUpdateBlogPostDto input)
{
var post = await _postRepository.GetAsync(id);
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Update"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Title = input.Title;
post.Slug = input.Slug;
post.Summary = input.Summary;
post.CoverImage = input.CoverImage;
post.ContentTr = input.ContentTr;
post.ContentEn = input.ContentEn;
if (input.IsPublished) post.Publish(); else post.Unpublish();
if (post.CategoryId != input.CategoryId)
{
var oldCategory = await _categoryRepository.GetAsync(post.CategoryId);
oldCategory.DecrementPostCount();
await _categoryRepository.UpdateAsync(oldCategory);
var newCategory = await _categoryRepository.GetAsync(input.CategoryId);
newCategory.IncrementPostCount();
await _categoryRepository.UpdateAsync(newCategory);
post.CategoryId = input.CategoryId;
}
await _postRepository.UpdateAsync(post);
return await GetPostAsync(post.Id); // ✅ DTO dönülüyor
}
public async Task DeletePostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Delete"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
// Update category post count
var category = await _categoryRepository.GetAsync(post.CategoryId);
category.DecrementPostCount();
await _categoryRepository.UpdateAsync(category);
await _postRepository.DeleteAsync(id);
}
public async Task<BlogPostDto> PublishPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Publish"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Publish();
await _postRepository.UpdateAsync(post);
return await GetPostAsync(id);
}
public async Task<BlogPostDto> UnpublishPostAsync(Guid id)
{
var post = await _postRepository.GetAsync(id);
// Check if user is author or has permission
if (post.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("App.BlogManagement.Publish"))
{
throw new Volo.Abp.Authorization.AbpAuthorizationException();
}
post.Unpublish();
await _postRepository.UpdateAsync(post);
return await GetPostAsync(id);
}
// // Blog Category methods
// [AllowAnonymous]
// public async Task<List<BlogCategoryDto>> GetCategoriesAsync()
// {
// var categories = await _categoryRepository.GetListAsync();
// var postQuery = await _postRepository.GetQueryableAsync();
// var groupedCounts = postQuery
// .Where(p => p.IsPublished) // sadece yayınlanmış yazılar
// .GroupBy(p => p.CategoryId)
// .Select(g => new { CategoryId = g.Key, Count = g.Count() })
// .ToList();
// var dtoList = ObjectMapper.Map<List<BlogCategory>, List<BlogCategoryDto>>(categories);
// foreach (var dto in dtoList)
// {
// dto.PostCount = groupedCounts
// .FirstOrDefault(x => x.CategoryId == dto.Id)?.Count ?? 0;
// }
// return dtoList;
// }
public async Task<BlogCategoryDto> GetCategoryAsync(Guid id)
{
var category = await _categoryRepository.GetAsync(id);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Create")]
public async Task<BlogCategoryDto> CreateCategoryAsync(CreateUpdateBlogCategoryDto input)
{
var category = new BlogCategory(
GuidGenerator.Create(),
input.Name,
input.Slug,
input.Description,
CurrentTenant.Id
);
category.Icon = input.Icon;
category.DisplayOrder = input.DisplayOrder;
category.IsActive = input.IsActive;
await _categoryRepository.InsertAsync(category);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Update")]
public async Task<BlogCategoryDto> UpdateCategoryAsync(Guid id, CreateUpdateBlogCategoryDto input)
{
var category = await _categoryRepository.GetAsync(id);
category.Name = input.Name;
category.Slug = input.Slug;
category.Description = input.Description;
category.Icon = input.Icon;
category.DisplayOrder = input.DisplayOrder;
category.IsActive = input.IsActive;
await _categoryRepository.UpdateAsync(category);
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
}
[Authorize("App.BlogManagement.Delete")]
public async Task DeleteCategoryAsync(Guid id)
{
// Check if category has posts
var hasPost = await _postRepository.AnyAsync(x => x.CategoryId == id);
if (hasPost)
{
throw new Volo.Abp.BusinessException("Cannot delete category with posts");
}
await _categoryRepository.DeleteAsync(id);
}
}

View file

@ -42,7 +42,7 @@ public class Program
case DatabaseProvider.PostgreSql:
loggerConfig = loggerConfig.WriteTo.PostgreSQL(
connectionString: configuration.GetConnectionString(DefaultDatabaseProvider),
tableName: PlatformConsts.DbTablePrefix + "LogEntry",
tableName: PlatformConsts.SelectCommandByTableName("LogEntry"),
columnOptions: columnWriters,
needAutoCreateTable: true,
respectCase: true
@ -52,7 +52,7 @@ public class Program
case DatabaseProvider.SqlServer:
loggerConfig = loggerConfig.WriteTo.MSSqlServer(
connectionString: configuration.GetConnectionString(DefaultDatabaseProvider),
tableName: PlatformConsts.DbTablePrefix + "LogEntry",
tableName: PlatformConsts.SelectCommandByTableName("LogEntry"),
autoCreateSqlTable: true,
columnOptions: new Serilog.Sinks.MSSqlServer.ColumnOptions()
);

View file

@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.vah6gtb83uo"
"revision": "0.3u9qv452np"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

View file

@ -1,3 +1,5 @@
import { PagedResultDto } from '../abp'
export interface BlogPost {
id: string
title: string
@ -39,6 +41,11 @@ export interface BlogCategory {
tenantId?: string
}
export interface BlogPostAndCategoriesDto {
posts: PagedResultDto<BlogPost>
categories: BlogCategory[]
}
export interface CreateUpdateBlogPostDto {
title: string
slug: string
@ -71,11 +78,3 @@ export interface BlogListParams {
authorId?: string
sortBy?: 'latest' | 'popular' | 'trending'
}
export interface PaginatedResponse<T> {
items: T[]
totalCount: number
pageNumber: number
pageSize: number
totalPages: number
}

View file

@ -1,10 +1,17 @@
import { BlogCategory, BlogListParams, BlogPost, CreateUpdateBlogCategoryDto, CreateUpdateBlogPostDto, PaginatedResponse } from '@/proxy/blog/blog';
import {
BlogCategory,
BlogListParams,
BlogPost,
BlogPostAndCategoriesDto,
CreateUpdateBlogCategoryDto,
CreateUpdateBlogPostDto,
} from '@/proxy/blog/blog'
import apiService from '@/services/api.service'
class BlogService {
async getPosts(params: BlogListParams = {}): Promise<PaginatedResponse<BlogPost>> {
const response = await apiService.fetchData<PaginatedResponse<BlogPost>>({
url: '/api/app/blog/posts',
async getPosts(params: BlogListParams = {}): Promise<BlogPostAndCategoriesDto> {
const response = await apiService.fetchData<BlogPostAndCategoriesDto>({
url: '/api/app/blog/post-list',
method: 'GET',
params,
})
@ -13,10 +20,10 @@ class BlogService {
async getPostBySlug(slug: string): Promise<BlogPost> {
const response = await apiService.fetchData<BlogPost>({
url : `/api/app/blog/post-by-slug?slug=${slug}`,
url: `/api/app/blog/post-by-slug?slug=${slug}`,
method: 'GET',
})
return response.data;
return response.data
}
async getPost(idOrSlug: string): Promise<BlogPost> {
@ -68,13 +75,13 @@ class BlogService {
return response.data
}
async getCategories(): Promise<BlogCategory[]> {
const response = await apiService.fetchData<BlogCategory[]>({
url: '/api/app/blog/categories',
method: 'GET',
})
return response.data
}
// async getCategories(): Promise<BlogCategory[]> {
// const response = await apiService.fetchData<BlogCategory[]>({
// url: '/api/app/blog/categories',
// method: 'GET',
// })
// return response.data
// }
async deleteComment(id: string): Promise<void> {
await apiService.fetchData({

View file

@ -1,11 +1,6 @@
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import {
FaCalendarAlt,
FaUser,
FaTag,
FaSearch
} from 'react-icons/fa';
import { FaCalendarAlt, FaUser, FaTag, FaSearch } from 'react-icons/fa'
import dayjs from 'dayjs'
import 'dayjs/locale/tr'
import { BlogCategory, BlogPost } from '@/proxy/blog/blog'
@ -33,19 +28,24 @@ const Blog = () => {
const loadBlogData = async () => {
try {
setLoading(true)
const [postsData, categoriesData] = await Promise.all([
blogService.getPosts({
page: currentPage,
pageSize: 10,
categoryId: selectedCategory,
search: searchQuery,
}),
blogService.getCategories(),
])
setPosts(postsData.items.filter((a) => a.isPublished))
setTotalPages(postsData.totalPages)
setCategories(categoriesData.filter((a) => a.isActive))
const postsData = await blogService.getPosts({
page: currentPage,
pageSize: 10,
categoryId: selectedCategory,
search: searchQuery,
})
if (
postsData.posts &&
postsData.posts.items &&
postsData.posts.totalCount &&
postsData.categories
) {
setPosts(postsData.posts.items.filter((a) => a.isPublished))
setTotalPages(postsData.posts.totalCount / 10)
setCategories(postsData.categories.filter((a) => a.isActive))
}
} catch (error) {
console.error('Blog verileri yüklenemedi:', error)
setPosts([])

View file

@ -116,7 +116,9 @@ const BlogDetail: React.FC = () => {
className="prose max-w-none text-gray-800"
dangerouslySetInnerHTML={{
__html:
currentLang == 'tr' ? translate(blogPost.contentTr!) : translate(blogPost.contentEn!),
currentLang == 'tr'
? translate('::' + blogPost.contentTr!)
: translate('::' + blogPost.contentEn!),
}}
/>
</div>