feat(email): Ukrainian source labels, full lead details in email (guests, date, message)
This commit is contained in:
parent
65c47359d5
commit
04b28e7620
3 changed files with 116 additions and 27 deletions
|
|
@ -86,6 +86,10 @@ export async function POST(req: NextRequest): Promise<NextResponse> {
|
|||
phone: data.phone,
|
||||
email: data.email,
|
||||
formSource: data.formSource,
|
||||
groupSize: data.groupSize,
|
||||
preferredDate: data.preferredDate,
|
||||
message: data.message,
|
||||
packageSlug: data.packageSlug,
|
||||
utmSource: data.utmSource,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {
|
|||
Container,
|
||||
Head,
|
||||
Heading,
|
||||
Hr,
|
||||
Html,
|
||||
Preview,
|
||||
Section,
|
||||
|
|
@ -14,54 +15,120 @@ interface LeadAlertEmailProps {
|
|||
phone: string
|
||||
email?: string
|
||||
formSource: string
|
||||
formSourceLabel: string
|
||||
groupSize?: number
|
||||
preferredDate?: string
|
||||
message?: string
|
||||
packageSlug?: string
|
||||
utmSource?: string
|
||||
submittedAt: string
|
||||
}
|
||||
|
||||
function Row({ label, value, bold }: { label: string; value: string; bold?: boolean }) {
|
||||
return (
|
||||
<Text style={{ margin: '0 0 8px', fontSize: 15, color: '#272727' }}>
|
||||
<span style={{ color: '#6b7280', fontSize: 13 }}>{label}: </span>
|
||||
<span style={{ fontWeight: bold ? 700 : 400 }}>{value}</span>
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export function LeadAlertEmail({
|
||||
name,
|
||||
phone,
|
||||
email,
|
||||
formSource,
|
||||
formSourceLabel,
|
||||
groupSize,
|
||||
preferredDate,
|
||||
message,
|
||||
packageSlug,
|
||||
utmSource,
|
||||
submittedAt,
|
||||
}: LeadAlertEmailProps) {
|
||||
const hasDetails = groupSize ?? preferredDate ?? packageSlug ?? message
|
||||
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<Preview>Новий лід: {name}</Preview>
|
||||
<Body style={{ fontFamily: 'sans-serif', backgroundColor: '#f4f4f5' }}>
|
||||
<Preview>
|
||||
{formSourceLabel}: {name} — {phone}
|
||||
</Preview>
|
||||
<Body style={{ fontFamily: 'Arial, sans-serif', backgroundColor: '#f1fbeb' }}>
|
||||
<Container
|
||||
style={{
|
||||
maxWidth: 480,
|
||||
maxWidth: 520,
|
||||
margin: '32px auto',
|
||||
backgroundColor: '#fff',
|
||||
padding: 24,
|
||||
borderRadius: 8,
|
||||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
boxShadow: '0 2px 16px rgba(57,104,23,0.12)',
|
||||
}}
|
||||
>
|
||||
<Heading style={{ fontSize: 20, marginBottom: 16 }}>Новий лід з сайту Shumiland</Heading>
|
||||
<Section>
|
||||
<Text>
|
||||
<strong>Ім'я:</strong> {name}
|
||||
</Text>
|
||||
<Text>
|
||||
<strong>Телефон:</strong> {phone}
|
||||
</Text>
|
||||
{email && (
|
||||
<Text>
|
||||
<strong>Email:</strong> {email}
|
||||
{/* Header */}
|
||||
<Section
|
||||
style={{
|
||||
background: 'linear-gradient(90deg,#f28b4a 0%,#fdcf54 100%)',
|
||||
padding: '20px 28px',
|
||||
}}
|
||||
>
|
||||
<Heading style={{ margin: 0, fontSize: 20, color: '#272727', fontWeight: 700 }}>
|
||||
🌿 Нова заявка — {formSourceLabel}
|
||||
</Heading>
|
||||
</Section>
|
||||
|
||||
{/* Contact */}
|
||||
<Section style={{ padding: '20px 28px 8px' }}>
|
||||
<Heading
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: '#396817',
|
||||
margin: '0 0 12px',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
Контактні дані
|
||||
</Heading>
|
||||
<Row label="Ім'я" value={name} />
|
||||
<Row label="Телефон" value={phone} bold />
|
||||
{email ? <Row label="Email" value={email} /> : null}
|
||||
</Section>
|
||||
|
||||
{/* Details */}
|
||||
{hasDetails ? (
|
||||
<>
|
||||
<Hr style={{ margin: '0 28px', borderColor: '#d8f0c2' }} />
|
||||
<Section style={{ padding: '16px 28px 8px' }}>
|
||||
<Heading
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: '#396817',
|
||||
margin: '0 0 12px',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
Деталі заявки
|
||||
</Heading>
|
||||
{groupSize ? <Row label="Кількість гостей" value={String(groupSize)} /> : null}
|
||||
{preferredDate ? <Row label="Бажана дата" value={preferredDate} /> : null}
|
||||
{packageSlug ? <Row label="Пакет" value={packageSlug} /> : null}
|
||||
{message ? <Row label="Повідомлення" value={message} /> : null}
|
||||
</Section>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{/* Footer */}
|
||||
<Hr style={{ margin: '0 28px', borderColor: '#d8f0c2' }} />
|
||||
<Section style={{ padding: '12px 28px 20px' }}>
|
||||
{utmSource ? (
|
||||
<Text style={{ margin: '0 0 4px', fontSize: 12, color: '#9ca3af' }}>
|
||||
Джерело трафіку: {utmSource}
|
||||
</Text>
|
||||
)}
|
||||
<Text>
|
||||
<strong>Форма:</strong> {formSource}
|
||||
) : null}
|
||||
<Text style={{ margin: 0, fontSize: 12, color: '#9ca3af' }}>
|
||||
Отримано: {submittedAt}
|
||||
</Text>
|
||||
{utmSource && (
|
||||
<Text>
|
||||
<strong>UTM Source:</strong> {utmSource}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={{ color: '#6b7280', fontSize: 12 }}>Отримано: {submittedAt}</Text>
|
||||
</Section>
|
||||
</Container>
|
||||
</Body>
|
||||
|
|
|
|||
|
|
@ -12,11 +12,26 @@ function getResend() {
|
|||
const FROM = process.env['RESEND_FROM'] ?? 'noreply@shumiland.ua'
|
||||
const MANAGER_EMAILS = (process.env['MANAGER_EMAILS'] ?? '').split(',').filter(Boolean)
|
||||
|
||||
const SOURCE_LABELS: Record<string, string> = {
|
||||
'birthday-booking': 'Дні народження',
|
||||
'group-request': 'Групові відвідування',
|
||||
'ticket-purchase': 'Купівля квитків',
|
||||
general: 'Загальна заявка',
|
||||
}
|
||||
|
||||
function sourceLabel(formSource: string): string {
|
||||
return SOURCE_LABELS[formSource] ?? formSource
|
||||
}
|
||||
|
||||
export type LeadAlertData = {
|
||||
name: string
|
||||
phone: string
|
||||
email?: string
|
||||
formSource: string
|
||||
groupSize?: number
|
||||
preferredDate?: string
|
||||
message?: string
|
||||
packageSlug?: string
|
||||
utmSource?: string
|
||||
}
|
||||
|
||||
|
|
@ -26,9 +41,12 @@ export async function sendLeadAlert(lead: LeadAlertData): Promise<void> {
|
|||
return
|
||||
}
|
||||
|
||||
const label = sourceLabel(lead.formSource)
|
||||
|
||||
const html = await render(
|
||||
LeadAlertEmail({
|
||||
...lead,
|
||||
formSourceLabel: label,
|
||||
submittedAt: new Date().toLocaleString('uk-UA', { timeZone: 'Europe/Kyiv' }),
|
||||
})
|
||||
)
|
||||
|
|
@ -43,7 +61,7 @@ export async function sendLeadAlert(lead: LeadAlertData): Promise<void> {
|
|||
await resend.emails.send({
|
||||
from: FROM,
|
||||
to: MANAGER_EMAILS,
|
||||
subject: `Новий лід: ${lead.name} (${lead.formSource})`,
|
||||
subject: `Нова заявка — ${label}: ${lead.name} (${lead.phone})`,
|
||||
html,
|
||||
})
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue