mirror of
http://172.20.10.11:3000/gitadmin/INSIGHT-MVP.git
synced 2026-06-25 00:16:41 +02:00
feat: Firmendaten um Geschäftsführer, Amtsgericht, Handelsregister erweitert
- Backend: CompanySettings Interface + GET/POST um managingDirector, localCourt, commercialRegister ergänzt (Redis-Storage) - Frontend AdminCompanyPage: neue Sektion „Rechtliche Angaben" mit 3 Feldern, Footer-Vorschau zeigt alle Angaben inkl. HR-Nummer - Export-Service: PDF- und DOCX-Fußzeile enthält jetzt Geschäftsführer und Handelsregistereintrag (HRB + Amtsgericht kombiniert) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0f5d01df2a
commit
69305a0b0b
3 changed files with 81 additions and 16 deletions
|
|
@ -245,12 +245,17 @@ export class ProfileExportService {
|
||||||
if (companyRaw) {
|
if (companyRaw) {
|
||||||
const c = JSON.parse(companyRaw) as Record<string, unknown>;
|
const c = JSON.parse(companyRaw) as Record<string, unknown>;
|
||||||
const address = [c['street'], [c['postalCode'], c['city']].filter(Boolean).join(' ')].filter(Boolean).join(', ');
|
const address = [c['street'], [c['postalCode'], c['city']].filter(Boolean).join(' ')].filter(Boolean).join(', ');
|
||||||
|
const hrEntry = c['commercialRegister'] && c['localCourt']
|
||||||
|
? `${c['commercialRegister']} ${c['localCourt']}`
|
||||||
|
: (c['commercialRegister'] || c['localCourt'] || null);
|
||||||
companyFooterText = [
|
companyFooterText = [
|
||||||
c['name'],
|
c['name'],
|
||||||
address || null,
|
address || null,
|
||||||
c['phone'] ? `Tel: ${c['phone']}` : null,
|
c['phone'] ? `Tel: ${c['phone']}` : null,
|
||||||
c['email'],
|
c['email'],
|
||||||
c['website'],
|
c['website'],
|
||||||
|
c['managingDirector'] ? `Geschäftsführer: ${c['managingDirector']}` : null,
|
||||||
|
hrEntry,
|
||||||
].filter(Boolean).join(' | ');
|
].filter(Boolean).join(' | ');
|
||||||
}
|
}
|
||||||
if (brandingRaw) {
|
if (brandingRaw) {
|
||||||
|
|
@ -713,6 +718,7 @@ export class ProfileExportService {
|
||||||
const c = JSON.parse(companyRaw) as {
|
const c = JSON.parse(companyRaw) as {
|
||||||
name?: string | null; street?: string | null; postalCode?: string | null;
|
name?: string | null; street?: string | null; postalCode?: string | null;
|
||||||
city?: string | null; phone?: string | null; email?: string | null; website?: string | null;
|
city?: string | null; phone?: string | null; email?: string | null; website?: string | null;
|
||||||
|
managingDirector?: string | null; localCourt?: string | null; commercialRegister?: string | null;
|
||||||
};
|
};
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
if (c.name) parts.push(c.name);
|
if (c.name) parts.push(c.name);
|
||||||
|
|
@ -721,6 +727,11 @@ export class ProfileExportService {
|
||||||
if (c.phone) parts.push(`Tel: ${c.phone}`);
|
if (c.phone) parts.push(`Tel: ${c.phone}`);
|
||||||
if (c.email) parts.push(c.email);
|
if (c.email) parts.push(c.email);
|
||||||
if (c.website) parts.push(c.website);
|
if (c.website) parts.push(c.website);
|
||||||
|
if (c.managingDirector) parts.push(`Geschäftsführer: ${c.managingDirector}`);
|
||||||
|
const hrEntry = c.commercialRegister && c.localCourt
|
||||||
|
? `${c.commercialRegister} ${c.localCourt}`
|
||||||
|
: (c.commercialRegister || c.localCourt || null);
|
||||||
|
if (hrEntry) parts.push(hrEntry);
|
||||||
if (parts.length) companyFooterText = parts.join(' | ');
|
if (parts.length) companyFooterText = parts.join(' | ');
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ interface CompanySettings {
|
||||||
phone: string | null;
|
phone: string | null;
|
||||||
email: string | null;
|
email: string | null;
|
||||||
website: string | null;
|
website: string | null;
|
||||||
|
managingDirector: string | null;
|
||||||
|
localCourt: string | null;
|
||||||
|
commercialRegister: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -428,19 +431,23 @@ export class SettingsController {
|
||||||
const empty: CompanySettings = {
|
const empty: CompanySettings = {
|
||||||
name: null, street: null, postalCode: null, city: null,
|
name: null, street: null, postalCode: null, city: null,
|
||||||
phone: null, email: null, website: null,
|
phone: null, email: null, website: null,
|
||||||
|
managingDirector: null, localCourt: null, commercialRegister: null,
|
||||||
};
|
};
|
||||||
const raw = await this.redis.get(COMPANY_SETTINGS_KEY);
|
const raw = await this.redis.get(COMPANY_SETTINGS_KEY);
|
||||||
if (!raw) return empty;
|
if (!raw) return empty;
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(raw) as Record<string, unknown>;
|
const data = JSON.parse(raw) as Record<string, unknown>;
|
||||||
return {
|
return {
|
||||||
name: typeof data.name === 'string' ? data.name : null,
|
name: typeof data.name === 'string' ? data.name : null,
|
||||||
street: typeof data.street === 'string' ? data.street : null,
|
street: typeof data.street === 'string' ? data.street : null,
|
||||||
postalCode: typeof data.postalCode === 'string' ? data.postalCode : null,
|
postalCode: typeof data.postalCode === 'string' ? data.postalCode : null,
|
||||||
city: typeof data.city === 'string' ? data.city : null,
|
city: typeof data.city === 'string' ? data.city : null,
|
||||||
phone: typeof data.phone === 'string' ? data.phone : null,
|
phone: typeof data.phone === 'string' ? data.phone : null,
|
||||||
email: typeof data.email === 'string' ? data.email : null,
|
email: typeof data.email === 'string' ? data.email : null,
|
||||||
website: typeof data.website === 'string' ? data.website : null,
|
website: typeof data.website === 'string' ? data.website : null,
|
||||||
|
managingDirector: typeof data.managingDirector === 'string' ? data.managingDirector : null,
|
||||||
|
localCourt: typeof data.localCourt === 'string' ? data.localCourt : null,
|
||||||
|
commercialRegister: typeof data.commercialRegister === 'string' ? data.commercialRegister : null,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
return empty;
|
return empty;
|
||||||
|
|
@ -459,13 +466,16 @@ export class SettingsController {
|
||||||
@Body() body: CompanySettings,
|
@Body() body: CompanySettings,
|
||||||
): Promise<{ success: boolean }> {
|
): Promise<{ success: boolean }> {
|
||||||
const data: CompanySettings = {
|
const data: CompanySettings = {
|
||||||
name: body.name?.trim() || null,
|
name: body.name?.trim() || null,
|
||||||
street: body.street?.trim() || null,
|
street: body.street?.trim() || null,
|
||||||
postalCode: body.postalCode?.trim() || null,
|
postalCode: body.postalCode?.trim() || null,
|
||||||
city: body.city?.trim() || null,
|
city: body.city?.trim() || null,
|
||||||
phone: body.phone?.trim() || null,
|
phone: body.phone?.trim() || null,
|
||||||
email: body.email?.trim() || null,
|
email: body.email?.trim() || null,
|
||||||
website: body.website?.trim() || null,
|
website: body.website?.trim() || null,
|
||||||
|
managingDirector: body.managingDirector?.trim() || null,
|
||||||
|
localCourt: body.localCourt?.trim() || null,
|
||||||
|
commercialRegister: body.commercialRegister?.trim() || null,
|
||||||
};
|
};
|
||||||
await this.redis.set(COMPANY_SETTINGS_KEY, JSON.stringify(data));
|
await this.redis.set(COMPANY_SETTINGS_KEY, JSON.stringify(data));
|
||||||
this.logger.log('Firmendaten aktualisiert');
|
this.logger.log('Firmendaten aktualisiert');
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,15 @@ interface CompanySettings {
|
||||||
phone: string | null;
|
phone: string | null;
|
||||||
email: string | null;
|
email: string | null;
|
||||||
website: string | null;
|
website: string | null;
|
||||||
|
managingDirector: string | null;
|
||||||
|
localCourt: string | null;
|
||||||
|
commercialRegister: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const empty: CompanySettings = {
|
const empty: CompanySettings = {
|
||||||
name: null, street: null, postalCode: null, city: null,
|
name: null, street: null, postalCode: null, city: null,
|
||||||
phone: null, email: null, website: null,
|
phone: null, email: null, website: null,
|
||||||
|
managingDirector: null, localCourt: null, commercialRegister: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const cardStyle: React.CSSProperties = {
|
const cardStyle: React.CSSProperties = {
|
||||||
|
|
@ -163,7 +167,7 @@ export function AdminCompanyPage() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginBottom: '1.5rem' }}>
|
<div style={{ marginBottom: '1rem' }}>
|
||||||
<label style={labelStyle}>Website</label>
|
<label style={labelStyle}>Website</label>
|
||||||
<input
|
<input
|
||||||
style={inputStyle}
|
style={inputStyle}
|
||||||
|
|
@ -173,6 +177,42 @@ export function AdminCompanyPage() {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr style={{ border: 'none', borderTop: '1px solid var(--color-border)', margin: '1.25rem 0' }} />
|
||||||
|
<p style={{ margin: '0 0 1rem', fontSize: '0.8125rem', fontWeight: 600, color: 'var(--color-text-secondary)', textTransform: 'uppercase', letterSpacing: '0.04em' }}>
|
||||||
|
Rechtliche Angaben
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '1rem' }}>
|
||||||
|
<label style={labelStyle}>Geschäftsführer</label>
|
||||||
|
<input
|
||||||
|
style={inputStyle}
|
||||||
|
value={form.managingDirector ?? ''}
|
||||||
|
onChange={(e) => set('managingDirector', e.target.value)}
|
||||||
|
placeholder="Max Mustermann"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ ...rowStyle, marginBottom: '1.5rem' }}>
|
||||||
|
<div>
|
||||||
|
<label style={labelStyle}>Amtsgericht</label>
|
||||||
|
<input
|
||||||
|
style={inputStyle}
|
||||||
|
value={form.localCourt ?? ''}
|
||||||
|
onChange={(e) => set('localCourt', e.target.value)}
|
||||||
|
placeholder="Amtsgericht Köln"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label style={labelStyle}>Handelsregisternummer</label>
|
||||||
|
<input
|
||||||
|
style={inputStyle}
|
||||||
|
value={form.commercialRegister ?? ''}
|
||||||
|
onChange={(e) => set('commercialRegister', e.target.value)}
|
||||||
|
placeholder="HRB 12345"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
|
||||||
<button
|
<button
|
||||||
style={btnPrimary}
|
style={btnPrimary}
|
||||||
|
|
@ -195,7 +235,7 @@ export function AdminCompanyPage() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Vorschau Fußzeile */}
|
{/* Vorschau Fußzeile */}
|
||||||
{(form.name || form.city || form.phone || form.email || form.website) && (
|
{(form.name || form.city || form.phone || form.email || form.website || form.managingDirector || form.commercialRegister) && (
|
||||||
<div style={cardStyle}>
|
<div style={cardStyle}>
|
||||||
<h3 style={{ margin: '0 0 0.75rem', fontSize: '0.875rem', fontWeight: 600, color: 'var(--color-text-secondary)' }}>
|
<h3 style={{ margin: '0 0 0.75rem', fontSize: '0.875rem', fontWeight: 600, color: 'var(--color-text-secondary)' }}>
|
||||||
VORSCHAU FUSSZEILE
|
VORSCHAU FUSSZEILE
|
||||||
|
|
@ -213,6 +253,10 @@ export function AdminCompanyPage() {
|
||||||
form.phone ? `Tel: ${form.phone}` : null,
|
form.phone ? `Tel: ${form.phone}` : null,
|
||||||
form.email,
|
form.email,
|
||||||
form.website,
|
form.website,
|
||||||
|
form.managingDirector ? `Geschäftsführer: ${form.managingDirector}` : null,
|
||||||
|
form.commercialRegister && form.localCourt
|
||||||
|
? `${form.commercialRegister} ${form.localCourt}`
|
||||||
|
: form.commercialRegister || (form.localCourt ? form.localCourt : null),
|
||||||
].filter(Boolean).join(' | ')}
|
].filter(Boolean).join(' | ')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue