[CLAUDE] CICD+FE-Admin+FE-User: deploy pool-state guard + SlaTimer component
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Has been cancelled

CICD: check app pool state before Stop-WebAppPool (idempotent).

FE: new SlaTimer component with color-coded countdown (emerald/amber/red)
and progress bar. Two variants:
- inline: used in list tables (Inbox, Contracts list x2, MyContracts)
- full: used in ContractDetail card with progress bar + deadline timestamp

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-04-21 15:04:44 +07:00
parent b40da1e726
commit 290936a0ca
8 changed files with 189 additions and 24 deletions

View File

@ -4,21 +4,13 @@ import { Inbox } from 'lucide-react'
import { PageHeader } from '@/components/PageHeader'
import { DataTable, type Column } from '@/components/DataTable'
import { PhaseBadge } from '@/components/PhaseBadge'
import { SlaTimer } from '@/components/SlaTimer'
import { useAuth } from '@/contexts/AuthContext'
import { api } from '@/lib/api'
import type { ContractListItem } from '@/types/contracts'
import { ContractTypeLabel } from '@/types/forms'
const fmtMoney = (v: number) => v.toLocaleString('vi-VN')
const fmtSla = (s: string | null) => {
if (!s) return '—'
const ms = new Date(s).getTime() - Date.now()
const days = Math.floor(ms / (1000 * 60 * 60 * 24))
const hours = Math.floor((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
if (ms < 0) return <span className="text-red-600">Quá hạn</span>
if (days > 0) return `còn ${days}d ${hours}h`
return <span className="text-amber-600">còn {hours}h</span>
}
export function InboxPage() {
const navigate = useNavigate()
@ -36,7 +28,7 @@ export function InboxPage() {
{ key: 'phase', header: 'Phase hiện tại', width: 'w-36', render: c => <PhaseBadge phase={c.phase} /> },
{ key: 'supplierName', header: 'NCC', render: c => c.supplierName },
{ key: 'giaTri', header: 'Giá trị', align: 'right', width: 'w-32', render: c => fmtMoney(c.giaTri) },
{ key: 'slaDeadline', header: 'SLA', width: 'w-32', render: c => fmtSla(c.slaDeadline) },
{ key: 'slaDeadline', header: 'SLA', width: 'w-40', render: c => <SlaTimer deadline={c.slaDeadline} createdAt={c.createdAt} /> },
]
return (