fix: [stocks] 재고생산 상세 복원 버튼 제거, 목록 통계 카드 제거

- 상세 화면에서 불필요한 복원 버튼 제거 (삭제 버튼은 유지)
- 목록 화면에서 통계 카드 4개(전체/등록/확정/생산중) 제거
This commit is contained in:
김보곤
2026-03-18 22:05:13 +09:00
parent 3e06f3ea92
commit be9dd6f42d
2 changed files with 2 additions and 98 deletions

View File

@@ -7,7 +7,7 @@
* - 기본 정보, 품목 선택, LOT 정보, 메모 섹션
*/
import { useState, useEffect, useMemo, useCallback } from 'react';
import { useState, useEffect, useMemo } from 'react';
import { useRouter, useParams } from 'next/navigation';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
@@ -18,7 +18,6 @@ import {
MessageSquare,
Tag,
Layers,
RotateCcw,
} from 'lucide-react';
import { toast } from 'sonner';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
@@ -27,14 +26,11 @@ import { BadgeSm } from '@/components/atoms/BadgeSm';
import {
getStockOrderById,
getBendingCodeMap,
updateStockOrderStatus,
deleteStockOrder,
type StockOrder,
type StockStatus,
type BendingCodeMap,
} from './actions';
import type { DetailConfig } from '@/components/templates/IntegratedDetailTemplate/types';
import type { ActionItem } from '@/components/templates/IntegratedDetailTemplate/types';
// ============================================================================
// Config
@@ -94,7 +90,6 @@ export function StockProductionDetail({ orderId }: StockProductionDetailProps) {
const [order, setOrder] = useState<StockOrder | null>(null);
const [codeMap, setCodeMap] = useState<BendingCodeMap | null>(null);
const [loading, setLoading] = useState(true);
const [isProcessing, setIsProcessing] = useState(false);
// 데이터 로드
useEffect(() => {
@@ -148,44 +143,6 @@ export function StockProductionDetail({ orderId }: StockProductionDetailProps) {
// 연기차단재 여부
const isSmokeBarrier = order?.bendingLot?.prodCode === 'G';
// 상태 변경
const handleStatusChange = useCallback(async (newStatus: StockStatus) => {
if (!order) return;
setIsProcessing(true);
try {
const result = await updateStockOrderStatus(order.id, newStatus);
if (result.__authError) {
toast.error('인증이 만료되었습니다.');
return;
}
if (result.success && result.data) {
setOrder(result.data);
toast.success('상태가 변경되었습니다.');
} else {
toast.error(result.error || '상태 변경에 실패했습니다.');
}
} finally {
setIsProcessing(false);
}
}, [order]);
// 헤더 액션 버튼
const headerActionItems = useMemo((): ActionItem[] => {
if (!order) return [];
const items: ActionItem[] = [];
if (order.status === 'cancelled') {
items.push({
icon: RotateCcw,
label: '복원',
onClick: () => handleStatusChange('draft'),
className: 'bg-blue-600 hover:bg-blue-500 text-white',
disabled: isProcessing,
});
}
return items;
}, [order, isProcessing, handleStatusChange]);
// 품목 정보 (첫 번째 아이템)
const item = order?.items?.[0];
@@ -327,7 +284,6 @@ export function StockProductionDetail({ orderId }: StockProductionDetailProps) {
return { success: result.success, error: result.error };
}}
headerActions={null}
headerActionItems={headerActionItems}
renderView={(data) => renderViewContent(data as unknown as StockOrder)}
/>
</>

View File

@@ -17,10 +17,6 @@ import {
Edit,
Eye,
Loader2,
ClipboardList,
CheckCircle,
Clock,
Archive,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
@@ -38,12 +34,10 @@ import { ListMobileCard, InfoField } from "@/components/organisms/MobileCard";
import { DeleteConfirmDialog } from "@/components/ui/confirm-dialog";
import {
getStockOrders,
getStockOrderStats,
deleteStockOrder,
deleteStockOrders,
type StockOrder,
type StockStatus,
type StockOrderStats,
} from "./actions";
// 상태 뱃지
@@ -100,27 +94,19 @@ export function StockProductionList() {
// API 데이터
const [orders, setOrders] = useState<StockOrder[]>([]);
const [apiStats, setApiStats] = useState<StockOrderStats | null>(null);
const [isLoading, setIsLoading] = useState(true);
// 데이터 로드
const loadData = useCallback(async () => {
try {
setIsLoading(true);
const [ordersResult, statsResult] = await Promise.all([
getStockOrders(),
getStockOrderStats(),
]);
const ordersResult = await getStockOrders();
if (ordersResult.success && ordersResult.data) {
setOrders(ordersResult.data.items);
} else {
toast.error(ordersResult.error || "재고생산 목록을 불러오는데 실패했습니다.");
}
if (statsResult.success && statsResult.data) {
setApiStats(statsResult.data);
}
} catch (error) {
console.error("Error loading stock orders:", error);
toast.error("데이터를 불러오는 중 오류가 발생했습니다.");
@@ -150,34 +136,6 @@ export function StockProductionList() {
})
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
// 통계
const stats = [
{
label: "전체",
value: `${apiStats?.total ?? orders.length}`,
icon: Archive,
iconColor: "text-gray-600",
},
{
label: "등록",
value: `${apiStats?.draft ?? 0}`,
icon: Clock,
iconColor: "text-gray-600",
},
{
label: "확정",
value: `${apiStats?.confirmed ?? 0}`,
icon: CheckCircle,
iconColor: "text-blue-600",
},
{
label: "생산중",
value: `${apiStats?.inProgress ?? 0}`,
icon: ClipboardList,
iconColor: "text-green-600",
},
];
// 핸들러
const handleView = (order: StockOrder) => {
router.push(`/sales/stocks/${order.id}?mode=view`);
@@ -202,8 +160,6 @@ export function StockProductionList() {
setOrders(orders.filter((o) => o.id !== deleteTargetIds[0]));
setSelectedItems(new Set());
toast.success("재고생산이 삭제되었습니다.");
const statsResult = await getStockOrderStats();
if (statsResult.success && statsResult.data) setApiStats(statsResult.data);
} else {
toast.error(result.error || "삭제에 실패했습니다.");
}
@@ -215,8 +171,6 @@ export function StockProductionList() {
setSelectedItems(new Set());
if (result.deletedCount) toast.success(`${result.deletedCount}개 삭제되었습니다.`);
if (result.skippedCount) toast.warning(`${result.skippedCount}개는 삭제할 수 없습니다.`);
const statsResult = await getStockOrderStats();
if (statsResult.success && statsResult.data) setApiStats(statsResult.data);
} else {
toast.error(result.error || "삭제에 실패했습니다.");
}
@@ -394,8 +348,6 @@ export function StockProductionList() {
const result = await deleteStockOrder(id);
if (result.success) {
setOrders((prev) => prev.filter((o) => o.id !== id));
const statsResult = await getStockOrderStats();
if (statsResult.success && statsResult.data) setApiStats(statsResult.data);
}
return result;
},
@@ -404,8 +356,6 @@ export function StockProductionList() {
if (result.success) {
const skippedSet = new Set((result.skippedIds ?? []).map(String));
setOrders((prev) => prev.filter((o) => skippedSet.has(o.id) || !ids.includes(o.id)));
const statsResult = await getStockOrderStats();
if (statsResult.success && statsResult.data) setApiStats(statsResult.data);
}
return result;
},
@@ -413,8 +363,6 @@ export function StockProductionList() {
columns: tableColumns,
computeStats: () => stats,
searchPlaceholder: "생산번호, 품목명, 로트번호 검색...",
dateRangeSelector: {