Files
vf_react/src/components/Subscription/SubscriptionButton.js
2025-10-21 15:48:38 +08:00

212 lines
6.3 KiB
JavaScript

// src/components/Subscription/SubscriptionButton.js
import React from 'react';
import { Box, VStack, HStack, Text, Tooltip, Divider, useColorModeValue } from '@chakra-ui/react';
import PropTypes from 'prop-types';
/**
* 订阅徽章按钮组件 - 用于导航栏头像旁边
* 简洁显示订阅等级,hover 显示详细卡片式 Tooltip
*/
export default function SubscriptionButton({ subscriptionInfo, onClick }) {
const tooltipBg = useColorModeValue('white', 'gray.800');
const tooltipBorder = useColorModeValue('gray.200', 'gray.600');
const tooltipText = useColorModeValue('gray.700', 'gray.100');
const dividerColor = useColorModeValue('gray.200', 'gray.600');
// 根据订阅类型返回样式配置
const getButtonStyles = () => {
if (subscriptionInfo.type === 'max') {
return {
bg: 'transparent',
color: '#3182CE',
icon: '👑',
label: 'Max',
shadow: 'none',
hoverShadow: '0 2px 8px rgba(49, 130, 206, 0.2)',
border: '1.5px solid',
borderColor: '#4299E1',
accentColor: '#3182CE',
};
}
if (subscriptionInfo.type === 'pro') {
return {
bg: 'transparent',
color: '#667eea',
icon: '💎',
label: 'Pro',
shadow: 'none',
hoverShadow: '0 2px 8px rgba(102, 126, 234, 0.2)',
border: '1.5px solid',
borderColor: '#667eea',
accentColor: '#667eea',
};
}
// 基础版
return {
bg: 'transparent',
color: useColorModeValue('gray.600', 'gray.400'),
icon: '✨',
label: '基础版',
shadow: 'none',
hoverShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
border: '1.5px solid',
borderColor: useColorModeValue('gray.300', 'gray.600'),
accentColor: useColorModeValue('#718096', '#A0AEC0'),
};
};
const styles = getButtonStyles();
// 增强的卡片式 Tooltip 内容
const TooltipContent = () => {
const { type, days_left, is_active } = subscriptionInfo;
// 基础版用户
if (type === 'free') {
return (
<VStack spacing={2} align="stretch" minW="200px">
<Text fontSize="md" fontWeight="bold" color={tooltipText}>
基础版用户
</Text>
<Divider borderColor={dividerColor} />
<Text fontSize="sm" color={tooltipText} opacity={0.8}>
解锁更多高级功能
</Text>
<Box
mt={1}
px={3}
py={2}
borderRadius="md"
bg="linear-gradient(135deg, #667eea 0%, #3182CE 100%)"
color="white"
textAlign="center"
fontWeight="600"
fontSize="sm"
cursor="pointer"
_hover={{ transform: 'scale(1.02)' }}
transition="transform 0.2s"
>
🚀 立即升级
</Box>
</VStack>
);
}
// 付费用户
const isExpired = !is_active;
const isUrgent = days_left < 7;
const isWarning = days_left < 30;
return (
<VStack spacing={2} align="stretch" minW="200px">
<HStack justify="space-between">
<Text fontSize="md" fontWeight="bold" color={tooltipText}>
{type === 'pro' ? '💎 Pro 会员' : '👑 Max 会员'}
</Text>
{isExpired && <Text fontSize="xs" color="red.500">已过期</Text>}
</HStack>
<Divider borderColor={dividerColor} />
{/* 状态信息 */}
{isExpired ? (
<HStack spacing={2}>
<Text fontSize="sm" color="red.500"></Text>
<Text fontSize="sm" color={tooltipText}>
会员已过期,续费恢复权益
</Text>
</HStack>
) : (
<VStack spacing={1} align="stretch">
<HStack spacing={2}>
<Text fontSize="sm" color={tooltipText}>
{isUrgent ? '⚠️' : isWarning ? '⏰' : '📅'}
</Text>
<Text fontSize="sm" color={tooltipText}>
{isUrgent && <Text as="span" color="red.500" fontWeight="600">紧急!</Text>}
{' '}还有 <Text as="span" fontWeight="600">{days_left}</Text>
</Text>
</HStack>
<Text fontSize="xs" color={tooltipText} opacity={0.7} pl={6}>
享受全部高级功能
</Text>
</VStack>
)}
{/* 行动按钮 */}
<Box
mt={1}
px={3}
py={2}
borderRadius="md"
bg={isExpired || isUrgent ? 'linear-gradient(135deg, #FC8181 0%, #F56565 100%)' : `linear-gradient(135deg, ${styles.accentColor} 0%, ${styles.accentColor}dd 100%)`}
color="white"
textAlign="center"
fontWeight="600"
fontSize="sm"
cursor="pointer"
_hover={{ transform: 'scale(1.02)' }}
transition="transform 0.2s"
>
{isExpired ? '💳 立即续费' : isUrgent ? '⚡ 紧急续费' : '💼 管理订阅'}
</Box>
</VStack>
);
};
return (
<Tooltip
label={<TooltipContent />}
hasArrow
placement="bottom"
bg={tooltipBg}
color={tooltipText}
borderRadius="lg"
border="1px solid"
borderColor={tooltipBorder}
boxShadow="lg"
p={3}
>
<Box
as="button"
onClick={onClick}
px={2}
py={1}
w="70px"
h="32px"
borderRadius="md"
bg={styles.bg}
color={styles.color}
border={styles.border}
borderColor={styles.borderColor}
cursor="pointer"
transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
boxShadow={styles.shadow}
display="flex"
alignItems="center"
justifyContent="center"
_hover={{
transform: 'translateY(-1px)',
boxShadow: styles.hoverShadow,
}}
_active={{
transform: 'translateY(0)',
}}
>
<Text fontSize="sm" fontWeight="600" lineHeight="1">
<Text as="span" fontSize="md">{styles.icon}</Text> {styles.label}
</Text>
</Box>
</Tooltip>
);
}
SubscriptionButton.propTypes = {
subscriptionInfo: PropTypes.shape({
type: PropTypes.oneOf(['free', 'pro', 'max']).isRequired,
days_left: PropTypes.number,
is_active: PropTypes.bool,
}).isRequired,
onClick: PropTypes.func.isRequired,
};