100 lines
5.1 KiB
TypeScript
100 lines
5.1 KiB
TypeScript
/**
|
|
* Welcome Email — sent once when a user first connects their email address.
|
|
*/
|
|
|
|
import { getSmtpTransport } from "./notification-service";
|
|
|
|
export async function sendWelcomeEmail(email: string, username: string): Promise<void> {
|
|
const transport = await getSmtpTransport();
|
|
if (!transport) {
|
|
console.warn("[welcome-email] No SMTP transport available");
|
|
return;
|
|
}
|
|
|
|
const displayName = username || "there";
|
|
const demoUrl = "https://demo.rspace.online";
|
|
const createUrl = "https://rspace.online/create";
|
|
|
|
const html = `
|
|
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 520px; margin: 0 auto; padding: 24px;">
|
|
<div style="background: #1e293b; border-radius: 12px; padding: 28px; color: #e2e8f0;">
|
|
<h1 style="margin: 0 0 4px; font-size: 22px; color: #f1f5f9;">
|
|
Welcome to <span style="color: #f97316;">r</span><span style="color: #14b8a6;">Space</span>, ${escapeHtml(displayName)}!
|
|
</h1>
|
|
<p style="margin: 0 0 24px; font-size: 15px; color: #94a3b8;">
|
|
Reclaim (you)<span style="color: #f97316;">r</span><span style="color: #14b8a6;">Space</span> on the internet — one place for your group to coordinate around what you care about.
|
|
</p>
|
|
|
|
<div style="background: #0f172a; border-radius: 8px; padding: 16px; margin-bottom: 20px;">
|
|
<p style="margin: 0 0 12px; font-size: 14px; color: #e2e8f0; line-height: 1.6;">
|
|
Instead of scattering your group across Slack, Google Docs, Trello, Zoom, Splitwise, and a dozen other apps —
|
|
<strong style="color: #14b8a6;">(you)rSpace puts it all in one shared workspace</strong> that your group actually owns.
|
|
</p>
|
|
<p style="margin: 0; font-size: 14px; color: #94a3b8; line-height: 1.6;">
|
|
Plan together. Decide together. Fund together. Build together. No corporate middlemen.
|
|
</p>
|
|
</div>
|
|
|
|
<p style="margin: 0 0 12px; font-size: 13px; color: #94a3b8; text-transform: uppercase; letter-spacing: 0.05em;">How groups use rSpace</p>
|
|
<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
|
|
<tr>
|
|
<td style="padding: 8px; font-size: 14px; color: #e2e8f0; line-height: 1.5; border-bottom: 1px solid #334155;">
|
|
<strong style="color: #f1f5f9;">Plan & Decide</strong><br>
|
|
<span style="color: #94a3b8; font-size: 13px;">Schedule, vote, set priorities — decisions flow into tasks automatically</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px; font-size: 14px; color: #e2e8f0; line-height: 1.5; border-bottom: 1px solid #334155;">
|
|
<strong style="color: #f1f5f9;">Create & Share</strong><br>
|
|
<span style="color: #94a3b8; font-size: 13px;">Docs, maps, data — all synced, all encrypted, all yours</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px; font-size: 14px; color: #e2e8f0; line-height: 1.5; border-bottom: 1px solid #334155;">
|
|
<strong style="color: #f1f5f9;">Fund & Sustain</strong><br>
|
|
<span style="color: #94a3b8; font-size: 13px;">Shared wallets, resource flows, transparent budgets</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px; font-size: 14px; color: #e2e8f0; line-height: 1.5;">
|
|
<strong style="color: #f1f5f9;">Stay Connected</strong><br>
|
|
<span style="color: #94a3b8; font-size: 13px;">Chat, meet, coordinate — without giving your conversations to ad companies</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<div style="background: #0f172a; border-radius: 8px; padding: 12px 16px; margin-bottom: 20px;">
|
|
<p style="margin: 0; font-size: 13px; color: #94a3b8; line-height: 1.5;">
|
|
🔐 <strong style="color: #e2e8f0;">Your identity is yours.</strong>
|
|
One passkey — no passwords, no seeds, no email loops. Works everywhere, owned by nobody but you.
|
|
</p>
|
|
</div>
|
|
|
|
<div style="text-align: center;">
|
|
<a href="${demoUrl}" style="display: inline-block; padding: 10px 22px; background: linear-gradient(135deg, #14b8a6, #0d9488); color: white; text-decoration: none; border-radius: 6px; font-size: 14px; font-weight: 600; margin-right: 8px;">Explore the Demo Space</a>
|
|
<a href="${createUrl}" style="display: inline-block; padding: 10px 22px; background: transparent; color: #14b8a6; text-decoration: none; border-radius: 6px; font-size: 14px; font-weight: 600; border: 1px solid #14b8a6;">Create Your Space</a>
|
|
</div>
|
|
</div>
|
|
<p style="margin: 14px 0 0; font-size: 11px; color: #64748b; text-align: center;">
|
|
You can manage your email in profile settings at any time.
|
|
</p>
|
|
</div>`;
|
|
|
|
try {
|
|
await transport.sendMail({
|
|
from: "rSpace <hello@rspace.online>",
|
|
to: email,
|
|
subject: `Welcome to rSpace, ${displayName} — your group's new home`,
|
|
html,
|
|
replyTo: "hello@rspace.online",
|
|
});
|
|
console.log(`[welcome-email] Sent to ${email}`);
|
|
} catch (err: any) {
|
|
console.error(`[welcome-email] Failed to send to ${email}:`, err.message);
|
|
}
|
|
}
|
|
|
|
function escapeHtml(s: string): string {
|
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
}
|