refactor: Phase 7-2 - Inquiry page API-First (partial)
TaxBaik CI/CD / build-and-deploy (push) Successful in 48s
TaxBaik CI/CD / build-and-deploy (push) Successful in 48s
**Implementation:** - InquiryBrowserClient: HTTP API client interface * GetPagedAsync(page, pageSize): Fetch inquiries * GetByIdAsync(id): Fetch single inquiry * UpdateStatusAsync(id, status): Change status - Program.cs: Register InquiryBrowserClient * AddHttpClient with TokenRefreshHandler - InquiryTable.razor: Refactored * Before: @inject InquiryService (direct service call) * After: @inject IInquiryBrowserClient (API call) * Status labels: Use InquiryStatusMapper * API calls via client instead of service **Status:** - Blog page: ✅ Already API-First (ApiClient) - Inquiry table: ✅ API-First (IInquiryBrowserClient) - Inquiry detail: ⏳ Pending (needs additional API endpoints) * UpdateAdminMemoAsync * LinkClientAsync * ConvertToClientAsync **SOLID Applied:** ✓ S (Single Responsibility): InquiryBrowserClient handles only Inquiry API calls ✓ D (Dependency Inversion): Blazor depends on IInquiryBrowserClient abstraction ✓ O (Open/Closed): Client can be extended without Blazor changes Next: Implement remaining API endpoints for InquiryDetail refactoring Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
@using TaxBaik.Application.Services
|
@using TaxBaik.Web.Services
|
||||||
@inject InquiryService InquiryService
|
@inject IInquiryBrowserClient InquiryClient
|
||||||
|
|
||||||
<MudSimpleTable Striped="true" Dense="true" Class="admin-table mt-4">
|
<MudSimpleTable Striped="true" Dense="true" Class="admin-table mt-4">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var (items, _) = await InquiryService.GetPagedAsync(1, 100);
|
var (items, _) = await InquiryClient.GetPagedAsync(1, 100);
|
||||||
inquiries = items.ToList();
|
inquiries = items.ToList();
|
||||||
FilterInquiries();
|
FilterInquiries();
|
||||||
}
|
}
|
||||||
@@ -69,18 +69,14 @@
|
|||||||
private static Color GetStatusColor(string status) => status switch
|
private static Color GetStatusColor(string status) => status switch
|
||||||
{
|
{
|
||||||
"new" => Color.Warning,
|
"new" => Color.Warning,
|
||||||
"contacted" => Color.Info,
|
"consulting" => Color.Info,
|
||||||
"completed" => Color.Success,
|
"contracted" => Color.Success,
|
||||||
|
"rejected" => Color.Error,
|
||||||
|
"closed" => Color.Dark,
|
||||||
_ => Color.Default
|
_ => Color.Default
|
||||||
};
|
};
|
||||||
|
|
||||||
private static string GetStatusLabel(string status) => status switch
|
private static string GetStatusLabel(string status) => InquiryStatusMapper.Labels.GetValueOrDefault(status, status);
|
||||||
{
|
|
||||||
"new" => "신규",
|
|
||||||
"contacted" => "연락함",
|
|
||||||
"completed" => "완료",
|
|
||||||
_ => status
|
|
||||||
};
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ builder.Services.AddHttpClient<IAdminDashboardClient, AdminDashboardClient>(clie
|
|||||||
client.BaseAddress = new Uri("http://localhost:5001/taxbaik/api/");
|
client.BaseAddress = new Uri("http://localhost:5001/taxbaik/api/");
|
||||||
})
|
})
|
||||||
.AddHttpMessageHandler<TokenRefreshHandler>();
|
.AddHttpMessageHandler<TokenRefreshHandler>();
|
||||||
|
builder.Services.AddHttpClient<IInquiryBrowserClient, InquiryBrowserClient>()
|
||||||
|
.AddHttpMessageHandler<TokenRefreshHandler>();
|
||||||
|
|
||||||
// UI & 캐시
|
// UI & 캐시
|
||||||
builder.Services.AddMudServices();
|
builder.Services.AddMudServices();
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
namespace TaxBaik.Web.Services;
|
||||||
|
|
||||||
|
using System.Net.Http.Json;
|
||||||
|
using TaxBaik.Domain.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inquiry API Client for Admin Blazor
|
||||||
|
/// SOLID: Single Responsibility - Inquiry API calls only
|
||||||
|
/// Dependency Inversion - abstraction via interface
|
||||||
|
/// </summary>
|
||||||
|
public interface IInquiryBrowserClient
|
||||||
|
{
|
||||||
|
Task<(IEnumerable<Inquiry> Items, int Total)> GetPagedAsync(int page = 1, int pageSize = 20, CancellationToken ct = default);
|
||||||
|
Task<Inquiry?> GetByIdAsync(int id, CancellationToken ct = default);
|
||||||
|
Task<bool> UpdateStatusAsync(int id, string status, CancellationToken ct = default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InquiryBrowserClient : IInquiryBrowserClient
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
private readonly ILogger<InquiryBrowserClient> _logger;
|
||||||
|
|
||||||
|
public InquiryBrowserClient(HttpClient http, ILogger<InquiryBrowserClient> logger)
|
||||||
|
{
|
||||||
|
_http = http;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(IEnumerable<Inquiry> Items, int Total)> GetPagedAsync(
|
||||||
|
int page = 1, int pageSize = 20, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = await _http.GetFromJsonAsync<InquiryPagedResponse>(
|
||||||
|
$"http://localhost:5001/taxbaik/api/inquiry?page={page}&pageSize={pageSize}",
|
||||||
|
cancellationToken: ct);
|
||||||
|
|
||||||
|
return result != null
|
||||||
|
? (result.Data, result.Total)
|
||||||
|
: ([], 0);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to fetch inquiries");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Inquiry?> GetByIdAsync(int id, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await _http.GetFromJsonAsync<Inquiry>(
|
||||||
|
$"http://localhost:5001/taxbaik/api/inquiry/{id}",
|
||||||
|
cancellationToken: ct);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to fetch inquiry {InquiryId}", id);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateStatusAsync(int id, string status, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new { status };
|
||||||
|
var response = await _http.PutAsJsonAsync(
|
||||||
|
$"http://localhost:5001/taxbaik/api/inquiry/{id}/status",
|
||||||
|
request,
|
||||||
|
cancellationToken: ct);
|
||||||
|
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
catch (HttpRequestException ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Failed to update inquiry {InquiryId} status", id);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InquiryPagedResponse
|
||||||
|
{
|
||||||
|
public List<Inquiry> Data { get; set; } = [];
|
||||||
|
public int Total { get; set; }
|
||||||
|
public int Page { get; set; }
|
||||||
|
public int PageSize { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user