From 6a5740ec68742904d1259fe81a0fde6aed0847df Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Mon, 29 Jun 2026 00:05:32 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B3=A0=EA=B0=9D=20=ED=8F=AC=ED=84=B8?= =?UTF-8?q?=20=EC=84=B8=EB=AC=B4=20=EC=8B=A0=EA=B3=A0=20=EB=B0=8F=20?= =?UTF-8?q?=EC=83=81=EB=8B=B4=20=EC=9A=94=EC=95=BD=20=EC=8B=A4=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EB=8C=80=EC=8B=9C=EB=B3=B4=EB=93=9C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B3=A0=EB=8F=84=ED=99=94=20=EB=B0=8F=20=EC=96=B4?= =?UTF-8?q?=EB=93=9C=EB=AF=BC=20UX=20=EB=A6=AC=EC=82=AC=EC=9D=B4=EC=A7=95?= =?UTF-8?q?=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TaxBaik.Web/Pages/Portal/Index.cshtml | 187 ++++++++++++++++++++--- TaxBaik.Web/Pages/Portal/Index.cshtml.cs | 38 ++++- TaxBaik.Web/wwwroot/css/admin.css | 170 +++++++++++++++------ 3 files changed, 324 insertions(+), 71 deletions(-) diff --git a/TaxBaik.Web/Pages/Portal/Index.cshtml b/TaxBaik.Web/Pages/Portal/Index.cshtml index 5d8f74b..42a3a64 100644 --- a/TaxBaik.Web/Pages/Portal/Index.cshtml +++ b/TaxBaik.Web/Pages/Portal/Index.cshtml @@ -1,34 +1,171 @@ @page "/portal" @model TaxBaik.Web.Pages.Portal.IndexModel @{ - ViewData["Title"] = "고객 포털"; - ViewData["Description"] = "고객이 신고 일정, 상담 요약, 중요 알림을 확인하는 전용 포털입니다."; - ViewData["CanonicalUrl"] = $"{Request.Scheme}://{Request.Host}/taxbaik/portal"; + ViewData["Title"] = "마이 포털 - 세무사 백원숙"; + ViewData["Description"] = "고객님의 세무 신고 일정과 상담 이력을 실시간으로 확인하실 수 있는 마이페이지입니다."; } -
-
-
-

Portal

-

고객 포털

-

- 신고 일정, 상담 요약, 승인된 알림을 확인할 수 있는 전용 공간입니다. -

-
- 로그인 - 회원가입 +
+
+ +
+
+

TaxBaik My Portal

+

안녕하세요, @(User.Identity?.Name)님!

+ @if (Model.ClientInfo != null) + { +

+ @(string.IsNullOrEmpty(Model.ClientInfo.CompanyName) ? "개인 고객" : Model.ClientInfo.CompanyName) + | @Model.ClientInfo.Phone +

+ } +
+
+
+ @Html.AntiForgeryToken() + +
-
-
-

제공 예정 기능

-
    -
  • 본인 신고 일정 확인
  • -
  • 상담 요약 열람
  • -
  • 중요 알림 수신
  • -
  • 관리자 승인 범위 내 정보 제공
  • -
