[CLAUDE] FE: HĐ move Lich su dieu chinh sang Panel 3 duoi Lich su duyet
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m55s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m55s
User request: 'cho hop dong dua cac thong tin lich su dieu chinh sang duoi lich su duyet nhen'. ContractDetailContent (Panel 2): xoa section 'Lich su dieu chinh' (cot 3/10 grid 7/3) → Chi tiet HD gio full-width. Remove import History + ContractChangelogsTab. WorkflowHistoryPanel (Panel 3): them section Lich su dieu chinh duoi Lich su duyet. Import History icon + ContractChangelogsTab. Reuse same component, chi doi vi tri render. Mirror fe-admin + fe-user.
This commit is contained in:
@ -1,16 +1,15 @@
|
||||
// Reusable detail body — used by full-page ContractDetailPage AND embedded
|
||||
// in ContractsListPage 3-panel layout (Panel 2). Admin variant include thêm
|
||||
// Phòng ban + Bypass CCM trong Info section. Workflow + history live separately
|
||||
// trong WorkflowHistoryPanel (Panel 3).
|
||||
// in MyContractsPage 3-panel layout (Panel 2). Renders header (title + phase
|
||||
// + actions) + Info + Comments + Attachments + transition Dialog. Workflow +
|
||||
// approval history live separately in WorkflowHistoryPanel (Panel 3).
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { ArrowLeft, CheckCircle2, MessageSquare, XCircle, ListChecks, History } from 'lucide-react'
|
||||
import { ArrowLeft, CheckCircle2, MessageSquare, XCircle, ListChecks } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { PhaseBadge } from '@/components/PhaseBadge'
|
||||
import { SlaTimer } from '@/components/SlaTimer'
|
||||
import { ContractAttachmentsSection } from '@/components/ContractAttachmentsSection'
|
||||
import { ContractDetailsTab } from '@/components/contracts/ContractDetailsTab'
|
||||
import { ContractChangelogsTab } from '@/components/contracts/ContractChangelogsTab'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Select } from '@/components/ui/Select'
|
||||
import { Textarea } from '@/components/ui/Textarea'
|
||||
@ -49,7 +48,7 @@ export function ContractDetailContent({
|
||||
},
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['contract', c.id] })
|
||||
qc.invalidateQueries({ queryKey: ['contracts'] })
|
||||
qc.invalidateQueries({ queryKey: ['my-contracts'] })
|
||||
qc.invalidateQueries({ queryKey: ['inbox'] })
|
||||
toast.success('Đã chuyển phase')
|
||||
setActionOpen(false)
|
||||
@ -65,7 +64,7 @@ export function ContractDetailContent({
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: ['contract', c.id] })
|
||||
setCommentInput('')
|
||||
toast.success('Đã gửi comment')
|
||||
toast.success('Đã gửi')
|
||||
},
|
||||
onError: err => toast.error(getErrorMessage(err)),
|
||||
})
|
||||
@ -84,7 +83,7 @@ export function ContractDetailContent({
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Header — sticky inside scroll container */}
|
||||
{/* Header — sticky inside scroll container so actions luôn visible */}
|
||||
<div className="sticky top-0 z-10 -mx-5 -mt-5 border-b border-slate-200 bg-white px-5 pt-5 pb-3 md:-mx-6 md:-mt-6 md:px-6 md:pt-6">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
@ -126,13 +125,11 @@ export function ContractDetailContent({
|
||||
<div><dt className="text-slate-500">Giá trị</dt><dd>{fmtMoney(c.giaTri)}</dd></div>
|
||||
<div><dt className="text-slate-500">NCC</dt><dd>{c.supplierName}</dd></div>
|
||||
<div><dt className="text-slate-500">Dự án</dt><dd>{c.projectName}</dd></div>
|
||||
<div><dt className="text-slate-500">Phòng ban</dt><dd>{c.departmentName ?? '—'}</dd></div>
|
||||
<div><dt className="text-slate-500">Người soạn</dt><dd>{c.drafterName ?? '—'}</dd></div>
|
||||
<div className="col-span-2">
|
||||
<dt className="text-slate-500 mb-1">SLA</dt>
|
||||
<dd><SlaTimer deadline={c.slaDeadline} createdAt={c.createdAt} variant="full" /></dd>
|
||||
</div>
|
||||
<div><dt className="text-slate-500">Bypass CCM</dt><dd>{c.bypassProcurementAndCCM ? 'Có (HĐ Chủ đầu tư)' : 'Không'}</dd></div>
|
||||
</dl>
|
||||
{c.noiDung && (
|
||||
<div className="mt-3">
|
||||
@ -176,23 +173,14 @@ export function ContractDetailContent({
|
||||
|
||||
<ContractAttachmentsSection contractId={c.id} attachments={c.attachments} />
|
||||
|
||||
{/* Chi tiết + Lịch sử điều chỉnh — 7/3 grid bên dưới */}
|
||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-10">
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5 lg:col-span-7">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<ListChecks className="h-4 w-4" />
|
||||
Chi tiết ({ContractTypeLabel[c.type] ?? '—'})
|
||||
</h2>
|
||||
<ContractDetailsTab contract={c} />
|
||||
</section>
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5 lg:col-span-3">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<History className="h-4 w-4" />
|
||||
Lịch sử điều chỉnh
|
||||
</h2>
|
||||
<ContractChangelogsTab contractId={c.id} />
|
||||
</section>
|
||||
</div>
|
||||
{/* Chi tiết HĐ full-width — Lịch sử điều chỉnh đã move sang Panel 3 */}
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<ListChecks className="h-4 w-4" />
|
||||
Chi tiết ({ContractTypeLabel[c.type] ?? '—'})
|
||||
</h2>
|
||||
<ContractDetailsTab contract={c} />
|
||||
</section>
|
||||
|
||||
<Dialog
|
||||
open={actionOpen}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
// Panel 3 cho 3-panel layout — gom WorkflowSummaryCard (timeline policy) +
|
||||
// approval history (ai/khi/quyết định gì) vào 1 stack.
|
||||
import { ArrowRight, Clock } from 'lucide-react'
|
||||
// approval history (ai/khi/quyết định gì) + ContractChangelogsTab (mọi thay
|
||||
// đổi header/detail/comment/attachment/transition) vào 1 stack. Dùng cho cả
|
||||
// MyContracts 3-panel và ContractDetailPage fullpage.
|
||||
import { ArrowRight, Clock, History } from 'lucide-react'
|
||||
import { PhaseBadge } from '@/components/PhaseBadge'
|
||||
import { WorkflowSummaryCard } from '@/components/WorkflowSummaryCard'
|
||||
import { ContractChangelogsTab } from '@/components/contracts/ContractChangelogsTab'
|
||||
import type { ContractDetail } from '@/types/contracts'
|
||||
|
||||
const fmt = (s: string) => new Date(s).toLocaleString('vi-VN')
|
||||
@ -40,6 +43,14 @@ export function WorkflowHistoryPanel({ contract: c }: { contract: ContractDetail
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<History className="h-4 w-4" />
|
||||
Lịch sử điều chỉnh
|
||||
</h2>
|
||||
<ContractChangelogsTab contractId={c.id} />
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -4,13 +4,12 @@
|
||||
// approval history live separately in WorkflowHistoryPanel (Panel 3).
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { ArrowLeft, CheckCircle2, MessageSquare, XCircle, ListChecks, History } from 'lucide-react'
|
||||
import { ArrowLeft, CheckCircle2, MessageSquare, XCircle, ListChecks } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { PhaseBadge } from '@/components/PhaseBadge'
|
||||
import { SlaTimer } from '@/components/SlaTimer'
|
||||
import { ContractAttachmentsSection } from '@/components/ContractAttachmentsSection'
|
||||
import { ContractDetailsTab } from '@/components/contracts/ContractDetailsTab'
|
||||
import { ContractChangelogsTab } from '@/components/contracts/ContractChangelogsTab'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { Select } from '@/components/ui/Select'
|
||||
import { Textarea } from '@/components/ui/Textarea'
|
||||
@ -174,23 +173,14 @@ export function ContractDetailContent({
|
||||
|
||||
<ContractAttachmentsSection contractId={c.id} attachments={c.attachments} />
|
||||
|
||||
{/* Chi tiết + Lịch sử điều chỉnh — 7/3 grid bên dưới */}
|
||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-10">
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5 lg:col-span-7">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<ListChecks className="h-4 w-4" />
|
||||
Chi tiết ({ContractTypeLabel[c.type] ?? '—'})
|
||||
</h2>
|
||||
<ContractDetailsTab contract={c} />
|
||||
</section>
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5 lg:col-span-3">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<History className="h-4 w-4" />
|
||||
Lịch sử điều chỉnh
|
||||
</h2>
|
||||
<ContractChangelogsTab contractId={c.id} />
|
||||
</section>
|
||||
</div>
|
||||
{/* Chi tiết HĐ full-width — Lịch sử điều chỉnh đã move sang Panel 3 */}
|
||||
<section className="rounded-lg border border-slate-200 bg-white p-5">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<ListChecks className="h-4 w-4" />
|
||||
Chi tiết ({ContractTypeLabel[c.type] ?? '—'})
|
||||
</h2>
|
||||
<ContractDetailsTab contract={c} />
|
||||
</section>
|
||||
|
||||
<Dialog
|
||||
open={actionOpen}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
// Panel 3 cho 3-panel layout — gom WorkflowSummaryCard (timeline policy) +
|
||||
// approval history (ai/khi/quyết định gì) vào 1 stack. Dùng cho cả MyContracts
|
||||
// 3-panel và ContractDetailPage fullpage.
|
||||
import { ArrowRight, Clock } from 'lucide-react'
|
||||
// approval history (ai/khi/quyết định gì) + ContractChangelogsTab (mọi thay
|
||||
// đổi header/detail/comment/attachment/transition) vào 1 stack. Dùng cho cả
|
||||
// MyContracts 3-panel và ContractDetailPage fullpage.
|
||||
import { ArrowRight, Clock, History } from 'lucide-react'
|
||||
import { PhaseBadge } from '@/components/PhaseBadge'
|
||||
import { WorkflowSummaryCard } from '@/components/WorkflowSummaryCard'
|
||||
import { ContractChangelogsTab } from '@/components/contracts/ContractChangelogsTab'
|
||||
import type { ContractDetail } from '@/types/contracts'
|
||||
|
||||
const fmt = (s: string) => new Date(s).toLocaleString('vi-VN')
|
||||
@ -41,6 +43,14 @@ export function WorkflowHistoryPanel({ contract: c }: { contract: ContractDetail
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||
<h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
||||
<History className="h-4 w-4" />
|
||||
Lịch sử điều chỉnh
|
||||
</h2>
|
||||
<ContractChangelogsTab contractId={c.id} />
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user