import React from 'react'; import { cn } from '@/lib/utils'; import type { PaceInfo } from '@/lib/quota'; import { getPaceStatusColor, formatRemainingTime } from '@/lib/quota'; import { useI18n } from '@/lib/i18n'; interface PaceIndicatorProps { paceInfo: PaceInfo; className?: string; /** Compact mode shows just the status dot and prediction */ compact?: boolean; } /** * Visual indicator showing whether usage is on track, slightly fast, or too fast. * Inspired by opencode-bar's pace visualization. */ export const PaceIndicator: React.FC = ({ paceInfo, className, compact = false, }) => { const { t } = useI18n(); const statusColor = getPaceStatusColor(paceInfo.status); const statusLabel = React.useMemo(() => { switch (paceInfo.status) { case 'on-track': return t('settings.usage.pace.status.onTrack'); case 'slightly-fast': return t('settings.usage.pace.status.slightlyFast'); case 'too-fast': return t('settings.usage.pace.status.tooFast'); case 'exhausted': return t('settings.usage.pace.status.usedUp'); } }, [paceInfo.status, t]); const predictionTooltip = t('settings.usage.pace.predictionTooltip', { prediction: paceInfo.predictText }); if (compact) { return (
{paceInfo.isExhausted ? ( <>{t('settings.usage.pace.wait', { duration: formatRemainingTime(paceInfo.remainingSeconds) })} ) : ( <>{t('settings.usage.pace.prediction', { prediction: paceInfo.predictText })} )}
); } return (
{!paceInfo.isExhausted && ( {t('settings.usage.pace.rate', { rate: paceInfo.paceRateText })} )}
{paceInfo.isExhausted ? ( <> {statusLabel} {t('settings.usage.pace.waitSeparator')} {formatRemainingTime(paceInfo.remainingSeconds)} ) : ( {t('settings.usage.pace.predictionLabel')} {paceInfo.predictText} )}
); };