feat: enhance contact management UI with improved layout and validation messages

This commit is contained in:
olli 2025-11-09 11:50:30 +01:00
parent 6f971be904
commit 45232be689

View File

@ -192,59 +192,44 @@
<!-- Basisdaten --> <!-- Basisdaten -->
<Card class="mb-3"> <Card class="mb-3">
<template #title> <template #title>
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-building text-primary"></i> <i class="pi pi-building text-primary"></i>
<span>Basisdaten</span> <span>Basisdaten</span>
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="formgrid grid"> <div class="flex flex-col gap-4">
<div class="field col-12 md:col-8"> <div class="flex flex-col md:flex-row gap-4">
<label for="companyName" class="block mb-2 font-medium"> <div class="flex flex-col gap-2 w-full md:w-2/3">
Firmenname <span class="text-red-500">*</span> <label for="companyName">Firmenname <span class="text-red-500">*</span></label>
</label>
<InputText <InputText
id="companyName" id="companyName"
v-model="editingContact.companyName" v-model="editingContact.companyName"
class="w-full" :invalid="submitted && !editingContact.companyName"
:class="{ 'p-invalid': submitted && !editingContact.companyName }"
/> />
<small v-if="submitted && !editingContact.companyName" class="p-error"> <small v-if="submitted && !editingContact.companyName" class="text-red-500">
Firmenname ist erforderlich Firmenname ist erforderlich
</small> </small>
</div> </div>
<div class="field col-12 md:col-4"> <div class="flex flex-col gap-2 w-full md:w-1/3">
<label for="companyNumber" class="block mb-2 font-medium">Kundennummer</label> <label for="companyNumber">Kundennummer</label>
<InputText id="companyNumber" v-model="editingContact.companyNumber" class="w-full" /> <InputText id="companyNumber" v-model="editingContact.companyNumber" />
</div>
</div> </div>
<div class="field col-12">
<div class="flex gap-4"> <div class="flex gap-4">
<div class="field-checkbox mb-0"> <div class="flex items-center gap-2">
<Checkbox <Checkbox inputId="isDebtor" v-model="editingContact.isDebtor" :binary="true" />
inputId="isDebtor" <label for="isDebtor">Debitor</label>
v-model="editingContact.isDebtor"
:binary="true"
/>
<label for="isDebtor" class="ml-2">Debitor</label>
</div> </div>
<div class="field-checkbox mb-0"> <div class="flex items-center gap-2">
<Checkbox <Checkbox inputId="isCreditor" v-model="editingContact.isCreditor" :binary="true" />
inputId="isCreditor" <label for="isCreditor">Kreditor</label>
v-model="editingContact.isCreditor"
:binary="true"
/>
<label for="isCreditor" class="ml-2">Kreditor</label>
</div>
<div class="field-checkbox mb-0">
<Checkbox
inputId="isActive"
v-model="editingContact.isActive"
:binary="true"
/>
<label for="isActive" class="ml-2">Aktiv</label>
</div> </div>
<div class="flex items-center gap-2">
<Checkbox inputId="isActive" v-model="editingContact.isActive" :binary="true" />
<label for="isActive">Aktiv</label>
</div> </div>
</div> </div>
</div> </div>
@ -254,31 +239,33 @@
<!-- Adresse --> <!-- Adresse -->
<Card class="mb-3"> <Card class="mb-3">
<template #title> <template #title>
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-map-marker text-primary"></i> <i class="pi pi-map-marker text-primary"></i>
<span>Adresse</span> <span>Adresse</span>
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="formgrid grid"> <div class="flex flex-col gap-4">
<div class="field col-12"> <div class="flex flex-col gap-2">
<label for="street" class="block mb-2 font-medium">Straße</label> <label for="street">Straße</label>
<InputText id="street" v-model="editingContact.street" class="w-full" /> <InputText id="street" v-model="editingContact.street" />
</div> </div>
<div class="field col-12 md:col-3"> <div class="flex flex-col md:flex-row gap-4">
<label for="zipCode" class="block mb-2 font-medium">PLZ</label> <div class="flex flex-col gap-2 w-full md:w-1/4">
<InputText id="zipCode" v-model="editingContact.zipCode" class="w-full" /> <label for="zipCode">PLZ</label>
<InputText id="zipCode" v-model="editingContact.zipCode" />
</div> </div>
<div class="field col-12 md:col-5"> <div class="flex flex-col gap-2 w-full md:w-1/2">
<label for="city" class="block mb-2 font-medium">Ort</label> <label for="city">Ort</label>
<InputText id="city" v-model="editingContact.city" class="w-full" /> <InputText id="city" v-model="editingContact.city" />
</div> </div>
<div class="field col-12 md:col-4"> <div class="flex flex-col gap-2 w-full md:w-1/4">
<label for="country" class="block mb-2 font-medium">Land</label> <label for="country">Land</label>
<InputText id="country" v-model="editingContact.country" class="w-full" /> <InputText id="country" v-model="editingContact.country" />
</div>
</div> </div>
</div> </div>
</template> </template>
@ -287,31 +274,35 @@
<!-- Kontaktdaten --> <!-- Kontaktdaten -->
<Card class="mb-3"> <Card class="mb-3">
<template #title> <template #title>
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-phone text-primary"></i> <i class="pi pi-phone text-primary"></i>
<span>Kontaktdaten</span> <span>Kontaktdaten</span>
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="formgrid grid"> <div class="flex flex-col gap-4">
<div class="field col-12 md:col-6"> <div class="flex flex-col md:flex-row gap-4">
<label for="phone" class="block mb-2 font-medium">Telefon</label> <div class="flex flex-col gap-2 w-full">
<InputText id="phone" v-model="editingContact.phone" class="w-full" /> <label for="phone">Telefon</label>
<InputText id="phone" v-model="editingContact.phone" />
</div> </div>
<div class="field col-12 md:col-6"> <div class="flex flex-col gap-2 w-full">
<label for="fax" class="block mb-2 font-medium">Fax</label> <label for="fax">Fax</label>
<InputText id="fax" v-model="editingContact.fax" class="w-full" /> <InputText id="fax" v-model="editingContact.fax" />
</div>
</div> </div>
<div class="field col-12 md:col-6"> <div class="flex flex-col md:flex-row gap-4">
<label for="email" class="block mb-2 font-medium">E-Mail</label> <div class="flex flex-col gap-2 w-full">
<InputText id="email" v-model="editingContact.email" type="email" class="w-full" /> <label for="email">E-Mail</label>
<InputText id="email" v-model="editingContact.email" type="email" />
</div> </div>
<div class="field col-12 md:col-6"> <div class="flex flex-col gap-2 w-full">
<label for="website" class="block mb-2 font-medium">Website</label> <label for="website">Website</label>
<InputText id="website" v-model="editingContact.website" class="w-full" /> <InputText id="website" v-model="editingContact.website" />
</div>
</div> </div>
</div> </div>
</template> </template>
@ -320,21 +311,21 @@
<!-- Steuerdaten --> <!-- Steuerdaten -->
<Card class="mb-3"> <Card class="mb-3">
<template #title> <template #title>
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-calculator text-primary"></i> <i class="pi pi-calculator text-primary"></i>
<span>Steuerdaten</span> <span>Steuerdaten</span>
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="formgrid grid"> <div class="flex flex-col md:flex-row gap-4">
<div class="field col-12 md:col-6"> <div class="flex flex-col gap-2 w-full">
<label for="taxNumber" class="block mb-2 font-medium">Steuernummer</label> <label for="taxNumber">Steuernummer</label>
<InputText id="taxNumber" v-model="editingContact.taxNumber" class="w-full" /> <InputText id="taxNumber" v-model="editingContact.taxNumber" />
</div> </div>
<div class="field col-12 md:col-6"> <div class="flex flex-col gap-2 w-full">
<label for="vatNumber" class="block mb-2 font-medium">USt-IdNr.</label> <label for="vatNumber">USt-IdNr.</label>
<InputText id="vatNumber" v-model="editingContact.vatNumber" class="w-full" /> <InputText id="vatNumber" v-model="editingContact.vatNumber" />
</div> </div>
</div> </div>
</template> </template>
@ -343,8 +334,8 @@
<!-- Ansprechpartner --> <!-- Ansprechpartner -->
<Card class="mb-3"> <Card class="mb-3">
<template #title> <template #title>
<div class="flex align-items-center justify-content-between"> <div class="flex items-center justify-between">
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-users text-primary"></i> <i class="pi pi-users text-primary"></i>
<span>Ansprechpartner</span> <span>Ansprechpartner</span>
</div> </div>
@ -370,8 +361,8 @@
class="mb-4" class="mb-4"
> >
<Divider v-if="index > 0" /> <Divider v-if="index > 0" />
<div class="formgrid grid"> <div class="flex flex-col gap-4">
<div class="field col-12 flex justify-content-between align-items-center mb-3"> <div class="flex justify-between items-center mb-3">
<h4 class="m-0 font-semibold"> <h4 class="m-0 font-semibold">
<i class="pi pi-user mr-2"></i> <i class="pi pi-user mr-2"></i>
Ansprechpartner {{ index + 1 }} Ansprechpartner {{ index + 1 }}
@ -387,105 +378,85 @@
/> />
</div> </div>
<div class="field col-12 md:col-3"> <div class="flex flex-col md:flex-row gap-4">
<label :for="'salutation-' + index" class="block mb-2 font-medium"> <div class="flex flex-col gap-2 w-full md:w-1/4">
Anrede <label :for="'salutation-' + index">Anrede</label>
</label>
<Dropdown <Dropdown
:id="'salutation-' + index" :id="'salutation-' + index"
v-model="person.salutation" v-model="person.salutation"
:options="salutations" :options="salutations"
placeholder="Wählen..." placeholder="Wählen..."
class="w-full"
/> />
</div> </div>
<div class="field col-12 md:col-3"> <div class="flex flex-col gap-2 w-full md:w-1/4">
<label :for="'title-' + index" class="block mb-2 font-medium">Titel</label> <label :for="'title-' + index">Titel</label>
<InputText :id="'title-' + index" v-model="person.title" class="w-full" /> <InputText :id="'title-' + index" v-model="person.title" />
</div> </div>
<div class="field col-12 md:col-3"> <div class="flex flex-col gap-2 w-full md:w-1/4">
<label :for="'firstName-' + index" class="block mb-2 font-medium"> <label :for="'firstName-' + index">
Vorname <span class="text-red-500">*</span> Vorname <span class="text-red-500">*</span>
</label> </label>
<InputText <InputText
:id="'firstName-' + index" :id="'firstName-' + index"
v-model="person.firstName" v-model="person.firstName"
class="w-full" :invalid="submitted && !person.firstName"
:class="{ 'p-invalid': submitted && !person.firstName }"
/> />
</div> </div>
<div class="field col-12 md:col-3"> <div class="flex flex-col gap-2 w-full md:w-1/4">
<label :for="'lastName-' + index" class="block mb-2 font-medium"> <label :for="'lastName-' + index">
Nachname <span class="text-red-500">*</span> Nachname <span class="text-red-500">*</span>
</label> </label>
<InputText <InputText
:id="'lastName-' + index" :id="'lastName-' + index"
v-model="person.lastName" v-model="person.lastName"
class="w-full" :invalid="submitted && !person.lastName"
:class="{ 'p-invalid': submitted && !person.lastName }"
/> />
</div> </div>
<div class="field col-12 md:col-6">
<label :for="'position-' + index" class="block mb-2 font-medium">
Position
</label>
<InputText :id="'position-' + index" v-model="person.position" class="w-full" />
</div> </div>
<div class="field col-12 md:col-6"> <div class="flex flex-col md:flex-row gap-4">
<label :for="'department-' + index" class="block mb-2 font-medium"> <div class="flex flex-col gap-2 w-full">
Abteilung <label :for="'position-' + index">Position</label>
</label> <InputText :id="'position-' + index" v-model="person.position" />
<InputText
:id="'department-' + index"
v-model="person.department"
class="w-full"
/>
</div> </div>
<div class="field col-12 md:col-4"> <div class="flex flex-col gap-2 w-full">
<label :for="'personPhone-' + index" class="block mb-2 font-medium"> <label :for="'department-' + index">Abteilung</label>
Telefon <InputText :id="'department-' + index" v-model="person.department" />
</label> </div>
<InputText
:id="'personPhone-' + index"
v-model="person.phone"
class="w-full"
/>
</div> </div>
<div class="field col-12 md:col-4"> <div class="flex flex-col md:flex-row gap-4">
<label :for="'mobile-' + index" class="block mb-2 font-medium">Mobil</label> <div class="flex flex-col gap-2 w-full">
<InputText :id="'mobile-' + index" v-model="person.mobile" class="w-full" /> <label :for="'personPhone-' + index">Telefon</label>
<InputText :id="'personPhone-' + index" v-model="person.phone" />
</div> </div>
<div class="field col-12 md:col-4"> <div class="flex flex-col gap-2 w-full">
<label :for="'personEmail-' + index" class="block mb-2 font-medium"> <label :for="'mobile-' + index">Mobil</label>
E-Mail <InputText :id="'mobile-' + index" v-model="person.mobile" />
</label> </div>
<div class="flex flex-col gap-2 w-full">
<label :for="'personEmail-' + index">E-Mail</label>
<InputText <InputText
:id="'personEmail-' + index" :id="'personEmail-' + index"
v-model="person.email" v-model="person.email"
type="email" type="email"
class="w-full"
/> />
</div> </div>
</div>
<div class="field col-12"> <div class="flex items-center gap-2">
<div class="field-checkbox mb-0">
<Checkbox <Checkbox
:inputId="'isPrimary-' + index" :inputId="'isPrimary-' + index"
v-model="person.isPrimary" v-model="person.isPrimary"
:binary="true" :binary="true"
/> />
<label :for="'isPrimary-' + index" class="ml-2"> <label :for="'isPrimary-' + index">Hauptansprechpartner</label>
Hauptansprechpartner
</label>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -495,19 +466,21 @@
<!-- Notizen --> <!-- Notizen -->
<Card> <Card>
<template #title> <template #title>
<div class="flex align-items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-comment text-primary"></i> <i class="pi pi-comment text-primary"></i>
<span>Notizen</span> <span>Notizen</span>
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="flex flex-col gap-2">
<label for="notes">Interne Notizen zu diesem Kontakt</label>
<Textarea <Textarea
id="notes" id="notes"
v-model="editingContact.notes" v-model="editingContact.notes"
class="w-full"
:rows="4" :rows="4"
placeholder="Interne Notizen zu diesem Kontakt..." placeholder="Interne Notizen..."
/> />
</div>
</template> </template>
</Card> </Card>
</div> </div>