'use client' import { useState } from 'react' import { useRouter } from 'next/navigation' import { UserPlus, ClipboardList, CheckCircle, PenLine, ScanSearch, Building2, XCircle, BadgeCheck, Video, MessageCircle, } from 'lucide-react' import { ResponsiveLayout } from '@/components/layout/ResponsiveLayout' import { cn } from '@/lib/utils' // 消息类型 type MessageType = | 'invite' // 代理商邀请 | 'new_task' // 新任务分配 | 'pass' // 审核通过 | 'need_fix' // 需要修改 | 'ai_complete' // AI审核完成 | 'agency_pass' // 代理商审核通过 | 'agency_reject' // 代理商审核驳回 | 'brand_pass' // 品牌方审核通过 | 'brand_reject' // 品牌方审核驳回 | 'video_ai' // 视频AI审核完成 | 'appeal' // 申诉结果 | 'video_agency_reject' // 视频代理商驳回 | 'video_brand_reject' // 视频品牌方驳回 type Message = { id: string type: MessageType title: string content: string time: string read: boolean taskId?: string hasActions?: boolean // 是否有操作按钮(邀请类型) } // 消息配置 const messageConfig: Record = { invite: { icon: UserPlus, iconColor: 'text-purple-400', bgColor: 'bg-purple-500/20' }, new_task: { icon: ClipboardList, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, pass: { icon: CheckCircle, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, need_fix: { icon: PenLine, iconColor: 'text-accent-coral', bgColor: 'bg-accent-coral/20' }, ai_complete: { icon: ScanSearch, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, agency_pass: { icon: Building2, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, agency_reject: { icon: XCircle, iconColor: 'text-accent-coral', bgColor: 'bg-accent-coral/20' }, brand_pass: { icon: BadgeCheck, iconColor: 'text-accent-green', bgColor: 'bg-accent-green/20' }, brand_reject: { icon: XCircle, iconColor: 'text-accent-coral', bgColor: 'bg-accent-coral/20' }, video_ai: { icon: Video, iconColor: 'text-accent-indigo', bgColor: 'bg-accent-indigo/20' }, appeal: { icon: MessageCircle, iconColor: 'text-accent-blue', bgColor: 'bg-accent-blue/20' }, video_agency_reject: { icon: XCircle, iconColor: 'text-accent-coral', bgColor: 'bg-accent-coral/20' }, video_brand_reject: { icon: XCircle, iconColor: 'text-accent-coral', bgColor: 'bg-accent-coral/20' }, } // 12条消息数据 const mockMessages: Message[] = [ { id: 'msg-001', type: 'invite', title: '代理商邀请', content: '「星辰传媒」邀请您成为签约达人,加入后可接收该代理商分配的推广任务', time: '5分钟前', read: false, hasActions: true, }, { id: 'msg-002', type: 'new_task', title: '新任务分配', content: '您有一个新任务【XX品牌618推广】,请在3天内提交脚本', time: '10分钟前', read: false, taskId: 'task-001', }, { id: 'msg-003', type: 'pass', title: '审核通过', content: '恭喜!您的视频【AA数码新品发布】已通过审核,可安排发布', time: '2小时前', read: true, taskId: 'task-004', }, { id: 'msg-004', type: 'need_fix', title: '需要修改', content: '您的视频【ZZ饮品夏日】有2处需修改:00:15竞品露出、00:42口播违规词,点击查看详情', time: '昨天 14:30', read: true, taskId: 'task-003', }, { id: 'msg-005', type: 'ai_complete', title: 'AI审核完成', content: '您的脚本【CC服装春季款】AI预审已完成,已进入代理商审核', time: '30分钟前', read: true, taskId: 'task-006', }, { id: 'msg-006', type: 'agency_pass', title: '代理商审核通过', content: '您的脚本【DD家电测评】已通过代理商审核,等待品牌方终审', time: '1小时前', read: true, taskId: 'task-007', }, { id: 'msg-007', type: 'agency_reject', title: '代理商审核驳回', content: '您的脚本【HH美妆代言】被代理商驳回,原因:品牌调性不符,请修改后重新提交', time: '2小时前', read: true, taskId: 'task-010', }, { id: 'msg-008', type: 'brand_pass', title: '品牌方审核通过', content: '恭喜!您的脚本【EE食品试吃】已通过品牌方终审,请在7天内上传视频', time: '昨天 14:30', read: true, taskId: 'task-008', }, { id: 'msg-009', type: 'brand_reject', title: '品牌方审核驳回', content: '您的脚本【II数码配件】被品牌方驳回,原因:产品卖点不够突出,请修改后重新提交', time: '昨天 16:45', read: true, taskId: 'task-011', }, { id: 'msg-010', type: 'video_ai', title: '视频AI审核完成', content: '您的视频【JJ旅行vlog】AI预审已完成,已进入代理商审核环节', time: '今天 09:15', read: true, taskId: 'task-013', }, { id: 'msg-011', type: 'appeal', title: '申诉结果通知', content: '您的申诉已通过,AI已学习您的反馈,感谢您帮助我们改进系统', time: '3天前', read: false, }, { id: 'msg-012', type: 'video_agency_reject', title: '视频代理商审核驳回', content: '您的视频【KK宠物用品】被代理商驳回,原因:背景音乐版权问题,请修改后重新提交', time: '今天 11:20', read: true, taskId: 'task-014', }, { id: 'msg-013', type: 'video_brand_reject', title: '视频品牌方审核驳回', content: '您的视频【MM厨房电器】被品牌方驳回,原因:产品使用场景不够真实,请修改后重新提交', time: '昨天 18:30', read: true, taskId: 'task-015', }, ] // 消息卡片组件 function MessageCard({ message, onRead, onNavigate, onAcceptInvite, onIgnoreInvite, }: { message: Message onRead: () => void onNavigate: () => void onAcceptInvite?: () => void onIgnoreInvite?: () => void }) { const config = messageConfig[message.type] const Icon = config.icon return (
{ onRead() if (message.taskId) onNavigate() }} > {/* 图标 */}
{/* 内容 */}
{/* 头部 */}
{message.title} {message.time}
{/* 描述 */}

{message.content}

{/* 邀请类型的操作按钮 */} {message.hasActions && (
)}
{/* 未读标记 */} {!message.read && (
)}
) } // 邀请确认弹窗 function InviteConfirmModal({ isOpen, type, agencyName, onClose, onConfirm, }: { isOpen: boolean type: 'accept' | 'ignore' agencyName: string onClose: () => void onConfirm: () => void }) { if (!isOpen) return null const isAccept = type === 'accept' return (

{isAccept ? '确认接受邀请' : '确认忽略邀请'}

{isAccept ? `您确定要接受「${agencyName}」的签约邀请吗?接受后您将成为该代理商的签约达人,可以接收推广任务。` : `您确定要忽略「${agencyName}」的邀请吗?您可以稍后在消息中心重新查看此邀请。`}

) } // 成功提示弹窗 function SuccessModal({ isOpen, message, onClose, }: { isOpen: boolean message: string onClose: () => void }) { if (!isOpen) return null return (

{message}

) } export default function CreatorMessagesPage() { const router = useRouter() const [messages, setMessages] = useState(mockMessages) const [confirmModal, setConfirmModal] = useState<{ isOpen: boolean; type: 'accept' | 'ignore'; messageId: string }>({ isOpen: false, type: 'accept', messageId: '', }) const [successModal, setSuccessModal] = useState<{ isOpen: boolean; message: string }>({ isOpen: false, message: '', }) const markAsRead = (id: string) => { setMessages(prev => prev.map(msg => msg.id === id ? { ...msg, read: true } : msg )) } const markAllAsRead = () => { setMessages(prev => prev.map(msg => ({ ...msg, read: true }))) } // 根据消息类型跳转到对应页面 const navigateByMessage = (message: Message) => { // 标记已读 markAsRead(message.id) // 根据消息类型决定跳转目标 switch (message.type) { case 'invite': // 邀请消息不跳转,在卡片内有操作按钮 break case 'new_task': // 新任务 -> 跳转到任务详情(上传脚本) if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'pass': // 审核通过 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'need_fix': // 需要修改 -> 跳转到任务详情(查看问题) if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'ai_complete': // AI审核完成 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'agency_pass': // 代理商审核通过 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'agency_reject': // 代理商审核驳回 -> 跳转到任务详情(查看驳回原因) if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'brand_pass': // 品牌方审核通过 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'brand_reject': // 品牌方审核驳回 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'video_ai': // 视频AI审核完成 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'appeal': // 申诉结果 -> 跳转到申诉中心 router.push('/creator/appeals') break case 'video_agency_reject': // 视频代理商驳回 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break case 'video_brand_reject': // 视频品牌方驳回 -> 跳转到任务详情 if (message.taskId) router.push(`/creator/task/${message.taskId}`) break default: if (message.taskId) router.push(`/creator/task/${message.taskId}`) } } const handleAcceptInvite = (messageId: string) => { setConfirmModal({ isOpen: true, type: 'accept', messageId }) } const handleIgnoreInvite = (messageId: string) => { setConfirmModal({ isOpen: true, type: 'ignore', messageId }) } const handleConfirmAction = () => { const { type, messageId } = confirmModal setConfirmModal({ ...confirmModal, isOpen: false }) // 更新消息状态 setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, hasActions: false, read: true } : msg )) // 显示成功提示 setSuccessModal({ isOpen: true, message: type === 'accept' ? '已成功接受邀请!您现在可以接收该代理商分配的推广任务了。' : '已忽略该邀请。如需重新查看,请联系代理商。', }) } // 获取当前确认弹窗的代理商名称 const getAgencyName = () => { const message = messages.find(m => m.id === confirmModal.messageId) if (message?.content.includes('「')) { const match = message.content.match(/「([^」]+)」/) return match ? match[1] : '该代理商' } return '该代理商' } return (
{/* 顶部栏 */}

消息中心

查看任务通知、审核结果和申诉反馈

{/* 消息列表 - 可滚动 */}
{messages.map((message) => ( markAsRead(message.id)} onNavigate={() => navigateByMessage(message)} onAcceptInvite={() => handleAcceptInvite(message.id)} onIgnoreInvite={() => handleIgnoreInvite(message.id)} /> ))}
{/* 确认弹窗 */} setConfirmModal({ ...confirmModal, isOpen: false })} onConfirm={handleConfirmAction} /> {/* 成功提示弹窗 */} setSuccessModal({ ...successModal, isOpen: false })} />
) }