import { useCallback, useEffect, useState } from 'react'; import { Link, useParams } from 'react-router-dom'; import { ArrowLeft, ArrowRight, CalendarRange, Copy, KeyRound, Pencil, Plus, X } from 'lucide-react'; import type { Project, WorkCollection } from '@shared/types'; import { api } from '@/api/client'; import CollectionStatusBadge from '@/components/CollectionStatusBadge'; export default function ProjectPage() { const id = Number(useParams().projectId); const [project, setProject] = useState(null); const [collections, setCollections] = useState([]); const [collectionOpen, setCollectionOpen] = useState(false); const [editOpen, setEditOpen] = useState(false); const [accessOpen, setAccessOpen] = useState(false); const [name, setName] = useState(''); const [desc, setDesc] = useState(''); const [projectName, setProjectName] = useState(''); const [projectDesc, setProjectDesc] = useState(''); const [accessEnabled, setAccessEnabled] = useState(false); const [accessPassword, setAccessPassword] = useState(''); const [expiresAt, setExpiresAt] = useState(''); const [message, setMessage] = useState(''); const load = useCallback(async () => { const [nextProject, nextCollections] = await Promise.all([api.getProject(id), api.listCollections(id)]); setProject(nextProject); setCollections(nextCollections); }, [id]); useEffect(() => { void load(); }, [load]); if (!project) return null; const reviewUrl = `${window.location.origin}/review/${project.slug}`; const createCollection = async () => { await api.createCollection(id, { name, client_description: desc }); setCollectionOpen(false); setName(''); setDesc(''); await load(); }; const editProject = async () => { setProject(await api.updateProject(id, { name: projectName, client_description: projectDesc })); setEditOpen(false); }; const openAccess = () => { setAccessEnabled(Boolean(project.customer_access_enabled)); setAccessPassword(''); setExpiresAt(project.access_expires_at?.slice(0, 16) || ''); setMessage(''); setAccessOpen(true); }; const saveAccess = async () => { try { const updated = await api.updateCustomerAccess(id, { enabled: accessEnabled, password: accessPassword || undefined, expires_at: expiresAt || null }); setProject(updated); setMessage('客户访问设置已保存'); setAccessPassword(''); } catch (reason) { setMessage(reason instanceof Error ? reason.message : '保存失败'); } }; return
返回项目

Client Project / {project.slug}

{project.name}

{project.client_description}

COLLECTIONS

作品交付集

{collections.map((item,index)=>
{String(index+1).padStart(2,'0')}

{item.name}

{item.client_description || '暂无说明'}

{item.approved_count}/{item.work_count}{item.work_count ? '已通过' : '尚无待验收作品'}
)}
{collectionOpen&&setCollectionOpen(false)} icon={} title="新建作品交付集">setName(e.target.value)}/>