mirror of
https://github.com/myronblair/tomsjavajive
synced 2026-06-30 17:50:32 -05:00
244 lines
11 KiB
PHP
244 lines
11 KiB
PHP
<?php
|
|
ob_start();
|
|
/**
|
|
* Tom's Java Jive - Admin Email Campaigns
|
|
*/
|
|
|
|
$pageTitle = 'Email Campaigns';
|
|
require_once __DIR__ . '/includes/header.php';
|
|
|
|
// Handle send campaign
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_POST['action'] === 'send') {
|
|
$subject = trim($_POST['subject'] ?? '');
|
|
$content = trim($_POST['content'] ?? '');
|
|
$testEmail = trim($_POST['test_email'] ?? '');
|
|
|
|
if (empty($subject) || empty($content)) {
|
|
setFlash('error', 'Subject and content are required');
|
|
} else {
|
|
if ($testEmail) {
|
|
// Send test email
|
|
$sent = sendEmail($testEmail, $subject, $content);
|
|
if ($sent) {
|
|
setFlash('success', 'Test email sent to ' . $testEmail);
|
|
} else {
|
|
setFlash('error', 'Failed to send test email');
|
|
}
|
|
} else {
|
|
// Send to all subscribers
|
|
$subscribers = db()->fetchAll("SELECT email, name FROM email_subscribers WHERE is_active = 1");
|
|
$sentCount = 0;
|
|
|
|
foreach ($subscribers as $sub) {
|
|
$personalizedContent = str_replace(
|
|
['{{name}}', '{{email}}'],
|
|
[$sub['name'] ?? 'Valued Customer', $sub['email']],
|
|
$content
|
|
);
|
|
|
|
if (sendEmail($sub['email'], $subject, $personalizedContent)) {
|
|
$sentCount++;
|
|
}
|
|
}
|
|
|
|
setFlash('success', "Campaign sent to $sentCount subscribers");
|
|
}
|
|
}
|
|
|
|
header('Location: /admin/campaigns.php');
|
|
exit;
|
|
}
|
|
|
|
// Get subscriber stats
|
|
$totalSubscribers = db()->count('email_subscribers', 'is_active = 1');
|
|
$recentSubscribers = db()->fetchAll(
|
|
"SELECT * FROM email_subscribers ORDER BY created_at DESC LIMIT 10"
|
|
);
|
|
?>
|
|
|
|
<div class="page-header">
|
|
<h1 class="page-title">Email Campaigns</h1>
|
|
</div>
|
|
|
|
<?php if (hasFlash('success')): ?>
|
|
<div class="alert alert-success"><i class="fas fa-check-circle"></i> <?= getFlash('success') ?></div>
|
|
<?php endif; ?>
|
|
<?php if (hasFlash('error')): ?>
|
|
<div class="alert alert-error"><i class="fas fa-exclamation-circle"></i> <?= getFlash('error') ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem;">
|
|
<!-- Campaign Form -->
|
|
<div>
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="send">
|
|
<div class="admin-card">
|
|
<div class="admin-card-header">
|
|
<h3 class="admin-card-title">Create Campaign</h3>
|
|
</div>
|
|
<div class="admin-card-body">
|
|
<div class="form-group">
|
|
<label class="form-label">Subject Line *</label>
|
|
<input type="text" name="subject" class="form-input" required placeholder="e.g., New Coffee Arrivals!">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Email Content (HTML) *</label>
|
|
<textarea name="content" class="form-textarea" rows="15" required placeholder="Enter HTML email content..."></textarea>
|
|
<small class="text-muted">Use {{name}} for subscriber name, {{email}} for email</small>
|
|
</div>
|
|
|
|
<div style="border-top: 1px solid var(--admin-border); padding-top: 1rem; margin-top: 1rem;">
|
|
<div class="form-group">
|
|
<label class="form-label">Send Test Email First (optional)</label>
|
|
<div style="display: flex; gap: 0.5rem;">
|
|
<input type="email" name="test_email" class="form-input" placeholder="your@email.com">
|
|
<button type="submit" class="btn btn-secondary">Send Test</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-lg" onclick="return confirm('Send this campaign to <?= $totalSubscribers ?> subscribers?')">
|
|
<i class="fas fa-paper-plane"></i> Send to All Subscribers (<?= $totalSubscribers ?>)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Email Templates -->
|
|
<div class="admin-card">
|
|
<div class="admin-card-header">
|
|
<h3 class="admin-card-title">Quick Templates</h3>
|
|
</div>
|
|
<div class="admin-card-body">
|
|
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem;">
|
|
<button class="btn btn-secondary" onclick="loadTemplate('welcome')">
|
|
<i class="fas fa-hand-wave"></i> Welcome
|
|
</button>
|
|
<button class="btn btn-secondary" onclick="loadTemplate('promo')">
|
|
<i class="fas fa-percent"></i> Promo
|
|
</button>
|
|
<button class="btn btn-secondary" onclick="loadTemplate('new_product')">
|
|
<i class="fas fa-box-open"></i> New Product
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div>
|
|
<!-- Stats -->
|
|
<div class="admin-card">
|
|
<div class="admin-card-header">
|
|
<h3 class="admin-card-title">Subscriber Stats</h3>
|
|
</div>
|
|
<div class="admin-card-body">
|
|
<div style="text-align: center; margin-bottom: 1rem;">
|
|
<div style="font-size: 2.5rem; font-weight: 700; color: var(--admin-primary);"><?= $totalSubscribers ?></div>
|
|
<div class="text-muted">Active Subscribers</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Subscribers -->
|
|
<div class="admin-card">
|
|
<div class="admin-card-header">
|
|
<h3 class="admin-card-title">Recent Subscribers</h3>
|
|
</div>
|
|
<div class="admin-card-body" style="padding: 0;">
|
|
<?php if (empty($recentSubscribers)): ?>
|
|
<p class="text-muted" style="padding: 1rem; text-align: center;">No subscribers yet</p>
|
|
<?php else: ?>
|
|
<ul style="list-style: none; padding: 0; margin: 0;">
|
|
<?php foreach ($recentSubscribers as $sub): ?>
|
|
<li style="padding: 0.75rem 1rem; border-bottom: 1px solid var(--admin-border); display: flex; justify-content: space-between; align-items: center;">
|
|
<div>
|
|
<div style="font-size: 0.875rem;"><?= htmlspecialchars($sub['email']) ?></div>
|
|
<div class="text-muted" style="font-size: 0.75rem;"><?= formatDate($sub['created_at']) ?></div>
|
|
</div>
|
|
<?php if (!$sub['is_active']): ?>
|
|
<span class="badge badge-error">Unsubscribed</span>
|
|
<?php endif; ?>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const templates = {
|
|
welcome: {
|
|
subject: 'Welcome to Tom\'s Java Jive! ☕',
|
|
content: `<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<div style="background: #8B4513; color: white; padding: 30px; text-align: center;">
|
|
<h1 style="margin: 0;">Welcome to the Family!</h1>
|
|
</div>
|
|
<div style="padding: 30px; background: #FDFBF7;">
|
|
<p>Hi {{name}},</p>
|
|
<p>Thank you for subscribing to Tom's Java Jive newsletter! We're thrilled to have you as part of our coffee-loving community.</p>
|
|
<p>As a welcome gift, enjoy <strong>10% off</strong> your first order with code: <strong>WELCOME10</strong></p>
|
|
<p style="text-align: center; margin-top: 30px;">
|
|
<a href="https://tomsjavajive.com/shop.php" style="background: #E86A33; color: white; padding: 15px 30px; text-decoration: none; border-radius: 6px; font-weight: bold;">Shop Now</a>
|
|
</p>
|
|
<p style="margin-top: 30px;">Happy brewing!</p>
|
|
<p>- The Tom's Java Jive Team</p>
|
|
</div>
|
|
</div>`
|
|
},
|
|
promo: {
|
|
subject: '🎉 Special Offer Inside!',
|
|
content: `<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<div style="background: linear-gradient(135deg, #E86A33, #8B4513); color: white; padding: 40px; text-align: center;">
|
|
<h1 style="margin: 0; font-size: 36px;">FLASH SALE</h1>
|
|
<p style="font-size: 24px; margin-top: 10px;">20% OFF Everything</p>
|
|
</div>
|
|
<div style="padding: 30px; background: #FDFBF7; text-align: center;">
|
|
<p>Hi {{name}},</p>
|
|
<p>For a limited time, enjoy 20% off your entire order!</p>
|
|
<p style="font-size: 24px; font-weight: bold; color: #E86A33; margin: 20px 0;">Use code: FLASH20</p>
|
|
<p>Hurry - offer ends soon!</p>
|
|
<p style="margin-top: 30px;">
|
|
<a href="https://tomsjavajive.com/shop.php" style="background: #E86A33; color: white; padding: 15px 30px; text-decoration: none; border-radius: 6px; font-weight: bold;">Shop the Sale</a>
|
|
</p>
|
|
</div>
|
|
</div>`
|
|
},
|
|
new_product: {
|
|
subject: '☕ New Arrival: You\'re Going to Love This!',
|
|
content: `<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
|
|
<div style="background: #8B4513; color: white; padding: 20px; text-align: center;">
|
|
<h1 style="margin: 0;">New Coffee Alert!</h1>
|
|
</div>
|
|
<div style="padding: 30px; background: #FDFBF7;">
|
|
<p>Hi {{name}},</p>
|
|
<p>We're excited to introduce our latest addition to the Tom's Java Jive family!</p>
|
|
<div style="background: white; padding: 20px; border-radius: 8px; margin: 20px 0; text-align: center;">
|
|
<h2 style="color: #8B4513;">[Product Name]</h2>
|
|
<p>[Product Description]</p>
|
|
<p style="font-size: 20px; font-weight: bold; color: #E86A33;">$XX.XX</p>
|
|
</div>
|
|
<p>Be among the first to try it!</p>
|
|
<p style="text-align: center; margin-top: 30px;">
|
|
<a href="https://tomsjavajive.com/shop.php" style="background: #E86A33; color: white; padding: 15px 30px; text-decoration: none; border-radius: 6px; font-weight: bold;">Try It Now</a>
|
|
</p>
|
|
</div>
|
|
</div>`
|
|
}
|
|
};
|
|
|
|
function loadTemplate(name) {
|
|
const template = templates[name];
|
|
if (template) {
|
|
document.querySelector('input[name="subject"]').value = template.subject;
|
|
document.querySelector('textarea[name="content"]').value = template.content;
|
|
AdminToast.success('Template loaded');
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|