import { useEffect, useState, useRef } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import api from '../../api/client'; const STATUS_LABEL = { draft: '임시저장', pending: '검토 대기', approved: '승인됨', rejected: '반려됨', suspended: '정지됨', }; export default function ProjectEdit() { const { id } = useParams(); const navigate = useNavigate(); const [project, setProject] = useState(null); const [form, setForm] = useState({}); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(''); const [msg, setMsg] = useState(''); const [files, setFiles] = useState([]); const [fileType, setFileType] = useState('image'); const fileRef = useRef(); useEffect(() => { api.get(`/projects/${id}`) .then(r => { setProject(r.data); setForm({ title: r.data.title, description: r.data.description, difficultyLevel: r.data.difficultyLevel }); }) .catch(() => navigate('/dashboard')) .finally(() => setLoading(false)); }, [id]); async function handleSave(e) { e.preventDefault(); setSaving(true); try { await api.put(`/projects/${id}`, form); setMsg('저장되었습니다'); } catch (err) { setError(err.response?.data?.error || '저장 실패'); } finally { setSaving(false); } } async function handleUpload() { if (!files.length) return; setSaving(true); try { const fd = new FormData(); fd.append('fileType', fileType); files.forEach(f => fd.append('files', f)); const { data } = await api.post(`/projects/${id}/files`, fd, { headers: { 'Content-Type': 'multipart/form-data' }, }); setProject(p => ({ ...p, files: [...(p.files || []), ...data] })); setFiles([]); setMsg('파일이 업로드되었습니다'); } catch (err) { setError(err.response?.data?.error || '업로드 실패'); } finally { setSaving(false); } } async function handleDeleteFile(fileId) { if (!confirm('파일을 삭제하시겠습니까?')) return; await api.delete(`/projects/${id}/files/${fileId}`); setProject(p => ({ ...p, files: p.files.filter(f => f.id !== fileId) })); } async function handleSubmit() { setSaving(true); try { await api.post(`/projects/${id}/submit`); navigate('/dashboard'); } catch (err) { setError(err.response?.data?.error || '제출 실패'); } finally { setSaving(false); } } if (loading) return
; const canEdit = ['draft', 'rejected'].includes(project?.status); return (

프로젝트 관리

{STATUS_LABEL[project.status]}
{project.adminNote && (
관리자 메모: {project.adminNote}
)} {error &&
{error}
} {msg &&
{msg}
} {/* 기본 정보 수정 */}

기본 정보

setForm(f => ({ ...f, title: e.target.value }))} />