diff --git a/src/pages/TaskDetail.jsx b/src/pages/TaskDetail.jsx index 6e91dca..05a457b 100644 --- a/src/pages/TaskDetail.jsx +++ b/src/pages/TaskDetail.jsx @@ -63,7 +63,7 @@ const LABEL = { fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', l const META_LABEL = { fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 4 }; const CARD_META_LABEL = { fontSize: 11, fontWeight: 500, color: 'var(--text-secondary)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 2 }; -const TABS = ['Overview', 'Revisions', 'Comments', 'Folder']; +const TABS = ['Overview', 'Revisions', 'Submissions', 'Comments', 'Folder']; function TimelineCard({ task, activityLog, currentSubmission }) { const status = task?.status; @@ -221,6 +221,7 @@ export default function TaskDetail() { const amendFileRef = useRef(null); const [reviewModal, setReviewModal] = useState(false); const [reviewFiles, setReviewFiles] = useState([]); + const [reviewNotes, setReviewNotes] = useState(''); const [reviewSaving, setReviewSaving] = useState(false); const reviewFileRef = useRef(null); const [comments, setComments] = useState([]); @@ -266,6 +267,7 @@ export default function TaskDetail() { const submission = submissions.find(s => s.type === 'initial') || submissions[0] || null; const amendments = submissions.filter(s => s.type === 'amendment'); const revisions = submissions.filter(s => s.type === 'revision').sort((a, b) => a.version_number - b.version_number); + const reviewSubmissions = submissions.filter(s => s.type === 'submission').sort((a, b) => new Date(b.submitted_at) - new Date(a.submitted_at)); const assignee = task.assignee; const assigneeName = assignee?.name || task.assigned_name || null; @@ -295,31 +297,28 @@ export default function TaskDetail() { const handleStart = () => updateStatus('in_progress', { assigned_to: currentUser.id, assigned_name: currentUser.name }, 'task_started'); const handleOnHold = () => updateStatus('on_hold', {}, 'task_on_hold'); const handleResume = () => updateStatus('in_progress', {}, 'task_resumed'); - const handleSendToReview = () => { setReviewFiles([]); setReviewModal(true); }; + const handleSendToReview = () => { setReviewFiles([]); setReviewNotes(''); setReviewModal(true); }; const handleRemoveFromReview = () => updateStatus('in_progress', {}, 'task_resumed'); const handleConfirmReview = async () => { setReviewSaving(true); try { - if (reviewFiles.length > 0) { - let sub = submission; - if (!sub) { - const { data: newSub } = await supabase.from('submissions').insert({ task_id: id, type: 'initial', version_number: task.current_version || 0, service_type: task.title, submitted_by: currentUser.id, submitted_by_name: currentUser.name }).select().single(); - sub = newSub; - } - if (sub) { - const uploaded = []; - for (const file of reviewFiles) { - const path = `${id}/${Date.now()}_${file.name}`; - const { data: up } = await supabase.storage.from('submissions').upload(path, file); - if (up) uploaded.push({ name: file.name, storage_path: path, size: file.size, submission_id: sub.id }); - } - if (uploaded.length > 0) await supabase.from('submission_files').insert(uploaded); - if (project?.name && task?.title) uploadFilesToRequestInfo(reviewFiles, company?.name, project.name, task.title, task.current_version || 0).catch(() => {}); + const { data: newSub } = await supabase.from('submissions').insert({ task_id: id, type: 'submission', version_number: task.current_version || 0, service_type: task.title, description: reviewNotes.trim() || null, submitted_by: currentUser.id, submitted_by_name: currentUser.name }).select().single(); + if (newSub && reviewFiles.length > 0) { + const uploaded = []; + for (const file of reviewFiles) { + const path = `${id}/${Date.now()}_${file.name}`; + const { data: up } = await supabase.storage.from('submissions').upload(path, file); + if (up) uploaded.push({ name: file.name, storage_path: path, size: file.size, submission_id: newSub.id }); } + if (uploaded.length > 0) await supabase.from('submission_files').insert(uploaded); + if (project?.name && task?.title) uploadFilesToRequestInfo(reviewFiles, company?.name, project.name, task.title, task.current_version || 0).catch(() => {}); } + const { data: subRows } = await supabase.from('submissions').select('id, type, version_number, submitted_by, submitted_by_name, submitted_at, service_type, deadline, description, is_hot, sign_family, sign_count, files:submission_files(id, name, storage_path, size)').eq('task_id', id).order('submitted_at', { ascending: true }); + setSubmissions(subRows || []); await updateStatus('client_review', {}, 'task_submitted'); setReviewModal(false); setReviewFiles([]); + setReviewNotes(''); } finally { setReviewSaving(false); } @@ -528,7 +527,7 @@ export default function TaskDetail() {