import TrendingDownIcon from '@mui/icons-material/TrendingDown'; import { Box, CircularProgress, Stack, Typography } from '@mui/material'; import { useLocaleContext } from '@arcblock/ux/lib/Locale/context'; import type { BillingIntervalData } from '@blocklet/payment-react-headless'; import { INTERVAL_LOCALE_KEY } from '../../utils/format'; interface BillingToggleProps { billingInterval: BillingIntervalData | null; } export default function BillingToggle({ billingInterval }: BillingToggleProps) { const { t } = useLocaleContext(); if (!billingInterval?.available?.length || billingInterval.available.length <= 1) { return null; } const best = billingInterval.available.reduce((a: any, b: any) => Number(b.savings || 0) > Number(a.savings || 0) ? b : a ); return ( {/* Capsule container — design: bg-white p-1 rounded-full border-slate-200 shadow-sm */} theme.palette.mode === 'dark' ? '0 1px 2px 0 rgba(0,0,0,0.3)' : '0 1px 2px 0 rgba(0,0,0,0.05)', }}> {billingInterval.available.map((option) => { const isSelected = option.interval === billingInterval.current; const selectedSx = { bgcolor: (th: any) => (th.palette.mode === 'dark' ? 'rgba(156,106,222,0.25)' : 'rgba(156,106,222,0.15)'), color: 'primary.main', backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)', boxShadow: (th: any) => th.palette.mode === 'dark' ? '0 2px 8px rgba(156,106,222,0.2), inset 0 1px 0 rgba(255,255,255,0.06)' : '0 2px 8px rgba(156,106,222,0.15), inset 0 1px 0 rgba(255,255,255,0.5)', border: '1px solid', borderColor: (th: any) => (th.palette.mode === 'dark' ? 'rgba(156,106,222,0.3)' : 'rgba(156,106,222,0.2)'), }; const unselectedSx = { color: 'text.secondary', border: '1px solid transparent', '&:hover': { color: 'text.primary' }, }; return ( { if (option.interval !== billingInterval.current && !billingInterval.switching) { billingInterval.switch(option.interval); } }} sx={{ px: 3.5, py: 1, borderRadius: '9999px', cursor: 'pointer', transition: 'all 0.3s ease', userSelect: 'none', ...(isSelected ? selectedSx : unselectedSx), }}> {billingInterval.switching && isSelected ? ( ) : ( {t(INTERVAL_LOCALE_KEY[option.interval] || option.interval)} )} ); })} {/* SAVE badge — design: bg-[#ebfef5] text-[#12b886] border-[#d3f9e8] trending_down icon */} {best.savings && Number(best.savings) > 0 && ( (theme.palette.mode === 'dark' ? 'rgba(18,184,134,0.1)' : '#ebfef5'), color: '#12b886', fontSize: 11, fontWeight: 700, borderRadius: '9999px', border: '1px solid', borderColor: (theme) => (theme.palette.mode === 'dark' ? 'rgba(18,184,134,0.2)' : '#d3f9e8'), textTransform: 'uppercase', letterSpacing: '0.05em', }}> SAVE {best.savings}% )} ); }