admin: add common-code crud and business-day rules
This commit is contained in:
@@ -1,19 +1,16 @@
|
||||
@page "/admin/blog"
|
||||
@attribute [Authorize]
|
||||
@inject IApiClient ApiClient
|
||||
@inject IBlogBrowserClient BlogClient
|
||||
@inject ISnackbar Snackbar
|
||||
|
||||
<PageTitle>블로그 관리</PageTitle>
|
||||
|
||||
<section class="admin-page-hero">
|
||||
<div>
|
||||
<MudText Typo="Typo.caption" Class="admin-eyebrow">Content</MudText>
|
||||
<MudText Typo="Typo.h4" Class="admin-page-title">블로그 관리</MudText>
|
||||
<MudText Typo="Typo.body2" Class="admin-page-subtitle">검색 유입 콘텐츠의 발행 상태와 성과를 관리합니다.</MudText>
|
||||
</div>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.EditNote"
|
||||
Href="/taxbaik/admin/blog/create">새 포스트 작성</MudButton>
|
||||
</section>
|
||||
<AdminPageHeader Title="블로그 관리" Eyebrow="Content" Subtitle="검색 유입 콘텐츠의 발행 상태와 성과를 관리합니다.">
|
||||
<ChildContent>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.EditNote"
|
||||
Href="/taxbaik/admin/blog/create">새 포스트 작성</MudButton>
|
||||
</ChildContent>
|
||||
</AdminPageHeader>
|
||||
|
||||
<div class="d-flex pa-4 gap-4 align-center">
|
||||
<MudTextField @bind-Value="searchQuery" Placeholder="블로그 제목 또는 본문 검색..." Adornment="Adornment.Start"
|
||||
@@ -58,7 +55,7 @@
|
||||
[CascadingParameter]
|
||||
private Task<AuthenticationState>? AuthStateTask { get; set; }
|
||||
|
||||
private List<TaxBaik.Domain.Entities.BlogPost> posts = [];
|
||||
private List<TaxBaik.Application.DTOs.BlogPostResponseDto> posts = [];
|
||||
private string searchQuery = "";
|
||||
private bool isLoading = true;
|
||||
private int currentPage = 1;
|
||||
@@ -66,23 +63,19 @@
|
||||
private int totalPosts = 0;
|
||||
private const int PageSize = 20;
|
||||
|
||||
private IEnumerable<TaxBaik.Domain.Entities.BlogPost> FilteredPosts => posts?
|
||||
.Where(p => string.IsNullOrEmpty(searchQuery) ||
|
||||
p.Title.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
(p.Content != null && p.Content.Contains(searchQuery, StringComparison.OrdinalIgnoreCase))) ?? Enumerable.Empty<TaxBaik.Domain.Entities.BlogPost>();
|
||||
private IEnumerable<TaxBaik.Application.DTOs.BlogPostResponseDto> FilteredPosts => posts
|
||||
.Where(p => string.IsNullOrEmpty(searchQuery) ||
|
||||
p.Title.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
(p.Content != null && p.Content.Contains(searchQuery, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (firstRender)
|
||||
if (AuthStateTask != null)
|
||||
{
|
||||
if (AuthStateTask != null)
|
||||
var authState = await AuthStateTask;
|
||||
if (authState.User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
var authState = await AuthStateTask;
|
||||
if (authState.User.Identity?.IsAuthenticated == true)
|
||||
{
|
||||
await LoadPosts();
|
||||
StateHasChanged();
|
||||
}
|
||||
await LoadPosts();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,9 +85,9 @@
|
||||
isLoading = true;
|
||||
try
|
||||
{
|
||||
var result = await ApiClient.GetAsync<PagedBlogResponse>($"blog/admin?page={currentPage}&pageSize={PageSize}");
|
||||
posts = result?.Data ?? [];
|
||||
totalPosts = result?.Total ?? 0;
|
||||
var result = await BlogClient.GetAdminPagedAsync(currentPage, PageSize);
|
||||
posts = result.Items.ToList();
|
||||
totalPosts = result.Total;
|
||||
totalPages = Math.Max(1, (int)Math.Ceiling(totalPosts / (double)PageSize));
|
||||
}
|
||||
catch
|
||||
@@ -124,21 +117,21 @@
|
||||
await LoadPosts();
|
||||
}
|
||||
|
||||
private async Task TogglePublish(TaxBaik.Domain.Entities.BlogPost post, bool isPublished)
|
||||
private async Task TogglePublish(TaxBaik.Application.DTOs.BlogPostResponseDto post, bool isPublished)
|
||||
{
|
||||
var previous = post.IsPublished;
|
||||
post.IsPublished = isPublished;
|
||||
var result = await ApiClient.PutAsync<TaxBaik.Domain.Entities.BlogPost>($"blog/{post.Id}", new
|
||||
var result = await BlogClient.UpdateAsync(post.Id, new TaxBaik.Application.DTOs.CreateBlogPostDto
|
||||
{
|
||||
post.Title,
|
||||
post.Content,
|
||||
post.CategoryId,
|
||||
post.Tags,
|
||||
post.SeoTitle,
|
||||
post.SeoDescription,
|
||||
post.ThumbnailUrl,
|
||||
Title = post.Title,
|
||||
Content = post.Content,
|
||||
CategoryId = post.CategoryId,
|
||||
Tags = post.Tags,
|
||||
SeoTitle = post.SeoTitle,
|
||||
SeoDescription = post.SeoDescription,
|
||||
ThumbnailUrl = post.ThumbnailUrl,
|
||||
IsPublished = isPublished,
|
||||
post.AuthorId
|
||||
AuthorId = post.AuthorId
|
||||
});
|
||||
|
||||
if (result == null)
|
||||
@@ -153,14 +146,13 @@
|
||||
|
||||
private async Task DeletePost(int postId)
|
||||
{
|
||||
await ApiClient.DeleteAsync($"blog/{postId}");
|
||||
var deleted = await BlogClient.DeleteAsync(postId);
|
||||
if (!deleted)
|
||||
{
|
||||
Snackbar.Add("포스트 삭제에 실패했습니다.", Severity.Error);
|
||||
return;
|
||||
}
|
||||
Snackbar.Add("포스트가 삭제되었습니다.", Severity.Success);
|
||||
await LoadPosts();
|
||||
}
|
||||
|
||||
private class PagedBlogResponse
|
||||
{
|
||||
public List<TaxBaik.Domain.Entities.BlogPost> Data { get; set; } = [];
|
||||
public int Total { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user