import { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import { useAppPath } from '@core/hooks/useAppPath' import { apiFetch } from '@core/lib/api' const STAGES = ['prospecting', 'qualification', 'proposal', 'negotiation', 'closed_won', 'closed_lost'] const SOURCES = ['inbound', 'outbound', 'referral', 'event', 'paid', 'organic'] interface DealForm { title: string stage: string value: string close_date: string probability: string source: string } const EMPTY: DealForm = { title: '', stage: 'prospecting', value: '', close_date: '', probability: '', source: '' } export default function DealDetailPage() { const { id } = useParams<{ id: string }>() const navigate = useNavigate() const appPath = useAppPath() const isNew = !id || id === 'new' const [form, setForm] = useState(EMPTY) const [loading, setLoading] = useState(!isNew) const [saving, setSaving] = useState(false) const [error, setError] = useState(null) useEffect(() => { if (isNew) return apiFetch(`/api/admin-data?action=get&entity=items&id=${id}`) .then(r => r.json()) .then(raw => { const json = raw?.data ?? raw if (json) { setForm({ title: json.title || '', stage: json.data?.stage || 'prospecting', value: json.data?.value?.toString() || '', close_date: json.data?.close_date || '', probability: json.data?.probability?.toString() || '', source: json.data?.source || '', }) } }) .catch(() => setError('Failed to load deal')) .finally(() => setLoading(false)) }, [id, isNew]) const handleSave = async () => { if (!form.title.trim()) { setError('Title is required'); return } setSaving(true) setError(null) try { const payload = { title: form.title.trim(), type_slug: 'deal', data: { stage: form.stage, value: form.value ? Number(form.value) : null, close_date: form.close_date || null, probability: form.probability ? Number(form.probability) : null, source: form.source || null, }, } let res: Response if (isNew) { res = await apiFetch('/api/admin-data?action=create&entity=items', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) } else { res = await apiFetch(`/api/admin-data?action=update&entity=items&id=${id}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) } if (!res.ok) { const e = await res.json(); throw new Error(e?.error || 'Save failed') } const saved = await res.json() navigate(`/crm/deals/${isNew ? saved.id : id}`) } catch (e: any) { setError(e.message) } finally { setSaving(false) } } const handleDelete = async () => { if (!confirm('Delete this deal?')) return await apiFetch(`/api/admin-data?action=delete&entity=items&id=${id}`, { method: 'POST' }) navigate(appPath('/crm/deals')) } const set = (field: keyof DealForm) => (e: React.ChangeEvent) => setForm(f => ({ ...f, [field]: e.target.value })) if (loading) return
Loading…
return (

{isNew ? 'New Deal' : 'Edit Deal'}

{error &&
{error}
}

Deal Info

Financials

{!isNew ? ( ) :
}
) }