Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -4,16 +4,11 @@
|
||||
* 중간검사 미리보기 모달
|
||||
*
|
||||
* 설정된 검사 항목들로 실제 성적서가 어떻게 보일지 미리보기
|
||||
* DocumentViewer preset="readonly" 사용 → 줌/드래그/인쇄/PDF 자동 제공
|
||||
*/
|
||||
|
||||
import { Fragment } from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DocumentViewer } from '@/components/document-system';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import type { InspectionSetting } from '@/types/process';
|
||||
|
||||
@@ -30,21 +25,16 @@ export function InspectionPreviewModal({
|
||||
}: InspectionPreviewModalProps) {
|
||||
if (!inspectionSetting) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-4xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>중간검사 미리보기</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="py-12 text-center text-muted-foreground">
|
||||
검사 설정이 없습니다. 먼저 검사 설정을 완료해주세요.
|
||||
</div>
|
||||
<div className="flex justify-end">
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
||||
닫기
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<DocumentViewer
|
||||
title="중간검사 미리보기"
|
||||
preset="readonly"
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
>
|
||||
<div className="py-12 text-center text-muted-foreground">
|
||||
검사 설정이 없습니다. 먼저 검사 설정을 완료해주세요.
|
||||
</div>
|
||||
</DocumentViewer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,214 +59,206 @@ export function InspectionPreviewModal({
|
||||
const sampleRows = [1, 2, 3, 4, 5];
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="w-[95vw] max-w-[1400px] sm:max-w-[1400px] max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>중간검사 미리보기</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-6 mt-4">
|
||||
{/* 헤더 정보 */}
|
||||
<div className="flex items-center gap-4 p-4 bg-muted/50 rounded-lg">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium">기준서명:</span>
|
||||
<Badge variant="outline">{inspectionSetting.standardName || '미설정'}</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium">활성 항목:</span>
|
||||
<Badge>{activeAppearanceItems.length + activeDimensionItems.length}개</Badge>
|
||||
</div>
|
||||
<DocumentViewer
|
||||
title="중간검사 미리보기"
|
||||
preset="readonly"
|
||||
open={open}
|
||||
onOpenChange={onOpenChange}
|
||||
>
|
||||
<div className="space-y-6 p-6">
|
||||
{/* 헤더 정보 */}
|
||||
<div className="flex items-center gap-4 p-4 bg-muted/50 rounded-lg">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium">기준서명:</span>
|
||||
<Badge variant="outline">{inspectionSetting.standardName || '미설정'}</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium">활성 항목:</span>
|
||||
<Badge>{activeAppearanceItems.length + activeDimensionItems.length}개</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 중간검사 기준서 */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-b">
|
||||
중간검사 기준서
|
||||
{/* 중간검사 기준서 */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-b">
|
||||
중간검사 기준서
|
||||
</div>
|
||||
<div className="p-4 grid grid-cols-2 gap-4">
|
||||
{/* 도해 이미지 영역 */}
|
||||
<div className="border rounded-lg p-4 min-h-[200px] flex items-center justify-center bg-muted/30">
|
||||
{inspectionSetting.schematicImage ? (
|
||||
<img
|
||||
src={inspectionSetting.schematicImage}
|
||||
alt="도해 이미지"
|
||||
className="max-w-full max-h-[180px] object-contain"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-muted-foreground text-sm">도해 이미지 없음</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-4 grid grid-cols-2 gap-4">
|
||||
{/* 도해 이미지 영역 */}
|
||||
<div className="border rounded-lg p-4 min-h-[200px] flex items-center justify-center bg-muted/30">
|
||||
{inspectionSetting.schematicImage ? (
|
||||
<img
|
||||
src={inspectionSetting.schematicImage}
|
||||
alt="도해 이미지"
|
||||
className="max-w-full max-h-[180px] object-contain"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-muted-foreground text-sm">도해 이미지 없음</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 검사기준 이미지 또는 검사 항목 테이블 */}
|
||||
<div className="border rounded-lg overflow-hidden min-h-[200px] flex items-center justify-center bg-muted/30">
|
||||
{inspectionSetting.inspectionStandardImage ? (
|
||||
<img
|
||||
src={inspectionSetting.inspectionStandardImage}
|
||||
alt="검사기준 이미지"
|
||||
className="max-w-full max-h-[180px] object-contain"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-muted/50">
|
||||
<tr>
|
||||
<th className="border-b px-3 py-2 text-left">검사항목</th>
|
||||
<th className="border-b px-3 py-2 text-left">검사방법</th>
|
||||
<th className="border-b px-3 py-2 text-left">포인트</th>
|
||||
{/* 검사기준 이미지 또는 검사 항목 테이블 */}
|
||||
<div className="border rounded-lg overflow-hidden min-h-[200px] flex items-center justify-center bg-muted/30">
|
||||
{inspectionSetting.inspectionStandardImage ? (
|
||||
<img
|
||||
src={inspectionSetting.inspectionStandardImage}
|
||||
alt="검사기준 이미지"
|
||||
className="max-w-full max-h-[180px] object-contain"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-muted/50">
|
||||
<tr>
|
||||
<th className="border-b px-3 py-2 text-left">검사항목</th>
|
||||
<th className="border-b px-3 py-2 text-left">검사방법</th>
|
||||
<th className="border-b px-3 py-2 text-left">포인트</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<tr key={item.key} className="border-b last:border-b-0">
|
||||
<td className="px-3 py-2">{item.label}</td>
|
||||
<td className="px-3 py-2">양자택일</td>
|
||||
<td className="px-3 py-2">-</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<tr key={item.key} className="border-b last:border-b-0">
|
||||
<td className="px-3 py-2">{item.label}</td>
|
||||
<td className="px-3 py-2">양자택일</td>
|
||||
<td className="px-3 py-2">-</td>
|
||||
</tr>
|
||||
))}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<tr key={item.key} className="border-b last:border-b-0">
|
||||
<td className="px-3 py-2">{item.label}</td>
|
||||
<td className="px-3 py-2">{item.method}</td>
|
||||
<td className="px-3 py-2">{item.point}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<tr key={item.key} className="border-b last:border-b-0">
|
||||
<td className="px-3 py-2">{item.label}</td>
|
||||
<td className="px-3 py-2">{item.method}</td>
|
||||
<td className="px-3 py-2">{item.point}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 중간검사 DATA */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-b">
|
||||
중간검사 DATA
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-muted/50">
|
||||
<tr>
|
||||
<th className="border-b border-r px-3 py-2 text-center w-12">No.</th>
|
||||
{/* 겉모양 항목들 */}
|
||||
{/* 중간검사 DATA */}
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-b">
|
||||
중간검사 DATA
|
||||
</div>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-muted/50">
|
||||
<tr>
|
||||
<th className="border-b border-r px-3 py-2 text-center w-12">No.</th>
|
||||
{/* 겉모양 항목들 */}
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<th
|
||||
key={item.key}
|
||||
className="border-b border-r px-3 py-2 text-center min-w-[80px]"
|
||||
>
|
||||
{item.label}
|
||||
</th>
|
||||
))}
|
||||
{/* 치수 항목들 */}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<th
|
||||
key={item.key}
|
||||
className="border-b border-r px-3 py-2 text-center"
|
||||
colSpan={2}
|
||||
>
|
||||
{item.label} (mm)
|
||||
</th>
|
||||
))}
|
||||
{/* 판정 */}
|
||||
{inspectionSetting.judgment && (
|
||||
<th className="border-b px-3 py-2 text-center w-20">
|
||||
판정
|
||||
<br />
|
||||
<span className="text-xs">(적/부)</span>
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
{/* 치수 서브헤더 */}
|
||||
{activeDimensionItems.length > 0 && (
|
||||
<tr className="bg-muted/30">
|
||||
<th className="border-b border-r px-3 py-1"></th>
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<th
|
||||
key={item.key}
|
||||
className="border-b border-r px-3 py-2 text-center min-w-[80px]"
|
||||
>
|
||||
{item.label}
|
||||
<th key={item.key} className="border-b border-r px-3 py-1 text-xs">
|
||||
양호/불량
|
||||
</th>
|
||||
))}
|
||||
{/* 치수 항목들 */}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<th
|
||||
key={item.key}
|
||||
className="border-b border-r px-3 py-2 text-center"
|
||||
colSpan={2}
|
||||
>
|
||||
{item.label} (mm)
|
||||
</th>
|
||||
<Fragment key={`${item.key}-header`}>
|
||||
<th className="border-b border-r px-3 py-1 text-xs">
|
||||
도면치수
|
||||
</th>
|
||||
<th className="border-b border-r px-3 py-1 text-xs">
|
||||
측정값
|
||||
</th>
|
||||
</Fragment>
|
||||
))}
|
||||
{/* 판정 */}
|
||||
{inspectionSetting.judgment && (
|
||||
<th className="border-b px-3 py-2 text-center w-20">
|
||||
판정
|
||||
<br />
|
||||
<span className="text-xs">(적/부)</span>
|
||||
</th>
|
||||
<th className="border-b px-3 py-1"></th>
|
||||
)}
|
||||
</tr>
|
||||
{/* 치수 서브헤더 */}
|
||||
{activeDimensionItems.length > 0 && (
|
||||
<tr className="bg-muted/30">
|
||||
<th className="border-b border-r px-3 py-1"></th>
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<th key={item.key} className="border-b border-r px-3 py-1 text-xs">
|
||||
양호/불량
|
||||
</th>
|
||||
))}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<Fragment key={`${item.key}-header`}>
|
||||
<th className="border-b border-r px-3 py-1 text-xs">
|
||||
도면치수
|
||||
</th>
|
||||
<th className="border-b border-r px-3 py-1 text-xs">
|
||||
측정값
|
||||
</th>
|
||||
</Fragment>
|
||||
))}
|
||||
{inspectionSetting.judgment && (
|
||||
<th className="border-b px-3 py-1"></th>
|
||||
)}
|
||||
</tr>
|
||||
)}
|
||||
</thead>
|
||||
<tbody>
|
||||
{sampleRows.map((row) => (
|
||||
<tr key={row} className="border-b last:border-b-0 hover:bg-muted/20">
|
||||
<td className="border-r px-3 py-2 text-center">{row}</td>
|
||||
{/* 겉모양 샘플 데이터 */}
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<td key={item.key} className="border-r px-3 py-2 text-center">
|
||||
<span className="text-muted-foreground">☐ 양호</span>
|
||||
<br />
|
||||
<span className="text-muted-foreground">☐ 불량</span>
|
||||
)}
|
||||
</thead>
|
||||
<tbody>
|
||||
{sampleRows.map((row) => (
|
||||
<tr key={row} className="border-b last:border-b-0 hover:bg-muted/20">
|
||||
<td className="border-r px-3 py-2 text-center">{row}</td>
|
||||
{/* 겉모양 샘플 데이터 */}
|
||||
{activeAppearanceItems.map((item) => (
|
||||
<td key={item.key} className="border-r px-3 py-2 text-center">
|
||||
<span className="text-muted-foreground">☐ 양호</span>
|
||||
<br />
|
||||
<span className="text-muted-foreground">☐ 불량</span>
|
||||
</td>
|
||||
))}
|
||||
{/* 치수 샘플 데이터 */}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<Fragment key={`${item.key}-data-${row}`}>
|
||||
<td className="border-r px-3 py-2 text-center text-muted-foreground">
|
||||
-
|
||||
</td>
|
||||
))}
|
||||
{/* 치수 샘플 데이터 */}
|
||||
{activeDimensionItems.map((item) => (
|
||||
<Fragment key={`${item.key}-data-${row}`}>
|
||||
<td className="border-r px-3 py-2 text-center text-muted-foreground">
|
||||
-
|
||||
</td>
|
||||
<td className="border-r px-3 py-2 text-center text-muted-foreground">
|
||||
-
|
||||
</td>
|
||||
</Fragment>
|
||||
))}
|
||||
{/* 판정 샘플 */}
|
||||
{inspectionSetting.judgment && (
|
||||
<td className="px-3 py-2 text-center">
|
||||
<span className="text-muted-foreground">-</span>
|
||||
<td className="border-r px-3 py-2 text-center text-muted-foreground">
|
||||
-
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</Fragment>
|
||||
))}
|
||||
{/* 판정 샘플 */}
|
||||
{inspectionSetting.judgment && (
|
||||
<td className="px-3 py-2 text-center">
|
||||
<span className="text-muted-foreground">-</span>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 부적합 내용 */}
|
||||
{inspectionSetting.nonConformingContent && (
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="grid grid-cols-2">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-r">
|
||||
부적합 내용
|
||||
</div>
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm">
|
||||
종합판정
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2">
|
||||
<div className="px-4 py-3 border-r min-h-[60px] text-muted-foreground text-sm">
|
||||
(부적합 사항 입력 영역)
|
||||
</div>
|
||||
<div className="px-4 py-3 text-center text-muted-foreground text-sm">
|
||||
합격 / 불합격
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 부적합 내용 */}
|
||||
{inspectionSetting.nonConformingContent && (
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
<div className="grid grid-cols-2">
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm border-r">
|
||||
부적합 내용
|
||||
</div>
|
||||
<div className="bg-muted/50 px-4 py-2 font-semibold text-sm">
|
||||
종합판정
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2">
|
||||
<div className="px-4 py-3 border-r min-h-[60px] text-muted-foreground text-sm">
|
||||
(부적합 사항 입력 영역)
|
||||
</div>
|
||||
<div className="px-4 py-3 text-center text-muted-foreground text-sm">
|
||||
합격 / 불합격
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 버튼 영역 */}
|
||||
<div className="flex justify-end mt-6">
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
||||
닫기
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)}
|
||||
</div>
|
||||
</DocumentViewer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { PageHeader } from '@/components/organisms/PageHeader';
|
||||
import { useMenuStore } from '@/store/menuStore';
|
||||
import { useMenuStore } from '@/stores/menuStore';
|
||||
import { usePermission } from '@/hooks/usePermission';
|
||||
import { toast } from 'sonner';
|
||||
import { DeleteConfirmDialog } from '@/components/ui/confirm-dialog';
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { PageLayout } from '@/components/organisms/PageLayout';
|
||||
import { PageHeader } from '@/components/organisms/PageHeader';
|
||||
import { useMenuStore } from '@/store/menuStore';
|
||||
import { useMenuStore } from '@/stores/menuStore';
|
||||
import { usePermission } from '@/hooks/usePermission';
|
||||
import { deleteProcessStep } from './actions';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
Reference in New Issue
Block a user