Files
vf_react/src/components/Subscription/CrownTooltip.js
2025-10-21 15:43:35 +08:00

138 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/components/Subscription/CrownTooltip.js
import React from 'react';
import {
Box,
VStack,
HStack,
Text,
Divider,
useColorModeValue
} from '@chakra-ui/react';
import PropTypes from 'prop-types';
/**
* Tooltip 内容组件 - 显示详细的会员信息
* 导出此组件供头像也使用相同的 Tooltip 内容
*/
export const TooltipContent = ({ subscriptionInfo }) => {
const tooltipText = useColorModeValue('gray.700', 'gray.100');
const dividerColor = useColorModeValue('gray.200', 'gray.600');
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>
<Text fontSize="xs" color={tooltipText} opacity={0.6} textAlign="center" mt={1}>
点击头像升级会员
</Text>
</VStack>
);
}
// 付费用户
const isExpired = !is_active;
const isUrgent = days_left < 7;
const isWarning = days_left < 30;
return (
<VStack spacing={2} align="stretch" minW="220px">
<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">
{isUrgent ? '⚠️' : isWarning ? '⏰' : '📅'}
</Text>
<Text fontSize="sm" color={tooltipText}>
{isUrgent && <Text as="span" color="red.500" fontWeight="600">紧急! </Text>}
还有 <Text as="span" fontWeight="600" color={isUrgent ? 'red.500' : isWarning ? 'orange.500' : tooltipText}>{days_left}</Text>
</Text>
</HStack>
<Text fontSize="xs" color={tooltipText} opacity={0.7} pl={6}>
享受全部高级功能
</Text>
</VStack>
)}
{/* 操作提示 */}
<Text fontSize="xs" color={tooltipText} opacity={0.6} textAlign="center" mt={1}>
{isExpired || isUrgent ? '点击头像立即续费' : '点击头像管理订阅'}
</Text>
</VStack>
);
};
/**
* 皇冠图标组件 - 显示在头像左上角的会员标识(纯图标,无 Tooltip
* Tooltip 由外层统一包裹
*
* @param {Object} subscriptionInfo - 订阅信息
* @param {string} subscriptionInfo.type - 订阅类型: 'free' | 'pro' | 'max'
*/
export function CrownIcon({ subscriptionInfo }) {
// 基础版用户不显示皇冠
if (subscriptionInfo.type === 'free') {
return null;
}
return (
<Box
position="absolute"
top="-8px"
left="-8px"
zIndex={2}
display="flex"
alignItems="center"
justifyContent="center"
w="24px"
h="24px"
_hover={{
transform: 'scale(1.2)',
}}
transition="all 0.3s ease"
>
<Text fontSize="20px" filter="drop-shadow(0 2px 4px rgba(0,0,0,0.3))">
{subscriptionInfo.type === 'max' ? '👑' : '💎'}
</Text>
</Box>
);
}
CrownIcon.propTypes = {
subscriptionInfo: PropTypes.shape({
type: PropTypes.oneOf(['free', 'pro', 'max']).isRequired,
}).isRequired,
};
TooltipContent.propTypes = {
subscriptionInfo: PropTypes.shape({
type: PropTypes.oneOf(['free', 'pro', 'max']).isRequired,
days_left: PropTypes.number,
is_active: PropTypes.bool,
}).isRequired,
};