feat: add newsletter broadcast system with admin login and dynamic QR code redirect service with scan tracking.

This commit is contained in:
Timo
2026-01-02 18:07:18 +01:00
parent a15e3b67c2
commit 0302821f0f
7 changed files with 78 additions and 57 deletions

View File

@@ -57,7 +57,7 @@ export async function sendPasswordResetEmail(email: string, resetToken: string)
try {
await resend.emails.send({
from: 'QR Master Security <onboarding@resend.dev>',
from: 'QR Master Security <noreply@qrmaster.net>',
replyTo: 'support@qrmaster.net',
to: email,
subject: '🔐 Reset Your QR Master Password (Expires in 1 Hour)',
@@ -189,7 +189,7 @@ export async function sendNewsletterWelcomeEmail(email: string) {
try {
await resend.emails.send({
from: 'Timo from QR Master <onboarding@resend.dev>',
from: 'Timo from QR Master <timo@qrmaster.net>',
replyTo: 'support@qrmaster.net',
to: email,
subject: '🎉 You\'re In! Here\'s What Happens Next (AI QR Features)',
@@ -361,7 +361,7 @@ export async function sendAIFeatureLaunchEmail(email: string) {
try {
await resend.emails.send({
from: 'Timo from QR Master <onboarding@resend.dev>',
from: 'Timo from QR Master <timo@qrmaster.net>',
replyTo: 'support@qrmaster.net',
to: email,
subject: '🚀 They\'re Live! Your AI QR Features Are Ready',

View File

@@ -24,11 +24,11 @@ export function parseUserAgent(userAgent: string | null): { device: string | nul
let device: string | null = null;
let os: string | null = null;
// Detect device
if (/Mobile|Android|iPhone|iPad/.test(userAgent)) {
device = 'mobile';
} else if (/Tablet|iPad/.test(userAgent)) {
// Detect device - check tablet FIRST since iPad can match mobile patterns
if (/Tablet|iPad/i.test(userAgent)) {
device = 'tablet';
} else if (/Mobile|Android|iPhone/i.test(userAgent)) {
device = 'mobile';
} else {
device = 'desktop';
}

View File

@@ -46,6 +46,7 @@ export function organizationSchema() {
'@type': 'Organization',
'@id': 'https://www.qrmaster.net/#organization',
name: 'QR Master',
alternateName: 'QRMaster',
url: 'https://www.qrmaster.net',
logo: {
'@type': 'ImageObject',
@@ -53,6 +54,7 @@ export function organizationSchema() {
width: 1200,
height: 630,
},
image: 'https://www.qrmaster.net/static/og-image.png',
sameAs: [
'https://twitter.com/qrmaster',
],
@@ -60,8 +62,45 @@ export function organizationSchema() {
'@type': 'ContactPoint',
contactType: 'Customer Support',
email: 'support@qrmaster.net',
availableLanguage: ['English', 'German'],
},
description: 'B2B SaaS platform for dynamic QR code generation with analytics, branding, and bulk generation for enterprise marketing campaigns.',
slogan: 'Dynamic QR codes that work smarter',
foundingDate: '2025',
areaServed: 'Worldwide',
serviceType: 'Software as a Service',
priceRange: '$0 - $29',
knowsAbout: [
'QR Code Generation',
'Marketing Analytics',
'Campaign Tracking',
'Dynamic QR Codes',
'Bulk QR Generation',
],
hasOfferCatalog: {
'@type': 'OfferCatalog',
name: 'QR Master Plans',
itemListElement: [
{
'@type': 'Offer',
itemOffered: {
'@type': 'SoftwareApplication',
name: 'QR Master Free',
applicationCategory: 'BusinessApplication',
operatingSystem: 'Web Browser',
},
},
{
'@type': 'Offer',
itemOffered: {
'@type': 'SoftwareApplication',
name: 'QR Master Pro',
applicationCategory: 'BusinessApplication',
operatingSystem: 'Web Browser',
},
},
],
},
description: 'Dynamic QR code generator with analytics, branding, and bulk generation for modern marketing campaigns.',
inLanguage: 'en',
mainEntityOfPage: 'https://www.qrmaster.net',
};