fix: 빌드 오류 수정 및 출고관리 컴포넌트 추가
- ShippingManagement.tsx 컴포넌트 생성 (출고관리 기능) - sonner import 오류 수정 (sonner@2.0.3 → sonner) - lucide-react 중복 import 제거 (Calculator, FileText, Palette) - vite.config.ts 서버 포트 3002로 변경 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
12
src/App.tsx
12
src/App.tsx
@@ -140,9 +140,11 @@ import {
|
|||||||
User,
|
User,
|
||||||
Database,
|
Database,
|
||||||
FileText,
|
FileText,
|
||||||
|
FileText as FileTextIcon,
|
||||||
BarChart3,
|
BarChart3,
|
||||||
ShoppingCart,
|
ShoppingCart,
|
||||||
Calculator,
|
Calculator,
|
||||||
|
Calculator as CalculatorIcon,
|
||||||
Truck,
|
Truck,
|
||||||
Car,
|
Car,
|
||||||
MessageSquare,
|
MessageSquare,
|
||||||
@@ -173,12 +175,9 @@ import {
|
|||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Box,
|
Box,
|
||||||
FileText,
|
|
||||||
FileText as FileTextIcon,
|
|
||||||
Archive as ArchiveIcon,
|
|
||||||
Calculator as CalculatorIcon,
|
|
||||||
Tag,
|
|
||||||
Archive,
|
Archive,
|
||||||
|
Archive as ArchiveIcon,
|
||||||
|
Tag,
|
||||||
Calendar,
|
Calendar,
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
Building,
|
Building,
|
||||||
@@ -188,7 +187,6 @@ import {
|
|||||||
FileCheck,
|
FileCheck,
|
||||||
Edit,
|
Edit,
|
||||||
MapPin,
|
MapPin,
|
||||||
Palette,
|
|
||||||
TestTube,
|
TestTube,
|
||||||
Hash,
|
Hash,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
@@ -198,7 +196,7 @@ import { Input } from "./components/ui/input";
|
|||||||
import { Badge } from "./components/ui/badge";
|
import { Badge } from "./components/ui/badge";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./components/ui/dropdown-menu";
|
||||||
import { Toaster } from "./components/ui/sonner";
|
import { Toaster } from "./components/ui/sonner";
|
||||||
import { toast } from "sonner@2.0.3";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
const getMenuItems = (userRole: string) => {
|
const getMenuItems = (userRole: string) => {
|
||||||
if (userRole === "SystemAdmin") {
|
if (userRole === "SystemAdmin") {
|
||||||
|
|||||||
@@ -1,4 +1,256 @@
|
|||||||
// ShippingManagement - 출고관리 컴포넌트
|
import { useState } from "react";
|
||||||
// ShippingScheduleManagement를 ShippingManagement로 re-export
|
import { ListPageTemplate } from "./templates/ListPageTemplate";
|
||||||
|
import { Column } from "./organisms/DataTable";
|
||||||
|
import { Button } from "./ui/button";
|
||||||
|
import { Badge } from "./ui/badge";
|
||||||
|
import {
|
||||||
|
Plus,
|
||||||
|
Truck,
|
||||||
|
CheckCircle,
|
||||||
|
Clock,
|
||||||
|
AlertTriangle
|
||||||
|
} from "lucide-react";
|
||||||
|
|
||||||
export { ShippingScheduleManagement as ShippingManagement } from "./ShippingScheduleManagement";
|
interface ShippingRecord {
|
||||||
|
id: string;
|
||||||
|
shippingNumber: string;
|
||||||
|
lotNumber: string;
|
||||||
|
item: string;
|
||||||
|
spec: string;
|
||||||
|
unit: string;
|
||||||
|
quantity: number;
|
||||||
|
weight: string;
|
||||||
|
destination: string;
|
||||||
|
requestDate: string;
|
||||||
|
shippingDate: string;
|
||||||
|
status: string;
|
||||||
|
managerApproval: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShippingManagement() {
|
||||||
|
const [shippingView, setShippingView] = useState<"list" | "write">("list");
|
||||||
|
|
||||||
|
const shippingList: ShippingRecord[] = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
shippingNumber: "SHP-250723-001",
|
||||||
|
lotNumber: "250723-04",
|
||||||
|
item: "EGIT-SST",
|
||||||
|
spec: "1219*3500",
|
||||||
|
unit: "EA",
|
||||||
|
quantity: 50,
|
||||||
|
weight: "2,600",
|
||||||
|
destination: "생산1라인",
|
||||||
|
requestDate: "2025-07-23",
|
||||||
|
shippingDate: "2025-07-23",
|
||||||
|
status: "출고완료",
|
||||||
|
managerApproval: "승인완료"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
shippingNumber: "SHP-250722-003",
|
||||||
|
lotNumber: "250716-01",
|
||||||
|
item: "용강코일",
|
||||||
|
spec: "EGIT-SST(W)350",
|
||||||
|
unit: "롤",
|
||||||
|
quantity: 3,
|
||||||
|
weight: "3,070",
|
||||||
|
destination: "생산2라인",
|
||||||
|
requestDate: "2025-07-22",
|
||||||
|
shippingDate: "2025-07-22",
|
||||||
|
status: "출고완료",
|
||||||
|
managerApproval: "승인완료"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "3",
|
||||||
|
shippingNumber: "SHP-250724-001",
|
||||||
|
lotNumber: "-",
|
||||||
|
item: "베링용장",
|
||||||
|
spec: "3808",
|
||||||
|
unit: "EA",
|
||||||
|
quantity: 100,
|
||||||
|
weight: "-",
|
||||||
|
destination: "조립라인",
|
||||||
|
requestDate: "2025-07-24",
|
||||||
|
shippingDate: "-",
|
||||||
|
status: "출고대기",
|
||||||
|
managerApproval: "대기"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "4",
|
||||||
|
shippingNumber: "SHP-250724-002",
|
||||||
|
lotNumber: "250720-02",
|
||||||
|
item: "알루미늄판",
|
||||||
|
spec: "1000*2000*2T",
|
||||||
|
unit: "장",
|
||||||
|
quantity: 20,
|
||||||
|
weight: "108",
|
||||||
|
destination: "가공라인",
|
||||||
|
requestDate: "2025-07-24",
|
||||||
|
shippingDate: "-",
|
||||||
|
status: "승인대기",
|
||||||
|
managerApproval: "대기"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const getStatusBadgeVariant = (status: string): "default" | "secondary" | "destructive" | "outline" => {
|
||||||
|
switch (status) {
|
||||||
|
case "출고완료":
|
||||||
|
case "승인완료":
|
||||||
|
return "default";
|
||||||
|
case "출고취소":
|
||||||
|
case "반려":
|
||||||
|
return "destructive";
|
||||||
|
case "대기":
|
||||||
|
case "출고대기":
|
||||||
|
case "승인대기":
|
||||||
|
return "secondary";
|
||||||
|
default:
|
||||||
|
return "outline";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusIcon = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case "출고완료":
|
||||||
|
case "승인완료":
|
||||||
|
return <CheckCircle className="w-3 h-3 mr-1" />;
|
||||||
|
case "대기":
|
||||||
|
case "출고대기":
|
||||||
|
case "승인대기":
|
||||||
|
return <Clock className="w-3 h-3 mr-1" />;
|
||||||
|
case "출고취소":
|
||||||
|
case "반려":
|
||||||
|
return <AlertTriangle className="w-3 h-3 mr-1" />;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: Column<ShippingRecord>[] = [
|
||||||
|
{
|
||||||
|
key: "shippingNumber",
|
||||||
|
label: "출고번호",
|
||||||
|
render: (value) => <span className="font-mono text-primary">{value}</span>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "lotNumber",
|
||||||
|
label: "로트번호",
|
||||||
|
render: (value) => <span className="font-mono">{value}</span>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "item",
|
||||||
|
label: "품목"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "spec",
|
||||||
|
label: "규격"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "quantity",
|
||||||
|
label: "수량",
|
||||||
|
render: (value, row) => `${value} ${row.unit}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "weight",
|
||||||
|
label: "중량(kg)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "destination",
|
||||||
|
label: "출고처"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "requestDate",
|
||||||
|
label: "요청일"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "shippingDate",
|
||||||
|
label: "출고일"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "status",
|
||||||
|
label: "상태",
|
||||||
|
render: (value) => (
|
||||||
|
<Badge variant={getStatusBadgeVariant(value as string)}>
|
||||||
|
{getStatusIcon(value as string)}
|
||||||
|
{value}
|
||||||
|
</Badge>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "managerApproval",
|
||||||
|
label: "팀장승인",
|
||||||
|
render: (value) => (
|
||||||
|
<Badge variant={getStatusBadgeVariant(value as string)}>
|
||||||
|
{getStatusIcon(value as string)}
|
||||||
|
{value}
|
||||||
|
</Badge>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListPageTemplate
|
||||||
|
title="출고 관리"
|
||||||
|
description="자재 출고 내역 및 관리"
|
||||||
|
icon={Truck}
|
||||||
|
actions={
|
||||||
|
<Button onClick={() => setShippingView("write")}>
|
||||||
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
|
출고 등록
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
searchPlaceholder=""
|
||||||
|
filterButton={false}
|
||||||
|
showSearch={false}
|
||||||
|
data={shippingList}
|
||||||
|
keyField="id"
|
||||||
|
columns={columns}
|
||||||
|
renderMobileCard={(item) => ({
|
||||||
|
title: item.item,
|
||||||
|
subtitle: item.spec,
|
||||||
|
icon: (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Badge variant="outline" className="font-mono text-xs">
|
||||||
|
{item.shippingNumber}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
badge: {
|
||||||
|
label: item.status,
|
||||||
|
variant: getStatusBadgeVariant(item.status)
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
label: "수량",
|
||||||
|
value: `${item.quantity} ${item.unit}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "중량",
|
||||||
|
value: `${item.weight} kg`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "출고처",
|
||||||
|
value: item.destination
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "요청일",
|
||||||
|
value: item.requestDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "출고일",
|
||||||
|
value: item.shippingDate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "팀장승인",
|
||||||
|
value: item.managerApproval
|
||||||
|
}
|
||||||
|
],
|
||||||
|
actions: []
|
||||||
|
})}
|
||||||
|
emptyIcon={Truck}
|
||||||
|
emptyTitle="출고 데이터가 없습니다"
|
||||||
|
emptyDescription="출고 내역을 등록해주세요"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
outDir: 'build',
|
outDir: 'build',
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3002,
|
||||||
open: true,
|
open: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user