E-Mail name contains tenant longName + fix user invite to use selected language

This commit is contained in:
Karl Ludwig Weise
2026-04-28 21:00:46 +02:00
parent 7a955b3a70
commit 9895b57d73
5 changed files with 34 additions and 30 deletions
+7 -5
View File
@@ -28,15 +28,17 @@
</script>
<EmailLayout>
<EmailText variant="md">{m["emails.greeting"]({ name: user.name })}</EmailText>
<EmailText variant="md">{m["emails.greeting"]({ name: user.name }, { locale })}</EmailText>
<EmailText variant="md">
{m["emails.userInvite.introduction"]({ tenant: tenant.longName })}
{m["emails.userInvite.introduction"]({ tenant: tenant.longName }, { locale })}
</EmailText>
<EmailButton href={confirmUrl}>{m["emails.userInvite.action"]()}</EmailButton>
<EmailButton href={confirmUrl} {locale}>
{m["emails.userInvite.action"]({}, { locale })}
</EmailButton>
<EmailText variant="md">
{m["emails.userInvite.hint"]({ expirationMinutes })}
{m["emails.userInvite.hint"]({ expirationMinutes }, { locale })}
</EmailText>
<EmailText variant="md" color="text-light">
{m["emails.userInvite.reason"]()}
{m["emails.userInvite.reason"]({}, { locale })}
</EmailText>
</EmailLayout>
+5 -3
View File
@@ -1,7 +1,9 @@
<script lang="js">
<script lang="ts">
import { m } from "$i18n/messages";
import type { Locale } from "$i18n/runtime";
import type { Snippet } from "svelte";
let { children, href } = $props();
let { children, href, locale }: { children: Snippet; href: string; locale?: Locale } = $props();
</script>
<div class="button-container">
@@ -10,7 +12,7 @@
</div>
<span class="html-only md">
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
{m["emails.buttonAlternativeLink"]()}: <a {href}>{href}</a>
{m["emails.buttonAlternativeLink"]({}, { locale })}: <a {href}>{href}</a>
</span>
<svelte:head>
@@ -71,7 +71,7 @@ describe("Email System", () => {
expect(mockSendMail).toHaveBeenCalledWith({
from: {
name: "Test App",
name: "OpenReception",
address: "noreply@test.com",
},
to: {
@@ -291,7 +291,7 @@ describe("Email System", () => {
expect(mockSendMail).toHaveBeenCalledWith({
from: {
name: "Test App",
name: "Test Organization",
address: "noreply@test.com",
},
to: {
@@ -358,7 +358,7 @@ describe("Email System", () => {
expect(mockSendMail).toHaveBeenCalledWith({
from: {
name: "Test App",
name: "Test Organization",
address: "noreply@test.com",
},
to: {
+17 -18
View File
@@ -95,7 +95,7 @@ export async function sendTemplatedEmail(
try {
const rendered = await templateEngine.renderTemplate(templateType, data);
await sendEmail(recipient, rendered.subject, rendered.html, rendered.text);
await sendEmail(recipient, rendered.subject, rendered.html, rendered.text, tenant.longName);
} catch (error) {
console.error(`Failed to send templated email (${templateType}):`, error);
throw error;
@@ -153,7 +153,7 @@ export async function sendPinResetEmail(
const html = renderOutputToHtml(emailRender);
const text = htmlToText(html);
await sendEmail(recipient, subject, html, text);
await sendEmail(recipient, subject, html, text, tenant.longName);
}
/**
@@ -210,7 +210,7 @@ export async function sendAppointmentReminderEmail(
const html = renderOutputToHtml(emailRender);
const text = htmlToText(html);
await sendEmail(recipient, subject, html, text);
await sendEmail(recipient, subject, html, text, tenant.longName);
}
const getRecipient = async (user: SelectClient | SelectUser) => {
@@ -276,7 +276,7 @@ export async function sendAppointmentRejectedEmail(
const html = renderOutputToHtml(emailRender);
const text = htmlToText(html);
await sendEmail(recipient, subject, html, text);
await sendEmail(recipient, subject, html, text, tenant.longName);
}
/**
@@ -321,7 +321,7 @@ export async function sendAppointmentCreatedEmail(
const html = renderOutputToHtml(emailRender);
const text = htmlToText(html);
await sendEmail(recipient, subject, html, text);
await sendEmail(recipient, subject, html, text, tenant.longName);
}
/**
@@ -361,7 +361,7 @@ export async function sendAppointmentRequestEmail(
const html = renderOutputToHtml(emailRender);
const text = htmlToText(html);
await sendEmail(recipient, subject, html, text);
await sendEmail(recipient, subject, html, text, tenant.longName);
}
/**
@@ -456,7 +456,7 @@ export async function sendConfirmationEmail(
const text = htmlToText(html);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await sendEmail(recipient as any, subject, html, text);
await sendEmail(recipient as any, subject, html, text, tenant.longName);
}
/**
@@ -478,19 +478,18 @@ export async function sendUserInviteEmail(
registrationUrl: string,
language: Language = "en",
): Promise<void> {
const recipient: EmailRecipient = {
email: userEmail,
name: userName,
language,
};
const { recipient, locale } = await getRecipient({ email: userEmail, name: userName, language });
// Generate email
const subject = m["emails.userInvite.subject"]({
tenant: tenant.longName,
});
const subject = m["emails.userInvite.subject"](
{
tenant: tenant.longName,
},
{ locale },
);
const emailRender = render(UserInvite, {
props: {
locale: language ?? "en",
locale,
user: recipient as SelectUserEmail,
tenant,
confirmUrl: registrationUrl,
@@ -501,7 +500,7 @@ export async function sendUserInviteEmail(
const text = htmlToText(html);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await sendEmail(recipient as any, subject, html, text);
await sendEmail(recipient as any, subject, html, text, tenant.longName);
}
/**
@@ -540,5 +539,5 @@ export async function sendAppointmentCancelledEmail(
const text = htmlToText(html);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await sendEmail(recipient as any, subject, html, text);
await sendEmail(recipient as any, subject, html, text, tenant.longName);
}
+2 -1
View File
@@ -91,6 +91,7 @@ export async function sendEmail(
subject: string,
htmlContent: string,
textContent: string,
tenantName?: string,
): Promise<void> {
const transporter = createTransporter();
logger.setContext("sendMail");
@@ -109,7 +110,7 @@ export async function sendEmail(
const mailOptions: Mail.Options = {
from: {
name: env.SMTP_FROM_NAME || "Open Reception",
name: tenantName || "OpenReception",
address: from_address,
},
to: {