diff --git a/frontend/app/agency/profile/page.tsx b/frontend/app/agency/profile/page.tsx
index 1980e90..cfe5707 100644
--- a/frontend/app/agency/profile/page.tsx
+++ b/frontend/app/agency/profile/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import React, { useState } from 'react'
+import React, { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import {
CircleUser,
@@ -18,19 +18,23 @@ import {
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { useToast } from '@/components/ui/Toast'
+import { useAuth } from '@/contexts/AuthContext'
+import { USE_MOCK } from '@/contexts/AuthContext'
+import { api } from '@/lib/api'
+import type { AgencyDashboard } from '@/types/dashboard'
-// 代理商数据
+// Mock 数据(USE_MOCK 模式)
const mockAgency = {
name: '星辰传媒',
initial: '星',
- agencyId: 'AG789012', // 代理商ID
+ agencyId: 'AG789012',
companyName: '上海星辰文化传媒有限公司',
role: '官方认证代理商',
stats: {
- creators: 156, // 管理达人数
- reviewed: 1280, // 累计审核数
- passRate: 88, // 通过率
- monthlyTasks: 45, // 本月任务
+ creators: 156,
+ reviewed: 1280,
+ passRate: 88,
+ monthlyTasks: 45,
},
}
@@ -89,12 +93,48 @@ const menuItems = [
// 代理商卡片组件
function AgencyCard() {
const toast = useToast()
+ const { user } = useAuth()
const [copied, setCopied] = useState(false)
+ const [stats, setStats] = useState({ creators: 0, totalTasks: 0, passRate: 0, pendingReview: 0 })
+
+ useEffect(() => {
+ const loadStats = async () => {
+ if (USE_MOCK) {
+ setStats({
+ creators: mockAgency.stats.creators,
+ totalTasks: mockAgency.stats.reviewed,
+ passRate: mockAgency.stats.passRate,
+ pendingReview: mockAgency.stats.monthlyTasks,
+ })
+ return
+ }
+ try {
+ const dashboard = await api.getAgencyDashboard()
+ const totalPassed = dashboard.today_passed.script + dashboard.today_passed.video
+ const totalPending = dashboard.pending_review.script + dashboard.pending_review.video
+ setStats({
+ creators: dashboard.total_creators,
+ totalTasks: dashboard.total_tasks,
+ passRate: dashboard.total_tasks > 0 ? Math.round((totalPassed / Math.max(totalPassed + totalPending, 1)) * 100) : 0,
+ pendingReview: totalPending,
+ })
+ } catch {
+ // 静默失败
+ }
+ }
+ loadStats()
+ }, [])
+
+ const displayName = USE_MOCK ? mockAgency.name : (user?.name || '代理商')
+ const displayInitial = USE_MOCK ? mockAgency.initial : (user?.name?.[0] || '?')
+ const displayAgencyId = USE_MOCK ? mockAgency.agencyId : (user?.agency_id || '--')
+ const displayRole = USE_MOCK ? mockAgency.role : (user?.is_verified ? '认证代理商' : '代理商')
+ const displayCompany = USE_MOCK ? mockAgency.companyName : (user?.tenant_name || '--')
// 复制代理商ID
const handleCopyId = async () => {
try {
- await navigator.clipboard.writeText(mockAgency.agencyId)
+ await navigator.clipboard.writeText(displayAgencyId)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch {
@@ -113,17 +153,17 @@ function AgencyCard() {
background: 'linear-gradient(135deg, #6366F1 0%, #4F46E5 100%)',
}}
>
- {mockAgency.initial}
+ {displayInitial}
{/* 代理商信息 */}
-
{mockAgency.name}
-
{mockAgency.role}
+
{displayName}
+
{displayRole}
{/* 代理商ID */}
代理商ID:
- {mockAgency.agencyId}
+ {displayAgencyId}
{/* 统计数据 */}
@@ -155,24 +195,24 @@ function AgencyCard() {
- {mockAgency.stats.creators}
+ {stats.creators}
管理达人
- {mockAgency.stats.reviewed}
+ {stats.totalTasks}
-
累计审核
+
总任务数
- {mockAgency.stats.passRate}%
+ {stats.passRate}%
通过率
- {mockAgency.stats.monthlyTasks}
- 本月任务
+ {stats.pendingReview}
+ 待审核
@@ -245,6 +285,7 @@ function LogoutCard({ onLogout }: { onLogout: () => void }) {
export default function AgencyProfilePage() {
const router = useRouter()
+ const { logout } = useAuth()
// 菜单项点击处理
const handleMenuClick = (menuId: string) => {
@@ -264,7 +305,7 @@ export default function AgencyProfilePage() {
// 退出登录
const handleLogout = () => {
- // TODO: 实际退出逻辑
+ logout()
router.push('/login')
}
diff --git a/frontend/app/creator/profile/page.tsx b/frontend/app/creator/profile/page.tsx
index e0f6472..9f84b7f 100644
--- a/frontend/app/creator/profile/page.tsx
+++ b/frontend/app/creator/profile/page.tsx
@@ -1,6 +1,6 @@
'use client'
-import React, { useState } from 'react'
+import React, { useState, useEffect, useCallback } from 'react'
import { useRouter } from 'next/navigation'
import {
CircleUser,
@@ -17,12 +17,16 @@ import {
import { ResponsiveLayout } from '@/components/layout/ResponsiveLayout'
import { cn } from '@/lib/utils'
import { useToast } from '@/components/ui/Toast'
+import { useAuth } from '@/contexts/AuthContext'
+import { USE_MOCK } from '@/contexts/AuthContext'
+import { api } from '@/lib/api'
+import type { CreatorDashboard } from '@/types/dashboard'
-// 用户数据
+// Mock 数据(USE_MOCK 模式)
const mockUser = {
name: '李小红',
initial: '李',
- creatorId: 'CR123456', // 达人ID
+ creatorId: 'CR123456',
role: '抖音达人 · 已认证',
stats: {
completed: 28,
@@ -86,12 +90,40 @@ const menuItems = [
// 用户卡片组件
function UserCard() {
const toast = useToast()
+ const { user } = useAuth()
const [copied, setCopied] = useState(false)
+ const [stats, setStats] = useState({ completed: 0, inProgress: 0, totalTasks: 0 })
+
+ useEffect(() => {
+ const loadStats = async () => {
+ if (USE_MOCK) {
+ setStats({ completed: mockUser.stats.completed, inProgress: mockUser.stats.inProgress, totalTasks: mockUser.stats.completed + mockUser.stats.inProgress })
+ return
+ }
+ try {
+ const dashboard = await api.getCreatorDashboard()
+ setStats({
+ completed: dashboard.completed,
+ inProgress: dashboard.pending_script + dashboard.pending_video + dashboard.in_review,
+ totalTasks: dashboard.total_tasks,
+ })
+ } catch {
+ // 静默失败,保持默认值
+ }
+ }
+ loadStats()
+ }, [])
+
+ const displayName = USE_MOCK ? mockUser.name : (user?.name || '用户')
+ const displayInitial = USE_MOCK ? mockUser.initial : (user?.name?.[0] || '?')
+ const displayCreatorId = USE_MOCK ? mockUser.creatorId : (user?.creator_id || '--')
+ const displayRole = USE_MOCK ? mockUser.role : (user?.is_verified ? '达人 · 已认证' : '达人')
+ const passRate = stats.totalTasks > 0 ? Math.round((stats.completed / stats.totalTasks) * 100) : 0
// 复制达人ID
const handleCopyId = async () => {
try {
- await navigator.clipboard.writeText(mockUser.creatorId)
+ await navigator.clipboard.writeText(displayCreatorId)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch {
@@ -110,17 +142,17 @@ function UserCard() {
background: 'linear-gradient(135deg, #6366F1 0%, #4F46E5 100%)',
}}
>
- {mockUser.initial}
+ {displayInitial}
{/* 用户信息 */}
-
{mockUser.name}
-
{mockUser.role}
+
{displayName}
+
{displayRole}
{/* 达人ID */}
达人ID:
-
{mockUser.creatorId}
+
{displayCreatorId}
@@ -226,6 +258,7 @@ function LogoutCard({ onLogout }: { onLogout: () => void }) {
export default function CreatorProfilePage() {
const router = useRouter()
+ const { logout } = useAuth()
// 菜单项点击处理
const handleMenuClick = (menuId: string) => {
@@ -245,7 +278,7 @@ export default function CreatorProfilePage() {
// 退出登录
const handleLogout = () => {
- // TODO: 实际退出逻辑
+ logout()
router.push('/login')
}