feat: 添加合规
This commit is contained in:
209
src/components/Subscription/SubscriptionButton.js
Normal file
209
src/components/Subscription/SubscriptionButton.js
Normal file
@@ -0,0 +1,209 @@
|
||||
// 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: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
||||
color: 'white',
|
||||
icon: '👑',
|
||||
label: 'Max',
|
||||
shadow: '0 4px 12px rgba(118, 75, 162, 0.4)',
|
||||
hoverShadow: '0 6px 16px rgba(118, 75, 162, 0.5)',
|
||||
border: 'none',
|
||||
accentColor: '#764ba2',
|
||||
};
|
||||
}
|
||||
if (subscriptionInfo.type === 'pro') {
|
||||
return {
|
||||
bg: 'linear-gradient(135deg, #667eea 0%, #3182CE 100%)',
|
||||
color: 'white',
|
||||
icon: '💎',
|
||||
label: 'Pro',
|
||||
shadow: '0 4px 12px rgba(49, 130, 206, 0.4)',
|
||||
hoverShadow: '0 6px 16px rgba(49, 130, 206, 0.5)',
|
||||
border: 'none',
|
||||
accentColor: '#3182CE',
|
||||
};
|
||||
}
|
||||
// 基础版
|
||||
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={3}
|
||||
py={2}
|
||||
minW="60px"
|
||||
h="40px"
|
||||
borderRadius="lg"
|
||||
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(-2px)',
|
||||
boxShadow: styles.hoverShadow,
|
||||
}}
|
||||
_active={{
|
||||
transform: 'translateY(0)',
|
||||
}}
|
||||
>
|
||||
<Text fontSize="sm" fontWeight="600" lineHeight="1">
|
||||
{styles.icon} {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,
|
||||
};
|
||||
Reference in New Issue
Block a user