Compare commits

...

2 Commits

Author SHA1 Message Date
6983609c7b [CLAUDE] FE: Hồ sơ NS — header chi tiết NV nổi bật (tên text-xl extrabold + drop-shadow · meta 13px font-medium trắng · badge trạng thái màu emerald/amber/slate) — x2 app SHA256
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m48s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:34:35 +07:00
11bc96dff1 [CLAUDE] Docs: S68 bootstrap drift-fix — dep-audit skill gotcha 64→65 + root CLAUDE test 263→286 (H1 monitor)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:34:35 +07:00
4 changed files with 22 additions and 14 deletions

View File

@ -150,6 +150,6 @@ Lưu vào `docs/changelog/deps-audit-{YYYY-MM-DD}.md` nếu có action.
## Related ## Related
- `docs/gotchas.md` — 64 bẫy package compat / CI / IIS / Identity / per-NV refactor / SQLite tie-break đã gặp - `docs/gotchas.md` — 65 bẫy package compat / CI / IIS / Identity / per-NV refactor / SQLite tie-break đã gặp
- `docs/changelog/migration-todos.md` Phase 5.1 — checklist deps scan CI - `docs/changelog/migration-todos.md` Phase 5.1 — checklist deps scan CI
- `SolutionErp.slnx` + `global.json` — .NET version pin - `SolutionErp.slnx` + `global.json` — .NET version pin

View File

@ -63,7 +63,7 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser
| Identity (User/Role/Permission/MenuItem) | `Domain/Identity/` | 1, 3, 11 | Feature-complete (30 demo user — 16 sample + 14 Solutions thật) | | Identity (User/Role/Permission/MenuItem) | `Domain/Identity/` | 1, 3, 11 | Feature-complete (30 demo user — 16 sample + 14 Solutions thật) |
| Forms (Template + Clause) | `Domain/Forms/` | 4 | Feature-complete | | Forms (Template + Clause) | `Domain/Forms/` | 4 | Feature-complete |
| Notifications | `Domain/Notifications/` | 6 | In-app + SignalR OK, email SMTP TODO | | Notifications | `Domain/Notifications/` | 6 | In-app + SignalR OK, email SMTP TODO |
| **Tests** | `tests/SolutionErp.{Domain,Infrastructure}.Tests/` | — | **263 test pass** (45 Domain + 218 Infra) — CI gate + path filter docs-only skip | | **Tests** | `tests/SolutionErp.{Domain,Infrastructure}.Tests/` | — | **286 test pass** (45 Domain + 241 Infra) — CI gate + path filter docs-only skip |
### Commit convention ### Commit convention

View File

@ -650,14 +650,18 @@ function EmployeeDetailTabs({ detail, onDelete }: { detail: EmployeeDetail; onDe
{initials(detail.fullName)} {initials(detail.fullName)}
</span> </span>
<div className="min-w-0"> <div className="min-w-0">
<h2 className="truncate text-lg font-bold leading-tight text-white">{detail.fullName ?? '—'}</h2> <h2 className="truncate text-xl font-extrabold leading-tight text-white drop-shadow-sm">{detail.fullName ?? '—'}</h2>
<div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-white/85"> <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-[13px] font-medium text-white">
<span className="font-mono">{detail.employeeCode}</span> <span className="font-mono font-semibold tracking-tight">{detail.employeeCode}</span>
{detail.departmentName && (<><span className="opacity-50"></span><span className="truncate">{detail.departmentName}</span></>)} {detail.departmentName && (<><span className="text-white/55"></span><span className="truncate">{detail.departmentName}</span></>)}
{detail.workLocation && (<><span className="opacity-50"></span><span className="truncate">{detail.workLocation}</span></>)} {detail.workLocation && (<><span className="text-white/55"></span><span className="truncate">{detail.workLocation}</span></>)}
</div> </div>
<div className="mt-2"> <div className="mt-2">
<span className="inline-flex items-center rounded-full bg-white/20 px-2 py-0.5 text-[11px] font-medium text-white ring-1 ring-white/25"> <span className={cn(
'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold shadow-sm ring-1 ring-black/5',
EmployeeStatusColor[detail.employeeStatus],
)}>
<span className="h-1.5 w-1.5 rounded-full bg-current opacity-70" />
{EmployeeStatusLabel[detail.employeeStatus]} {EmployeeStatusLabel[detail.employeeStatus]}
</span> </span>
</div> </div>

View File

@ -650,14 +650,18 @@ function EmployeeDetailTabs({ detail, onDelete }: { detail: EmployeeDetail; onDe
{initials(detail.fullName)} {initials(detail.fullName)}
</span> </span>
<div className="min-w-0"> <div className="min-w-0">
<h2 className="truncate text-lg font-bold leading-tight text-white">{detail.fullName ?? '—'}</h2> <h2 className="truncate text-xl font-extrabold leading-tight text-white drop-shadow-sm">{detail.fullName ?? '—'}</h2>
<div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-white/85"> <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-[13px] font-medium text-white">
<span className="font-mono">{detail.employeeCode}</span> <span className="font-mono font-semibold tracking-tight">{detail.employeeCode}</span>
{detail.departmentName && (<><span className="opacity-50"></span><span className="truncate">{detail.departmentName}</span></>)} {detail.departmentName && (<><span className="text-white/55"></span><span className="truncate">{detail.departmentName}</span></>)}
{detail.workLocation && (<><span className="opacity-50"></span><span className="truncate">{detail.workLocation}</span></>)} {detail.workLocation && (<><span className="text-white/55"></span><span className="truncate">{detail.workLocation}</span></>)}
</div> </div>
<div className="mt-2"> <div className="mt-2">
<span className="inline-flex items-center rounded-full bg-white/20 px-2 py-0.5 text-[11px] font-medium text-white ring-1 ring-white/25"> <span className={cn(
'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold shadow-sm ring-1 ring-black/5',
EmployeeStatusColor[detail.employeeStatus],
)}>
<span className="h-1.5 w-1.5 rounded-full bg-current opacity-70" />
{EmployeeStatusLabel[detail.employeeStatus]} {EmployeeStatusLabel[detail.employeeStatus]}
</span> </span>
</div> </div>