feat: [subscription] 구독관리 리팩토링 + 사용량 페이지 추가

- 구독관리 UI/로직 대폭 개선
- 사용량 페이지 신규 추가
- 입고관리 액션 정리
This commit is contained in:
유병철
2026-03-18 13:59:54 +09:00
parent b3c1ca6a97
commit e8fafaf5f4
9 changed files with 494 additions and 396 deletions

View File

@@ -787,6 +787,7 @@ export function ReceivingDetail({ id, mode = 'view' }: Props) {
specification: item.specification || '',
}));
}}
itemType="RM,SM,CS"
/>
<SupplierSearchModal

View File

@@ -683,58 +683,6 @@ export async function processReceiving(
return { success: result.success, data: result.data, error: result.error };
}
// ===== 품목 검색 (입고 등록용) =====
export interface ItemOption {
value: string; // itemCode
label: string; // itemCode 표시
description?: string; // 품목명 + 규격
itemName: string;
specification: string;
unit: string;
}
const MOCK_ITEMS: ItemOption[] = [
{ value: 'STEEL-001', label: 'STEEL-001', description: 'SUS304 스테인리스 판재 (1000x2000x3T)', itemName: 'SUS304 스테인리스 판재', specification: '1000x2000x3T', unit: 'EA' },
{ value: 'STEEL-002', label: 'STEEL-002', description: '알루미늄 프로파일 (40x40x2000L)', itemName: '알루미늄 프로파일', specification: '40x40x2000L', unit: 'EA' },
{ value: 'ELEC-002', label: 'ELEC-002', description: 'MCU 컨트롤러 IC (STM32F103C8T6)', itemName: 'MCU 컨트롤러 IC', specification: 'STM32F103C8T6', unit: 'EA' },
{ value: 'ELEC-005', label: 'ELEC-005', description: 'DC 모터 24V (24V 100RPM)', itemName: 'DC 모터 24V', specification: '24V 100RPM', unit: 'EA' },
{ value: 'ELEC-007', label: 'ELEC-007', description: '커패시터 100uF (100uF 50V)', itemName: '커패시터 100uF', specification: '100uF 50V', unit: 'EA' },
{ value: 'PLAS-003', label: 'PLAS-003', description: 'ABS 사출 케이스 (150x100x50)', itemName: 'ABS 사출 케이스', specification: '150x100x50', unit: 'SET' },
{ value: 'CHEM-001', label: 'CHEM-001', description: '에폭시 접착제 (500ml)', itemName: '에폭시 접착제', specification: '500ml', unit: 'EA' },
{ value: 'BOLT-001', label: 'BOLT-001', description: 'SUS 볼트 M8x30 (M8x30 SUS304)', itemName: 'SUS 볼트 M8x30', specification: 'M8x30 SUS304', unit: 'EA' },
];
export async function searchItems(query?: string): Promise<{
success: boolean;
data: ItemOption[];
}> {
if (USE_MOCK_DATA) {
if (!query) return { success: true, data: MOCK_ITEMS };
const q = query.toLowerCase();
const filtered = MOCK_ITEMS.filter(
(item) =>
item.value.toLowerCase().includes(q) ||
item.itemName.toLowerCase().includes(q)
);
return { success: true, data: filtered };
}
interface ItemApiData { data: Array<Record<string, string>> }
const result = await executeServerAction<ItemApiData, ItemOption[]>({
url: buildApiUrl('/api/v1/items', { search: query, per_page: 200, item_type: 'RM,SM,CS' }),
transform: (d) => (d.data || []).map((item) => ({
value: item.item_code,
label: item.item_code,
description: `${item.item_name} (${item.specification || '-'})`,
itemName: item.item_name,
specification: item.specification || '',
unit: item.unit || 'EA',
})),
errorMessage: '품목 검색에 실패했습니다.',
});
return { success: result.success, data: result.data || [] };
}
// ===== 발주처 검색 (입고 등록용) =====
export interface SupplierOption {
value: string;