'use client' import type { ComponentType, FC } from 'react' import * as React from 'react' import { useTranslation } from 'react-i18next' import Tooltip from '@/app/components/base/tooltip' import { cn } from '@/utils/classnames' import { NUM_INFINITE } from '../config' import ProgressBar from '../progress-bar' type Props = { className?: string Icon: ComponentType<{ className?: string }> name: string tooltip?: string usage: number total: number unit?: string unitPosition?: 'inline' | 'suffix' resetHint?: string resetInDays?: number hideIcon?: boolean // Props for the 50MB threshold display logic storageMode?: boolean storageThreshold?: number storageTooltip?: string isSandboxPlan?: boolean } const WARNING_THRESHOLD = 80 const UsageInfo: FC = ({ className, Icon, name, tooltip, usage, total, unit, unitPosition = 'suffix', resetHint, resetInDays, hideIcon = false, storageMode = false, storageThreshold = 50, storageTooltip, isSandboxPlan = false, }) => { const { t } = useTranslation() // Special display logic for usage below threshold (only in storage mode) const isBelowThreshold = storageMode && usage < storageThreshold // Sandbox at full capacity (usage >= threshold and it's sandbox plan) const isSandboxFull = storageMode && isSandboxPlan && usage >= storageThreshold const percent = usage / total * 100 const getProgressColor = () => { if (percent >= 100) return 'bg-components-progress-error-progress' if (percent >= WARNING_THRESHOLD) return 'bg-components-progress-warning-progress' return 'bg-components-progress-bar-progress-solid' } const color = getProgressColor() const isUnlimited = total === NUM_INFINITE let totalDisplay: string | number = isUnlimited ? t('plansCommon.unlimited', { ns: 'billing' }) : total if (!isUnlimited && unit && unitPosition === 'inline') totalDisplay = `${total}${unit}` const showUnit = !!unit && !isUnlimited && unitPosition === 'suffix' const resetText = resetHint ?? (typeof resetInDays === 'number' ? t('usagePage.resetsIn', { ns: 'billing', count: resetInDays }) : undefined) const renderRightInfo = () => { if (resetText) { return (
{resetText}
) } if (showUnit) { return (
{unit}
) } return null } // Render usage display const renderUsageDisplay = () => { // Storage mode: special display logic if (storageMode) { // Sandbox user at full capacity if (isSandboxFull) { return (
{storageThreshold} / {storageThreshold} {' '} {unit}
) } // Usage below threshold - show "< 50 MB" or "< 50 / 5GB" if (isBelowThreshold) { return (
< {' '} {storageThreshold} {!isSandboxPlan && ( <> / {totalDisplay} )} {isSandboxPlan && {unit}}
) } // Pro/Team users with usage >= threshold - show actual usage return (
{usage} / {totalDisplay}
) } // Default display (storageMode = false) return (
{usage} / {totalDisplay}
) } const renderWithTooltip = (children: React.ReactNode) => { if (storageMode && storageTooltip) { return ( {storageTooltip}} asChild={false} >
{children}
) } return children } // Render progress bar with optional tooltip wrapper const renderProgressBar = () => { const progressBar = ( ) return renderWithTooltip(progressBar) } const renderUsageWithTooltip = () => { return renderWithTooltip(renderUsageDisplay()) } return (
{!hideIcon && Icon && ( )}
{name}
{tooltip && ( {tooltip}
)} /> )}
{renderUsageWithTooltip()} {renderRightInfo()}
{renderProgressBar()} ) } export default React.memo(UsageInfo)