'use client' import { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' import PageLayout from '../../../components/PageLayout' import useAuthStore from '../../../store/authStore' import { useUserStatus } from '../../../hooks/useUserStatus' interface PersonalProfileData { dob: string nationality: string street: string postalCode: string city: string country: string accountHolder: string iban: string secondPhone: string emergencyName: 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 = { dob: '', nationality: '', street: '', postalCode: '', city: '', country: '', accountHolder: '', iban: '', secondPhone: '', emergencyName: '', emergencyPhone: '' } export default function PersonalAdditionalInformationPage() { const router = useRouter() const { accessToken } = useAuthStore() const { refreshStatus } = useUserStatus() const [form, setForm] = useState(initialData) const [loading, setLoading] = useState(false) const [success, setSuccess] = useState(false) 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) => { const { name, value } = e.target setForm(p => ({ ...p, [name]: value })) 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 requiredKeys: (keyof PersonalProfileData)[] = [ 'dob','nationality','street','postalCode','city','country','accountHolder','iban' ] for (const k of requiredKeys) { if (!form[k].trim()) { setError('Please fill in all required fields.') return false } } // Date of birth validation if (!validateDateOfBirth(form.dob)) { setError('Invalid date of birth. You must be at least 18 years old.') return false } // very loose IBAN check if (!/^([A-Z]{2}\d{2}[A-Z0-9]{10,30})$/i.test(form.iban.replace(/\s+/g,''))) { setError('Invalid IBAN.') return false } setError('') return true } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (loading || success) return if (!validate()) return if (!accessToken) { setError('Not authenticated. Please log in again.') return } setLoading(true) try { // Prepare data for backend with correct field names const profileData = { dateOfBirth: form.dob, nationality: form.nationality, address: form.street, // Backend expects 'address', not nested object zip_code: form.postalCode, // Backend expects 'zip_code' city: form.city, country: form.country, phoneSecondary: form.secondPhone || null, // Backend expects 'phoneSecondary' emergencyContactName: form.emergencyName || null, emergencyContactPhone: form.emergencyPhone || null, accountHolderName: form.accountHolder, // Backend expects 'accountHolderName' iban: form.iban.replace(/\s+/g, '') // Remove spaces from IBAN } const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/profile/personal/complete`, { method: 'POST', headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify(profileData) }) if (!response.ok) { const errorData = await response.json().catch(() => ({ message: 'Save failed' })) throw new Error(errorData.message || 'Save failed') } setSuccess(true) // Refresh user status to update profile completion state await refreshStatus() // Redirect to next step 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/register-sign-contract/personal') } }, 1500) } catch (error: any) { console.error('Personal profile save error:', error) setError(error.message || 'Save failed. Please try again.') } finally { setLoading(false) } } return (
{/* Background */}

Complete Your Profile

{/* Personal Information */}

Personal Information


{/* Bank Details */}

Bank Details


{/* Additional Information */}

Additional Information

{error && (
{error}
)} {success && (
Data saved. Redirecting shortly…
)}
) }