'use client' import { useState, useEffect, useCallback } from 'react' import Link from 'next/link' import { Card, CardContent } from '@/components/ui/Card' import { Button } from '@/components/ui/Button' import { SuccessTag, PendingTag, WarningTag } from '@/components/ui/Tag' import { Modal } from '@/components/ui/Modal' import { Search, Plus, Filter, FileText, Video, ChevronRight, Calendar, Users, Pencil, Loader2 } from 'lucide-react' import { api } from '@/lib/api' import { USE_MOCK } from '@/contexts/AuthContext' import { useSSE } from '@/contexts/SSEContext' import { useToast } from '@/components/ui/Toast' import type { ProjectResponse } from '@/types/project' // ==================== Mock 数据 ==================== const mockProjects: ProjectResponse[] = [ { id: 'proj-001', name: 'XX品牌618推广', brand_id: 'br-001', brand_name: 'XX品牌', status: 'active', deadline: '2026-06-18', agencies: [], task_count: 20, created_at: '2026-02-01T00:00:00Z', updated_at: '2026-02-05T00:00:00Z', }, { id: 'proj-002', name: '新品口红系列', brand_id: 'br-001', brand_name: 'XX品牌', status: 'active', deadline: '2026-03-15', agencies: [], task_count: 12, created_at: '2026-01-15T00:00:00Z', updated_at: '2026-02-01T00:00:00Z', }, { id: 'proj-003', name: '护肤品秋季活动', brand_id: 'br-001', brand_name: 'XX品牌', status: 'completed', deadline: '2025-11-30', agencies: [], task_count: 15, created_at: '2025-08-01T00:00:00Z', updated_at: '2025-11-30T00:00:00Z', }, { id: 'proj-004', name: '双11预热活动', brand_id: 'br-001', brand_name: 'XX品牌', status: 'active', deadline: '2026-11-11', agencies: [], task_count: 18, created_at: '2026-01-10T00:00:00Z', updated_at: '2026-02-04T00:00:00Z', }, ] // ==================== 组件 ==================== function StatusTag({ status }: { status: string }) { if (status === 'active') return 进行中 if (status === 'completed') return 已完成 if (status === 'archived') return 已归档 return 暂停 } function ProjectCard({ project, onEditDeadline }: { project: ProjectResponse; onEditDeadline: (project: ProjectResponse) => void }) { return (
{project.brand_name || '品牌项目'}

{project.name}

截止 {project.deadline ? new Date(project.deadline).toLocaleDateString('zh-CN') : '未设置'}
{project.task_count} 个任务 {project.agencies.length} 个代理商
创建于 {new Date(project.created_at).toLocaleDateString('zh-CN')}
) } function ProjectsSkeleton() { return (
{[1, 2, 3, 4].map(i => (
))}
) } export default function BrandProjectsPage() { const [searchQuery, setSearchQuery] = useState('') const [statusFilter, setStatusFilter] = useState('all') const [projects, setProjects] = useState([]) const [loading, setLoading] = useState(true) const toast = useToast() const { subscribe } = useSSE() // 编辑截止日期 const [showDeadlineModal, setShowDeadlineModal] = useState(false) const [editingProject, setEditingProject] = useState(null) const [newDeadline, setNewDeadline] = useState('') const loadProjects = useCallback(async () => { if (USE_MOCK) { setProjects(mockProjects) setLoading(false) return } try { const statusParam = statusFilter !== 'all' ? statusFilter : undefined const data = await api.listProjects(1, 50, statusParam) setProjects(data.items) } catch (err) { console.error('Failed to load projects:', err) toast.error('加载项目列表失败') } finally { setLoading(false) } }, [statusFilter, toast]) useEffect(() => { loadProjects() }, [loadProjects]) useEffect(() => { const unsub = subscribe('task_updated', () => loadProjects()) return unsub }, [subscribe, loadProjects]) const handleEditDeadline = (project: ProjectResponse) => { setEditingProject(project) setNewDeadline(project.deadline || '') setShowDeadlineModal(true) } const handleSaveDeadline = async () => { if (!editingProject || !newDeadline) return try { if (!USE_MOCK) { await api.updateProject(editingProject.id, { deadline: newDeadline }) } setProjects(prev => prev.map(p => p.id === editingProject.id ? { ...p, deadline: newDeadline } : p )) toast.success('截止日期已更新') } catch (err) { console.error('Failed to update deadline:', err) toast.error('更新失败') } setShowDeadlineModal(false) setEditingProject(null) } if (loading) return const filteredProjects = projects.filter(project => { const matchesSearch = project.name.toLowerCase().includes(searchQuery.toLowerCase()) const matchesStatus = statusFilter === 'all' || project.status === statusFilter return matchesSearch && matchesStatus }) return (

项目看板

管理所有营销项目的审核进度

setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-border-subtle rounded-lg bg-bg-elevated text-text-primary focus:outline-none focus:ring-2 focus:ring-accent-indigo" />
{filteredProjects.map((project) => ( ))}
{filteredProjects.length === 0 && (

暂无匹配的项目

)} { setShowDeadlineModal(false); setEditingProject(null) }} title="修改截止日期" >
{editingProject && (

项目名称

{editingProject.name}

)}
setNewDeadline(e.target.value)} className="w-full pl-12 pr-4 py-3 border border-border-subtle rounded-lg bg-bg-elevated text-text-primary focus:outline-none focus:ring-2 focus:ring-accent-indigo" />
) }