"use client"; import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent, type MouseEvent, } from "react"; import { CaretDown, FloppyDisk, X } from "@phosphor-icons/react"; import { filterFlockSavedFreight, loadFlockSavedFreight, persistFlockSavedFreight, removeFlockSavedFreight, upsertFlockSavedFreight, buildFlockSavedFreightPreset, type FlockSavedFreightPreset, type FlockSavedFreightSource, } from "@/lib/flock/saved-freight-presets"; import { quoteInputCls } from "@/components/quote/quote-form-chrome"; const inputCls = quoteInputCls; type Props = { customerId: string; disabled?: boolean; /** 保存后递增,触发搜索列表刷新 */ revision?: number; }; /** 顶部:搜索并选用常用货件 */ export function FlockSavedFreightSearch({ customerId, disabled, revision = 0, onSelect, }: Props & { onSelect: (preset: FlockSavedFreightPreset) => void }) { const [presets, setPresets] = useState([]); const [query, setQuery] = useState(""); const [open, setOpen] = useState(false); const rootRef = useRef(null); const reload = useCallback(() => { setPresets(loadFlockSavedFreight(customerId)); }, [customerId]); useEffect(() => { reload(); }, [reload, revision]); useEffect(() => { const onDoc = (e: globalThis.MouseEvent) => { if (!rootRef.current?.contains(e.target as Node)) setOpen(false); }; document.addEventListener("mousedown", onDoc); return () => document.removeEventListener("mousedown", onDoc); }, []); const filtered = useMemo( () => filterFlockSavedFreight(presets, query), [presets, query], ); const remove = (id: string, e: MouseEvent | KeyboardEvent) => { e.stopPropagation(); e.preventDefault(); const next = removeFlockSavedFreight(presets, id); persistFlockSavedFreight(customerId, next); setPresets(next); }; return (
{ setQuery(e.target.value); setOpen(true); }} onFocus={() => setOpen(true)} placeholder={ presets.length ? "搜索已保存的货件名称或描述" : "暂无常用货件,请先在货品描述处保存" } className={`${inputCls} pr-8`} autoComplete="off" /> {open ? (
    {filtered.length === 0 ? (
  • {presets.length === 0 ? "尚无保存记录" : "无匹配货件"}
  • ) : ( filtered.map((p) => (
  • )) )}
) : null}
); } /** 货品描述旁:保存当前货物行为常用货件 */ export function FlockSaveFreightButton({ customerId, disabled, source, onSaved, }: Props & { source: FlockSavedFreightSource; onSaved?: () => void; }) { const [open, setOpen] = useState(false); const [name, setName] = useState(""); const [hint, setHint] = useState(null); useEffect(() => { if (open) { setName(source.description.trim()); setHint(null); } }, [open, source.description]); const save = () => { const preset = buildFlockSavedFreightPreset(source, name); if (!preset) { setHint("请先填写货品描述或货件名称"); return; } const list = loadFlockSavedFreight(customerId); const next = upsertFlockSavedFreight(list, preset); persistFlockSavedFreight(customerId, next); setOpen(false); setHint("已保存到常用货件"); onSaved?.(); window.setTimeout(() => setHint(null), 2000); }; return (
{!open ? ( ) : (

货件名称(便于搜索)

setName(e.target.value)} className={`${inputCls} !h-9 min-w-[12rem] flex-1 text-sm`} placeholder="如:标准木托家电" />
)} {hint ?

{hint}

: null}
); }