Merge remote-tracking branch 'origin/master'

This commit is contained in:
2026-01-20 19:48:21 +09:00
2 changed files with 53 additions and 20 deletions

View File

@@ -1,54 +1,71 @@
/** /**
* 견적 등록 테스트 페이지 (V2 UI) * 견적 등록 테스트 페이지 (V2 UI)
* *
* IntegratedDetailTemplate 마이그레이션 (2026-01-20)
* 새로운 자동 견적 산출 UI 테스트용 * 새로운 자동 견적 산출 UI 테스트용
* 기존 견적 등록 페이지는 수정하지 않음
*/ */
"use client"; 'use client';
import { useRouter } from "next/navigation"; import { useRouter } from 'next/navigation';
import { useState } from "react"; import { useState, useCallback } from 'react';
import { QuoteRegistrationV2, QuoteFormDataV2 } from "@/components/quotes/QuoteRegistrationV2"; import { QuoteRegistrationV2, QuoteFormDataV2 } from '@/components/quotes/QuoteRegistrationV2';
import { toast } from "sonner"; import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { quoteCreateConfig } from '@/components/quotes/quoteConfig';
import { toast } from 'sonner';
export default function QuoteTestNewPage() { export default function QuoteTestNewPage() {
const router = useRouter(); const router = useRouter();
const [isSaving, setIsSaving] = useState(false); const [isSaving, setIsSaving] = useState(false);
const handleBack = () => { const handleBack = useCallback(() => {
router.push("/sales/quote-management"); router.push('/sales/quote-management');
}; }, [router]);
const handleSave = async (data: QuoteFormDataV2, saveType: "temporary" | "final") => { const handleSave = useCallback(async (data: QuoteFormDataV2, saveType: 'temporary' | 'final') => {
setIsSaving(true); setIsSaving(true);
try { try {
// TODO: API 연동 시 실제 저장 로직 구현 // TODO: API 연동 시 실제 저장 로직 구현
console.log("[테스트] 저장 데이터:", data); console.log('[테스트] 저장 데이터:', data);
console.log("[테스트] 저장 타입:", saveType); console.log('[테스트] 저장 타입:', saveType);
// 테스트용 지연 // 테스트용 지연
await new Promise((resolve) => setTimeout(resolve, 1000)); await new Promise((resolve) => setTimeout(resolve, 1000));
toast.success(`[테스트] ${saveType === "temporary" ? "임시" : "최종"} 저장 완료`); toast.success(`[테스트] ${saveType === 'temporary' ? '임시' : '최종'} 저장 완료`);
// 저장 후 상세 페이지로 이동 (테스트용으로 ID=1 사용) // 저장 후 상세 페이지로 이동 (테스트용으로 ID=1 사용)
if (saveType === "final") { if (saveType === 'final') {
router.push("/sales/quote-management/test/1"); router.push('/sales/quote-management/test/1');
} }
} catch (error) { } catch (error) {
toast.error("저장 중 오류가 발생했습니다."); toast.error('저장 중 오류가 발생했습니다.');
} finally { } finally {
setIsSaving(false); setIsSaving(false);
} }
}; }, [router]);
// 폼 콘텐츠 렌더링
const renderFormContent = useCallback(() => {
return (
<QuoteRegistrationV2
mode="create"
onBack={handleBack}
onSave={handleSave}
isLoading={isSaving}
hideHeader={true}
/>
);
}, [handleBack, handleSave, isSaving]);
return ( return (
<QuoteRegistrationV2 <IntegratedDetailTemplate
config={quoteCreateConfig}
mode="create" mode="create"
isLoading={false}
isSubmitting={isSaving}
onBack={handleBack} onBack={handleBack}
onSave={handleSave} renderForm={renderFormContent}
isLoading={isSaving}
/> />
); );
} }

View File

@@ -27,3 +27,19 @@ export const quoteConfig: DetailConfig = {
backLabel: '목록', backLabel: '목록',
}, },
}; };
/**
* 견적 등록 페이지 Config
*/
export const quoteCreateConfig: DetailConfig = {
title: '견적',
description: '새 견적을 등록합니다',
icon: FileText,
basePath: '/sales/quote-management',
fields: [],
actions: {
showBack: true,
showSave: false, // QuoteFooterBar에서 처리
backLabel: '목록',
},
};