'use client'; import { useRef, useState } from 'react'; import { apiFetch } from '../lib/api'; type ExistingSubmission = { id: number; comment: string | null; proof_url: string | null; resume_link: string | null; passport_url: string | null; photo_url: string | null; resume_url: string | null; status: 'pending' | 'approved' | 'rejected'; }; interface MissionSubmissionFormProps { missionId: number; token?: string; locked?: boolean; submission?: ExistingSubmission | null; completed?: boolean; requiresDocuments?: boolean; } export function MissionSubmissionForm({ missionId, token, locked = false, submission, completed = false, requiresDocuments = false }: MissionSubmissionFormProps) { const [comment, setComment] = useState(submission?.comment ?? ''); const [proofUrl, setProofUrl] = useState(submission?.proof_url ?? ''); const [resumeLink, setResumeLink] = useState(submission?.resume_link ?? ''); const initialStatus = submission?.status === 'approved' || completed ? 'Миссия уже зачтена. Вы можете просматривать прикреплённые документы.' : null; const [status, setStatus] = useState(initialStatus); const [loading, setLoading] = useState(false); const [currentSubmission, setCurrentSubmission] = useState(submission ?? null); const passportInputRef = useRef(null); const photoInputRef = useRef(null); const resumeInputRef = useRef(null); const isApproved = completed || currentSubmission?.status === 'approved'; async function handleSubmit(event: React.FormEvent) { event.preventDefault(); if (!token) { setStatus('Не удалось получить токен демо-пользователя.'); return; } if (locked) { setStatus('Миссия пока недоступна — выполните предыдущие условия.'); return; } if (isApproved) { setStatus('Миссия уже зачтена. Дополнительная отправка не требуется.'); return; } const passportFile = passportInputRef.current?.files?.[0]; const photoFile = photoInputRef.current?.files?.[0]; const resumeFile = resumeInputRef.current?.files?.[0]; const resumeTrimmed = resumeLink.trim(); if (requiresDocuments) { if (!currentSubmission?.passport_url && !passportFile) { setStatus('Добавьте скан паспорта кандидата.'); return; } if (!currentSubmission?.photo_url && !photoFile) { setStatus('Приложите фотографию кандидата.'); return; } const hasResumeAttachment = Boolean(currentSubmission?.resume_url || currentSubmission?.resume_link); if (!hasResumeAttachment && !resumeFile && !resumeTrimmed) { setStatus('Укажите ссылку на резюме или загрузите файл.'); return; } } const formData = new FormData(); formData.append('comment', comment.trim()); formData.append('proof_url', proofUrl.trim()); formData.append('resume_link', resumeTrimmed); if (passportFile) { formData.append('passport', passportFile); } if (photoFile) { formData.append('photo', photoFile); } if (resumeFile) { formData.append('resume_file', resumeFile); } try { setLoading(true); setStatus(null); const updated = await apiFetch(`/api/missions/${missionId}/submit`, { method: 'POST', body: formData, authToken: token }); setCurrentSubmission(updated); setComment(updated.comment ?? ''); setProofUrl(updated.proof_url ?? ''); setResumeLink(updated.resume_link ?? ''); if (passportInputRef.current) passportInputRef.current.value = ''; if (photoInputRef.current) photoInputRef.current.value = ''; if (resumeInputRef.current) resumeInputRef.current.value = ''; const nextStatus = updated.status === 'approved' ? 'Миссия уже зачтена. Вы можете просматривать прикреплённые документы.' : 'Отчёт и документы отправлены! HR проверит миссию в панели модерации.'; setStatus(nextStatus); } catch (error) { if (error instanceof Error) { setStatus(error.message); } else { setStatus('Не удалось отправить данные. Попробуйте позже.'); } } finally { setLoading(false); } } return (

Отправить отчёт

{requiresDocuments && (

Для этой миссии необходимо приложить паспорт, фотографию и резюме. Файлы попадут напрямую в панель HR.

)}