feat(WEB): 상세 페이지 권한 체계 통합 및 레이아웃/문서 기능 개선

권한 시스템 통합:
- BadDebtDetail, LaborDetail, PricingDetail 권한 로직 정리
- BoardDetail, ClientDetail, ItemDetail 권한 적용 개선
- ProcessDetail, StepDetail, PermissionDetail 권한 리팩토링
- ContractDetail, HandoverReport, ProgressBilling 권한 연동
- ReceivingDetail, ShipmentDetail, WorkOrderDetail 권한 적용
- InspectionDetail, OrderSalesDetail, QuoteFooterBar 권한 개선

기능 개선:
- AuthenticatedLayout 구조 리팩토링
- JointbarInspectionDocument 문서 레이아웃 개선
- PricingTableForm 폼 기능 보강
- DynamicItemForm, SectionsTab 개선
- 주문관리 상세/생산지시 페이지 개선
- VendorLedgerDetail 수정

설정:
- Claude hooks 추가 (빌드 차단, 파일 크기 체크, 미사용 import 체크)
- 품질감사 문서관리 계획 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
유병철
2026-02-04 20:26:27 +09:00
parent c1b63b850a
commit bb7e7a75e9
30 changed files with 737 additions and 665 deletions

View File

@@ -70,38 +70,40 @@ export function QuoteFooterBar({
}: QuoteFooterBarProps) {
return (
<div className="sticky bottom-0 bg-gradient-to-r from-blue-50 to-indigo-50 border-t border-blue-200 shadow-lg">
<div className="px-6 py-4 flex items-center justify-between">
<div className="px-3 py-3 md:px-6 md:py-4 flex items-center justify-between">
{/* 왼쪽: 뒤로가기 + 금액 표시 */}
<div className="flex items-center gap-6">
<div className="flex items-center gap-3 md:gap-6">
<Button
variant="outline"
onClick={onBack}
className="gap-2"
size="sm"
className="md:size-default"
>
<ArrowLeft className="h-4 w-4" />
<ArrowLeft className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
<div>
<p className="text-sm text-gray-600"> </p>
<p className="text-3xl font-bold text-blue-600">
<p className="text-xs md:text-sm text-gray-600"> </p>
<p className="text-lg md:text-3xl font-bold text-blue-600">
{totalAmount.toLocaleString()}
<span className="text-lg font-normal text-gray-500 ml-1"></span>
<span className="text-sm md:text-lg font-normal text-gray-500 ml-1"></span>
</p>
</div>
</div>
{/* 오른쪽: 버튼들 */}
<div className="flex items-center gap-3">
<div className="flex items-center gap-1 md:gap-3">
{/* 견적서 보기 */}
<Button
onClick={onQuoteView}
disabled={totalLocations === 0}
variant="outline"
className="gap-2 px-6"
size="sm"
className="md:size-default md:px-6"
>
<FileText className="h-4 w-4" />
<FileText className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"> </span>
</Button>
{/* 거래명세서 보기 */}
@@ -109,10 +111,11 @@ export function QuoteFooterBar({
onClick={onTransactionView}
disabled={totalLocations === 0}
variant="outline"
className="gap-2 px-6"
size="sm"
className="md:size-default md:px-6"
>
<ClipboardList className="h-4 w-4" />
<ClipboardList className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"> </span>
</Button>
{/* 수식보기 - 개발환경(local/development)에서만 표시 */}
@@ -121,10 +124,11 @@ export function QuoteFooterBar({
onClick={onFormulaView}
disabled={!hasBomResult}
variant="outline"
className="gap-2 px-6 border-purple-300 text-purple-600 hover:bg-purple-50"
size="sm"
className="border-purple-300 text-purple-600 hover:bg-purple-50 md:size-default md:px-6"
>
<Calculator className="h-4 w-4" />
<Calculator className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
)}
@@ -133,10 +137,11 @@ export function QuoteFooterBar({
<Button
onClick={onEdit}
variant="outline"
className="gap-2 px-6"
size="sm"
className="md:size-default md:px-6"
>
<Pencil className="h-4 w-4" />
<Pencil className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
)}
@@ -146,10 +151,11 @@ export function QuoteFooterBar({
onClick={onDiscount}
disabled={isViewMode}
variant="outline"
className="gap-2 px-6 border-orange-300 text-orange-600 hover:bg-orange-50"
size="sm"
className="border-orange-300 text-orange-600 hover:bg-orange-50 md:size-default md:px-6"
>
<Percent className="h-4 w-4" />
<Percent className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
)}
@@ -158,14 +164,15 @@ export function QuoteFooterBar({
<Button
onClick={onSave}
disabled={isSaving}
className="bg-slate-500 hover:bg-slate-600 text-white gap-2 px-6"
size="sm"
className="bg-slate-500 hover:bg-slate-600 text-white md:size-default md:px-6"
>
{isSaving ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Save className="h-4 w-4" />
<Save className="h-4 w-4 md:mr-2" />
)}
<span className="hidden md:inline"></span>
</Button>
)}
@@ -174,14 +181,15 @@ export function QuoteFooterBar({
<Button
onClick={onFinalize}
disabled={isSaving || totalAmount === 0}
className="bg-blue-600 hover:bg-blue-700 text-white gap-2 px-6"
size="sm"
className="bg-blue-600 hover:bg-blue-700 text-white md:size-default md:px-6"
>
{isSaving ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Check className="h-4 w-4" />
<Check className="h-4 w-4 md:mr-2" />
)}
<span className="hidden md:inline"></span>
</Button>
)}
@@ -189,10 +197,11 @@ export function QuoteFooterBar({
{status === "final" && onOrderRegister && (
<Button
onClick={onOrderRegister}
className="bg-green-600 hover:bg-green-700 text-white gap-2 px-6"
size="sm"
className="bg-green-600 hover:bg-green-700 text-white md:size-default md:px-6"
>
<ClipboardList className="h-4 w-4" />
<ClipboardList className="h-4 w-4 md:mr-2" />
<span className="hidden md:inline"></span>
</Button>
)}
</div>