This commit is contained in:
Flatlogic Bot 2026-03-10 06:01:30 +00:00
parent b12f985e57
commit a6a9d9d626
6 changed files with 204 additions and 46 deletions

View File

@ -49,6 +49,9 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
<meta charset="UTF-8">
<title>Admin Dashboard</title>
<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">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
:root {
@ -62,10 +65,15 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
--text-muted: #97acd0;
--accent: #2c4bd1;
--accent-strong: #1029a0;
--accent-soft: #bbc8fb;
--success: #18d1b3;
--danger: #ff6b81;
--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.26);
}
body {
font-family: var(--font-body);
min-height: 100vh;
margin: 0;
background:
@ -81,6 +89,19 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
h2, h3, .h5, p, label, th, td {
color: var(--text-main);
}
h2, h3, .h5, th, .btn, .page-link {
font-family: var(--font-display);
}
h2 {
font-size: 2rem;
font-weight: 700;
letter-spacing: -0.03em;
margin-bottom: 0.35rem;
}
h3, .h5 {
font-weight: 700;
letter-spacing: -0.02em;
}
p.text-muted, .text-muted {
color: var(--text-muted) !important;
}
@ -106,26 +127,43 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
color: var(--text-main);
border: 1px solid rgba(34, 199, 255, 0.28);
}
.btn,
.page-link {
border-radius: 14px;
font-weight: 700;
letter-spacing: 0.02em;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.btn:hover,
.page-link:hover {
transform: translateY(-1px);
}
.btn-outline-primary {
color: var(--accent-soft, #bbc8fb);
border-color: rgba(34, 199, 255, 0.35);
background: rgba(221, 226, 253, 0.06);
box-shadow: none;
}
.btn-outline-primary:hover {
background: rgba(187, 200, 251, 0.18);
border-color: rgba(34, 199, 255, 0.55);
box-shadow: var(--button-shadow);
}
.btn-success,
.btn-primary {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
border: none;
border: 1px solid rgba(221, 226, 253, 0.12);
box-shadow: var(--button-shadow);
}
.btn-success:hover,
.btn-primary:hover {
background: linear-gradient(135deg, #bbc8fb 0%, #2c4bd1 100%);
box-shadow: 0 20px 34px rgba(11, 32, 131, 0.32);
}
.btn-danger {
background: linear-gradient(135deg, #ff7a8b 0%, #f04f74 100%);
border: none;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 16px 30px rgba(72, 18, 36, 0.28);
}
.table {
margin-bottom: 0;
@ -138,8 +176,11 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
}
.table thead th {
border-bottom-color: rgba(221, 226, 253, 0.18);
color: var(--accent);
color: var(--accent-soft);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 0.78rem;
background: rgba(255, 255, 255, 0.02);
}
.table td,
@ -151,6 +192,7 @@ $chart_values = json_encode(array_column($chart_data, 'user_count'));
background: rgba(255, 255, 255, 0.04);
color: var(--text-main);
border-color: rgba(143, 232, 255, 0.12);
box-shadow: none;
}
.page-item.active .page-link {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);

View File

@ -8,6 +8,9 @@
--text-muted: #bbc8fb;
--gradient: linear-gradient(135deg, #2c4bd1 0%, #1029a0 100%);
--bg-gradient: linear-gradient(-45deg, #0b2083, #1029a0, #2c4bd1);
--font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-display: "Space Grotesk", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--button-shadow: 0 18px 32px rgba(11, 32, 131, 0.28);
}
body {
@ -15,7 +18,7 @@ body {
background-size: 400% 400%;
animation: gradient 15s ease infinite;
color: var(--text-main);
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-family: var(--font-body);
margin: 0;
min-height: 100vh;
}
@ -54,17 +57,22 @@ body {
/* Buttons */
button {
background: var(--gradient);
border: none;
padding: 0.75rem 1.5rem;
border-radius: 12px;
border: 1px solid rgba(221, 226, 253, 0.14);
padding: 0.82rem 1.55rem;
border-radius: 14px;
color: white;
cursor: pointer;
font-weight: 600;
transition: transform 0.2s;
font-family: var(--font-display);
font-weight: 700;
letter-spacing: 0.03em;
box-shadow: var(--button-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 22px 36px rgba(11, 32, 131, 0.34);
filter: brightness(1.04);
}
/* Inputs */

View File

@ -63,6 +63,9 @@ try {
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Edit Attendee</title>
<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: #0b2083;
@ -74,8 +77,12 @@ try {
--accent: #2c4bd1;
--accent-strong: #1029a0;
--accent-soft: #bbc8fb;
--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%);
@ -89,9 +96,15 @@ try {
}
h1 {
color: var(--text-main);
font-weight: 800;
font-family: var(--font-display);
font-weight: 700;
letter-spacing: -0.04em;
margin-bottom: 1.5rem;
}
.form-label,
.btn {
font-family: var(--font-display);
}
form {
background: var(--surface);
border: 1px solid var(--line);
@ -115,17 +128,29 @@ try {
border-color: rgba(44, 75, 209, 0.65);
box-shadow: 0 0 0 0.2rem rgba(187, 200, 251, 0.18);
}
.btn {
border-radius: 14px;
font-weight: 700;
letter-spacing: 0.03em;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.btn:hover {
transform: translateY(-1px);
}
.btn-primary {
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
border: none;
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);
}
.btn-secondary:hover {
background: rgba(221, 226, 253, 0.18);
border-color: rgba(221, 226, 253, 0.32);
box-shadow: 0 14px 26px rgba(11, 32, 131, 0.18);
}
</style>
</head>

View File

@ -6,6 +6,9 @@
<title>AppWizzy Webinar Registration</title>
<meta name="description" content="Register for the AppWizzy webinar about building scalable apps with real frameworks, your own server, and your own database.">
<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: #0b2083;
@ -21,12 +24,15 @@
--accent-strong: #1029a0;
--accent-soft: #bbc8fb;
--success: #18d1b3;
--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 18px 36px rgba(11, 32, 131, 0.34);
}
* {
box-sizing: border-box;
}
body {
font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-family: var(--font-body);
background:
radial-gradient(circle at top left, rgba(221, 226, 253, 0.24), transparent 30%),
radial-gradient(circle at bottom right, rgba(44, 75, 209, 0.24), transparent 35%),
@ -66,17 +72,29 @@
margin-bottom: 40px;
color: var(--accent-soft);
}
.brand-logo,
.webinar-title,
.webinar-subtitle,
.speakers-section h3,
.what-you-learn h4,
.right-column h2,
.btn-register,
.btn-light,
.btn-outline-light {
font-family: var(--font-display);
}
.webinar-title {
font-size: 2.8rem;
font-weight: 800;
margin-top: 10px;
margin-bottom: 12px;
color: var(--text-main);
letter-spacing: -0.03em;
letter-spacing: -0.04em;
}
.webinar-subtitle {
font-size: 1.2rem;
font-size: 1.15rem;
font-weight: 700;
letter-spacing: 0.01em;
margin-top: 10px;
color: var(--accent-soft);
}
@ -149,17 +167,46 @@
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
color: #fff;
border: none;
border-radius: 14px;
padding: 14px;
border: 1px solid rgba(221, 226, 253, 0.18);
border-radius: 16px;
padding: 15px 18px;
width: 100%;
font-weight: 800;
letter-spacing: 0.01em;
transition: all 0.25s ease;
box-shadow: 0 16px 32px rgba(16, 41, 160, 0.35);
font-weight: 700;
font-size: 0.98rem;
letter-spacing: 0.03em;
text-transform: uppercase;
transition: transform 0.25s ease, box-shadow 0.25s ease, filter 0.25s ease;
box-shadow: var(--button-shadow);
}
.btn-register:hover {
transform: translateY(-2px);
box-shadow: 0 22px 36px rgba(16, 41, 160, 0.42);
box-shadow: 0 24px 40px rgba(11, 32, 131, 0.42);
filter: brightness(1.04);
}
.btn-light,
.btn-outline-light {
border-radius: 14px;
padding: 12px 18px;
font-size: 0.92rem;
font-weight: 700;
letter-spacing: 0.02em;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.btn-light {
background: linear-gradient(135deg, #dde2fd 0%, #bbc8fb 100%);
border: 1px solid rgba(221, 226, 253, 0.55);
color: #0b2083;
box-shadow: 0 14px 28px rgba(11, 32, 131, 0.2);
}
.btn-outline-light {
background: rgba(221, 226, 253, 0.08);
border: 1px solid rgba(221, 226, 253, 0.22);
color: var(--text-main);
}
.btn-light:hover,
.btn-outline-light:hover {
transform: translateY(-1px);
box-shadow: 0 18px 30px rgba(11, 32, 131, 0.24);
}
.what-you-learn {
margin-top: 40px;
@ -214,7 +261,7 @@
<h1 class="webinar-title" style="line-height: 1.2;">Building Scalable Apps with AppWizzy</h1>
<h2 class="webinar-subtitle">Professional Vibe-Coding Webinar</h2>
<div class="webinar-time">WEDNESDAY, NOVEMBER 19 | 10AM EST | 7AM PST | 4PM CET</div>
<div class="webinar-time">WEDNESDAY, MARCH 25 | 12PM EDT | 9AM PDT | 6PM CET</div>
<p class="webinar-description">The fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.</p>
<div class="speakers-section">
<h3>Speakers</h3>
@ -265,8 +312,8 @@
<input type="text" class="form-control" name="company" placeholder="Company">
</div>
<div class="mb-3">
<select class="form-select form-control" name="how_did_you_hear">
<option selected>How did you hear about this webinar?</option>
<select class="form-select form-control" name="how_did_you_hear" required>
<option value="" selected disabled hidden>How did you hear about this webinar?</option>
<option value="Social Media">Social Media (X, Instargram, Facebook, etc.)</option>
<option value="LinkedIn">LinkedIn</option>
<option value="Reddit">Reddit</option>

View File

@ -43,7 +43,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - Webinar Platform</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" 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 {
--primary-color: #2c4bd1;
@ -57,12 +59,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
--input-focus-border: #2c4bd1;
--error-color: #ff8ea0;
--success-color: #18d1b3;
--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 18px 36px rgba(11, 32, 131, 0.34);
}
* {
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
font-family: var(--font-body);
background:
radial-gradient(circle at top left, rgba(221, 226, 253, 0.22), transparent 28%),
linear-gradient(135deg, var(--background-start) 0%, #1029a0 55%, var(--background-end) 100%);
@ -75,11 +80,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
min-height: 100vh;
}
.logo {
font-family: var(--font-display);
font-weight: 700;
font-size: 28px;
margin-bottom: 1.5rem;
color: #bbc8fb;
letter-spacing: 0.02em;
letter-spacing: -0.02em;
}
.login-container {
width: 100%;
@ -95,8 +101,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
backdrop-filter: blur(16px);
}
h1 {
font-size: 28px;
font-family: var(--font-display);
font-size: 30px;
font-weight: 700;
letter-spacing: -0.04em;
margin-top: 0;
margin-bottom: 0.5rem;
text-align: center;
@ -105,15 +113,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
text-align: center;
margin-bottom: 2rem;
color: var(--muted-text);
font-size: 0.98rem;
font-weight: 500;
}
.form-group {
margin-bottom: 1.25rem;
}
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
font-size: 14px;
margin-bottom: 0.55rem;
font-weight: 600;
font-size: 0.85rem;
letter-spacing: 0.02em;
color: var(--text-color);
}
input[type="email"], input[type="password"] {
@ -139,19 +150,23 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
.submit-button {
width: 100%;
padding: 14px;
border: none;
border: 1px solid rgba(221, 226, 253, 0.16);
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
color: white;
font-family: var(--font-display);
font-weight: 700;
font-size: 16px;
border-radius: 12px;
font-size: 0.96rem;
letter-spacing: 0.04em;
text-transform: uppercase;
border-radius: 15px;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 16px 30px rgba(19, 105, 179, 0.32);
transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
box-shadow: var(--button-shadow);
}
.submit-button:hover {
transform: translateY(-1px);
box-shadow: 0 20px 34px rgba(19, 105, 179, 0.38);
box-shadow: 0 22px 38px rgba(11, 32, 131, 0.4);
filter: brightness(1.05);
}
.message {
padding: 1rem;
@ -176,6 +191,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email'])) {
font-size: 14px;
color: var(--muted-text);
}
.footer-link a,
.back-link a {
font-family: var(--font-display);
letter-spacing: 0.01em;
}
.footer-link a {
color: var(--primary-color);
text-decoration: none;

View File

@ -38,15 +38,31 @@ $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$first_name = filter_input(INPUT_POST, 'first_name', FILTER_SANITIZE_STRING);
$last_name = filter_input(INPUT_POST, 'last_name', FILTER_SANITIZE_STRING);
$company = filter_input(INPUT_POST, 'company', FILTER_SANITIZE_STRING);
$how_did_you_hear = filter_input(INPUT_POST, 'how_did_you_hear', FILTER_SANITIZE_STRING);
$how_did_you_hear = trim((string) filter_input(INPUT_POST, 'how_did_you_hear', FILTER_UNSAFE_RAW));
$timezone = filter_input(INPUT_POST, 'timezone', FILTER_SANITIZE_STRING);
$allowed_sources = [
'Social Media',
'LinkedIn',
'Reddit',
'Threads',
'Advertisement',
'ChatGPT',
'Flatlogic Community Discord',
'Other',
];
// --- VALIDATION ---
if (!$first_name || !$last_name || !$email) {
if (!$first_name || !$last_name || !$email || $how_did_you_hear === '') {
echo json_encode(['success' => false, 'error' => 'Please fill out all required fields.']);
exit;
}
if (!in_array($how_did_you_hear, $allowed_sources, true)) {
echo json_encode(['success' => false, 'error' => 'Please choose how you heard about this webinar from the list.']);
exit;
}
try {
// --- CHECK IF ALREADY REGISTERED OR SOFT-DELETED -- -
$stmt = db()->prepare("SELECT id, deleted_at FROM attendees WHERE webinar_id = ? AND email = ?");
@ -83,14 +99,14 @@ try {
$host = $_SERVER['HTTP_HOST'];
$logo_url = $protocol . '://' . $host . '/assets/pasted-20251030-095744-1b7c02ab.png';
$subject = "Confirmation: You're Registered for Building Scalable Apps with AppWizzy";
$webinar_date_obj = new DateTime('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
$webinar_date_obj = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
// --- PREPARE CALENDAR LINK ---
$event_title_cal = 'Building Scalable Apps with AppWizzy';
$event_description_cal = 'Professional Vibe-Coding Webinar. Join us to learn the fastest way to go from an idea to a working app you own.';
$event_description_cal = 'Professional Vibe-Coding Webinar. Join us on March 25th at 6PM CET | 12PM EDT | 9AM PDT to learn the fastest way to go from an idea to a working app you own.';
// Use the same webinar date as in the email body
$webinar_date_for_cal = new DateTime('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
$webinar_date_for_cal = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
// Convert to UTC for Google Calendar
$webinar_date_for_cal->setTimezone(new DateTimeZone('UTC'));
@ -135,7 +151,7 @@ try {
<p style="font-size: 16px; line-height: 1.6;">We're excited to have you join us for this professional vibe-coding session.</p>
<div style="background-color: #f9f9f9; border-left: 4px solid #673ab7; padding: 15px 20px; margin: 20px 0;">
<p style="margin: 0; font-size: 16px;"><strong>Webinar Details:</strong></p>
<p style="margin: 10px 0 0; font-size: 16px;">{$webinar_date_obj->format('l, F j, Y')} | <strong>4PM CET</strong> | {$webinar_date_obj->format('g:i A T')}</p>
<p style="margin: 10px 0 0; font-size: 16px;">{$webinar_date_obj->format('l, F j, Y')} | <strong>6PM CET</strong> | 12PM EDT | 9AM PDT</p>
</div>
<p style="font-size: 16px; line-height: 1.6;">You'll learn the fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.</p>
<p style="font-size: 16px; line-height: 1.6;"><strong>Your personal webinar access link will be emailed to you 1 day before the event.</strong></p>
@ -163,14 +179,14 @@ HTML;
}
// --- PREPARE SUCCESS RESPONSE ---
$webinar_date = new DateTime('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
$webinar_date = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
$webinar_date->setTimezone(new DateTimeZone('UTC'));
$start_time_utc = $webinar_date->format('Ymd\THis\Z');
$webinar_date->add(new DateInterval('PT1H')); // Assume 1 hour duration
$end_time_utc = $webinar_date->format('Ymd\THis\Z');
$event_title = 'Building Scalable Apps with AppWizzy at 4PM CET';
$event_description = 'Professional Vibe-Coding Webinar\n\nJoin us for this webinar at 4PM CET | 10AM EST | 7AM PST. The fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.';
$event_title = 'Building Scalable Apps with AppWizzy at 6PM CET';
$event_description = 'Professional Vibe-Coding Webinar\n\nJoin us for this webinar on March 25th at 6PM CET | 12PM EDT | 9AM PDT. The fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.';
$google_link = 'https://www.google.com/calendar/render?action=TEMPLATE&text=' . urlencode($event_title) . '&dates=' . $start_time_utc . '/' . $end_time_utc . '&details=' . urlencode($event_description) . '&location=' . urlencode('Online') . '&ctz=UTC';