'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import PageLayout from '../../../components/PageLayout' import useAuthStore from '../../../store/authStore' import { useUserStatus } from '../../../hooks/useUserStatus' import { API_BASE_URL } from '../../../utils/api' export default function CompanySignContractPage() { const router = useRouter() const { accessToken } = useAuthStore() const { refreshStatus } = useUserStatus() const [companyName, setCompanyName] = useState('') const [repName, setRepName] = useState('') const [repTitle, setRepTitle] = useState('') const [location, setLocation] = useState('') const [date, setDate] = useState('') const [note, setNote] = useState('') const [agreeContract, setAgreeContract] = useState(false) const [agreeData, setAgreeData] = useState(false) const [confirmSignature, setConfirmSignature] = useState(false) const [submitting, setSubmitting] = useState(false) const [success, setSuccess] = useState(false) const [error, setError] = useState('') const [previewLoading, setPreviewLoading] = useState(false) const [previewHtml, setPreviewHtml] = useState(null) const [previewError, setPreviewError] = useState(null) useEffect(() => { setDate(new Date().toISOString().slice(0,10)) }, []) // Load latest contract preview for company user useEffect(() => { const loadPreview = async () => { if (!accessToken) return setPreviewLoading(true) setPreviewError(null) try { const res = await fetch(`${API_BASE_URL}/api/contracts/preview/latest`, { method: 'GET', headers: { Authorization: `Bearer ${accessToken}` }, credentials: 'include' }) if (!res.ok) { const text = await res.text().catch(() => '') throw new Error(text || 'Failed to load contract preview') } const html = await res.text() setPreviewHtml(html) } catch (e: any) { console.error('CompanySignContractPage.loadPreview error:', e) setPreviewError(e?.message || 'Failed to load contract preview') setPreviewHtml(null) } finally { setPreviewLoading(false) } } loadPreview() }, [accessToken]) const valid = () => { const companyValid = companyName.trim().length >= 3 // Min 3 characters for company name const repNameValid = repName.trim().length >= 3 // Min 3 characters for representative name const repTitleValid = repTitle.trim().length >= 2 // Min 2 characters for title const locationValid = location.trim().length >= 2 // Min 2 characters for location const contractChecked = agreeContract const dataChecked = agreeData const signatureChecked = confirmSignature return companyValid && repNameValid && repTitleValid && locationValid && contractChecked && dataChecked && signatureChecked } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!valid()) { // Detailed error message to help debug const issues = [] if (companyName.trim().length < 3) issues.push('Company name (min 3 characters)') if (repName.trim().length < 3) issues.push('Representative name (min 3 characters)') if (repTitle.trim().length < 2) issues.push('Representative title (min 2 characters)') if (location.trim().length < 2) issues.push('Location (min 2 characters)') if (!agreeContract) issues.push('Contract read and understood') if (!agreeData) issues.push('Privacy policy accepted') if (!confirmSignature) issues.push('Electronic signature confirmed') setError(`Please complete: ${issues.join(', ')}`) return } if (!accessToken) { setError('Not authenticated. Please log in again.') return } setError('') setSubmitting(true) try { const contractData = { companyName: companyName.trim(), representativeName: repName.trim(), representativeTitle: repTitle.trim(), location: location.trim(), date, note: note.trim() || null, contractType: 'company', confirmations: { agreeContract, agreeData, confirmSignature } } // Create FormData for the existing backend endpoint const formData = new FormData() formData.append('contractData', JSON.stringify(contractData)) // Create a dummy PDF file since the backend expects one (electronic signature) const dummyPdfContent = '%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n2 0 obj\n<<\n/Type /Pages\n/Kids [3 0 R]\n/Count 1\n>>\nendobj\n3 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/MediaBox [0 0 612 792]\n/Contents 4 0 R\n>>\nendobj\n4 0 obj\n<<\n/Length 44\n>>\nstream\nBT\n/F1 12 Tf\n100 700 Td\n(Electronic Signature) Tj\nET\nendstream\nendobj\nxref\n0 5\n0000000000 65535 f \n0000000010 00000 n \n0000000079 00000 n \n0000000136 00000 n \n0000000225 00000 n \ntrailer\n<<\n/Size 5\n/Root 1 0 R\n>>\nstartxref\n319\n%%EOF' const dummyFile = new Blob([dummyPdfContent], { type: 'application/pdf' }) formData.append('contract', dummyFile, 'electronic_signature.pdf') const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/upload/contract/company`, { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}` // Don't set Content-Type, let browser set it for FormData }, body: formData }) if (!response.ok) { const errorData = await response.json().catch(() => ({ message: 'Contract signing failed' })) throw new Error(errorData.message || 'Contract signing failed') } setSuccess(true) // Refresh user status to update contract signed state await refreshStatus() // Redirect to main dashboard after short delay setTimeout(() => { // Check if we came from tutorial const urlParams = new URLSearchParams(window.location.search) const fromTutorial = urlParams.get('tutorial') === 'true' if (fromTutorial) { router.push('/quickaction-dashboard?tutorial=true') } else { router.push('/quickaction-dashboard') } }, 2000) } catch (error: any) { console.error('Contract signing error:', error) setError(error.message || 'Signature failed. Please try again.') } finally { setSubmitting(false) } } return (
{/* Background */}

Sign Company Partnership Contract

Please review the contract details and sign on behalf of the company.

{/* Meta + Preview */}

Contract Information

  • Contract ID: COMP-2024-017
  • Version: 2.4 (valid from 01.11.2024)
  • Jurisdiction: EU / Germany
  • Language: DE (binding)

Attention

You confirm that you are authorized to sign on behalf of the company.

Company Contract Preview

{previewLoading ? (
Loading preview…
) : previewError ? (
{previewError}
) : previewHtml ? (