From e60871fcd3525c1f969bffcb3bc5758665ba8cbc Mon Sep 17 00:00:00 2001 From: Thomas Peterson Date: Tue, 9 Jun 2026 19:38:56 +0200 Subject: [PATCH] Wallet: neue Mitarbeiterfelder als Bindings; Modal breiter + Overflow-Fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - WalletService BINDINGS + bindingValue: Titel, Privat-E-Mail, Fax, Zentrale, Website, Adresse (einzeilig); fullName mit Titel-Präfix - Wallet-Design-Dropdown-Labels (deutsch) ergänzt - Modal --wide auf 820px; grid2/grid-addr min-width:0, schmalere Vorwahl → kein horizontaler Overflow im Mitarbeiter-Formular mehr Co-Authored-By: Claude Opus 4.8 --- .../src/Controller/WalletDesignController.php | 6 +++-- backend/src/Service/WalletService.php | 25 ++++++++++++++++--- frontend/src/components/Modal.vue | 2 +- frontend/src/components/PhoneInput.vue | 4 +-- frontend/src/views/EmployeesView.vue | 2 ++ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/backend/src/Controller/WalletDesignController.php b/backend/src/Controller/WalletDesignController.php index b744a83..3457141 100644 --- a/backend/src/Controller/WalletDesignController.php +++ b/backend/src/Controller/WalletDesignController.php @@ -30,8 +30,10 @@ final class WalletDesignController { private const BINDING_LABELS = [ 'fullName' => 'Name', 'firstName' => 'Vorname', 'lastName' => 'Nachname', - 'position' => 'Position', 'department' => 'Abteilung', 'email' => 'E-Mail', - 'phone' => 'Telefon', 'mobile' => 'Mobil', 'company' => 'Firma', 'profileUrl' => 'Profil-Link', + 'title' => 'Titel', 'position' => 'Position', 'department' => 'Abteilung', + 'email' => 'E-Mail', 'emailPrivate' => 'E-Mail (privat)', + 'phone' => 'Telefon', 'mobile' => 'Mobil', 'fax' => 'Fax', 'phoneCentral' => 'Zentrale', + 'website' => 'Website', 'company' => 'Firma', 'address' => 'Adresse', 'profileUrl' => 'Profil-Link', ]; public function __construct( diff --git a/backend/src/Service/WalletService.php b/backend/src/Service/WalletService.php index 65eb307..f80c51c 100644 --- a/backend/src/Service/WalletService.php +++ b/backend/src/Service/WalletService.php @@ -18,8 +18,9 @@ final class WalletService { /** Verfügbare Datenfelder (Mitarbeiterprofil). */ public const BINDINGS = [ - 'fullName', 'firstName', 'lastName', 'position', 'department', - 'email', 'phone', 'mobile', 'company', 'profileUrl', + 'fullName', 'firstName', 'lastName', 'title', 'position', 'department', + 'email', 'emailPrivate', 'phone', 'mobile', 'fax', 'phoneCentral', + 'website', 'company', 'address', 'profileUrl', ]; /** Apple-Slots; Google bildet sie auf Header/Textmodule ab. */ public const SLOTS = ['primary', 'secondary', 'auxiliary', 'back']; @@ -97,20 +98,38 @@ final class WalletService public function bindingValue(Employee $e, string $binding): string { return match ($binding) { - 'fullName' => trim($e->getFirstName().' '.$e->getLastName()), + 'fullName' => trim(($e->getTitle() ? $e->getTitle().' ' : '').$e->getFirstName().' '.$e->getLastName()), 'firstName' => $e->getFirstName(), 'lastName' => $e->getLastName(), + 'title' => (string) ($e->getTitle() ?? ''), 'position' => (string) ($e->getPosition() ?? ''), 'department' => (string) ($e->getDepartment() ?? ''), 'email' => (string) ($e->getEmail() ?? ''), + 'emailPrivate' => (string) ($e->getEmailPrivate() ?? ''), 'phone' => (string) ($e->getPhone() ?? ''), 'mobile' => (string) ($e->getMobile() ?? ''), + 'fax' => (string) ($e->getFax() ?? ''), + 'phoneCentral' => (string) ($e->getPhoneCentral() ?? ''), + 'website' => (string) ($e->getWebsite() ?? ''), 'company' => $e->getCompany()->getName(), + 'address' => $this->formatAddress($e->getAddressBusiness()), 'profileUrl' => $this->shareUrl($e), default => '', }; } + /** Einzeilige Geschäftsadresse: "Straße Nr., PLZ Ort". */ + private function formatAddress(?array $a): string + { + if (null === $a) { + return ''; + } + $street = trim((string) ($a['street'] ?? '').' '.(string) ($a['houseNumber'] ?? '')); + $city = trim((string) ($a['zip'] ?? '').' '.(string) ($a['city'] ?? '')); + + return trim(implode(', ', array_filter([$street, $city])), ', '); + } + /** Rohes Logo-PNG/JPG aus dem Object-Storage (für die öffentliche Logo-URL). */ public function logoBytes(Company $company): ?string { diff --git a/frontend/src/components/Modal.vue b/frontend/src/components/Modal.vue index 32647d1..71b4bbf 100644 --- a/frontend/src/components/Modal.vue +++ b/frontend/src/components/Modal.vue @@ -23,7 +23,7 @@ const emit = defineEmits<{ close: [] }>() display: flex; align-items: center; justify-content: center; padding: 1rem; z-index: 50; } .modal { width: 100%; max-width: 480px; max-height: 90vh; overflow: auto; } -.modal--wide { max-width: 680px; } +.modal--wide { max-width: 820px; } .modal__head { display: flex; align-items: center; justify-content: space-between; padding: 1.1rem 1.4rem; border-bottom: 1px solid var(--line); diff --git a/frontend/src/components/PhoneInput.vue b/frontend/src/components/PhoneInput.vue index 897bda9..98727f9 100644 --- a/frontend/src/components/PhoneInput.vue +++ b/frontend/src/components/PhoneInput.vue @@ -41,7 +41,7 @@ function emitValue() { diff --git a/frontend/src/views/EmployeesView.vue b/frontend/src/views/EmployeesView.vue index 2720ff1..e14cdf4 100644 --- a/frontend/src/views/EmployeesView.vue +++ b/frontend/src/views/EmployeesView.vue @@ -570,7 +570,9 @@ onMounted(load) .right .btn { margin-left: .3rem; } .empty { text-align: center; color: var(--muted); padding: 2rem; } .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; } +.grid2 > * { min-width: 0; } .grid-addr { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; } +.grid-addr > * { min-width: 0; } .grid-addr .s3 { grid-column: span 1; } .actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1.2rem; } .error { color: var(--danger); font-size: .88rem; }