feat: 添加导航徽章
This commit is contained in:
@@ -38,6 +38,8 @@ import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '../../contexts/AuthContext';
|
||||
import { useAuthModal } from '../../contexts/AuthModalContext';
|
||||
import { logger } from '../../utils/logger';
|
||||
import SubscriptionBadge from '../Subscription/SubscriptionBadge';
|
||||
import SubscriptionModal from '../Subscription/SubscriptionModal';
|
||||
|
||||
/** 二级导航栏组件 - 显示当前一级菜单下的所有二级菜单项 */
|
||||
const SecondaryNav = () => {
|
||||
@@ -417,6 +419,15 @@ export default function HomeNavbar() {
|
||||
// 添加标志位:追踪是否已经检查过资料完整性(避免重复请求)
|
||||
const hasCheckedCompleteness = React.useRef(false);
|
||||
|
||||
// 订阅信息状态
|
||||
const [subscriptionInfo, setSubscriptionInfo] = React.useState({
|
||||
type: 'free',
|
||||
status: 'active',
|
||||
days_left: 0,
|
||||
is_active: true
|
||||
});
|
||||
const [isSubscriptionModalOpen, setIsSubscriptionModalOpen] = React.useState(false);
|
||||
|
||||
const loadWatchlistQuotes = useCallback(async () => {
|
||||
try {
|
||||
setWatchlistLoading(true);
|
||||
@@ -613,6 +624,57 @@ export default function HomeNavbar() {
|
||||
}
|
||||
}, [isAuthenticated, user, checkProfileCompleteness]);
|
||||
|
||||
// 加载订阅信息
|
||||
React.useEffect(() => {
|
||||
console.log('🔍 [HomeNavbar] 订阅徽章 - 认证状态:', isAuthenticated, 'userId:', user?.id);
|
||||
|
||||
if (isAuthenticated && user) {
|
||||
const loadSubscriptionInfo = async () => {
|
||||
try {
|
||||
const base = getApiBase();
|
||||
console.log('🌐 [HomeNavbar] 订阅徽章 - API:', base + '/api/subscription/current');
|
||||
const response = await fetch(base + '/api/subscription/current', {
|
||||
credentials: 'include',
|
||||
});
|
||||
console.log('📡 [HomeNavbar] 订阅徽章 - 响应:', response.status);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('✅ [HomeNavbar] 订阅徽章 - 完整响应数据:', data);
|
||||
console.log('🔍 [HomeNavbar] 订阅徽章 - data.data:', data.data);
|
||||
console.log('🔍 [HomeNavbar] 订阅徽章 - type值:', data.data?.type, '类型:', typeof data.data?.type);
|
||||
|
||||
if (data.success && data.data) {
|
||||
// 数据标准化处理:确保type字段是小写的 'free', 'pro', 或 'max'
|
||||
const normalizedData = {
|
||||
type: (data.data.type || data.data.subscription_type || 'free').toLowerCase(),
|
||||
status: data.data.status || 'active',
|
||||
days_left: data.data.days_left || 0,
|
||||
is_active: data.data.is_active !== false,
|
||||
end_date: data.data.end_date || null
|
||||
};
|
||||
console.log('✨ [HomeNavbar] 订阅徽章 - 标准化后:', normalizedData);
|
||||
setSubscriptionInfo(normalizedData);
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ [HomeNavbar] 订阅徽章 - API 失败,使用默认值');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ [HomeNavbar] 订阅徽章 - 错误:', error);
|
||||
}
|
||||
};
|
||||
loadSubscriptionInfo();
|
||||
} else {
|
||||
// 用户未登录时,重置为免费版
|
||||
console.warn('🚫 [HomeNavbar] 订阅徽章 - 用户未登录,重置为免费版');
|
||||
setSubscriptionInfo({
|
||||
type: 'free',
|
||||
status: 'active',
|
||||
days_left: 0,
|
||||
is_active: true
|
||||
});
|
||||
}
|
||||
}, [isAuthenticated, user?.id]); // 只依赖 user.id 而不是整个 user 对象
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* 资料完整性提醒横幅 */}
|
||||
@@ -711,6 +773,23 @@ export default function HomeNavbar() {
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
/>
|
||||
|
||||
{/* 订阅状态徽章 - 仅登录用户可见 */}
|
||||
{console.log('🎨 [HomeNavbar] 订阅徽章 - 渲染:', { isAuthenticated, user: !!user, subscriptionInfo })}
|
||||
{isAuthenticated && user && (
|
||||
<>
|
||||
<SubscriptionBadge
|
||||
subscriptionInfo={subscriptionInfo}
|
||||
onClick={() => setIsSubscriptionModalOpen(true)}
|
||||
/>
|
||||
<SubscriptionModal
|
||||
isOpen={isSubscriptionModalOpen}
|
||||
onClose={() => setIsSubscriptionModalOpen(false)}
|
||||
subscriptionInfo={subscriptionInfo}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 显示加载状态 */}
|
||||
{isLoading ? (
|
||||
<HStack spacing={2}>
|
||||
|
||||
Reference in New Issue
Block a user