"use client"; import { useCallback, useEffect, useState } from "react"; import { Card } from "@/components/ui/card"; import { PrimaryButton, SecondaryButton, } from "@/components/ui/primary-button"; import { InputField } from "@/components/ui/input-field"; import { ErrorBanner } from "@/components/ui/error-banner"; import { Skeleton } from "@/components/ui/skeleton"; import { EmbeddedQuoteWidget } from "@/components/embed/embedded-quote-widget"; import { embedGetProviderCredentials, embedSaveProviderCredential, type EmbedProviderCredential, } from "@/lib/frontend/api-client"; type QuoteProvider = "mothership" | "flock"; type QuoteMode = "anon" | "login"; interface ModuleDef { provider: QuoteProvider; title: string; desc: string; } /** 门户仅两模块:MotherShip / Flock(进入后可选免账号或登录后) */ const MODULES: ModuleDef[] = [ { provider: "mothership", title: "MotherShip", desc: "免账号实时报价,或使用官网账号登录后查价", }, { provider: "flock", title: "Flock Freight", desc: "ZIP Direct 匿名询价,或使用官网账号登录后查价", }, ]; interface QuoteRouteHubProps { customerId: string; apiBaseUrl?: string; } export function QuoteRouteHub({ customerId, apiBaseUrl = "", }: QuoteRouteHubProps) { const [loading, setLoading] = useState(true); const [creds, setCreds] = useState< Record >({ mothership: { provider: "mothership", email: null, password: null, has_password: false, updated_at: null, }, flock: { provider: "flock", email: null, password: null, has_password: false, updated_at: null, }, }); const [selected, setSelected] = useState(null); const [mode, setMode] = useState("anon"); const loadCreds = useCallback(async () => { setLoading(true); const res = await embedGetProviderCredentials(apiBaseUrl); if (res.code === 0) { setCreds((prev) => { const next = { ...prev }; for (const item of res.data.list) { if (item.provider === "mothership" || item.provider === "flock") { next[item.provider] = item; } } return next; }); } setLoading(false); }, [apiBaseUrl]); useEffect(() => { void loadCreds(); }, [loadCreds]); const handleSaved = useCallback((saved: EmbedProviderCredential) => { setCreds((prev) => ({ ...prev, [saved.provider]: saved })); }, []); const openModule = (mod: ModuleDef) => { setSelected(mod); // 已配置账密时默认进登录后;否则免账号 setMode(creds[mod.provider].has_password ? "login" : "anon"); }; if (loading) { return ; } if (!selected) { return (
{MODULES.map((mod) => { const hasPassword = creds[mod.provider].has_password; return ( openModule(mod)} data-testid={`quote-route-module-${mod.provider}`} >
{mod.title} {hasPassword ? "已配置官网账号" : "可免账号查价"}
{mod.desc}
); })}
); } const providerCred = creds[selected.provider]; const requiresAccount = mode === "login"; const canQuote = !requiresAccount || providerCred.has_password; return (

当前查价模块

{selected.title}

setSelected(null)}> 返回模块列表
{( [ { id: "anon" as const, label: "免账号", desc: "无需官网登录" }, { id: "login" as const, label: "登录后", desc: "使用官网账密" }, ] as const ).map((tab) => ( ))}
{requiresAccount && ( )} {canQuote ? ( ) : (

「登录后」查价需先保存承运商账号密码,保存成功后即可开始。

)}
); } interface ProviderCredentialPanelProps { provider: QuoteProvider; apiBaseUrl: string; current: EmbedProviderCredential; onSaved: (saved: EmbedProviderCredential) => void; } function ProviderCredentialPanel({ provider, apiBaseUrl, current, onSaved, }: ProviderCredentialPanelProps) { const [email, setEmail] = useState(current.email ?? ""); const [password, setPassword] = useState(current.password ?? ""); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [savedHint, setSavedHint] = useState(null); useEffect(() => { setEmail(current.email ?? ""); setPassword(current.password ?? ""); setError(null); setSavedHint(null); }, [provider, current.email, current.password]); const handleSave = async () => { if (saving) return; if (!email.trim()) { setError("请填写登录邮箱"); return; } if (!password.trim()) { setError("请填写登录密码(明文展示便于核对,修改后请点保存)"); return; } setSaving(true); setError(null); setSavedHint(null); const res = await embedSaveProviderCredential( apiBaseUrl, provider, email.trim(), password, ); setSaving(false); if (res.code !== 0) { setError(res.message || "保存失败"); return; } setEmail(res.data.email ?? email.trim()); setPassword(res.data.password ?? password); setSavedHint( "账号密码已保存。若官网已改密,请确认此处已同步更新后再查价。", ); onSaved(res.data); }; return (

承运商账号密码

{current.has_password ? "以下为当前已保存的明文账密,请核对是否与官网一致。官网改密后须在此即时保存,否则查价会卡在登录页并报错。" : "首次使用请填写官网账号邮箱与密码,保存后方可查价。"}

{error && (
{error}
)} {savedHint && (

{savedHint}

)}
setEmail(e.target.value)} /> setPassword(e.target.value)} /> void handleSave()} > {current.has_password ? "保存修改" : "保存"}
); }