'use client'; import { useEffect, useState } from 'react'; import { useI18n } from '../components/I18nProvider'; type User = { id: string; email: string; role: string; status: string; emailVerifiedAt: string | null; approvedAt: string | null; name: string | null; phone: string | null }; type BillingListing = { id: string; title: string; slug: string; locale: string; billingAccountName: string | null; billingIban: string | null; billingIncludeVatLine: boolean | null; }; export default function ProfilePage() { const { t } = useI18n(); const [user, setUser] = useState(null); const [error, setError] = useState(null); const [name, setName] = useState(''); const [phone, setPhone] = useState(''); const [password, setPassword] = useState(''); const [saving, setSaving] = useState(false); const [message, setMessage] = useState(null); const [billingEnabled, setBillingEnabled] = useState(false); const [billingAccountName, setBillingAccountName] = useState(''); const [billingIban, setBillingIban] = useState(''); const [billingIncludeVatLine, setBillingIncludeVatLine] = useState(false); const [billingListings, setBillingListings] = useState([]); const [billingLoading, setBillingLoading] = useState(false); const [billingSaving, setBillingSaving] = useState(false); const [billingMessage, setBillingMessage] = useState(null); const [billingError, setBillingError] = useState(null); useEffect(() => { fetch('/api/auth/me', { cache: 'no-store' }) .then((res) => res.json()) .then((data) => { if (data.user) { setUser(data.user); setName(data.user.name ?? ''); setPhone(data.user.phone ?? ''); } else setError(t('notLoggedIn')); }) .catch(() => setError(t('notLoggedIn'))); }, [t]); useEffect(() => { setBillingLoading(true); fetch('/api/me/billing', { cache: 'no-store' }) .then(async (res) => { const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Failed'); return data; }) .then((data) => { setBillingEnabled(Boolean(data.settings?.enabled)); setBillingAccountName(data.settings?.accountName ?? ''); setBillingIban(data.settings?.iban ?? ''); setBillingIncludeVatLine(Boolean(data.settings?.includeVatLine)); setBillingListings( Array.isArray(data.listings) ? data.listings.map((l: any) => ({ id: l.id, title: l.title, slug: l.slug, locale: l.locale, billingAccountName: l.billingAccountName ?? '', billingIban: l.billingIban ?? '', billingIncludeVatLine: l.billingIncludeVatLine ?? null, })) : [], ); setBillingError(null); }) .catch(() => setBillingError(t('billingLoadFailed'))) .finally(() => setBillingLoading(false)); }, [t]); async function onSave(e: React.FormEvent) { e.preventDefault(); setSaving(true); setError(null); setMessage(null); try { const res = await fetch('/api/me', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, phone, password: password || undefined }), }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Update failed'); } else { setUser(data.user); setPassword(''); setMessage(t('profileUpdated')); } } catch (err) { setError('Update failed'); } finally { setSaving(false); } } async function onSaveBilling(e: React.FormEvent) { e.preventDefault(); setBillingSaving(true); setBillingError(null); setBillingMessage(null); try { const res = await fetch('/api/me/billing', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: billingEnabled, accountName: billingAccountName, iban: billingIban, includeVatLine: billingIncludeVatLine, listings: billingListings.map((l) => ({ id: l.id, accountName: l.billingAccountName, iban: l.billingIban, includeVatLine: l.billingIncludeVatLine, })), }), }); const data = await res.json(); if (!res.ok) { setBillingError(data.error || t('billingSaveFailed')); return; } setBillingEnabled(Boolean(data.settings?.enabled)); setBillingAccountName(data.settings?.accountName ?? ''); setBillingIban(data.settings?.iban ?? ''); setBillingIncludeVatLine(Boolean(data.settings?.includeVatLine)); setBillingListings( Array.isArray(data.listings) ? data.listings.map((l: any) => ({ id: l.id, title: l.title, slug: l.slug, locale: l.locale, billingAccountName: l.billingAccountName ?? '', billingIban: l.billingIban ?? '', billingIncludeVatLine: l.billingIncludeVatLine ?? null, })) : [], ); setBillingMessage(t('billingSaved')); } catch (err) { setBillingError(t('billingSaveFailed')); } finally { setBillingSaving(false); } } return (

{t('myProfileTitle')}

{message ?

{message}

: null}
{user ? ( <>
{t('profileEmail')}: {user.email}
{t('profileName')}: {user.name ?? '—'}
{t('profilePhone')}: {user.phone ?? '—'}
{t('profileRole')}: {user.role}
{t('profileStatus')}: {user.status}
{t('profileEmailVerified')}: {user.emailVerifiedAt ? t('yes') : t('no')}
{t('profileApproved')}: {user.approvedAt ? t('yes') : t('no')}
) : (

{error ?? t('notLoggedIn')}

)}
{user ? ( <>

{t('myProfileTitle')}

{t('emailLocked')}

{t('billingSettingsTitle')}

{t('billingSettingsLead')}

{billingMessage ?

{billingMessage}

: null} {billingError ?

{billingError}

: null}
{billingEnabled ? ( <>
{t('billingListingsTitle')}
{t('billingListingsLead')}
{billingLoading ? (

{t('loading')}

) : billingListings.length === 0 ? (

{t('billingNoListings')}

) : (
{billingListings.map((listing) => { const vatValue = listing.billingIncludeVatLine === null || listing.billingIncludeVatLine === undefined ? 'inherit' : listing.billingIncludeVatLine ? 'yes' : 'no'; return (
{listing.title} ({listing.slug})
); })}
)}
) : (

{t('billingDisabledHint')}

)}
) : null}
); }