Kundendaten-Modal: E-Mail-Wahl Stammdaten vs. Absender
In der "Anrede & Name"-Section neue Radio-Wahl, sobald die Section aktiv ist: - Stammdaten-E-Mail (customer.email) – default wenn vorhanden - Absender-Adresse (Postfach von dem gesendet wird) - Keine E-Mail einfügen Wird in den Customer-Block-Builder durchgereicht und ersetzt die fix verdrahtete customer.email-Zeile. Wenn die Stammdaten-Mail fehlt, ist der Radio "Stammdaten" disabled und der Default springt auf "Absender". Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -420,6 +420,7 @@ export default function ComposeEmailModal({
|
|||||||
isOpen={showInsertDataModal}
|
isOpen={showInsertDataModal}
|
||||||
onClose={() => setShowInsertDataModal(false)}
|
onClose={() => setShowInsertDataModal(false)}
|
||||||
contractId={contractId}
|
contractId={contractId}
|
||||||
|
senderEmail={account.email}
|
||||||
currentBody={body}
|
currentBody={body}
|
||||||
currentAttachments={attachments}
|
currentAttachments={attachments}
|
||||||
onResult={(newBody, addedAtt) => {
|
onResult={(newBody, addedAtt) => {
|
||||||
|
|||||||
@@ -18,11 +18,21 @@ interface Props {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
contractId: number;
|
contractId: number;
|
||||||
|
/**
|
||||||
|
* E-Mail-Adresse des Postfachs, von dem die Mail abgeschickt wird.
|
||||||
|
* Wird in der "Anrede & Name"-Section als Alternative zur Stammdaten-
|
||||||
|
* E-Mail angeboten – User-Wunsch 2026-06-21: bei Kundendaten wählen,
|
||||||
|
* ob die Customer-Email oder die Stressfrei-Wechseln-Absender-Adresse
|
||||||
|
* eingefügt wird.
|
||||||
|
*/
|
||||||
|
senderEmail: string;
|
||||||
currentBody: string;
|
currentBody: string;
|
||||||
currentAttachments: EmailAttachment[];
|
currentAttachments: EmailAttachment[];
|
||||||
onResult: (newBody: string, addedAttachments: EmailAttachment[]) => void;
|
onResult: (newBody: string, addedAttachments: EmailAttachment[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EmailChoice = 'master' | 'sender' | 'none';
|
||||||
|
|
||||||
const MAX_TOTAL_SIZE = 25 * 1024 * 1024;
|
const MAX_TOTAL_SIZE = 25 * 1024 * 1024;
|
||||||
|
|
||||||
type SectionKey =
|
type SectionKey =
|
||||||
@@ -37,6 +47,7 @@ export default function InsertCustomerDataModal({
|
|||||||
isOpen,
|
isOpen,
|
||||||
onClose,
|
onClose,
|
||||||
contractId,
|
contractId,
|
||||||
|
senderEmail,
|
||||||
currentBody,
|
currentBody,
|
||||||
currentAttachments,
|
currentAttachments,
|
||||||
onResult,
|
onResult,
|
||||||
@@ -73,6 +84,11 @@ export default function InsertCustomerDataModal({
|
|||||||
});
|
});
|
||||||
const [attachBankCard, setAttachBankCard] = useState(false);
|
const [attachBankCard, setAttachBankCard] = useState(false);
|
||||||
const [attachIdentity, setAttachIdentity] = useState(false);
|
const [attachIdentity, setAttachIdentity] = useState(false);
|
||||||
|
// Welche E-Mail-Adresse in der Customer-Section steht:
|
||||||
|
// - 'master' = Stammdaten-E-Mail (customer.email)
|
||||||
|
// - 'sender' = Postfach-Adresse, von der die Mail abgeht (Stressfrei)
|
||||||
|
// - 'none' = E-Mail-Zeile weglassen
|
||||||
|
const [emailChoice, setEmailChoice] = useState<EmailChoice>('master');
|
||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
|
|
||||||
// Bei jedem Öffnen sinnvoll vorbelegen (sonst bleiben "checked" stale
|
// Bei jedem Öffnen sinnvoll vorbelegen (sonst bleiben "checked" stale
|
||||||
@@ -89,6 +105,8 @@ export default function InsertCustomerDataModal({
|
|||||||
});
|
});
|
||||||
setAttachBankCard(false);
|
setAttachBankCard(false);
|
||||||
setAttachIdentity(false);
|
setAttachIdentity(false);
|
||||||
|
// Default: Stammdaten-E-Mail wenn vorhanden, sonst Absender-Adresse.
|
||||||
|
setEmailChoice(customer?.email ? 'master' : 'sender');
|
||||||
}
|
}
|
||||||
}, [isOpen, contract, customer, deliveryAddress]);
|
}, [isOpen, contract, customer, deliveryAddress]);
|
||||||
|
|
||||||
@@ -108,7 +126,13 @@ export default function InsertCustomerDataModal({
|
|||||||
const blocks: string[] = [];
|
const blocks: string[] = [];
|
||||||
|
|
||||||
if (checked.customer && customer) {
|
if (checked.customer && customer) {
|
||||||
blocks.push(formatCustomerBlock(customer, contract));
|
const chosenEmail =
|
||||||
|
emailChoice === 'master'
|
||||||
|
? customer.email || ''
|
||||||
|
: emailChoice === 'sender'
|
||||||
|
? senderEmail
|
||||||
|
: '';
|
||||||
|
blocks.push(formatCustomerBlock(customer, contract, chosenEmail));
|
||||||
}
|
}
|
||||||
if (checked.deliveryAddress && deliveryAddress) {
|
if (checked.deliveryAddress && deliveryAddress) {
|
||||||
blocks.push(formatAddressBlock('Lieferadresse', deliveryAddress));
|
blocks.push(formatAddressBlock('Lieferadresse', deliveryAddress));
|
||||||
@@ -214,6 +238,56 @@ export default function InsertCustomerDataModal({
|
|||||||
checked={checked.customer}
|
checked={checked.customer}
|
||||||
onToggle={() => toggle('customer')}
|
onToggle={() => toggle('customer')}
|
||||||
preview={previewCustomer(customer, contract)}
|
preview={previewCustomer(customer, contract)}
|
||||||
|
extra={
|
||||||
|
checked.customer && (
|
||||||
|
<div className="mt-2 ml-6 space-y-1">
|
||||||
|
<div className="text-xs font-medium text-gray-600">
|
||||||
|
E-Mail im Text:
|
||||||
|
</div>
|
||||||
|
<label className="flex items-center gap-2 text-xs text-gray-700 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="emailChoice"
|
||||||
|
checked={emailChoice === 'master'}
|
||||||
|
onChange={() => setEmailChoice('master')}
|
||||||
|
disabled={!customer.email}
|
||||||
|
className="text-blue-600"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Stammdaten-E-Mail
|
||||||
|
{customer.email ? (
|
||||||
|
<span className="text-gray-400"> ({customer.email})</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-gray-400"> (nicht hinterlegt)</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label className="flex items-center gap-2 text-xs text-gray-700 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="emailChoice"
|
||||||
|
checked={emailChoice === 'sender'}
|
||||||
|
onChange={() => setEmailChoice('sender')}
|
||||||
|
className="text-blue-600"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
Absender-Adresse
|
||||||
|
<span className="text-gray-400"> ({senderEmail})</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label className="flex items-center gap-2 text-xs text-gray-700 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="emailChoice"
|
||||||
|
checked={emailChoice === 'none'}
|
||||||
|
onChange={() => setEmailChoice('none')}
|
||||||
|
className="text-blue-600"
|
||||||
|
/>
|
||||||
|
<span>Keine E-Mail einfügen</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{deliveryAddress && (
|
{deliveryAddress && (
|
||||||
@@ -368,12 +442,16 @@ function fullName(
|
|||||||
return parts.filter(Boolean).join(' ');
|
return parts.filter(Boolean).join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatCustomerBlock(customer: NonNullable<Contract['customer']>, contract: Contract): string {
|
function formatCustomerBlock(
|
||||||
|
customer: NonNullable<Contract['customer']>,
|
||||||
|
contract: Contract,
|
||||||
|
email: string,
|
||||||
|
): string {
|
||||||
const lines: string[] = ['Kundendaten:'];
|
const lines: string[] = ['Kundendaten:'];
|
||||||
lines.push(fullName(customer, contract.type));
|
lines.push(fullName(customer, contract.type));
|
||||||
if (customer.customerNumber) lines.push(`Kundennummer: ${customer.customerNumber}`);
|
if (customer.customerNumber) lines.push(`Kundennummer: ${customer.customerNumber}`);
|
||||||
if (customer.birthDate) lines.push(`Geburtsdatum: ${formatDate(customer.birthDate)}`);
|
if (customer.birthDate) lines.push(`Geburtsdatum: ${formatDate(customer.birthDate)}`);
|
||||||
if (customer.email) lines.push(`E-Mail: ${customer.email}`);
|
if (email) lines.push(`E-Mail: ${email}`);
|
||||||
if (customer.phone) lines.push(`Telefon: ${customer.phone}`);
|
if (customer.phone) lines.push(`Telefon: ${customer.phone}`);
|
||||||
if (customer.mobile) lines.push(`Mobil: ${customer.mobile}`);
|
if (customer.mobile) lines.push(`Mobil: ${customer.mobile}`);
|
||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
|
|||||||
Reference in New Issue
Block a user