"use client"; import { MessageSquareQuote, PhoneCall } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { adminApi, errMessage, type Customer, type TalkTemplate, type Visit } from "@/lib/admin-api"; import { Badge, Button, Card, EmptyState, ErrorState, LoadingBlock, Pagination, Select, TextInput, formatTime, useToast, } from "@/components/admin/ui"; const VISIT_TYPES = ["电话回访", "线上沟通", "线下拜访"]; export function VisitsSection() { const toast = useToast(); const [customers, setCustomers] = useState([]); const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [totalPages, setTotalPages] = useState(0); const [page, setPage] = useState(1); const [templates, setTemplates] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [customerId, setCustomerId] = useState(""); const [visitType, setVisitType] = useState(VISIT_TYPES[0]); const [visitTime, setVisitTime] = useState(""); const [summary, setSummary] = useState(""); const [editingId, setEditingId] = useState(null); const [busy, setBusy] = useState(false); const load = useCallback(async () => { setLoading(true); setError(""); try { const result = await adminApi.visits({ page, page_size: 10 }); setItems(result.items ?? []); setTotal(result.total ?? 0); setTotalPages(result.total_pages ?? 0); } catch (e) { setError(errMessage(e, "回访记录加载失败")); } finally { setLoading(false); } }, [page]); useEffect(() => { void (async () => { try { const [customerPage, templateList] = await Promise.all([ adminApi.customers({ page: 1, page_size: 100 }), adminApi.talkTemplates().catch(() => []), ]); setCustomers(customerPage.items ?? []); setTemplates(templateList ?? []); if (!customerId && customerPage.items?.length) { setCustomerId(String(customerPage.items[0].customer_id)); } } catch { /* 客户列表失败时用户仍可手动选择 */ } })(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { void load(); }, [load]); function resetForm() { setEditingId(null); setVisitType(VISIT_TYPES[0]); setVisitTime(""); setSummary(""); } async function submit() { if (!customerId) { toast("请先选择客户", "error"); return; } if (!visitTime) { toast("请选择回访时间", "error"); return; } setBusy(true); try { const body = { customer_id: Number(customerId), visit_type: visitType, visit_time: new Date(visitTime).toISOString(), summary: summary || undefined, }; if (editingId) await adminApi.updateVisit(editingId, body); else await adminApi.createVisit(body); toast(editingId ? "回访已更新" : "回访已新增"); resetForm(); await load(); } catch (e) { toast(errMessage(e, "保存失败"), "error"); } finally { setBusy(false); } } return (
setVisitTime(event.target.value)} />