Improve notification bell placement and change sender to MOPC Portal
Build and Push Docker Image / build (push) Successful in 8m14s
Details
Build and Push Docker Image / build (push) Successful in 8m14s
Details
- Move notification bell to sidebar header next to logo (desktop) - Keep bell in mobile header bar (already well-placed) - Change email sender name from 'MOPC Platform' to 'MOPC Portal' Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b663aae846
commit
1d137ce93e
|
|
@ -170,9 +170,12 @@ export function AdminSidebar({ user }: AdminSidebarProps) {
|
||||||
isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full'
|
isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{/* Logo */}
|
{/* Logo + Notification */}
|
||||||
<div className="flex h-16 items-center border-b px-6">
|
<div className="flex h-16 items-center justify-between border-b px-6">
|
||||||
<Logo showText textSuffix="Admin" />
|
<Logo showText textSuffix="Admin" />
|
||||||
|
<div className="hidden lg:block">
|
||||||
|
<NotificationBell />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Edition Selector */}
|
{/* Edition Selector */}
|
||||||
|
|
@ -245,10 +248,6 @@ export function AdminSidebar({ user }: AdminSidebarProps) {
|
||||||
|
|
||||||
{/* User Profile Section */}
|
{/* User Profile Section */}
|
||||||
<div className="border-t p-3">
|
<div className="border-t p-3">
|
||||||
{/* Notification Bell - Desktop */}
|
|
||||||
<div className="hidden lg:flex justify-end mb-2">
|
|
||||||
<NotificationBell />
|
|
||||||
</div>
|
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<button className="group flex w-full items-center gap-3 rounded-xl p-2.5 text-left transition-all duration-200 hover:bg-slate-100 dark:hover:bg-slate-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
|
<button className="group flex w-full items-center gap-3 rounded-xl p-2.5 text-left transition-all duration-200 hover:bg-slate-100 dark:hover:bg-slate-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ async function getTransporter(): Promise<{ transporter: Transporter; from: strin
|
||||||
const port = db.smtp_port || process.env.SMTP_PORT || '587'
|
const port = db.smtp_port || process.env.SMTP_PORT || '587'
|
||||||
const user = db.smtp_user || process.env.SMTP_USER || ''
|
const user = db.smtp_user || process.env.SMTP_USER || ''
|
||||||
const pass = db.smtp_password || process.env.SMTP_PASS || ''
|
const pass = db.smtp_password || process.env.SMTP_PASS || ''
|
||||||
const from = db.email_from || process.env.EMAIL_FROM || 'MOPC Platform <noreply@monaco-opc.com>'
|
const from = db.email_from || process.env.EMAIL_FROM || 'MOPC Portal <noreply@monaco-opc.com>'
|
||||||
|
|
||||||
// Check if config changed since last call
|
// Check if config changed since last call
|
||||||
const configHash = `${host}:${port}:${user}:${pass}:${from}`
|
const configHash = `${host}:${port}:${user}:${pass}:${from}`
|
||||||
|
|
@ -52,7 +52,7 @@ async function getTransporter(): Promise<{ transporter: Transporter; from: strin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy references for backward compat — default sender from env
|
// Legacy references for backward compat — default sender from env
|
||||||
const defaultFrom = process.env.EMAIL_FROM || 'MOPC Platform <noreply@monaco-opc.com>'
|
const defaultFrom = process.env.EMAIL_FROM || 'MOPC Portal <noreply@monaco-opc.com>'
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Brand Colors & Logo URLs
|
// Brand Colors & Logo URLs
|
||||||
|
|
@ -248,7 +248,7 @@ interface EmailTemplate {
|
||||||
function getMagicLinkTemplate(url: string, expiryMinutes: number = 15): EmailTemplate {
|
function getMagicLinkTemplate(url: string, expiryMinutes: number = 15): EmailTemplate {
|
||||||
const content = `
|
const content = `
|
||||||
${sectionTitle('Sign in to your account')}
|
${sectionTitle('Sign in to your account')}
|
||||||
${paragraph('Click the button below to securely sign in to the MOPC Platform.')}
|
${paragraph('Click the button below to securely sign in to the MOPC Portal.')}
|
||||||
${infoBox(`<strong>This link expires in ${expiryMinutes} minutes</strong>`, 'warning')}
|
${infoBox(`<strong>This link expires in ${expiryMinutes} minutes</strong>`, 'warning')}
|
||||||
${ctaButton(url, 'Sign In to MOPC')}
|
${ctaButton(url, 'Sign In to MOPC')}
|
||||||
<p style="color: ${BRAND.textMuted}; margin: 24px 0 0 0; font-size: 13px; text-align: center;">
|
<p style="color: ${BRAND.textMuted}; margin: 24px 0 0 0; font-size: 13px; text-align: center;">
|
||||||
|
|
@ -257,10 +257,10 @@ function getMagicLinkTemplate(url: string, expiryMinutes: number = 15): EmailTem
|
||||||
`
|
`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subject: 'Sign in to MOPC Platform',
|
subject: 'Sign in to MOPC Portal',
|
||||||
html: getEmailWrapper(content),
|
html: getEmailWrapper(content),
|
||||||
text: `
|
text: `
|
||||||
Sign in to MOPC Platform
|
Sign in to MOPC Portal
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
Click the link below to sign in to your account:
|
Click the link below to sign in to your account:
|
||||||
|
|
@ -298,7 +298,7 @@ function getGenericInvitationTemplate(
|
||||||
`
|
`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subject: "You're invited to join the MOPC Platform",
|
subject: "You're invited to join the MOPC Portal",
|
||||||
html: getEmailWrapper(content),
|
html: getEmailWrapper(content),
|
||||||
text: `
|
text: `
|
||||||
${greeting}
|
${greeting}
|
||||||
|
|
@ -693,7 +693,7 @@ export async function sendTestEmail(toEmail: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const content = `
|
const content = `
|
||||||
${sectionTitle('Test Email')}
|
${sectionTitle('Test Email')}
|
||||||
${paragraph('This is a test email from the MOPC Platform.')}
|
${paragraph('This is a test email from the MOPC Portal.')}
|
||||||
${infoBox('If you received this, your email configuration is working correctly!', 'success')}
|
${infoBox('If you received this, your email configuration is working correctly!', 'success')}
|
||||||
<p style="color: ${BRAND.textMuted}; margin: 20px 0 0 0; font-size: 13px; text-align: center;">
|
<p style="color: ${BRAND.textMuted}; margin: 20px 0 0 0; font-size: 13px; text-align: center;">
|
||||||
Sent at ${new Date().toISOString()}
|
Sent at ${new Date().toISOString()}
|
||||||
|
|
@ -704,8 +704,8 @@ export async function sendTestEmail(toEmail: string): Promise<boolean> {
|
||||||
await transporter.sendMail({
|
await transporter.sendMail({
|
||||||
from,
|
from,
|
||||||
to: toEmail,
|
to: toEmail,
|
||||||
subject: 'MOPC Platform - Test Email',
|
subject: 'MOPC Portal - Test Email',
|
||||||
text: 'This is a test email from the MOPC Platform. If you received this, your email configuration is working correctly.',
|
text: 'This is a test email from the MOPC Portal. If you received this, your email configuration is working correctly.',
|
||||||
html: getEmailWrapper(content),
|
html: getEmailWrapper(content),
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
|
|
@ -806,7 +806,7 @@ function getNotificationEmailTemplate(
|
||||||
</div>
|
</div>
|
||||||
${linkUrl ? ctaButton(linkUrl, 'View Details') : ''}
|
${linkUrl ? ctaButton(linkUrl, 'View Details') : ''}
|
||||||
<p style="color: ${BRAND.textMuted}; margin: 24px 0 0 0; font-size: 13px; text-align: center;">
|
<p style="color: ${BRAND.textMuted}; margin: 24px 0 0 0; font-size: 13px; text-align: center;">
|
||||||
You received this email because of your notification preferences on the MOPC Platform.
|
You received this email because of your notification preferences on the MOPC Portal.
|
||||||
</p>
|
</p>
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue