feat: update success messages for document uploads and contract signing to include redirect notice + remove cow

This commit is contained in:
seaznCode 2025-11-29 15:23:18 +01:00
parent 1f91f09777
commit 6bf1ca006e
6 changed files with 113 additions and 69 deletions

View File

@ -211,11 +211,11 @@ export default function TutorialModal({
{/* Visual Section - Right Half */} {/* Visual Section - Right Half */}
<div className="relative lg:flex-1 mt-4 lg:mt-0 h-32 lg:h-full lg:min-h-[150px] flex items-end justify-end"> <div className="relative lg:flex-1 mt-4 lg:mt-0 h-32 lg:h-full lg:min-h-[150px] flex items-end justify-end">
<img {/* <img
src="/images/misc/cow.png" src="/images/misc/cow.png"
alt="Profit Planet Mascot" alt="Profit Planet Mascot"
className="max-h-full max-w-full object-contain opacity-90 pl-30" className="max-h-full max-w-full object-contain opacity-90 pl-30"
/> /> */}
</div> </div>
</div> </div>
</Dialog.Panel> </Dialog.Panel>
@ -324,7 +324,7 @@ export const createTutorialSteps = (
{ {
id: 6, id: 6,
title: "You're all set! 🎉 Welcome to the family", title: "You're all set! 🎉 Welcome to the family",
description: "Congratulations! You've completed all the steps perfectly. Our friendly team will now review your information - we'll have you approved and ready to go very soon!", description: "Congratulations! Our team will now review your information and have you approved very soon!",
details: [ details: [
"Our team will carefully review everything you've submitted", "Our team will carefully review everything you've submitted",
"This usually takes just 1-2 business days", "This usually takes just 1-2 business days",

View File

@ -1,6 +1,6 @@
'use client' 'use client'
import { useState } from 'react' import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import PageLayout from '../../../components/PageLayout' import PageLayout from '../../../components/PageLayout'
import useAuthStore from '../../../store/authStore' import useAuthStore from '../../../store/authStore'
@ -64,6 +64,50 @@ export default function PersonalAdditionalInformationPage() {
const [success, setSuccess] = useState(false) const [success, setSuccess] = useState(false)
const [error, setError] = useState('') const [error, setError] = useState('')
// Prefill form if profile already exists
useEffect(() => {
let abort = false
async function loadProfile() {
if (!accessToken) return
try {
const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/me`, {
method: 'GET',
headers: { Authorization: `Bearer ${accessToken}` }
})
if (!res.ok) return
const data = await res.json().catch(() => null)
const profile = data?.profile
const user = data?.user
if (!profile || abort) return
const toDateInput = (d?: string) => {
if (!d) return ''
const dt = new Date(d)
if (Number.isNaN(dt.getTime())) return ''
return dt.toISOString().split('T')[0]
}
setForm(prev => ({
...prev,
dob: toDateInput(profile.date_of_birth || profile.dateOfBirth),
nationality: profile.nationality || prev.nationality,
street: profile.address || prev.street,
postalCode: profile.zip_code || profile.zipCode || prev.postalCode,
city: profile.city || prev.city,
country: profile.country || prev.country,
accountHolder: profile.account_holder_name || profile.accountHolderName || prev.accountHolder,
// Prefer IBAN from users table (data.user.iban), fallback to profile if any
iban: (user?.iban ?? profile.iban ?? prev.iban) as string,
secondPhone: profile.phone_secondary || profile.phoneSecondary || prev.secondPhone,
emergencyName: profile.emergency_contact_name || profile.emergencyContactName || prev.emergencyName,
emergencyPhone: profile.emergency_contact_phone || profile.emergencyContactPhone || prev.emergencyPhone,
}))
} catch (_) {
// ignore prefill errors; user can still fill manually
}
}
loadProfile()
return () => { abort = true }
}, [accessToken])
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => { const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target const { name, value } = e.target
setForm(p => ({ ...p, [name]: value })) setForm(p => ({ ...p, [name]: value }))
@ -101,20 +145,20 @@ export default function PersonalAdditionalInformationPage() {
] ]
for (const k of requiredKeys) { for (const k of requiredKeys) {
if (!form[k].trim()) { if (!form[k].trim()) {
setError('Bitte alle Pflichtfelder ausfüllen.') setError('Please fill in all required fields.')
return false return false
} }
} }
// Date of birth validation // Date of birth validation
if (!validateDateOfBirth(form.dob)) { if (!validateDateOfBirth(form.dob)) {
setError('Ungültiges Geburtsdatum. Sie müssen mindestens 18 Jahre alt sein.') setError('Invalid date of birth. You must be at least 18 years old.')
return false 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('Invalid IBAN.')
return false return false
} }
setError('') setError('')
@ -183,7 +227,7 @@ export default function PersonalAdditionalInformationPage() {
} catch (error: any) { } catch (error: any) {
console.error('Personal profile save error:', error) console.error('Personal profile save error:', error)
setError(error.message || 'Speichern fehlgeschlagen. Bitte erneut versuchen.') setError(error.message || 'Save failed. Please try again.')
} finally { } finally {
setLoading(false) setLoading(false)
} }
@ -413,7 +457,7 @@ export default function PersonalAdditionalInformationPage() {
)} )}
{success && ( {success && (
<div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-xs text-green-700"> <div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-xs text-green-700">
Daten gespeichert. Data saved. Redirecting shortly
</div> </div>
)} )}
@ -423,7 +467,7 @@ export default function PersonalAdditionalInformationPage() {
disabled={loading || success} disabled={loading || success}
className="inline-flex items-center rounded-md bg-indigo-600 px-6 py-2.5 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed" className="inline-flex items-center rounded-md bg-indigo-600 px-6 py-2.5 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed"
> >
{loading ? 'Speichern…' : success ? 'Gespeichert' : 'Save & Continue'} {loading ? 'Saving…' : success ? 'Saved' : 'Save & Continue'}
</button> </button>
</div> </div>
</div> </div>

View File

@ -78,15 +78,15 @@ export default function CompanySignContractPage() {
if (!valid()) { if (!valid()) {
// Detailed error message to help debug // Detailed error message to help debug
const issues = [] const issues = []
if (companyName.trim().length < 3) issues.push('Firmenname (mindestens 3 Zeichen)') if (companyName.trim().length < 3) issues.push('Company name (min 3 characters)')
if (repName.trim().length < 3) issues.push('Vertreter Name (mindestens 3 Zeichen)') if (repName.trim().length < 3) issues.push('Representative name (min 3 characters)')
if (repTitle.trim().length < 2) issues.push('Vertretertitel (mindestens 2 Zeichen)') if (repTitle.trim().length < 2) issues.push('Representative title (min 2 characters)')
if (location.trim().length < 2) issues.push('Ort (mindestens 2 Zeichen)') if (location.trim().length < 2) issues.push('Location (min 2 characters)')
if (!agreeContract) issues.push('Vertrag gelesen und verstanden') if (!agreeContract) issues.push('Contract read and understood')
if (!agreeData) issues.push('Datenschutzerklärung zugestimmt') if (!agreeData) issues.push('Privacy policy accepted')
if (!confirmSignature) issues.push('Elektronische Signatur bestätigt') if (!confirmSignature) issues.push('Electronic signature confirmed')
setError(`Bitte vervollständigen: ${issues.join(', ')}`) setError(`Please complete: ${issues.join(', ')}`)
return return
} }
@ -156,7 +156,7 @@ export default function CompanySignContractPage() {
} catch (error: any) { } catch (error: any) {
console.error('Contract signing error:', error) console.error('Contract signing error:', error)
setError(error.message || 'Signatur fehlgeschlagen. Bitte erneut versuchen.') setError(error.message || 'Signature failed. Please try again.')
} finally { } finally {
setSubmitting(false) setSubmitting(false)
} }
@ -193,7 +193,7 @@ export default function CompanySignContractPage() {
Sign Company Partnership Contract Sign Company Partnership Contract
</h1> </h1>
<p className="text-center text-sm text-gray-600 mb-8"> <p className="text-center text-sm text-gray-600 mb-8">
Prüfe die Vertragsdetails und unterschreibe im Namen des Unternehmens. Please review the contract details and sign on behalf of the company.
</p> </p>
{/* Meta + Preview */} {/* Meta + Preview */}
@ -203,22 +203,22 @@ export default function CompanySignContractPage() {
<h2 className="text-sm font-semibold text-gray-800 mb-3">Contract Information</h2> <h2 className="text-sm font-semibold text-gray-800 mb-3">Contract Information</h2>
<ul className="space-y-2 text-xs sm:text-sm text-gray-600"> <ul className="space-y-2 text-xs sm:text-sm text-gray-600">
<li><span className="font-medium text-gray-700">Contract ID:</span> COMP-2024-017</li> <li><span className="font-medium text-gray-700">Contract ID:</span> COMP-2024-017</li>
<li><span className="font-medium text-gray-700">Version:</span> 2.4 (gültig ab 01.11.2024)</li> <li><span className="font-medium text-gray-700">Version:</span> 2.4 (valid from 01.11.2024)</li>
<li><span className="font-medium text-gray-700">Jurisdiction:</span> EU / Germany</li> <li><span className="font-medium text-gray-700">Jurisdiction:</span> EU / Germany</li>
<li><span className="font-medium text-gray-700">Language:</span> DE (binding)</li> <li><span className="font-medium text-gray-700">Language:</span> DE (binding)</li>
</ul> </ul>
</div> </div>
<div className="rounded-lg border border-amber-200 bg-amber-50 p-5"> <div className="rounded-lg border border-amber-200 bg-amber-50 p-5">
<h3 className="text-sm font-semibold text-amber-900 mb-2">Achtung</h3> <h3 className="text-sm font-semibold text-amber-900 mb-2">Attention</h3>
<p className="text-xs sm:text-sm text-amber-800 leading-relaxed"> <p className="text-xs sm:text-sm text-amber-800 leading-relaxed">
Du bestätigst rechtsverbindlich, dass du bevollmächtigt bist im Namen des Unternehmens zu unterschreiben. You confirm that you are authorized to sign on behalf of the company.
</p> </p>
</div> </div>
</div> </div>
<div> <div>
<div className="rounded-lg border border-gray-200 bg-white relative overflow-hidden"> <div className="rounded-lg border border-gray-200 bg-white relative overflow-hidden">
<div className="flex items-center justify-between p-3 border-b border-gray-200 bg-gray-50"> <div className="flex items-center justify-between p-3 border-b border-gray-200 bg-gray-50">
<h3 className="text-sm font-semibold text-gray-900">Vertragsvorschau (Unternehmen)</h3> <h3 className="text-sm font-semibold text-gray-900">Company Contract Preview</h3>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
type="button" type="button"
@ -260,18 +260,18 @@ export default function CompanySignContractPage() {
disabled={previewLoading} disabled={previewLoading}
className="inline-flex items-center rounded-md bg-indigo-600 hover:bg-indigo-500 text-white px-2.5 py-1.5 text-xs disabled:opacity-60" className="inline-flex items-center rounded-md bg-indigo-600 hover:bg-indigo-500 text-white px-2.5 py-1.5 text-xs disabled:opacity-60"
> >
{previewLoading ? 'Lade…' : 'Refresh'} {previewLoading ? 'Loading…' : 'Refresh'}
</button> </button>
</div> </div>
</div> </div>
{previewLoading ? ( {previewLoading ? (
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Lade Vorschau</div> <div className="h-72 flex items-center justify-center text-xs text-gray-500">Loading preview</div>
) : previewError ? ( ) : previewError ? (
<div className="h-72 flex items-center justify-center text-xs text-red-600 px-4 text-center">{previewError}</div> <div className="h-72 flex items-center justify-center text-xs text-red-600 px-4 text-center">{previewError}</div>
) : previewHtml ? ( ) : previewHtml ? (
<iframe title="Company Contract Preview" className="w-full h-72" srcDoc={previewHtml} /> <iframe title="Company Contract Preview" className="w-full h-72" srcDoc={previewHtml} />
) : ( ) : (
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Keine Vorschau verfügbar.</div> <div className="h-72 flex items-center justify-center text-xs text-gray-500">No preview available.</div>
)} )}
</div> </div>
</div> </div>
@ -285,7 +285,7 @@ export default function CompanySignContractPage() {
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
<div className="sm:col-span-2 lg:col-span-2"> <div className="sm:col-span-2 lg:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Unternehmensname * Company Name *
</label> </label>
<input <input
value={companyName} value={companyName}
@ -297,7 +297,7 @@ export default function CompanySignContractPage() {
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Datum * Date *
</label> </label>
<input <input
type="date" type="date"
@ -308,8 +308,8 @@ export default function CompanySignContractPage() {
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text_sm font-medium text-gray-700 mb-1">
Ort * Location *
</label> </label>
<input <input
value={location} value={location}
@ -320,8 +320,8 @@ export default function CompanySignContractPage() {
/> />
</div> </div>
<div className="sm:col-span-2 lg:col-span-1"> <div className="sm:col-span-2 lg:col-span-1">
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text_sm font-medium text-gray-700 mb-1">
Vertreter Name * Representative Name *
</label> </label>
<input <input
value={repName} value={repName}
@ -333,7 +333,7 @@ export default function CompanySignContractPage() {
</div> </div>
<div className="sm:col-span-2 lg:col-span-2"> <div className="sm:col-span-2 lg:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Vertreter Position / Titel * Representative Position / Title *
</label> </label>
<input <input
value={repTitle} value={repTitle}
@ -345,7 +345,7 @@ export default function CompanySignContractPage() {
</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">
Notiz (optional) Note (optional)
</label> </label>
<input <input
value={note} value={note}
@ -361,7 +361,7 @@ export default function CompanySignContractPage() {
{/* Confirmations */} {/* Confirmations */}
<section className="space-y-5"> <section className="space-y-5">
<h2 className="text-sm font-semibold text-[#0F2460]">Bestätigungen</h2> <h2 className="text-sm font-semibold text-[#0F2460]">Confirmations</h2>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
type="checkbox" type="checkbox"
@ -369,7 +369,7 @@ export default function CompanySignContractPage() {
onChange={e => setAgreeContract(e.target.checked)} onChange={e => setAgreeContract(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich bestätige, den vollständigen Vertrag im Namen des Unternehmens gelesen und akzeptiert zu haben.</span> <span>I confirm I have read and accepted the full contract on behalf of the company.</span>
</label> </label>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
@ -378,7 +378,7 @@ export default function CompanySignContractPage() {
onChange={e => setAgreeData(e.target.checked)} onChange={e => setAgreeData(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich stimme der Verarbeitung der Unternehmens- & personenbezogenen Daten gemäß Datenschutzerklärung zu.</span> <span>I consent to processing of company and personal data in accordance with the privacy policy.</span>
</label> </label>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
@ -387,7 +387,7 @@ export default function CompanySignContractPage() {
onChange={e => setConfirmSignature(e.target.checked)} onChange={e => setConfirmSignature(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich bin bevollmächtigt, rechtsverbindlich für dieses Unternehmen zu unterschreiben.</span> <span>I am authorized to sign legally binding documents for this company.</span>
</label> </label>
</section> </section>
@ -398,7 +398,7 @@ export default function CompanySignContractPage() {
)} )}
{success && ( {success && (
<div className="mt-8 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700"> <div className="mt-8 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700">
Vertrag erfolgreich unterzeichnet. Contract signed successfully. Redirecting shortly
</div> </div>
)} )}
@ -408,7 +408,7 @@ export default function CompanySignContractPage() {
disabled={submitting || success} disabled={submitting || success}
className="inline-flex items-center justify-center rounded-md bg-indigo-600 px-8 py-3 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed transition" className="inline-flex items-center justify-center rounded-md bg-indigo-600 px-8 py-3 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed transition"
> >
{submitting ? 'Signiere…' : success ? 'Signiert' : 'Jetzt signieren'} {submitting ? 'Signing…' : success ? 'Signed' : 'Sign Now'}
</button> </button>
</div> </div>
</div> </div>

View File

@ -73,13 +73,13 @@ export default function PersonalSignContractPage() {
if (!valid()) { if (!valid()) {
// Detailed error message to help debug // Detailed error message to help debug
const issues = [] const issues = []
if (fullName.trim().length < 3) issues.push('Vollständiger Name (mindestens 3 Zeichen)') if (fullName.trim().length < 3) issues.push('Full name (min 3 characters)')
if (location.trim().length < 2) issues.push('Ort (mindestens 2 Zeichen)') if (location.trim().length < 2) issues.push('Location (min 2 characters)')
if (!agreeContract) issues.push('Vertrag gelesen und verstanden') if (!agreeContract) issues.push('Contract read and understood')
if (!agreeData) issues.push('Datenschutzerklärung zugestimmt') if (!agreeData) issues.push('Privacy policy accepted')
if (!confirmSignature) issues.push('Elektronische Signatur bestätigt') if (!confirmSignature) issues.push('Electronic signature confirmed')
setError(`Bitte vervollständigen: ${issues.join(', ')}`) setError(`Please complete: ${issues.join(', ')}`)
return return
} }
@ -147,7 +147,7 @@ export default function PersonalSignContractPage() {
} catch (error: any) { } catch (error: any) {
console.error('Contract signing error:', error) console.error('Contract signing error:', error)
setError(error.message || 'Signatur fehlgeschlagen. Bitte erneut versuchen.') setError(error.message || 'Signature failed. Please try again.')
} finally { } finally {
setSubmitting(false) setSubmitting(false)
} }
@ -184,7 +184,7 @@ export default function PersonalSignContractPage() {
Sign Personal Participation Contract Sign Personal Participation Contract
</h1> </h1>
<p className="text-center text-sm text-gray-600 mb-8"> <p className="text-center text-sm text-gray-600 mb-8">
Bitte überprüfe die Vertragsdetails und unterschreibe elektronisch. Please review the contract details and sign electronically.
</p> </p>
{/* Contract Meta + Preview */} {/* Contract Meta + Preview */}
@ -194,22 +194,22 @@ export default function PersonalSignContractPage() {
<h2 className="text-sm font-semibold text-gray-800 mb-3">Contract Information</h2> <h2 className="text-sm font-semibold text-gray-800 mb-3">Contract Information</h2>
<ul className="space-y-2 text-xs sm:text-sm text-gray-600"> <ul className="space-y-2 text-xs sm:text-sm text-gray-600">
<li><span className="font-medium text-gray-700">Contract ID:</span> PERS-2024-001</li> <li><span className="font-medium text-gray-700">Contract ID:</span> PERS-2024-001</li>
<li><span className="font-medium text-gray-700">Version:</span> 1.2 (gültig ab 01.11.2024)</li> <li><span className="font-medium text-gray-700">Version:</span> 1.2 (valid from 01.11.2024)</li>
<li><span className="font-medium text-gray-700">Jurisdiction:</span> EU / Germany</li> <li><span className="font-medium text-gray-700">Jurisdiction:</span> EU / Germany</li>
<li><span className="font-medium text-gray-700">Language:</span> DE (verbindlich)</li> <li><span className="font-medium text-gray-700">Language:</span> EN (binding)</li>
</ul> </ul>
</div> </div>
<div className="rounded-lg border border-indigo-100 bg-indigo-50/60 p-5"> <div className="rounded-lg border border-indigo-100 bg-indigo-50/60 p-5">
<h3 className="text-sm font-semibold text-indigo-900 mb-2">Hinweis</h3> <h3 className="text-sm font-semibold text-indigo-900 mb-2">Note</h3>
<p className="text-xs sm:text-sm text-indigo-800 leading-relaxed"> <p className="text-xs sm:text-sm text-indigo-800 leading-relaxed">
Deine elektronische Signatur ist rechtsverbindlich. Stelle sicher, dass alle Angaben korrekt sind. Your electronic signature is legally binding. Please ensure all details are correct.
</p> </p>
</div> </div>
</div> </div>
<div> <div>
<div className="rounded-lg border border-gray-200 bg-white relative overflow-hidden"> <div className="rounded-lg border border-gray-200 bg-white relative overflow-hidden">
<div className="flex items-center justify-between p-3 border-b border-gray-200 bg-gray-50"> <div className="flex items-center justify-between p-3 border-b border-gray-200 bg-gray-50">
<h3 className="text-sm font-semibold text-gray-900">Vertragsvorschau</h3> <h3 className="text-sm font-semibold text-gray-900">Contract Preview</h3>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<button <button
type="button" type="button"
@ -227,13 +227,13 @@ export default function PersonalSignContractPage() {
</div> </div>
</div> </div>
{previewLoading ? ( {previewLoading ? (
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Lade Vorschau</div> <div className="h-72 flex items-center justify-center text-xs text-gray-500">Loading preview</div>
) : previewError ? ( ) : previewError ? (
<div className="h-72 flex items-center justify-center text-xs text-red-600 px-4 text-center">{previewError}</div> <div className="h-72 flex items-center justify-center text-xs text-red-600 px-4 text-center">{previewError}</div>
) : previewHtml ? ( ) : previewHtml ? (
<iframe title="Contract Preview" className="w-full h-72" srcDoc={previewHtml} /> <iframe title="Contract Preview" className="w-full h-72" srcDoc={previewHtml} />
) : ( ) : (
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Keine Vorschau verfügbar.</div> <div className="h-72 flex items-center justify-center text-xs text-gray-500">No preview available.</div>
)} )}
</div> </div>
</div> </div>
@ -247,7 +247,7 @@ export default function PersonalSignContractPage() {
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
<div className="sm:col-span-2 lg:col-span-2"> <div className="sm:col-span-2 lg:col-span-2">
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Vollständiger Name (Signatur) * Full Name (Signature) *
</label> </label>
<input <input
value={fullName} value={fullName}
@ -257,12 +257,12 @@ export default function PersonalSignContractPage() {
required required
/> />
<p className="mt-1 text-xs text-gray-500"> <p className="mt-1 text-xs text-gray-500">
Muss deinem amtlichen Ausweis entsprechen. Must match your official ID.
</p> </p>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Datum * Date *
</label> </label>
<input <input
type="date" type="date"
@ -274,7 +274,7 @@ export default function PersonalSignContractPage() {
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-1"> <label className="block text-sm font-medium text-gray-700 mb-1">
Ort * Location *
</label> </label>
<input <input
value={location} value={location}
@ -286,7 +286,7 @@ export default function PersonalSignContractPage() {
</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">
Notiz (optional) Note (optional)
</label> </label>
<input <input
value={note} value={note}
@ -302,7 +302,7 @@ export default function PersonalSignContractPage() {
{/* Confirmations */} {/* Confirmations */}
<section className="space-y-5"> <section className="space-y-5">
<h2 className="text-sm font-semibold text-[#0F2460]">Bestätigungen</h2> <h2 className="text-sm font-semibold text-[#0F2460]">Confirmations</h2>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
type="checkbox" type="checkbox"
@ -310,7 +310,7 @@ export default function PersonalSignContractPage() {
onChange={e => setAgreeContract(e.target.checked)} onChange={e => setAgreeContract(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich bestätige, dass ich den Vertrag vollständig gelesen und verstanden habe.</span> <span>I confirm that I have read and understood the contract in full.</span>
</label> </label>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
@ -319,7 +319,7 @@ export default function PersonalSignContractPage() {
onChange={e => setAgreeData(e.target.checked)} onChange={e => setAgreeData(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich stimme der Verarbeitung meiner personenbezogenen Daten gemäß Datenschutzerklärung zu.</span> <span>I consent to the processing of my personal data in accordance with the privacy policy.</span>
</label> </label>
<label className="flex items-start gap-3 text-sm text-gray-700"> <label className="flex items-start gap-3 text-sm text-gray-700">
<input <input
@ -328,7 +328,7 @@ export default function PersonalSignContractPage() {
onChange={e => setConfirmSignature(e.target.checked)} onChange={e => setConfirmSignature(e.target.checked)}
className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" className="mt-1 h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
/> />
<span>Ich bestätige, dass diese elektronische Unterschrift rechtsverbindlich ist und einer handschriftlichen Signatur entspricht.</span> <span>I confirm this electronic signature is legally binding and equivalent to a handwritten signature.</span>
</label> </label>
</section> </section>
@ -339,7 +339,7 @@ export default function PersonalSignContractPage() {
)} )}
{success && ( {success && (
<div className="mt-8 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700"> <div className="mt-8 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700">
Vertrag erfolgreich unterzeichnet. Contract signed successfully. Redirecting shortly
</div> </div>
)} )}
@ -349,7 +349,7 @@ export default function PersonalSignContractPage() {
disabled={submitting || success} disabled={submitting || success}
className="inline-flex items-center justify-center rounded-md bg-indigo-600 px-8 py-3 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed transition" className="inline-flex items-center justify-center rounded-md bg-indigo-600 px-8 py-3 text-sm font-semibold text-white shadow hover:bg-indigo-500 disabled:bg-gray-400 disabled:cursor-not-allowed transition"
> >
{submitting ? 'Signiere…' : success ? 'Signiert' : 'Jetzt signieren'} {submitting ? 'Signing…' : success ? 'Signed' : 'Sign Now'}
</button> </button>
</div> </div>
</div> </div>

View File

@ -274,7 +274,7 @@ export default function CompanyIdUploadPage() {
)} )}
{success && ( {success && (
<div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700"> <div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700">
Documents uploaded successfully. Documents uploaded successfully. Redirecting shortly
</div> </div>
)} )}

View File

@ -285,7 +285,7 @@ export default function PersonalIdUploadPage() {
)} )}
{success && ( {success && (
<div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700"> <div className="mt-6 rounded-md border border-green-300 bg-green-50 px-4 py-3 text-sm text-green-700">
Upload saved successfully. Upload saved successfully. Redirecting shortly
</div> </div>
)} )}