@page "/admin/clients" @attribute [Authorize] @using TaxBaik.Web.Services @using TaxBaik.Domain.Entities @inject IClientBrowserClient ClientClient @inject NavigationManager Navigation @inject IDialogService DialogService @inject ISnackbar Snackbar 고객 관리
CRM 고객 관리 고객 카드를 등록하고 상담 이력을 관리합니다.
고객 등록
@* 검색/필터 바 *@ 전체 활성 비활성 검색 초기화 @if (clients is null) { } else if (!clients.Any()) {
등록된 고객이 없습니다.
} else { 이름 회사명 연락처 서비스 세금 유형 상태 유입 경로 등록일 @foreach (var c in clients) { @c.Name @(c.CompanyName ?? "—") @(c.Phone ?? "—") @if (!string.IsNullOrEmpty(c.ServiceType)) { @c.ServiceType } @(c.TaxType ?? "—") @if (c.Status == "active") { 활성 } else { 비활성 } @(c.Source ?? "—") @c.CreatedAt.ToLocalTime().ToString("yy.MM.dd") 수정 삭제 } @* 페이징 *@ @if (totalPages > 1) {
} 총 @(totalCount)명 }
@code { [CascadingParameter] private Task? AuthStateTask { get; set; } private List? clients; private string searchText = ""; private string statusFilter = ""; private int currentPage = 1; private int totalCount; private int totalPages; private const int PageSize = 20; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { if (AuthStateTask != null) { var authState = await AuthStateTask; if (authState.User.Identity?.IsAuthenticated == true) { await LoadAsync(); StateHasChanged(); } } } } private async Task LoadAsync() { try { var (items, total) = await ClientClient.GetPagedAsync( currentPage, PageSize, string.IsNullOrEmpty(statusFilter) ? null : statusFilter, string.IsNullOrEmpty(searchText) ? null : searchText); clients = items.ToList(); totalCount = total; totalPages = (int)Math.Ceiling((double)total / PageSize); } catch (Exception ex) { Snackbar.Add($"오류: {ex.Message}", Severity.Error); clients = []; totalCount = 0; totalPages = 0; } } private async Task SearchAsync() { currentPage = 1; await LoadAsync(); } private async Task ResetAsync() { searchText = ""; statusFilter = ""; currentPage = 1; await LoadAsync(); } private async Task OnPageChanged(int page) { currentPage = page; await LoadAsync(); } private async Task OnSearchKeyUp(KeyboardEventArgs e) { if (e.Key == "Enter") await SearchAsync(); } private async Task DeleteAsync(Client client) { var confirmed = await DialogService.ShowMessageBox( "고객 삭제", $"'{client.Name}' 고객을 삭제하시겠습니까? 관련 데이터도 함께 삭제됩니다.", yesText: "삭제", cancelText: "취소"); if (confirmed != true) return; try { var success = await ClientClient.DeleteAsync(client.Id); if (success) { Snackbar.Add($"{client.Name} 고객이 삭제되었습니다.", Severity.Success); await LoadAsync(); } else { Snackbar.Add("삭제에 실패했습니다.", Severity.Error); } } catch (Exception ex) { Snackbar.Add($"오류: {ex.Message}", Severity.Error); } await LoadAsync(); } }