Files
AudioCore/modules/newsletter/views/admin/index.php
2026-03-04 20:46:11 +00:00

260 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$pageTitle = 'Newsletter';
$campaigns = $campaigns ?? [];
ob_start();
?>
<section class="admin-card">
<div class="badge">Newsletter</div>
<div style="display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:16px;">
<div>
<h1 style="font-size:28px; margin:0;">Campaigns</h1>
<p style="color: var(--muted); margin-top:6px;">Build and send HTML newsletters.</p>
</div>
<div style="display:flex; gap:10px;">
<a href="/admin/newsletter/subscribers" class="btn outline small">Subscribers</a>
<form method="post" action="/admin/newsletter/campaigns/process" style="display:inline;">
<button type="submit" class="btn outline small">Process Queue</button>
</form>
<a href="/admin/newsletter/campaigns/new" class="btn small">New Campaign</a>
</div>
</div>
<div style="margin-top:18px; display:grid; gap:10px;">
<div style="display:grid; grid-template-columns: 2fr 1.4fr 120px 140px 140px 140px; gap:12px; font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:0.2em;">
<div>Title</div>
<div>Subject</div>
<div>Status</div>
<div>Scheduled</div>
<div>Sent At</div>
<div>Actions</div>
</div>
<?php if (!$campaigns): ?>
<div style="color: var(--muted); font-size:13px;">No campaigns yet.</div>
<?php else: ?>
<?php foreach ($campaigns as $campaign): ?>
<div style="display:grid; grid-template-columns: 2fr 1.4fr 120px 140px 140px 140px; gap:12px; align-items:center; padding:10px 12px; border-radius:16px; border:1px solid var(--stroke); background: rgba(14,14,16,0.9);">
<div style="font-weight:600;"><?= htmlspecialchars((string)($campaign['title'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<div style="font-size:12px; color:var(--muted);"><?= htmlspecialchars((string)($campaign['subject'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<div style="font-size:12px; color:<?= ((string)($campaign['status'] ?? '') === 'sent') ? 'var(--accent-2)' : 'var(--muted)' ?>;">
<?= htmlspecialchars((string)($campaign['status'] ?? 'draft'), ENT_QUOTES, 'UTF-8') ?>
</div>
<div style="font-size:12px; color:var(--muted);"><?= htmlspecialchars((string)($campaign['scheduled_at'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<div style="font-size:12px; color:var(--muted);"><?= htmlspecialchars((string)($campaign['sent_at'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div>
<div style="display:flex; gap:8px;">
<a href="/admin/newsletter/campaigns/edit?id=<?= (int)$campaign['id'] ?>" class="btn outline small">Edit</a>
<form method="post" action="/admin/newsletter/campaigns/send" onsubmit="return confirm('Send this campaign now?');">
<input type="hidden" name="id" value="<?= (int)$campaign['id'] ?>">
<button type="submit" class="btn small">Send</button>
</form>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</section>
<section class="admin-card" style="margin-top:16px;">
<div class="badge">Signup Form</div>
<p style="color: var(--muted); margin-top:10px;">Choose a signup form template to paste into any custom page.</p>
<div style="margin-top:12px; display:grid; gap:12px;">
<select id="signupTemplateSelect" class="input" style="text-transform:none;">
<option value="">Select template</option>
<option value="signup-compact">Compact Inline</option>
<option value="signup-card">Card Form</option>
<option value="signup-minimal">Minimal</option>
<option value="signup-banner">Banner CTA</option>
</select>
<div id="signupTemplatePreview" style="border:1px solid rgba(255,255,255,0.12); border-radius:14px; padding:12px; background: rgba(0,0,0,0.2); min-height:120px;"></div>
<div style="display:flex; gap:10px; justify-content:flex-end;">
<button type="button" id="copySignupTemplate" class="btn outline small">Copy HTML</button>
</div>
</div>
</section>
<section class="admin-card" style="margin-top:16px;">
<div class="badge">Template Starter</div>
<p style="color: var(--muted); margin-top:10px;">Pick a campaign template, preview it, then copy HTML.</p>
<div style="margin-top:12px; display:grid; gap:12px;">
<select id="newsletterTemplateSelect" class="input" style="text-transform:none;">
<option value="">Select template</option>
<option value="email-minimal">Minimal Update</option>
<option value="email-feature">Feature Promo</option>
<option value="email-digest">Weekly Digest</option>
<option value="email-event">Event Invite</option>
</select>
<div id="newsletterTemplatePreview" style="border:1px solid rgba(255,255,255,0.12); border-radius:14px; padding:12px; background: rgba(0,0,0,0.2); min-height:140px;"></div>
<div style="display:flex; gap:10px; justify-content:flex-end;">
<button type="button" id="copyNewsletterTemplate" class="btn outline small">Copy HTML</button>
</div>
</div>
</section>
<script>
(function () {
const signupTemplates = {
'signup-compact': {
html: `<form method="post" action="/newsletter/subscribe" style="display:flex; gap:8px; flex-wrap:wrap;">
<input type="text" name="name" placeholder="Name" style="padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb;">
<input type="email" name="email" placeholder="Email" required style="padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb;">
<button type="submit" style="padding:10px 16px; border-radius:999px; border:none; background:#22f2a5; color:#071016;">Subscribe</button>
</form>`,
preview: `<div style="background:#0f1117; padding:12px; border-radius:12px;">
<div style="color:#c9cbd4; font-size:12px; margin-bottom:8px;">Compact Inline</div>
<div style="display:flex; gap:8px; flex-wrap:wrap;">
<div style="flex:1; min-width:120px; height:34px; border-radius:8px; background:#1b1e26;"></div>
<div style="flex:1; min-width:120px; height:34px; border-radius:8px; background:#1b1e26;"></div>
<div style="width:110px; height:34px; border-radius:999px; background:#22f2a5;"></div>
</div>
</div>`
},
'signup-card': {
html: `<div style="padding:18px; border:1px solid #e5e7eb; border-radius:12px;">
<h3 style="margin:0 0 8px;">Join the newsletter</h3>
<p style="margin:0 0 12px;">Monthly updates and releases.</p>
<form method="post" action="/newsletter/subscribe" style="display:grid; gap:8px;">
<input type="text" name="name" placeholder="Name" style="padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb;">
<input type="email" name="email" placeholder="Email" required style="padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb;">
<button type="submit" style="padding:10px 16px; border-radius:999px; border:none; background:#22f2a5; color:#071016;">Subscribe</button>
</form>
</div>`,
preview: `<div style="background:#0f1117; padding:12px; border-radius:12px;">
<div style="height:10px; width:120px; background:#2a2e3a; border-radius:6px; margin-bottom:10px;"></div>
<div style="height:8px; width:180px; background:#1b1e26; border-radius:6px; margin-bottom:12px;"></div>
<div style="display:grid; gap:8px;">
<div style="height:34px; border-radius:8px; background:#1b1e26;"></div>
<div style="height:34px; border-radius:8px; background:#1b1e26;"></div>
<div style="height:34px; width:120px; border-radius:999px; background:#22f2a5;"></div>
</div>
</div>`
},
'signup-minimal': {
html: `<form method="post" action="/newsletter/subscribe">
<input type="email" name="email" placeholder="Email" required style="padding:10px 12px; border-radius:10px; border:1px solid #e5e7eb; width:100%; max-width:320px;">
<button type="submit" style="margin-top:8px; padding:8px 14px; border-radius:999px; border:1px solid #111; background:#111; color:#fff;">Subscribe</button>
</form>`,
preview: `<div style="background:#0f1117; padding:12px; border-radius:12px;">
<div style="height:34px; width:240px; border-radius:8px; background:#1b1e26;"></div>
<div style="height:30px; width:110px; border-radius:999px; background:#2a2e3a; margin-top:8px;"></div>
</div>`
},
'signup-banner': {
html: `<div style="padding:16px; border-radius:12px; background:#0f172a; color:#fff; display:flex; flex-wrap:wrap; gap:12px; align-items:center;">
<div style="flex:1; min-width:180px;">
<strong>Get updates</strong><br>
New releases, events, and drops.
</div>
<form method="post" action="/newsletter/subscribe" style="display:flex; gap:8px; flex-wrap:wrap;">
<input type="email" name="email" placeholder="Email" required style="padding:10px 12px; border-radius:10px; border:1px solid #1f2937;">
<button type="submit" style="padding:10px 16px; border-radius:999px; border:none; background:#22f2a5; color:#071016;">Subscribe</button>
</form>
</div>`,
preview: `<div style="background:#0f1117; padding:12px; border-radius:12px;">
<div style="height:16px; width:160px; background:#1b1e26; border-radius:6px; margin-bottom:8px;"></div>
<div style="display:flex; gap:8px; flex-wrap:wrap;">
<div style="height:34px; width:160px; border-radius:8px; background:#1b1e26;"></div>
<div style="height:34px; width:110px; border-radius:999px; background:#22f2a5;"></div>
</div>
</div>`
}
};
const emailTemplates = {
'email-minimal': {
html: `<div style="font-family:Arial, sans-serif; color:#111; line-height:1.6;">
<h1 style="margin:0 0 8px;">AudioCore Update</h1>
<p style="margin:0 0 16px;">Latest releases, news, and announcements.</p>
<p style="margin:0;">Thanks for listening.</p>
</div>`,
preview: `<div style="background:#fff; color:#111; padding:12px; border-radius:8px;">
<div style="height:16px; width:180px; background:#e5e7eb; border-radius:6px; margin-bottom:8px;"></div>
<div style="height:10px; width:240px; background:#f3f4f6; border-radius:6px; margin-bottom:10px;"></div>
<div style="height:10px; width:120px; background:#f3f4f6; border-radius:6px;"></div>
</div>`
},
'email-feature': {
html: `<div style="font-family:Arial, sans-serif; color:#111; line-height:1.6;">
<h1 style="margin:0 0 8px;">Featured Release</h1>
<img src="https://placehold.co/600x360/111827/ffffff?text=Cover" alt="" style="width:100%; border-radius:10px; margin:8px 0;">
<p style="margin:0 0 12px;">REC008 Night Drive EP now available.</p>
<a href="#" style="display:inline-block; padding:10px 16px; border-radius:999px; background:#22f2a5; color:#071016; text-decoration:none;">Listen now</a>
</div>`,
preview: `<div style="background:#fff; color:#111; padding:12px; border-radius:8px;">
<div style="height:16px; width:160px; background:#e5e7eb; border-radius:6px; margin-bottom:8px;"></div>
<div style="height:120px; background:#e5e7eb; border-radius:8px; margin-bottom:10px;"></div>
<div style="height:10px; width:200px; background:#f3f4f6; border-radius:6px; margin-bottom:12px;"></div>
<div style="height:30px; width:120px; background:#22f2a5; border-radius:999px;"></div>
</div>`
},
'email-digest': {
html: `<div style="font-family:Arial, sans-serif; color:#111; line-height:1.6;">
<h1 style="margin:0 0 12px;">Weekly Digest</h1>
<ul style="padding-left:18px; margin:0 0 12px;">
<li>New release: REC009 Twilight Runner</li>
<li>Label spotlight: Neon District</li>
<li>Playlist update: Midnight Circuit</li>
</ul>
<p style="margin:0;">See the full catalog for more.</p>
</div>`,
preview: `<div style="background:#fff; color:#111; padding:12px; border-radius:8px;">
<div style="height:16px; width:160px; background:#e5e7eb; border-radius:6px; margin-bottom:10px;"></div>
<div style="height:10px; width:240px; background:#f3f4f6; border-radius:6px; margin-bottom:6px;"></div>
<div style="height:10px; width:200px; background:#f3f4f6; border-radius:6px; margin-bottom:6px;"></div>
<div style="height:10px; width:180px; background:#f3f4f6; border-radius:6px; margin-bottom:12px;"></div>
<div style="height:10px; width:200px; background:#f3f4f6; border-radius:6px;"></div>
</div>`
},
'email-event': {
html: `<div style="font-family:Arial, sans-serif; color:#111; line-height:1.6;">
<h1 style="margin:0 0 8px;">Live Showcase</h1>
<p style="margin:0 0 12px;">Friday, 8PM · Warehouse 12</p>
<a href="#" style="display:inline-block; padding:10px 16px; border-radius:999px; background:#111; color:#fff; text-decoration:none;">RSVP</a>
</div>`,
preview: `<div style="background:#fff; color:#111; padding:12px; border-radius:8px;">
<div style="height:16px; width:140px; background:#e5e7eb; border-radius:6px; margin-bottom:8px;"></div>
<div style="height:10px; width:160px; background:#f3f4f6; border-radius:6px; margin-bottom:12px;"></div>
<div style="height:30px; width:80px; background:#111; border-radius:999px;"></div>
</div>`
}
};
function wirePicker(selectId, previewId, copyId, templates) {
const select = document.getElementById(selectId);
const preview = document.getElementById(previewId);
const copyBtn = document.getElementById(copyId);
if (!select || !preview || !copyBtn) {
return;
}
function renderPreview() {
const key = select.value;
preview.innerHTML = key && templates[key] ? templates[key].preview : '';
}
select.addEventListener('change', renderPreview);
copyBtn.addEventListener('click', async function () {
const key = select.value;
if (!key || !templates[key]) {
return;
}
const html = templates[key].html;
try {
await navigator.clipboard.writeText(html);
copyBtn.textContent = 'Copied';
setTimeout(() => (copyBtn.textContent = 'Copy HTML'), 1200);
} catch (err) {
copyBtn.textContent = 'Copy failed';
setTimeout(() => (copyBtn.textContent = 'Copy HTML'), 1200);
}
});
renderPreview();
}
wirePicker('signupTemplateSelect', 'signupTemplatePreview', 'copySignupTemplate', signupTemplates);
wirePicker('newsletterTemplateSelect', 'newsletterTemplatePreview', 'copyNewsletterTemplate', emailTemplates);
})();
</script>
<?php
$content = ob_get_clean();
require __DIR__ . '/../../../admin/views/layout.php';