feat: 생산/품질/자재/출고/주문 관리 페이지 구현
- 생산관리: 대시보드, 작업지시, 작업실적, 작업자화면 - 품질관리: 검사관리 (리스트/등록/상세) - 자재관리: 입고관리, 재고현황 - 출고관리: 출하관리 (리스트/등록/상세/수정) - 주문관리: 수주관리, 생산의뢰 - 기존 컴포넌트 개선: CardTransactionInquiry, VendorDetail, QuoteRegistration - IntegratedListTemplateV2 개선 - 공통 컴포넌트 분석 문서 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
112
src/components/production/WorkOrders/SalesOrderSelectModal.tsx
Normal file
112
src/components/production/WorkOrders/SalesOrderSelectModal.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
'use client';
|
||||
|
||||
/**
|
||||
* 수주 선택 모달
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import { Search, X, FileText } from 'lucide-react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { mockSalesOrders } from './mockData';
|
||||
import type { SalesOrder } from './types';
|
||||
|
||||
interface SalesOrderSelectModalProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
onSelect: (order: SalesOrder) => void;
|
||||
}
|
||||
|
||||
export function SalesOrderSelectModal({
|
||||
open,
|
||||
onOpenChange,
|
||||
onSelect,
|
||||
}: SalesOrderSelectModalProps) {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
|
||||
// 필터링된 수주 목록
|
||||
const filteredOrders = mockSalesOrders.filter((order) => {
|
||||
if (!searchTerm) return true;
|
||||
const term = searchTerm.toLowerCase();
|
||||
return (
|
||||
order.orderNo.toLowerCase().includes(term) ||
|
||||
order.client.toLowerCase().includes(term) ||
|
||||
order.projectName.toLowerCase().includes(term)
|
||||
);
|
||||
});
|
||||
|
||||
const handleSelect = (order: SalesOrder) => {
|
||||
onSelect(order);
|
||||
onOpenChange(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle>수주 선택</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{/* 검색 */}
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
|
||||
<Input
|
||||
placeholder="수주번호, 거래처, 현장명 검색..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="pl-9"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 안내 문구 */}
|
||||
<p className="text-sm text-muted-foreground">
|
||||
생산지시 가능한 수주 {filteredOrders.length}건 (회계확인 완료 상태)
|
||||
</p>
|
||||
|
||||
{/* 수주 목록 */}
|
||||
<div className="max-h-[400px] overflow-y-auto space-y-2">
|
||||
{filteredOrders.map((order) => (
|
||||
<div
|
||||
key={order.id}
|
||||
onClick={() => handleSelect(order)}
|
||||
className="p-4 border rounded-lg cursor-pointer hover:bg-muted/50 transition-colors"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-semibold">{order.orderNo}</span>
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
{order.status}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="text-sm text-right">
|
||||
<span className="text-muted-foreground">납기: </span>
|
||||
<span>{order.dueDate}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground mb-1">
|
||||
{order.client}
|
||||
</div>
|
||||
<div className="text-sm mb-2">{order.projectName}</div>
|
||||
<div className="flex items-center gap-4 text-xs text-muted-foreground">
|
||||
<span>{order.itemCount}개 품목</span>
|
||||
<span>분할 {order.splitCount}건</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{filteredOrders.length === 0 && (
|
||||
<div className="py-8 text-center text-muted-foreground">
|
||||
<FileText className="w-8 h-8 mx-auto mb-2 opacity-50" />
|
||||
<p>검색 결과가 없습니다.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user