Compare commits
No commits in common. "d96f13474cfcb27983bd6a5e87e1dcc8a68e5e7c" and "25fff9b1c3a261c84829f830bbd9cc6bff03cd7b" have entirely different histories.
d96f13474c
...
25fff9b1c3
@ -21,16 +21,6 @@ interface CompanyProfileData {
|
|||||||
emergencyPhone: string
|
emergencyPhone: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common countries list
|
|
||||||
const COUNTRIES = [
|
|
||||||
'Germany', 'Austria', 'Switzerland', 'Italy', 'France', 'Spain', 'Portugal', 'Netherlands',
|
|
||||||
'Belgium', 'Poland', 'Czech Republic', 'Hungary', 'Croatia', 'Slovenia', 'Slovakia',
|
|
||||||
'United Kingdom', 'Ireland', 'Sweden', 'Norway', 'Denmark', 'Finland', 'Russia',
|
|
||||||
'Turkey', 'Greece', 'Romania', 'Bulgaria', 'Serbia', 'Albania', 'Bosnia and Herzegovina',
|
|
||||||
'United States', 'Canada', 'Brazil', 'Argentina', 'Mexico', 'China', 'Japan',
|
|
||||||
'India', 'Pakistan', 'Australia', 'South Africa', 'Other'
|
|
||||||
]
|
|
||||||
|
|
||||||
const init: CompanyProfileData = {
|
const init: CompanyProfileData = {
|
||||||
companyName: '',
|
companyName: '',
|
||||||
vatNumber: '',
|
vatNumber: '',
|
||||||
@ -56,7 +46,7 @@ export default function CompanyAdditionalInformationPage() {
|
|||||||
const [success, setSuccess] = useState(false)
|
const [success, setSuccess] = useState(false)
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target
|
const { name, value } = e.target
|
||||||
setForm(p => ({ ...p, [name]: value }))
|
setForm(p => ({ ...p, [name]: value }))
|
||||||
setError('')
|
setError('')
|
||||||
@ -241,20 +231,13 @@ export default function CompanyAdditionalInformationPage() {
|
|||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Country *
|
Country *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<input
|
||||||
name="country"
|
name="country"
|
||||||
value={form.country}
|
value={form.country}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||||
required
|
required
|
||||||
>
|
/>
|
||||||
<option value="">Select country...</option>
|
|
||||||
{COUNTRIES.map(country => (
|
|
||||||
<option key={country} value={country}>
|
|
||||||
{country}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -20,26 +20,6 @@ interface PersonalProfileData {
|
|||||||
emergencyPhone: string
|
emergencyPhone: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common nationalities list
|
|
||||||
const NATIONALITIES = [
|
|
||||||
'German', 'Austrian', 'Swiss', 'Italian', 'French', 'Spanish', 'Portuguese', 'Dutch',
|
|
||||||
'Belgian', 'Polish', 'Czech', 'Hungarian', 'Croatian', 'Slovenian', 'Slovak',
|
|
||||||
'British', 'Irish', 'Swedish', 'Norwegian', 'Danish', 'Finnish', 'Russian',
|
|
||||||
'Turkish', 'Greek', 'Romanian', 'Bulgarian', 'Serbian', 'Albanian', 'Bosnian',
|
|
||||||
'American', 'Canadian', 'Brazilian', 'Argentinian', 'Mexican', 'Chinese',
|
|
||||||
'Japanese', 'Indian', 'Pakistani', 'Australian', 'South African', 'Other'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Common countries list
|
|
||||||
const COUNTRIES = [
|
|
||||||
'Germany', 'Austria', 'Switzerland', 'Italy', 'France', 'Spain', 'Portugal', 'Netherlands',
|
|
||||||
'Belgium', 'Poland', 'Czech Republic', 'Hungary', 'Croatia', 'Slovenia', 'Slovakia',
|
|
||||||
'United Kingdom', 'Ireland', 'Sweden', 'Norway', 'Denmark', 'Finland', 'Russia',
|
|
||||||
'Turkey', 'Greece', 'Romania', 'Bulgaria', 'Serbia', 'Albania', 'Bosnia and Herzegovina',
|
|
||||||
'United States', 'Canada', 'Brazil', 'Argentina', 'Mexico', 'China', 'Japan',
|
|
||||||
'India', 'Pakistan', 'Australia', 'South Africa', 'Other'
|
|
||||||
]
|
|
||||||
|
|
||||||
const initialData: PersonalProfileData = {
|
const initialData: PersonalProfileData = {
|
||||||
dob: '',
|
dob: '',
|
||||||
nationality: '',
|
nationality: '',
|
||||||
@ -64,37 +44,12 @@ export default function PersonalAdditionalInformationPage() {
|
|||||||
const [success, setSuccess] = useState(false)
|
const [success, setSuccess] = useState(false)
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const { name, value } = e.target
|
const { name, value } = e.target
|
||||||
setForm(p => ({ ...p, [name]: value }))
|
setForm(p => ({ ...p, [name]: value }))
|
||||||
setError('')
|
setError('')
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateDateOfBirth = (dob: string) => {
|
|
||||||
if (!dob) return false
|
|
||||||
|
|
||||||
const birthDate = new Date(dob)
|
|
||||||
const today = new Date()
|
|
||||||
|
|
||||||
// Check if date is valid
|
|
||||||
if (isNaN(birthDate.getTime())) return false
|
|
||||||
|
|
||||||
// Check if birth date is not in the future
|
|
||||||
if (birthDate > today) return false
|
|
||||||
|
|
||||||
// Check minimum age (18 years)
|
|
||||||
const minDate = new Date()
|
|
||||||
minDate.setFullYear(today.getFullYear() - 18)
|
|
||||||
if (birthDate > minDate) return false
|
|
||||||
|
|
||||||
// Check maximum age (120 years)
|
|
||||||
const maxDate = new Date()
|
|
||||||
maxDate.setFullYear(today.getFullYear() - 120)
|
|
||||||
if (birthDate < maxDate) return false
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const validate = () => {
|
const validate = () => {
|
||||||
const requiredKeys: (keyof PersonalProfileData)[] = [
|
const requiredKeys: (keyof PersonalProfileData)[] = [
|
||||||
'dob','nationality','street','postalCode','city','country','accountHolder','iban'
|
'dob','nationality','street','postalCode','city','country','accountHolder','iban'
|
||||||
@ -105,13 +60,6 @@ export default function PersonalAdditionalInformationPage() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Date of birth validation
|
|
||||||
if (!validateDateOfBirth(form.dob)) {
|
|
||||||
setError('Ungültiges Geburtsdatum. Sie müssen mindestens 18 Jahre alt sein.')
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// very loose IBAN check
|
// very loose IBAN check
|
||||||
if (!/^([A-Z]{2}\d{2}[A-Z0-9]{10,30})$/i.test(form.iban.replace(/\s+/g,''))) {
|
if (!/^([A-Z]{2}\d{2}[A-Z0-9]{10,30})$/i.test(form.iban.replace(/\s+/g,''))) {
|
||||||
setError('Ungültige IBAN.')
|
setError('Ungültige IBAN.')
|
||||||
@ -227,8 +175,6 @@ export default function PersonalAdditionalInformationPage() {
|
|||||||
name="dob"
|
name="dob"
|
||||||
value={form.dob}
|
value={form.dob}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
min={new Date(new Date().getFullYear() - 120, 0, 1).toISOString().split('T')[0]}
|
|
||||||
max={new Date(new Date().getFullYear() - 18, 11, 31).toISOString().split('T')[0]}
|
|
||||||
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
@ -237,20 +183,14 @@ export default function PersonalAdditionalInformationPage() {
|
|||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Nationality *
|
Nationality *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<input
|
||||||
name="nationality"
|
name="nationality"
|
||||||
value={form.nationality}
|
value={form.nationality}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
placeholder="e.g. German"
|
||||||
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||||
required
|
required
|
||||||
>
|
/>
|
||||||
<option value="">Select nationality...</option>
|
|
||||||
{NATIONALITIES.map(nationality => (
|
|
||||||
<option key={nationality} value={nationality}>
|
|
||||||
{nationality}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="sm:col-span-2 lg:col-span-3">
|
<div className="sm:col-span-2 lg:col-span-3">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
@ -295,20 +235,14 @@ export default function PersonalAdditionalInformationPage() {
|
|||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Country *
|
Country *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<input
|
||||||
name="country"
|
name="country"
|
||||||
value={form.country}
|
value={form.country}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
placeholder="e.g. Germany"
|
||||||
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||||
required
|
required
|
||||||
>
|
/>
|
||||||
<option value="">Select country...</option>
|
|
||||||
{COUNTRIES.map(country => (
|
|
||||||
<option key={country} value={country}>
|
|
||||||
{country}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -14,39 +14,8 @@ export default function EmailVerifyPage() {
|
|||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
const [success, setSuccess] = useState(false)
|
const [success, setSuccess] = useState(false)
|
||||||
const [resendCooldown, setResendCooldown] = useState(0)
|
const [resendCooldown, setResendCooldown] = useState(0)
|
||||||
const [initialEmailSent, setInitialEmailSent] = useState(false)
|
|
||||||
const inputsRef = useRef<Array<HTMLInputElement | null>>([])
|
const inputsRef = useRef<Array<HTMLInputElement | null>>([])
|
||||||
|
|
||||||
// Send verification email automatically on page load
|
|
||||||
useEffect(() => {
|
|
||||||
if (!token || initialEmailSent) return
|
|
||||||
|
|
||||||
const sendInitialEmail = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/send-verification-email`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${token}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const data = await response.json()
|
|
||||||
|
|
||||||
if (response.ok && data.success) {
|
|
||||||
setInitialEmailSent(true)
|
|
||||||
setResendCooldown(30) // Start cooldown after initial send
|
|
||||||
} else {
|
|
||||||
console.error('Failed to send initial verification email:', data.message)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error sending initial verification email:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendInitialEmail()
|
|
||||||
}, [token, initialEmailSent])
|
|
||||||
|
|
||||||
// Cooldown timer
|
// Cooldown timer
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!resendCooldown) return
|
if (!resendCooldown) return
|
||||||
@ -197,23 +166,12 @@ export default function EmailVerifyPage() {
|
|||||||
E-Mail verifizieren
|
E-Mail verifizieren
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-3 text-gray-300 text-sm sm:text-base">
|
<p className="mt-3 text-gray-300 text-sm sm:text-base">
|
||||||
{initialEmailSent ? (
|
Gib den 6-stelligen Code ein, den wir an
|
||||||
<>
|
{' '}
|
||||||
Wir haben einen 6-stelligen Code an{' '}
|
|
||||||
<span className="text-indigo-300 font-medium">
|
<span className="text-indigo-300 font-medium">
|
||||||
{user?.email || 'deine E-Mail'}
|
{user?.email || 'deine E-Mail'}
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
gesendet. Gib ihn unten ein.
|
gesendet haben.
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
E-Mail wird gesendet an{' '}
|
|
||||||
<span className="text-indigo-300 font-medium">
|
|
||||||
{user?.email || 'deine E-Mail'}
|
|
||||||
</span>
|
|
||||||
...
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -28,32 +28,19 @@ export default function CompanySignContractPage() {
|
|||||||
setDate(new Date().toISOString().slice(0,10))
|
setDate(new Date().toISOString().slice(0,10))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const valid = () => {
|
const valid = () =>
|
||||||
const companyValid = companyName.trim().length >= 3 // Min 3 characters for company name
|
companyName.trim().length > 2 &&
|
||||||
const repNameValid = repName.trim().length >= 3 // Min 3 characters for representative name
|
repName.trim().length > 4 &&
|
||||||
const repTitleValid = repTitle.trim().length >= 2 // Min 2 characters for title
|
repTitle.trim().length > 1 &&
|
||||||
const locationValid = location.trim().length >= 2 // Min 2 characters for location
|
location.trim().length > 1 &&
|
||||||
const contractChecked = agreeContract
|
agreeContract &&
|
||||||
const dataChecked = agreeData
|
agreeData &&
|
||||||
const signatureChecked = confirmSignature
|
confirmSignature
|
||||||
|
|
||||||
return companyValid && repNameValid && repTitleValid && locationValid && contractChecked && dataChecked && signatureChecked
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!valid()) {
|
if (!valid()) {
|
||||||
// Detailed error message to help debug
|
setError('Bitte alle Pflichtfelder & Bestätigungen ausfüllen.')
|
||||||
const issues = []
|
|
||||||
if (companyName.trim().length < 3) issues.push('Firmenname (mindestens 3 Zeichen)')
|
|
||||||
if (repName.trim().length < 3) issues.push('Vertreter Name (mindestens 3 Zeichen)')
|
|
||||||
if (repTitle.trim().length < 2) issues.push('Vertretertitel (mindestens 2 Zeichen)')
|
|
||||||
if (location.trim().length < 2) issues.push('Ort (mindestens 2 Zeichen)')
|
|
||||||
if (!agreeContract) issues.push('Vertrag gelesen und verstanden')
|
|
||||||
if (!agreeData) issues.push('Datenschutzerklärung zugestimmt')
|
|
||||||
if (!confirmSignature) issues.push('Elektronische Signatur bestätigt')
|
|
||||||
|
|
||||||
setError(`Bitte vervollständigen: ${issues.join(', ')}`)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,10 +71,9 @@ export default function CompanySignContractPage() {
|
|||||||
// Create FormData for the existing backend endpoint
|
// Create FormData for the existing backend endpoint
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('contractData', JSON.stringify(contractData))
|
formData.append('contractData', JSON.stringify(contractData))
|
||||||
// Create a dummy PDF file since the backend expects one (electronic signature)
|
// Create a dummy file since the backend expects one (we'll update backend later)
|
||||||
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(['Electronic signature data'], { type: 'text/plain' })
|
||||||
const dummyFile = new Blob([dummyPdfContent], { type: 'application/pdf' })
|
formData.append('contract', dummyFile, 'electronic_signature.txt')
|
||||||
formData.append('contract', dummyFile, 'electronic_signature.pdf')
|
|
||||||
|
|
||||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/upload/contract/company`, {
|
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/upload/contract/company`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@ -26,28 +26,17 @@ export default function PersonalSignContractPage() {
|
|||||||
setDate(new Date().toISOString().slice(0, 10))
|
setDate(new Date().toISOString().slice(0, 10))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const valid = () => {
|
const valid = () =>
|
||||||
const nameValid = fullName.trim().length >= 3 // Min 3 characters for name
|
fullName.trim().length > 4 &&
|
||||||
const locationValid = location.trim().length >= 2 // Min 2 characters for location
|
location.trim().length > 1 &&
|
||||||
const contractChecked = agreeContract
|
agreeContract &&
|
||||||
const dataChecked = agreeData
|
agreeData &&
|
||||||
const signatureChecked = confirmSignature
|
confirmSignature
|
||||||
|
|
||||||
return nameValid && locationValid && contractChecked && dataChecked && signatureChecked
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!valid()) {
|
if (!valid()) {
|
||||||
// Detailed error message to help debug
|
setError('Bitte alle Pflichtfelder & Bestätigungen ausfüllen.')
|
||||||
const issues = []
|
|
||||||
if (fullName.trim().length < 3) issues.push('Vollständiger Name (mindestens 3 Zeichen)')
|
|
||||||
if (location.trim().length < 2) issues.push('Ort (mindestens 2 Zeichen)')
|
|
||||||
if (!agreeContract) issues.push('Vertrag gelesen und verstanden')
|
|
||||||
if (!agreeData) issues.push('Datenschutzerklärung zugestimmt')
|
|
||||||
if (!confirmSignature) issues.push('Elektronische Signatur bestätigt')
|
|
||||||
|
|
||||||
setError(`Bitte vervollständigen: ${issues.join(', ')}`)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,10 +65,9 @@ export default function PersonalSignContractPage() {
|
|||||||
// Create FormData for the existing backend endpoint
|
// Create FormData for the existing backend endpoint
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('contractData', JSON.stringify(contractData))
|
formData.append('contractData', JSON.stringify(contractData))
|
||||||
// Create a dummy PDF file since the backend expects one (electronic signature)
|
// Create a dummy file since the backend expects one (we'll update backend later)
|
||||||
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(['Electronic signature data'], { type: 'text/plain' })
|
||||||
const dummyFile = new Blob([dummyPdfContent], { type: 'application/pdf' })
|
formData.append('contract', dummyFile, 'electronic_signature.txt')
|
||||||
formData.append('contract', dummyFile, 'electronic_signature.pdf')
|
|
||||||
|
|
||||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/upload/contract/personal`, {
|
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/upload/contract/personal`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user