Apply Yimaru Academy branding to email template seeds

Adds branded HTML layout matching the admin portal purple palette, updates 000066 seeds, and adds 000067 migration to refresh existing template rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Yared Yemane 2026-05-22 02:12:45 -07:00
parent 5937c5505a
commit 868e5ba001
5 changed files with 394 additions and 43 deletions

View File

@ -20,9 +20,38 @@ VALUES
( (
'otp', 'otp',
'One-Time Password', 'One-Time Password',
'Yimaru - One Time Password', 'Yimaru Academy — Your verification code',
'Welcome to Yimaru Online Learning Platform{{if .FirstName}}, {{.FirstName}}{{end}}. Your OTP is {{.OTP}}. It expires in {{.ExpiresMinutes}} minutes. Please do not share it with anyone.', 'Yimaru Academy{{if .FirstName}}, {{.FirstName}}{{end}}
'<p>Welcome to Yimaru Online Learning Platform{{if .FirstName}}, <strong>{{.FirstName}}</strong>{{end}}.</p><p>Your one-time password is <strong>{{.OTP}}</strong>.</p><p>It expires in {{.ExpiresMinutes}} minutes. Please do not share it with anyone.</p>',
Your verification code is {{.OTP}}.
It expires in {{.ExpiresMinutes}} minutes.
Please do not share this code with anyone.',
$otp_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;letter-spacing:0.3px;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;line-height:1.3;">Your verification code</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}use the code below to continue signing in to Yimaru Academy.</p>
<table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="background-color:#eef4ff;border-radius:8px;padding:20px;border:1px solid #e0e8f5;text-align:center;">
<p style="margin:0 0 6px;color:#9d2a83;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;">One-time password</p>
<p style="margin:0;color:#333333;font-size:34px;font-weight:700;letter-spacing:8px;font-family:Consolas,Monaco,monospace;">{{.OTP}}</p>
<p style="margin:12px 0 0;color:#666666;font-size:13px;">Expires in {{.ExpiresMinutes}} minutes</p>
</td></tr></table>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">If you did not request this code, you can safely ignore this email.</p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;line-height:1.5;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$otp_html$,
'["OTP", "FirstName", "ExpiresMinutes"]'::jsonb, '["OTP", "FirstName", "ExpiresMinutes"]'::jsonb,
TRUE, TRUE,
'ACTIVE' 'ACTIVE'
@ -30,9 +59,33 @@ VALUES
( (
'invitation', 'invitation',
'User Invitation', 'User Invitation',
'You are invited to join Yimaru', 'You are invited to Yimaru Academy',
'Hi{{if .FirstName}} {{.FirstName}}{{end}}, you have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Online Learning Platform. Accept your invitation: {{.InviteLink}}', 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
'<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>You have been invited{{if .InviterName}} by <strong>{{.InviterName}}</strong>{{end}} to join Yimaru Online Learning Platform.</p><p><a href="{{.InviteLink}}">Accept your invitation</a></p>',
You have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Academy.
Accept your invitation: {{.InviteLink}}',
$invite_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">You&rsquo;re invited</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}you have been invited{{if .InviterName}} by <strong style="color:#9d2a83;">{{.InviterName}}</strong>{{end}} to join Yimaru Academy.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.InviteLink}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Accept invitation</a></p>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">Or copy this link: <a href="{{.InviteLink}}" style="color:#9d2a83;">{{.InviteLink}}</a></p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$invite_html$,
'["FirstName", "InviterName", "InviteLink"]'::jsonb, '["FirstName", "InviterName", "InviteLink"]'::jsonb,
TRUE, TRUE,
'ACTIVE' 'ACTIVE'
@ -40,9 +93,33 @@ VALUES
( (
'password_reset', 'password_reset',
'Password Reset', 'Password Reset',
'Reset your Yimaru password', 'Reset your Yimaru Academy password',
'Hi{{if .FirstName}} {{.FirstName}}{{end}}, use this link to reset your password: {{.ResetLink}}. The link expires in {{.ExpiresMinutes}} minutes.', 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
'<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>Use the link below to reset your password. It expires in {{.ExpiresMinutes}} minutes.</p><p><a href="{{.ResetLink}}">Reset your password</a></p>',
Reset your password: {{.ResetLink}}
This link expires in {{.ExpiresMinutes}} minutes.',
$reset_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">Reset your password</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}we received a request to reset your Yimaru Academy password. The link below expires in {{.ExpiresMinutes}} minutes.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.ResetLink}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Reset password</a></p>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">If you did not request a reset, ignore this email.</p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$reset_html$,
'["FirstName", "ResetLink", "ExpiresMinutes"]'::jsonb, '["FirstName", "ResetLink", "ExpiresMinutes"]'::jsonb,
TRUE, TRUE,
'ACTIVE' 'ACTIVE'
@ -50,9 +127,30 @@ VALUES
( (
'welcome', 'welcome',
'Welcome Email', 'Welcome Email',
'Welcome to Yimaru', 'Welcome to Yimaru Academy',
'Hi{{if .FirstName}} {{.FirstName}}{{end}}, welcome to Yimaru Online Learning Platform! Sign in at {{.LoginURL}} to get started.', 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
'<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>Welcome to Yimaru Online Learning Platform!</p><p><a href="{{.LoginURL}}">Sign in to get started</a></p>',
Welcome to Yimaru Academy! Sign in to get started: {{.LoginURL}}',
$welcome_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">Welcome aboard</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}your Yimaru Academy account is ready. Start learning at your own pace.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.LoginURL}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Sign in to Yimaru Academy</a></p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$welcome_html$,
'["FirstName", "LoginURL"]'::jsonb, '["FirstName", "LoginURL"]'::jsonb,
TRUE, TRUE,
'ACTIVE' 'ACTIVE'
@ -62,7 +160,25 @@ VALUES
'Custom Message', 'Custom Message',
'{{.Subject}}', '{{.Subject}}',
'{{.Message}}', '{{.Message}}',
'<p>{{.Message}}</p>', $custom_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">{{.Subject}}</h1>
<div style="margin:0;color:#666666;font-size:15px;line-height:1.6;">{{.Message}}</div>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$custom_html$,
'["Subject", "Message"]'::jsonb, '["Subject", "Message"]'::jsonb,
TRUE, TRUE,
'ACTIVE' 'ACTIVE'

View File

@ -0,0 +1 @@
-- No-op: branded template content is not reverted automatically.

View File

@ -0,0 +1,156 @@
-- Refresh system email templates with Yimaru Academy branded HTML (admin portal colors).
-- Safe to run after 000066 when seeds used the original plain layout.
UPDATE email_templates SET
name = 'One-Time Password',
subject = 'Yimaru Academy — Your verification code',
body_text = 'Yimaru Academy{{if .FirstName}}, {{.FirstName}}{{end}}
Your verification code is {{.OTP}}.
It expires in {{.ExpiresMinutes}} minutes.
Please do not share this code with anyone.',
body_html = $otp_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;letter-spacing:0.3px;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;line-height:1.3;">Your verification code</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}use the code below to continue signing in to Yimaru Academy.</p>
<table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="background-color:#eef4ff;border-radius:8px;padding:20px;border:1px solid #e0e8f5;text-align:center;">
<p style="margin:0 0 6px;color:#9d2a83;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;">One-time password</p>
<p style="margin:0;color:#333333;font-size:34px;font-weight:700;letter-spacing:8px;font-family:Consolas,Monaco,monospace;">{{.OTP}}</p>
<p style="margin:12px 0 0;color:#666666;font-size:13px;">Expires in {{.ExpiresMinutes}} minutes</p>
</td></tr></table>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">If you did not request this code, you can safely ignore this email.</p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;line-height:1.5;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$otp_html$,
updated_at = NOW()
WHERE slug = 'otp';
UPDATE email_templates SET
name = 'User Invitation',
subject = 'You are invited to Yimaru Academy',
body_text = 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
You have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Academy.
Accept your invitation: {{.InviteLink}}',
body_html = $invite_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">You&rsquo;re invited</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}you have been invited{{if .InviterName}} by <strong style="color:#9d2a83;">{{.InviterName}}</strong>{{end}} to join Yimaru Academy.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.InviteLink}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Accept invitation</a></p>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">Or copy this link: <a href="{{.InviteLink}}" style="color:#9d2a83;">{{.InviteLink}}</a></p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$invite_html$,
updated_at = NOW()
WHERE slug = 'invitation';
UPDATE email_templates SET
name = 'Password Reset',
subject = 'Reset your Yimaru Academy password',
body_text = 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
Reset your password: {{.ResetLink}}
This link expires in {{.ExpiresMinutes}} minutes.',
body_html = $reset_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">Reset your password</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}we received a request to reset your Yimaru Academy password. The link below expires in {{.ExpiresMinutes}} minutes.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.ResetLink}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Reset password</a></p>
<p style="margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;">If you did not request a reset, ignore this email.</p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$reset_html$,
updated_at = NOW()
WHERE slug = 'password_reset';
UPDATE email_templates SET
name = 'Welcome Email',
subject = 'Welcome to Yimaru Academy',
body_text = 'Hi{{if .FirstName}} {{.FirstName}}{{end}},
Welcome to Yimaru Academy! Sign in to get started: {{.LoginURL}}',
body_html = $welcome_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">Welcome aboard</h1>
<p style="margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}your Yimaru Academy account is ready. Start learning at your own pace.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.LoginURL}}" style="display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;">Sign in to Yimaru Academy</a></p>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$welcome_html$,
updated_at = NOW()
WHERE slug = 'welcome';
UPDATE email_templates SET
name = 'Custom Message',
body_html = $custom_html$<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">
<h1 style="margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;">{{.Subject}}</h1>
<div style="margin:0;color:#666666;font-size:15px;line-height:1.6;">{{.Message}}</div>
</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>$custom_html$,
updated_at = NOW()
WHERE slug = 'custom_message';

View File

@ -0,0 +1,78 @@
package emailtemplates
// Yimaru Academy brand colors (aligned with admin portal):
// Primary #9d2a83, gradient #7b1f6e → #c43a9a, surface #eef4ff, text #333 / #666.
const (
brandEmailHeader = `<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Yimaru Academy</title></head>
<body style="margin:0;padding:0;background-color:#f4f6fb;font-family:Inter,Roboto,Helvetica,Arial,sans-serif;">
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" style="background-color:#f4f6fb;padding:32px 16px;">
<tr><td align="center">
<table role="presentation" width="600" cellspacing="0" cellpadding="0" style="max-width:600px;width:100%;background:#ffffff;border-radius:12px;overflow:hidden;box-shadow:0 4px 24px rgba(157,42,131,0.14);">
<tr><td style="background:linear-gradient(135deg,#7b1f6e 0%,#9d2a83 52%,#c43a9a 100%);padding:28px 32px;text-align:center;">
<p style="margin:0;color:#ffffff;font-size:22px;font-weight:700;letter-spacing:0.3px;">Yimaru Academy</p>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.88);font-size:11px;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;">Online Learning Platform</p>
</td></tr>
<tr><td style="padding:32px;">`
brandEmailFooter = `</td></tr>
<tr><td style="padding:20px 32px;background-color:#fafafa;border-top:1px solid #eeeeee;text-align:center;">
<p style="margin:0;color:#999999;font-size:12px;line-height:1.5;">&copy; 2026 Yimaru Academy &middot; All rights reserved</p>
</td></tr>
</table></td></tr></table></body></html>`
brandButtonPrimary = `display:inline-block;background-color:#9d2a83;color:#ffffff !important;text-decoration:none;padding:14px 28px;border-radius:8px;font-weight:600;font-size:15px;line-height:1.2;`
brandHeadingStyle = `margin:0 0 8px;color:#333333;font-size:24px;font-weight:700;line-height:1.3;`
brandBodyStyle = `margin:0 0 20px;color:#666666;font-size:15px;line-height:1.6;`
brandMutedStyle = `margin:24px 0 0;color:#666666;font-size:14px;line-height:1.6;`
brandAccentBox = `background-color:#eef4ff;border-radius:8px;padding:20px;border:1px solid #e0e8f5;text-align:center;`
)
const (
defaultOTPSubject = "Yimaru Academy — Your verification code"
defaultOTPText = "Yimaru Academy{{if .FirstName}}, {{.FirstName}}{{end}}\n\nYour verification code is {{.OTP}}.\nIt expires in {{.ExpiresMinutes}} minutes.\n\nPlease do not share this code with anyone."
defaultOTPHTML = brandEmailHeader + `
<h1 style="` + brandHeadingStyle + `">Your verification code</h1>
<p style="` + brandBodyStyle + `">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}use the code below to continue signing in to Yimaru Academy.</p>
<table role="presentation" width="100%" cellspacing="0" cellpadding="0"><tr><td style="` + brandAccentBox + `">
<p style="margin:0 0 6px;color:#9d2a83;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;">One-time password</p>
<p style="margin:0;color:#333333;font-size:34px;font-weight:700;letter-spacing:8px;font-family:Consolas,Monaco,monospace;">{{.OTP}}</p>
<p style="margin:12px 0 0;color:#666666;font-size:13px;">Expires in {{.ExpiresMinutes}} minutes</p>
</td></tr></table>
<p style="` + brandMutedStyle + `">If you did not request this code, you can safely ignore this email.</p>
` + brandEmailFooter
defaultInvitationSubject = "You are invited to Yimaru Academy"
defaultInvitationText = "Hi{{if .FirstName}} {{.FirstName}}{{end}},\n\nYou have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Academy.\n\nAccept your invitation: {{.InviteLink}}"
defaultInvitationHTML = brandEmailHeader + `
<h1 style="` + brandHeadingStyle + `">You&rsquo;re invited</h1>
<p style="` + brandBodyStyle + `">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}you have been invited{{if .InviterName}} by <strong style="color:#9d2a83;">{{.InviterName}}</strong>{{end}} to join Yimaru Academy.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.InviteLink}}" style="` + brandButtonPrimary + `">Accept invitation</a></p>
<p style="` + brandMutedStyle + `">Or copy this link: <a href="{{.InviteLink}}" style="color:#9d2a83;">{{.InviteLink}}</a></p>
` + brandEmailFooter
defaultPasswordResetSubject = "Reset your Yimaru Academy password"
defaultPasswordResetText = "Hi{{if .FirstName}} {{.FirstName}}{{end}},\n\nReset your password: {{.ResetLink}}\n\nThis link expires in {{.ExpiresMinutes}} minutes."
defaultPasswordResetHTML = brandEmailHeader + `
<h1 style="` + brandHeadingStyle + `">Reset your password</h1>
<p style="` + brandBodyStyle + `">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}we received a request to reset your Yimaru Academy password. The link below expires in {{.ExpiresMinutes}} minutes.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.ResetLink}}" style="` + brandButtonPrimary + `">Reset password</a></p>
<p style="` + brandMutedStyle + `">If you did not request a reset, ignore this email.</p>
` + brandEmailFooter
defaultWelcomeSubject = "Welcome to Yimaru Academy"
defaultWelcomeText = "Hi{{if .FirstName}} {{.FirstName}}{{end}},\n\nWelcome to Yimaru Academy! Sign in to get started: {{.LoginURL}}"
defaultWelcomeHTML = brandEmailHeader + `
<h1 style="` + brandHeadingStyle + `">Welcome aboard</h1>
<p style="` + brandBodyStyle + `">{{if .FirstName}}Hi <strong style="color:#333333;">{{.FirstName}}</strong>, {{end}}your Yimaru Academy account is ready. Start learning at your own pace.</p>
<p style="margin:0 0 24px;text-align:center;"><a href="{{.LoginURL}}" style="` + brandButtonPrimary + `">Sign in to Yimaru Academy</a></p>
` + brandEmailFooter
defaultCustomMessageHTML = brandEmailHeader + `
<h1 style="` + brandHeadingStyle + `">{{.Subject}}</h1>
<div style="` + brandBodyStyle + `margin-bottom:0;">{{.Message}}</div>
` + brandEmailFooter
)

View File

@ -7,49 +7,49 @@ import (
var defaultTemplates = map[string]domain.EmailTemplate{ var defaultTemplates = map[string]domain.EmailTemplate{
domain.EmailTemplateSlugOTP: { domain.EmailTemplateSlugOTP: {
Slug: domain.EmailTemplateSlugOTP, Slug: domain.EmailTemplateSlugOTP,
Name: "One-Time Password", Name: "One-Time Password",
Subject: "Yimaru - One Time Password", Subject: defaultOTPSubject,
BodyText: "Welcome to Yimaru Online Learning Platform{{if .FirstName}}, {{.FirstName}}{{end}}. Your OTP is {{.OTP}}. It expires in {{.ExpiresMinutes}} minutes. Please do not share it with anyone.", BodyText: defaultOTPText,
BodyHTML: "<p>Welcome to Yimaru Online Learning Platform{{if .FirstName}}, <strong>{{.FirstName}}</strong>{{end}}.</p><p>Your one-time password is <strong>{{.OTP}}</strong>.</p><p>It expires in {{.ExpiresMinutes}} minutes. Please do not share it with anyone.</p>", BodyHTML: defaultOTPHTML,
Variables: []string{"OTP", "FirstName", "ExpiresMinutes"}, Variables: []string{"OTP", "FirstName", "ExpiresMinutes"},
Status: domain.EmailTemplateStatusActive, Status: domain.EmailTemplateStatusActive,
}, },
domain.EmailTemplateSlugInvitation: { domain.EmailTemplateSlugInvitation: {
Slug: domain.EmailTemplateSlugInvitation, Slug: domain.EmailTemplateSlugInvitation,
Name: "User Invitation", Name: "User Invitation",
Subject: "You are invited to join Yimaru", Subject: defaultInvitationSubject,
BodyText: "Hi{{if .FirstName}} {{.FirstName}}{{end}}, you have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Online Learning Platform. Accept your invitation: {{.InviteLink}}", BodyText: defaultInvitationText,
BodyHTML: "<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>You have been invited{{if .InviterName}} by <strong>{{.InviterName}}</strong>{{end}} to join Yimaru Online Learning Platform.</p><p><a href=\"{{.InviteLink}}\">Accept your invitation</a></p>", BodyHTML: defaultInvitationHTML,
Variables: []string{"FirstName", "InviterName", "InviteLink"}, Variables: []string{"FirstName", "InviterName", "InviteLink"},
Status: domain.EmailTemplateStatusActive, Status: domain.EmailTemplateStatusActive,
}, },
domain.EmailTemplateSlugPasswordReset: { domain.EmailTemplateSlugPasswordReset: {
Slug: domain.EmailTemplateSlugPasswordReset, Slug: domain.EmailTemplateSlugPasswordReset,
Name: "Password Reset", Name: "Password Reset",
Subject: "Reset your Yimaru password", Subject: defaultPasswordResetSubject,
BodyText: "Hi{{if .FirstName}} {{.FirstName}}{{end}}, use this link to reset your password: {{.ResetLink}}. The link expires in {{.ExpiresMinutes}} minutes.", BodyText: defaultPasswordResetText,
BodyHTML: "<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>Use the link below to reset your password. It expires in {{.ExpiresMinutes}} minutes.</p><p><a href=\"{{.ResetLink}}\">Reset your password</a></p>", BodyHTML: defaultPasswordResetHTML,
Variables: []string{"FirstName", "ResetLink", "ExpiresMinutes"}, Variables: []string{"FirstName", "ResetLink", "ExpiresMinutes"},
Status: domain.EmailTemplateStatusActive, Status: domain.EmailTemplateStatusActive,
}, },
domain.EmailTemplateSlugWelcome: { domain.EmailTemplateSlugWelcome: {
Slug: domain.EmailTemplateSlugWelcome, Slug: domain.EmailTemplateSlugWelcome,
Name: "Welcome Email", Name: "Welcome Email",
Subject: "Welcome to Yimaru", Subject: defaultWelcomeSubject,
BodyText: "Hi{{if .FirstName}} {{.FirstName}}{{end}}, welcome to Yimaru Online Learning Platform! Sign in at {{.LoginURL}} to get started.", BodyText: defaultWelcomeText,
BodyHTML: "<p>Hi{{if .FirstName}} <strong>{{.FirstName}}</strong>{{end}},</p><p>Welcome to Yimaru Online Learning Platform!</p><p><a href=\"{{.LoginURL}}\">Sign in to get started</a></p>", BodyHTML: defaultWelcomeHTML,
Variables: []string{"FirstName", "LoginURL"}, Variables: []string{"FirstName", "LoginURL"},
Status: domain.EmailTemplateStatusActive, Status: domain.EmailTemplateStatusActive,
}, },
domain.EmailTemplateSlugCustomMessage: { domain.EmailTemplateSlugCustomMessage: {
Slug: domain.EmailTemplateSlugCustomMessage, Slug: domain.EmailTemplateSlugCustomMessage,
Name: "Custom Message", Name: "Custom Message",
Subject: "{{.Subject}}", Subject: "{{.Subject}}",
BodyText: "{{.Message}}", BodyText: "{{.Message}}",
BodyHTML: "<p>{{.Message}}</p>", BodyHTML: defaultCustomMessageHTML,
Variables: []string{"Subject", "Message"}, Variables: []string{"Subject", "Message"},
Status: domain.EmailTemplateStatusActive, Status: domain.EmailTemplateStatusActive,
}, },
} }