feat(WEB): DevToolbar - 견적→수주→작업지시→출하 테스트 자동화 도구

- DevFillContext: 전역 상태 관리 (활성화/페이지 타입/폼 채우기 함수)
- DevToolbar: 플로팅 UI 컴포넌트 (토글/자동 채우기 버튼)
- useDevFill: 각 폼에서 자동 채우기 함수 등록 커스텀 훅
- 데이터 생성기: 견적/수주/작업지시/출하 샘플 데이터
- 환경변수 제어: NEXT_PUBLIC_DEV_TOOLBAR_ENABLED로 On/Off
- 통합: QuoteRegistration, OrderRegistration, WorkOrderCreate, ShipmentCreate
- Hydration 불일치 방지: useState 초기값 false + useEffect 패턴
This commit is contained in:
2026-01-20 20:38:29 +09:00
parent c101b8bf7e
commit eae23d4457
15 changed files with 1048 additions and 5 deletions

View File

@@ -55,6 +55,8 @@ import { type QuotationForSelect, type QuotationItem } from "./actions";
import { ItemAddDialog, OrderItem } from "./ItemAddDialog";
import { formatAmount } from "@/utils/formatAmount";
import { cn } from "@/lib/utils";
import { useDevFill } from "@/components/dev";
import { generateOrderDataFull } from "@/components/dev/generators/orderData";
// 수주 폼 데이터 타입
export interface OrderFormData {
@@ -209,6 +211,24 @@ export function OrderRegistration({
}));
}, [form.items, form.discountRate]);
// DevToolbar 자동 채우기
useDevFill(
'order',
useCallback(() => {
const sampleData = generateOrderDataFull();
// 거래처 목록에서 실제 데이터 사용
if (clients.length > 0) {
const randomClient = clients[Math.floor(Math.random() * clients.length)];
sampleData.clientId = randomClient.id;
sampleData.clientName = randomClient.name;
}
setForm(sampleData);
toast.success('[Dev] 수주 폼이 자동으로 채워졌습니다.');
}, [clients])
);
// 견적 선택 핸들러
const handleQuotationSelect = (quotation: QuotationForSelect) => {
// 견적 정보로 폼 자동 채우기 (견적에서 가져온 품목은 삭제 불가)