129 lines
4.9 KiB
Plaintext
129 lines
4.9 KiB
Plaintext
@page "/admin/blog/create"
|
|
@attribute [Authorize]
|
|
@using TaxBaik.Application.DTOs
|
|
@using TaxBaik.Application.Services
|
|
@using TaxBaik.Domain.Interfaces
|
|
@inject BlogService BlogService
|
|
@inject ICategoryRepository CategoryRepository
|
|
@inject NavigationManager Navigation
|
|
@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.Outlined" StartIcon="@Icons.Material.Filled.Close" @onclick="GoBack">취소</MudButton>
|
|
</section>
|
|
|
|
<MudPaper Class="pa-4 mt-4" Elevation="1">
|
|
<MudForm @ref="form">
|
|
<MudTextField @bind-Value="model.Title" Label="제목 *"
|
|
Variant="Variant.Outlined" Class="mb-4" Required="true" RequiredError="제목을 입력하세요." Counter="100" MaxLength="100" />
|
|
|
|
<MudSelect T="int?" @bind-Value="model.CategoryId" Label="카테고리"
|
|
Variant="Variant.Outlined" Class="mb-4">
|
|
@foreach (var category in categories)
|
|
{
|
|
<MudSelectItem T="int?" Value="@((int?)category.Id)">@category.Name</MudSelectItem>
|
|
}
|
|
</MudSelect>
|
|
|
|
<MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-4" Class="mb-4">
|
|
<MudTabPanel Text="에디터" Icon="@Icons.Material.Filled.Edit">
|
|
<MudTextField @bind-Value="model.Content" Label="본문 내용 *"
|
|
Variant="Variant.Outlined" Lines="15" Required="true" RequiredError="본문 내용을 입력하세요." Counter="10000" MaxLength="10000" HelperText="HTML 태그를 사용해 꾸밀 수 있습니다." />
|
|
</MudTabPanel>
|
|
<MudTabPanel Text="실시간 미리보기" Icon="@Icons.Material.Filled.Visibility">
|
|
<div class="border rounded pa-4 article-body lh-lg" style="min-height: 330px; max-height: 500px; overflow-y: auto; background-color: #fafafa;">
|
|
@if (string.IsNullOrWhiteSpace(model.Content))
|
|
{
|
|
<p class="text-muted small text-center my-8">작성 중인 본문 내용이 이곳에 실시간으로 표시됩니다.</p>
|
|
}
|
|
else
|
|
{
|
|
@((MarkupString)model.Content)
|
|
}
|
|
</div>
|
|
</MudTabPanel>
|
|
</MudTabs>
|
|
|
|
<MudTextField @bind-Value="model.Tags" Label="태그 (쉼표로 구분)"
|
|
Variant="Variant.Outlined" Class="mb-4" />
|
|
|
|
<MudTextField @bind-Value="model.SeoTitle" Label="SEO 제목"
|
|
Variant="Variant.Outlined" Class="mb-4" />
|
|
|
|
<MudTextField @bind-Value="model.SeoDescription" Label="SEO 설명"
|
|
Variant="Variant.Outlined" Lines="3" Class="mb-4" />
|
|
|
|
<MudCheckBox @bind-Checked="model.IsPublished" Label="즉시 발행" Class="mb-4" />
|
|
|
|
<div class="d-flex gap-2">
|
|
<MudButton Variant="Variant.Filled" Color="Color.Primary"
|
|
@onclick="SavePost">저장</MudButton>
|
|
</div>
|
|
</MudForm>
|
|
</MudPaper>
|
|
|
|
@code {
|
|
private MudForm? form;
|
|
private List<Domain.Entities.Category> categories = [];
|
|
private CreatePostModel model = new();
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
categories = (await CategoryRepository.GetAllAsync()).ToList();
|
|
}
|
|
|
|
private void GoBack()
|
|
{
|
|
Navigation.NavigateTo("/taxbaik/admin/blog");
|
|
}
|
|
|
|
private async Task SavePost()
|
|
{
|
|
if (form == null)
|
|
return;
|
|
|
|
await form.Validate();
|
|
if (!form.IsValid)
|
|
return;
|
|
|
|
try
|
|
{
|
|
await BlogService.CreateAsync(new CreateBlogPostDto
|
|
{
|
|
Title = model.Title,
|
|
Content = model.Content,
|
|
CategoryId = model.CategoryId,
|
|
Tags = model.Tags,
|
|
SeoTitle = model.SeoTitle,
|
|
SeoDescription = model.SeoDescription,
|
|
IsPublished = model.IsPublished
|
|
});
|
|
|
|
Snackbar.Add("포스트가 저장되었습니다.", Severity.Success);
|
|
Navigation.NavigateTo("/taxbaik/admin/blog");
|
|
}
|
|
catch (ValidationException ex)
|
|
{
|
|
Snackbar.Add(ex.Message, Severity.Error);
|
|
}
|
|
}
|
|
|
|
private class CreatePostModel
|
|
{
|
|
public string Title { get; set; } = "";
|
|
public string Content { get; set; } = "";
|
|
public int? CategoryId { get; set; }
|
|
public string? Tags { get; set; }
|
|
public string? SeoTitle { get; set; }
|
|
public string? SeoDescription { get; set; }
|
|
public bool IsPublished { get; set; }
|
|
}
|
|
}
|