diff --git a/fe-admin/src/components/pe/PeWorkspaceCreateView.tsx b/fe-admin/src/components/pe/PeWorkspaceCreateView.tsx new file mode 100644 index 0000000..3f91927 --- /dev/null +++ b/fe-admin/src/components/pe/PeWorkspaceCreateView.tsx @@ -0,0 +1,308 @@ +// Create view cho workspace mode "new" — sectioned layout giống PeDetailTabs +// (5 section visible) nhưng trống hết. Section 1 + 2 editable (header + budget). +// Section 3-5 locked với placeholder "Lưu phiếu trước". Sau save → caller +// onSaved navigate sang ?id={newId} → workspace switch sang detail view (full +// PeDetailTabs với inline edit Section 1 + BudgetFieldRow + Suppliers/Items). +// +// Pattern user 2026-05-07: "Thêm mới list ra hết trường dữ liệu giống chỉnh +// sửa nhưng trống, mở rộng từng phần. Save header xong mới cho nhập chi tiết." +import { useState } from 'react' +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import { toast } from 'sonner' +import { Lock } from 'lucide-react' +import { Button } from '@/components/ui/Button' +import { Input } from '@/components/ui/Input' +import { Label } from '@/components/ui/Label' +import { Select } from '@/components/ui/Select' +import { Textarea } from '@/components/ui/Textarea' +import { api } from '@/lib/api' +import { getErrorMessage } from '@/lib/apiError' +import { + PurchaseEvaluationType, + PurchaseEvaluationTypeLabel, +} from '@/types/purchaseEvaluation' +import { BudgetPhase, type BudgetListItem } from '@/types/budget' +import type { Paged, Project } from '@/types/master' + +export function PeWorkspaceCreateView({ + defaultType, + onSaved, + onCancel, +}: { + defaultType: number + /** Callback sau khi POST thành công với (newId, type). Caller navigate. */ + onSaved: (id: string, type: number) => void + onCancel?: () => void +}) { + const qc = useQueryClient() + const [form, setForm] = useState({ + type: defaultType, + tenGoiThau: '', + projectId: '', + diaDiem: '', + moTa: '', + paymentTerms: '', + budgetId: '', + // Mig 17 — manual budget fallback + budgetManual: false, + budgetManualName: '', + budgetManualAmount: 0, + }) + + const projects = useQuery({ + queryKey: ['all-projects'], + queryFn: async () => (await api.get<{ items: Project[] }>('/projects', { params: { pageSize: 1000 } })).data.items, + }) + + const eligibleBudgets = useQuery({ + queryKey: ['eligible-budgets', form.projectId], + queryFn: async () => { + const res = await api.get>('/budgets', { + params: { pageSize: 100, projectId: form.projectId, phase: BudgetPhase.DaDuyet }, + }) + return res.data.items + }, + enabled: !!form.projectId, + }) + + const budgetPayload = form.budgetManual + ? { budgetId: null, budgetManualName: form.budgetManualName || null, budgetManualAmount: form.budgetManualAmount > 0 ? form.budgetManualAmount : null } + : { budgetId: form.budgetId || null, budgetManualName: null, budgetManualAmount: null } + + const create = useMutation({ + mutationFn: async () => { + const res = await api.post<{ id: string }>('/purchase-evaluations', { + type: form.type, + tenGoiThau: form.tenGoiThau, + projectId: form.projectId, + diaDiem: form.diaDiem || null, + moTa: form.moTa || null, + paymentTerms: form.paymentTerms || null, + ...budgetPayload, + }) + return res.data.id + }, + onSuccess: id => { + toast.success('Đã tạo phiếu — mở chi tiết để thêm NCC + hạng mục.') + qc.invalidateQueries({ queryKey: ['pe-list'] }) + onSaved(id, form.type) + }, + onError: e => toast.error(getErrorMessage(e)), + }) + + const canSubmit = !!form.tenGoiThau && !!form.projectId && !create.isPending + + return ( +
+ {/* Header bar */} +
+
+

Tạo phiếu Duyệt NCC mới

+

+ Nhập Section 1 + 2 → bấm “Tạo phiếu” → sau đó NCC / Hạng mục / Báo giá / Ý kiến mở khóa. +

+
+ {onCancel && ( + + )} +
+ +
+ {/* Section 1 — Thông tin gói thầu (editable) */} +
+
+
+ + +
+
+ + setForm({ ...form, tenGoiThau: e.target.value })} + placeholder="vd Cung cấp bê tông" + /> +
+
+ + +
+
+ + setForm({ ...form, diaDiem: e.target.value })} + placeholder="Lô K, KCN Lộc An..." + /> +
+
+ + setForm({ ...form, moTa: e.target.value })} + placeholder="Phương án A: ..." + /> +
+
+ +