39074-vm/edit_attendee.php
Flatlogic Bot 281e356fda 22
2026-03-10 06:25:57 +00:00

248 lines
12 KiB
PHP

<?php
session_start();
require_once 'db/config.php';
require_once 'includes/admin_auth.php';
admin_require_login();
$attendee = null;
$webinars = [];
$id = isset($_GET['id']) ? (int) $_GET['id'] : (int) ($_POST['id'] ?? 0);
if ($id <= 0) {
admin_set_flash('Select a valid attendee to edit.');
header('Location: admin.php');
exit;
}
try {
$pdo = db();
$webinars = $pdo->query('SELECT id, title FROM webinars ORDER BY scheduled_at DESC, id DESC')->fetchAll(PDO::FETCH_ASSOC);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$webinarId = max(1, (int) ($_POST['webinar_id'] ?? 1));
$firstName = trim((string) ($_POST['first_name'] ?? ''));
$lastName = trim((string) ($_POST['last_name'] ?? ''));
$email = strtolower(trim((string) ($_POST['email'] ?? '')));
$company = trim((string) ($_POST['company'] ?? ''));
$timezone = trim((string) ($_POST['timezone'] ?? ''));
$howDidYouHear = trim((string) ($_POST['how_did_you_hear'] ?? ''));
$consented = !empty($_POST['consented']) ? 1 : 0;
if ($firstName === '' || $lastName === '') {
throw new RuntimeException('First name and last name are required.');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new RuntimeException('Enter a valid email address.');
}
if ($timezone !== '' && !in_array($timezone, timezone_identifiers_list(), true)) {
throw new RuntimeException('Timezone must be a valid IANA timezone, for example Europe/Berlin or America/New_York.');
}
$webinarCheck = $pdo->prepare('SELECT COUNT(*) FROM webinars WHERE id = ?');
$webinarCheck->execute([$webinarId]);
if ((int) $webinarCheck->fetchColumn() === 0) {
throw new RuntimeException('Selected webinar was not found.');
}
$update = $pdo->prepare('UPDATE attendees SET webinar_id = ?, first_name = ?, last_name = ?, email = ?, company = ?, timezone = ?, how_did_you_hear = ?, consented = ? WHERE id = ?');
$update->execute([$webinarId, $firstName, $lastName, $email, $company !== '' ? $company : null, $timezone !== '' ? $timezone : null, $howDidYouHear !== '' ? $howDidYouHear : null, $consented, $id]);
admin_set_flash('Attendee #' . $id . ' was updated successfully.');
header('Location: admin.php');
exit;
}
$stmt = $pdo->prepare('SELECT * FROM attendees WHERE id = ? LIMIT 1');
$stmt->execute([$id]);
$attendee = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$attendee) {
admin_set_flash('Attendee not found.');
header('Location: admin.php');
exit;
}
} catch (RuntimeException $e) {
admin_set_flash($e->getMessage());
header('Location: edit_attendee.php?id=' . urlencode((string) $id));
exit;
} catch (PDOException $e) {
error_log('Edit attendee error: ' . $e->getMessage());
admin_set_flash('Unable to load or save attendee changes right now.');
header('Location: admin.php');
exit;
}
$message = admin_get_flash();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit attendee | Webinar admin</title>
<meta name="description" content="Edit webinar attendee details including webinar assignment, consent, timezone, and lead source.">
<meta name="robots" content="noindex, nofollow">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-start: #071659;
--bg-end: #1029a0;
--surface: rgba(11, 32, 131, 0.4);
--line: rgba(221, 226, 253, 0.18);
--text-main: #f3f9ff;
--text-soft: #dde2fd;
--accent: #2c4bd1;
--accent-strong: #1029a0;
--font-body: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-display: "Space Grotesk", "Inter", system-ui, sans-serif;
--button-shadow: 0 16px 30px rgba(11, 32, 131, 0.28);
}
body {
font-family: var(--font-body);
background: radial-gradient(circle at top left, rgba(221, 226, 253, 0.22), transparent 28%), linear-gradient(135deg, var(--bg-start) 0%, #1029a0 55%, var(--bg-end) 100%);
color: var(--text-main);
min-height: 100vh;
}
.container { max-width: 840px; padding-top: 3rem; padding-bottom: 3rem; }
.panel {
background: var(--surface);
border: 1px solid var(--line);
border-radius: 24px;
padding: 1.9rem;
box-shadow: 0 25px 60px rgba(3, 11, 25, 0.4);
backdrop-filter: blur(16px);
}
h1, h2, .btn, .form-label { font-family: var(--font-display); }
h1 { font-size: 2rem; letter-spacing: -0.04em; margin-bottom: 0.5rem; }
.lead-copy { color: var(--text-soft); margin-bottom: 1.5rem; }
.form-control, .form-select {
background: rgba(221, 226, 253, 0.08);
border-color: rgba(221, 226, 253, 0.18);
color: var(--text-main);
}
.form-control:focus, .form-select:focus {
background: rgba(221, 226, 253, 0.1);
color: var(--text-main);
border-color: rgba(44, 75, 209, 0.65);
box-shadow: 0 0 0 0.2rem rgba(187, 200, 251, 0.18);
}
.form-select option { color: #111827; }
.btn {
border-radius: 14px;
font-weight: 700;
letter-spacing: 0.03em;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
border: 1px solid rgba(221, 226, 253, 0.14);
box-shadow: var(--button-shadow);
}
.btn-secondary {
background: rgba(221, 226, 253, 0.12);
border-color: rgba(221, 226, 253, 0.22);
color: var(--text-main);
}
.mini-meta {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.meta-card {
background: rgba(221, 226, 253, 0.08);
border: 1px solid rgba(221, 226, 253, 0.12);
border-radius: 16px;
padding: 0.9rem 1rem;
}
.meta-label { color: var(--text-soft); font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.06em; }
.meta-value { font-weight: 700; margin-top: 0.35rem; }
@media (max-width: 768px) { .mini-meta { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<main class="container">
<section class="panel">
<h1>Edit attendee #<?php echo (int) $attendee['id']; ?></h1>
<p class="lead-copy">Update registration details safely. Changes here affect the admin table, CSV export, and registration analytics.</p>
<?php if ($message !== ''): ?>
<div class="alert alert-info"><?php echo htmlspecialchars($message); ?></div>
<?php endif; ?>
<div class="mini-meta" aria-label="Attendee summary">
<div class="meta-card">
<div class="meta-label">Registered at</div>
<div class="meta-value"><?php echo htmlspecialchars((string) ($attendee['created_at'] ?? '—')); ?></div>
</div>
<div class="meta-card">
<div class="meta-label">Current timezone</div>
<div class="meta-value"><?php echo htmlspecialchars((string) ($attendee['timezone'] ?? '—')); ?></div>
</div>
<div class="meta-card">
<div class="meta-label">Lead source</div>
<div class="meta-value"><?php echo htmlspecialchars((string) ($attendee['how_did_you_hear'] ?? '—')); ?></div>
</div>
</div>
<form method="POST" action="edit_attendee.php">
<input type="hidden" name="id" value="<?php echo (int) $attendee['id']; ?>">
<div class="row g-3">
<div class="col-md-6">
<label for="first_name" class="form-label">First name</label>
<input type="text" class="form-control" id="first_name" name="first_name" value="<?php echo htmlspecialchars((string) $attendee['first_name']); ?>" required>
</div>
<div class="col-md-6">
<label for="last_name" class="form-label">Last name</label>
<input type="text" class="form-control" id="last_name" name="last_name" value="<?php echo htmlspecialchars((string) $attendee['last_name']); ?>" required>
</div>
<div class="col-md-6">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars((string) $attendee['email']); ?>" required>
</div>
<div class="col-md-6">
<label for="company" class="form-label">Company</label>
<input type="text" class="form-control" id="company" name="company" value="<?php echo htmlspecialchars((string) ($attendee['company'] ?? '')); ?>">
</div>
<div class="col-md-6">
<label for="webinar_id" class="form-label">Webinar</label>
<select class="form-select" id="webinar_id" name="webinar_id" required>
<?php foreach ($webinars as $webinar): ?>
<option value="<?php echo (int) $webinar['id']; ?>" <?php echo (int) $webinar['id'] === (int) $attendee['webinar_id'] ? 'selected' : ''; ?>>
<?php echo htmlspecialchars((string) $webinar['title']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-6">
<label for="timezone" class="form-label">Timezone</label>
<input type="text" class="form-control" id="timezone" name="timezone" value="<?php echo htmlspecialchars((string) ($attendee['timezone'] ?? '')); ?>" placeholder="Europe/Berlin">
</div>
<div class="col-12">
<label for="how_did_you_hear" class="form-label">How did you hear about the webinar?</label>
<input type="text" class="form-control" id="how_did_you_hear" name="how_did_you_hear" value="<?php echo htmlspecialchars((string) ($attendee['how_did_you_hear'] ?? '')); ?>" placeholder="LinkedIn, newsletter, referral...">
</div>
<div class="col-12">
<div class="form-check mt-2">
<input type="hidden" name="consented" value="0">
<input type="checkbox" class="form-check-input" id="consented" name="consented" value="1" <?php echo !empty($attendee['consented']) ? 'checked' : ''; ?>>
<label class="form-check-label" for="consented">Marketing consent received</label>
</div>
</div>
</div>
<div class="d-flex gap-2 flex-wrap mt-4">
<button type="submit" class="btn btn-primary">Save changes</button>
<a href="admin.php" class="btn btn-secondary">Back to admin</a>
<a href="login.php?logout=1" class="btn btn-secondary">Log out</a>
</div>
</form>
</section>
</main>
</body>
</html>