+ + @if (Model.ClientInfo == null) + { + +
+
+
+ +
+

고객 정보 연동 대기 중

+

+ 가입하신 계정 정보(이메일/연락처)와 일치하는 세무 대리 고객 레코드를 찾지 못했습니다.
+ 세무사 측에서 고객 등록을 완료하거나 관리자 백오피스에서 이메일/전화번호가 일치하도록 지정하면 자동으로 포털 데이터가 활성화됩니다. +

+ + 세무사에게 문의하기 + +
-
+ } + else + { +
+ +
+
+
+
+

+ 나의 세무 신고 현황 +

+ 총 @(Model.Filings.Count)건 +
+ + @if (!Model.Filings.Any()) + { +
+ + 등록된 세무 신고 일정이 없습니다. +
+ } + else + { +
+ + + + + + + + + + + @foreach (var filing in Model.Filings) + { + var dDay = (filing.DueDate - DateTime.Today).Days; + var statusClass = filing.Status switch + { + "filed" => "bg-success-subtle text-success", + "overdue" => "bg-danger-subtle text-danger", + _ => "bg-warning-subtle text-warning-emphasis" + }; + var statusLabel = filing.Status switch + { + "filed" => "신고 완료", + "overdue" => "기한 초과", + _ => $"D-{dDay}" + }; + + + + + + + + } + +
신고 종류신고 기한진행 상태메모
+ @filing.FilingType + + @filing.DueDate.ToString("yyyy-MM-dd") + + @statusLabel + + @(string.IsNullOrEmpty(filing.Memo) ? "-" : filing.Memo) +
+
+ } +
+
+
+ + +
+
+
+

+ 최근 상담 및 지원 이력 +

+ + @if (!Model.Consultations.Any()) + { +
+ + 최근 상담 이력이 없습니다. +
+ } + else + { +
+ @foreach (var activity in Model.Consultations) + { +
+ +
+ +
+ @activity.ActivityType + @activity.ActivityDate.ToString("yyyy-MM-dd") +
+

@activity.Description

+ @if (!string.IsNullOrEmpty(activity.Outcome)) + { +
+ 결과: @activity.Outcome +
+ } +
+ } +
+ } +
+
+
+
+ }
-
+ diff --git a/TaxBaik.Web/Pages/Portal/Index.cshtml.cs b/TaxBaik.Web/Pages/Portal/Index.cshtml.cs index 8ec3edc..78a2560 100644 --- a/TaxBaik.Web/Pages/Portal/Index.cshtml.cs +++ b/TaxBaik.Web/Pages/Portal/Index.cshtml.cs @@ -1,5 +1,9 @@ +using System.Security.Claims; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; +using TaxBaik.Application.Services; +using TaxBaik.Domain.Entities; using TaxBaik.Web.Services; namespace TaxBaik.Web.Pages.Portal; @@ -7,7 +11,39 @@ namespace TaxBaik.Web.Pages.Portal; [Authorize(AuthenticationSchemes = PortalAuthDefaults.Scheme)] public class IndexModel : PageModel { - public void OnGet() + private readonly TaxFilingService _taxFilingService; + private readonly ConsultingActivityService _consultingActivityService; + private readonly ClientService _clientService; + + public IndexModel( + TaxFilingService taxFilingService, + ConsultingActivityService consultingActivityService, + ClientService clientService) { + _taxFilingService = taxFilingService; + _consultingActivityService = consultingActivityService; + _clientService = clientService; + } + + public Client? ClientInfo { get; private set; } + public List Filings { get; private set; } = new(); + public List Consultations { get; private set; } = new(); + + public async Task OnGetAsync() + { + var clientIdClaim = User.FindFirst("client_id"); + if (clientIdClaim != null && int.TryParse(clientIdClaim.Value, out var clientId)) + { + ClientInfo = await _clientService.GetByIdAsync(clientId); + if (ClientInfo != null) + { + var filingsData = await _taxFilingService.GetByClientIdAsync(clientId); + Filings = filingsData.OrderBy(f => f.DueDate).ToList(); + + var consultationsData = await _consultingActivityService.GetByClientIdAsync(clientId); + Consultations = consultationsData.OrderByDescending(c => c.ActivityDate).ToList(); + } + } + return Page(); } } diff --git a/TaxBaik.Web/wwwroot/css/admin.css b/TaxBaik.Web/wwwroot/css/admin.css index 573e417..1930695 100644 --- a/TaxBaik.Web/wwwroot/css/admin.css +++ b/TaxBaik.Web/wwwroot/css/admin.css @@ -411,11 +411,41 @@ textarea:focus-visible { background-color: var(--bg-secondary); } +.admin-shell .mud-typography--h4 { + font-size: 1.35rem; + line-height: 1.2; +} + +.admin-shell .mud-typography--h6 { + font-size: 0.88rem; + line-height: 1.2; +} + +.admin-shell .mud-typography--subtitle1 { + font-size: 0.82rem; + line-height: 1.3; +} + +.admin-shell .mud-typography--body1 { + font-size: 0.82rem; + line-height: 1.4; +} + +.admin-shell .mud-typography--body2 { + font-size: 0.75rem; + line-height: 1.35; +} + +.admin-shell .mud-typography--caption { + font-size: 0.68rem; + line-height: 1.2; +} + .admin-topbar { display: flex; align-items: center; - gap: var(--space-4); - padding: 8px 20px; + gap: 12px; + padding: 6px 16px; background-color: var(--bg-primary); border-bottom: 1px solid var(--border-color); z-index: var(--z-dropdown); @@ -429,7 +459,7 @@ textarea:focus-visible { .admin-topbar-title { display: flex; flex-direction: column; - gap: 2px; + gap: 0; } .admin-topbar-title span { @@ -437,20 +467,25 @@ textarea:focus-visible { } .admin-topbar-title .mud-typography--h6 { - font-size: 0.95rem; - line-height: 1.2; + font-size: 0.85rem; + line-height: 1.15; font-weight: var(--font-weight-semibold); } .admin-topbar-action { white-space: nowrap; - min-height: 36px; - padding: 6px 12px; - font-size: 0.875rem; + min-height: 32px; + padding: 4px 10px; + font-size: 0.8rem; +} + +.admin-shell .mud-button-root { + min-height: 32px; + font-size: 0.8rem; } .admin-drawer { - width: 224px; + width: 208px; background-color: var(--bg-primary); border-right: 1px solid var(--border-color); display: flex; @@ -460,8 +495,8 @@ textarea:focus-visible { .admin-drawer-brand { display: flex; align-items: center; - gap: var(--space-3); - padding: 12px; + gap: 10px; + padding: 10px 12px; border-bottom: 1px solid var(--border-color-light); } @@ -469,37 +504,37 @@ textarea:focus-visible { display: flex; align-items: center; justify-content: center; - width: 40px; - height: 40px; + width: 36px; + height: 36px; border-radius: var(--radius-md); background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%); color: var(--primary-contrast); font-weight: var(--font-weight-bold); - font-size: 1.125rem; + font-size: 1rem; flex-shrink: 0; } .admin-nav { - padding: 6px 0; + padding: 4px 0; flex: 1; overflow-y: auto; } .admin-nav .mud-nav-link, .admin-nav .mud-nav-group-header { - margin: 1px 8px !important; + margin: 1px 6px !important; border-radius: 6px !important; transition: all var(--transition-base) !important; } .admin-nav .mud-nav-link { - min-height: 36px; - font-size: 0.85rem; + min-height: 32px; + font-size: 0.78rem; } .admin-nav .mud-nav-group-header { - min-height: 36px; - font-size: 0.85rem; + min-height: 32px; + font-size: 0.78rem; } .admin-nav .mud-nav-link:hover { @@ -543,7 +578,7 @@ textarea:focus-visible { } .admin-content { - padding: 20px; + padding: 16px; max-width: 1400px; margin: 0 auto; width: 100%; @@ -557,9 +592,9 @@ textarea:focus-visible { display: flex; justify-content: space-between; align-items: center; - gap: 20px; - margin-bottom: 20px; - padding-bottom: 12px; + gap: 16px; + margin-bottom: 16px; + padding-bottom: 10px; border-bottom: 1px solid var(--border-color); } @@ -572,8 +607,8 @@ textarea:focus-visible { color: var(--primary-color); font-weight: var(--font-weight-semibold); text-transform: uppercase; - font-size: var(--font-size-xs); - letter-spacing: 0.5px; + font-size: 0.7rem; + letter-spacing: 0; margin-bottom: var(--space-1); } @@ -581,16 +616,16 @@ textarea:focus-visible { display: block; color: var(--text-primary); font-weight: var(--font-weight-semibold); - margin-bottom: 4px; - font-size: 1.75rem; + margin-bottom: 2px; + font-size: 1.45rem; line-height: var(--line-height-tight); } .admin-page-subtitle { display: block; color: var(--text-secondary); - font-size: 0.9rem; - line-height: var(--line-height-normal); + font-size: 0.8rem; + line-height: 1.35; } /* Metrics Grid */ @@ -604,7 +639,7 @@ textarea:focus-visible { /* Metric Card - Enterprise Grade */ .admin-metric-card { - padding: 12px; + padding: 10px; border-radius: var(--radius-md); background-color: var(--bg-primary); border: 1px solid var(--border-color); @@ -613,12 +648,52 @@ textarea:focus-visible { display: flex; flex-direction: column; justify-content: space-between; - min-height: 128px; + min-height: 116px; box-shadow: var(--shadow-xs); position: relative; overflow: hidden; } +.admin-metric-card-body { + display: flex; + flex-direction: column; + gap: 8px; + height: 100%; +} + +.admin-metric-card-label { + font-size: 0.68rem; + color: var(--text-tertiary); + text-transform: uppercase; + font-weight: var(--font-weight-semibold); +} + +.admin-metric-card-value-row { + display: flex; + justify-content: space-between; + align-items: center; + flex: 1; + gap: 8px; +} + +.admin-metric-card-value { + font-size: 1.45rem; + font-weight: var(--font-weight-bold); + line-height: 1; +} + +.admin-metric-card-icon { + font-size: 1.9rem; + opacity: 0.14; + line-height: 1; +} + +.admin-metric-card-caption { + font-size: 0.78rem; + color: var(--text-secondary); + line-height: 1.3; +} + .admin-metric-card::before { content: ''; position: absolute; @@ -692,11 +767,11 @@ textarea:focus-visible { /* Surfaces & Containers */ .admin-surface { - padding: 12px !important; + padding: 10px !important; border-radius: var(--radius-md) !important; background-color: var(--bg-primary) !important; border: 1px solid var(--border-color) !important; - margin-bottom: 12px !important; + margin-bottom: 10px !important; box-shadow: var(--shadow-xs); } @@ -704,9 +779,9 @@ textarea:focus-visible { display: flex; justify-content: space-between; align-items: flex-start; - gap: 12px; - margin-bottom: 12px; - padding-bottom: 8px; + gap: 10px; + margin-bottom: 10px; + padding-bottom: 6px; border-bottom: 1px solid var(--border-color-light); } @@ -715,14 +790,14 @@ textarea:focus-visible { } .admin-section-header h6 { - font-size: 0.95rem; + font-size: 0.85rem; font-weight: var(--font-weight-semibold); color: var(--text-primary); - margin-bottom: 4px; + margin-bottom: 2px; } .admin-section-header p { - font-size: 0.8rem; + font-size: 0.75rem; color: var(--text-secondary); margin: 0; } @@ -731,7 +806,7 @@ textarea:focus-visible { .admin-table { width: 100%; border-collapse: collapse; - font-size: 0.8rem; + font-size: 0.75rem; } .admin-table thead { @@ -740,13 +815,13 @@ textarea:focus-visible { } .admin-table thead th { - padding: 6px 10px; + padding: 5px 8px; text-align: left; font-weight: var(--font-weight-semibold); color: var(--text-secondary); - font-size: 0.7rem; + font-size: 0.65rem; text-transform: uppercase; - letter-spacing: 0.5px; + letter-spacing: 0; } .admin-table tbody tr { @@ -763,11 +838,16 @@ textarea:focus-visible { } .admin-table tbody td { - padding: 6px 10px; + padding: 5px 8px; color: var(--text-primary); vertical-align: middle; } +.admin-table .mud-chip { + font-size: 0.68rem; + height: 22px; +} + .admin-table tbody a { color: var(--primary-color); text-decoration: none;