import { useEffect, useState } from 'react' import { CheckCircle2 } from 'lucide-react' import { toast } from 'sonner' import { useMeQuery, useSaveExtraInfoMutation, getApiErrorMessage } from '@/apis' import type { SessionField } from '@/apis/auth/auth.type' import { useChatStore } from '@/features/chat/stores/useChatStore' import { useChatInitStore } from '@/features/chat/stores/useChatInitStore' // 협상 타결(Summary) 직후 부가정보 입력 폼. 필드 정의(session_fields)는 회사 설정(/me)에서 온다. // 저장하면 sessions.custom 에 기록되고 negodata 견적상세에 표시된다. 정의가 없으면 렌더하지 않는다. export function ExtraInfoForm() { const sessionId = useChatStore((s) => s.sessionId) const { data: user } = useMeQuery() const fields: SessionField[] = user?.sessionFields ?? [] const save = useSaveExtraInfoMutation() const existing = useChatInitStore((s) => s.custom) // 기존 입력값(재진입 프리필) const [values, setValues] = useState>({}) const [inited, setInited] = useState(false) const [saved, setSaved] = useState(false) // fields(회사 설정)와 기존값(sessions.custom)이 준비된 첫 시점에 프리필 — 이후 사용자 편집은 보존. useEffect(() => { if (inited || fields.length === 0) return const init: Record = {} for (const f of fields) init[f.key] = existing?.[f.key] ?? (f.type === 'boolean' ? false : '') setValues(init) setInited(true) }, [inited, fields, existing]) if (fields.length === 0) return null const set = (key: string, value: unknown) => setValues((v) => ({ ...v, [key]: value })) const handleSave = () => { const custom: Record = {} for (const f of fields) { const v = values[f.key] if (f.type === 'boolean') custom[f.key] = !!v else if (v !== '' && v != null) custom[f.key] = f.type === 'number' ? Number(v) : v } save.mutate( { sessionId, request: { custom } }, { onSuccess: () => { setSaved(true) toast.success('부가정보가 저장되었습니다.') }, onError: (error) => toast.error(getApiErrorMessage(error, '부가정보 저장에 실패했습니다.')), }, ) } return (

부가정보 입력

협상이 완료되었습니다. 아래 정보를 입력해 주세요. (저장 후에도 세션 목록에서 수정할 수 있습니다.)

{fields.map((f) => (
{f.type === 'boolean' ? ( ) : ( set(f.key, e.target.value)} disabled={saved} className="h-11 w-full rounded-xl border border-border bg-white px-3 text-sm outline-none focus:border-brand-600 focus:ring-1 focus:ring-brand-600 disabled:bg-neutral-10" placeholder={f.label} /> )}
))}
) }