"use client"; /** * ChatInsufficientCreditsBanner 积分不足横幅 * * 何时显示: * - 后端返回 cannotSendReason="insufficient_credits" * * 视觉规格(与设计稿对齐): * - 粉→品红渐变背景(与 splash 渐变一致) * - 大字号粉色/白色提示文案 * - 粉→品红渐变 pill 按钮 → 跳 /subscription?type=topup * * 业务关系: * - 与订阅页 top up 入口行为一致 * * 不做的事: * - 不直接管理 state machine(chat 机器不感知 UI 层) */ import { useAppNavigator } from "@/router/use-app-navigator"; import styles from "./chat-insufficient-credits-banner.module.css"; export interface ChatInsufficientCreditsBannerProps { title?: string; ctaLabel?: string; /** * 自定义点击回调(不传则默认走统一订阅导航) * - 测试时可传 mock * - 嵌入其他场景时(如 nested overlay)可传自定义 */ onUnlock?: () => void; } export function ChatInsufficientCreditsBanner({ title = "Insufficient credits\nTop up to continue chatting", ctaLabel = "Top up credits to continue", onUnlock, }: ChatInsufficientCreditsBannerProps) { const navigator = useAppNavigator(); const titleLines = title.split("\n"); const handleClick = () => { if (onUnlock) { onUnlock(); return; } navigator.openSubscription({ type: "topup", returnTo: "chat" }); }; return (
{titleLines.map((line, index) => (
{line}
{index < titleLines.length - 1 ?
: null}
))}