fix: [stocks] 재고생산 상세 복원 버튼 제거, 목록 통계 카드 제거
- 상세 화면에서 불필요한 복원 버튼 제거 (삭제 버튼은 유지) - 목록 화면에서 통계 카드 4개(전체/등록/확정/생산중) 제거
This commit is contained in:
@@ -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)}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user