From 3a42952593d2a017d6e643c09df504e27a61595f Mon Sep 17 00:00:00 2001 From: scoliono <2191476+scoliono@users.noreply.github.com> Date: Mon, 27 Dec 2021 07:01:20 +0000 Subject: [PATCH] Add admin panel --- admin/index.php | 71 +++++++++++++++++++++++++++++++++++++++++ admin/login.php | 34 ++++++++++++++++++++ admin/logout.php | 16 ++++++++++ admin/mail.php | 53 +++++++++++++++++++++++++++++++ admin/unsubscribe.php | 32 +++++++++++++++++++ css/main.css | 4 +++ index.html | 4 ++- js/app.js | 74 +++++++++++++++++++++++++++++++++++++++++++ mail.php | 46 --------------------------- subscribe.php | 48 ++++++++++++++-------------- 10 files changed, 312 insertions(+), 70 deletions(-) create mode 100644 admin/index.php create mode 100644 admin/login.php create mode 100644 admin/logout.php create mode 100644 admin/mail.php create mode 100644 admin/unsubscribe.php create mode 100644 js/app.js delete mode 100644 mail.php diff --git a/admin/index.php b/admin/index.php new file mode 100644 index 0000000..91d5d87 --- /dev/null +++ b/admin/index.php @@ -0,0 +1,71 @@ +query("SELECT * FROM subscribers"); +if (!$result) { + http_response_code(500); + die("Error: {$conn->error}"); +} + +$subscribers = []; +while ($row = $result->fetch_assoc()) { + $subscribers[] = $row; +} +?> + + + + + Miles Linden for San Jose City Council + + +

Admin Panel

+
+

Logout

+

Mail All

+
+

Subscribers

+ + + + + + + + + + + + + + + + + + + + + + + +
NameEmailPhoneJoin DateActions
+ +
+ + +
+
+ + diff --git a/admin/login.php b/admin/login.php new file mode 100644 index 0000000..3f3f7d9 --- /dev/null +++ b/admin/login.php @@ -0,0 +1,34 @@ + + + + +
+
+

Enter passcode:

+ +
+
+ +
+
+ + + + + + + + + +

Signed out.

+ + diff --git a/admin/mail.php b/admin/mail.php new file mode 100644 index 0000000..4fdee5d --- /dev/null +++ b/admin/mail.php @@ -0,0 +1,53 @@ + + + + +
+
+ +
+
+ +
+
+ + +query("SELECT email, full_name FROM subscribers"); +if (!$result) { + http_response_code(500); + die(json_encode(['message' => $conn->error])); +} +$to_emails = []; +while ($row = $result->fetch_row()) { + $to_emails[] = "$row[1] <$row[0]>"; +} + +$to = implode(", ", $to_emails); +$headers = [ + 'From: Miles Linden ', + 'X-Mailer: PHP/' . phpversion() +]; +$message = wordwrap($message, 80, "\r\n"); +if (!mail($to, "MILES LINDEN CAMPAIGN ALERT", $message, implode("\r\n", $headers), '-fno-reply@mileslinden.com')) { + http_response_code(500); + die("Error: failed to send email message."); +} + +die("Sent email successfully."); diff --git a/admin/unsubscribe.php b/admin/unsubscribe.php new file mode 100644 index 0000000..0f3ce95 --- /dev/null +++ b/admin/unsubscribe.php @@ -0,0 +1,32 @@ +prepare("DELETE FROM subscribers WHERE email = ?"); +if (!$query) { + http_response_code(500); + die("Error: {$conn->error}"); +} +$query->bind_param("s", $email); +$query->execute(); + +if ($query->affected_rows === 0) { + http_response_code(400); + die("Error: that email address does not exist"); +} else { + header('Location: /admin'); + die; +} diff --git a/css/main.css b/css/main.css index fb2e63a..e0dc925 100644 --- a/css/main.css +++ b/css/main.css @@ -98,6 +98,10 @@ nav a:hover { min-width: 250px; } +.banner form input.invalid { + border-bottom-color: red; +} + .banner input { border: none; font-size: 32px; diff --git a/index.html b/index.html index c59bad9..ff271b8 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,10 @@ - + + + Miles Linden for San Jose City Council diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..552c021 --- /dev/null +++ b/js/app.js @@ -0,0 +1,74 @@ +document.addEventListener('DOMContentLoaded', function () { + + var fullName = document.querySelector('input[name="full_name"]'); + var email = document.querySelector('input[name="email"]'); + var phone = document.querySelector('input[name="phone"]'); + var submit = document.querySelector('button[type="submit"]'); + + const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; + const phoneRegex = /^(\+?0?1\s?)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/; + const fullNameRegex = /[^\s.]{2,} [^\s.]{2,}/; + + + fullName.addEventListener('input', function (e) { + if (! fullName.value.toLowerCase().match(fullNameRegex)) { + fullName.classList.add('invalid'); + } else { + fullName.classList.remove('invalid'); + } + }); + + email.addEventListener('input', function (e) { + if (! email.value.toLowerCase().match(emailRegex)) { + email.classList.add('invalid'); + } else { + email.classList.remove('invalid'); + } + }); + + phone.addEventListener('input', function (e) { + if (! phone.value.match(phoneRegex)) { + phone.classList.add('invalid'); + } else { + phone.classList.remove('invalid'); + } + }); + + submit.addEventListener('click', function (e) { + e.preventDefault(); + + if (! fullName.value.toLowerCase().match(fullNameRegex)) { + alert("Your full name appears invalid."); + return; + } + if (! email.value.toLowerCase().match(emailRegex)) { + alert("Your email address is invalid."); + return; + } + if (! phone.value.match(phoneRegex)) { + alert("Your phone number is invalid."); + return; + } + var fd = new FormData(); + fd.append('full_name', fullName.value); + fd.append('email', email.value); + fd.append('phone', phone.value); + var req = fetch('/subscribe.php', { + method: 'POST', + body: fd + }).then(function (res) { + if (!res.ok) { + res.json().then(function (err) { + document.querySelector('input[name="'+ err.field + '"]').classList.add('invalid'); + alert(err.message); + }); + } else { + alert("You have subscribed successfully."); + fullName.value = ""; + email.value = ""; + phone.value = ""; + } + }); + }); + +}); diff --git a/mail.php b/mail.php deleted file mode 100644 index 9cebddb..0000000 --- a/mail.php +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Miles Linden for San Jose City Council - - -

Great success!

- - diff --git a/subscribe.php b/subscribe.php index 61cfaf2..f8669b6 100644 --- a/subscribe.php +++ b/subscribe.php @@ -1,9 +1,10 @@ 'email', + 'message' => 'Error: An email address, first name, and last name are required.' + ])); } if ($gender && $gender !== 'm' && $gender !== 'f') { - die("Error: An invalid gender was given."); + http_response_code(400); + die(json_encode([ + 'field' => 'full_name', + 'message' => 'Error: An invalid gender was given.' + ])); } -$conn = mysql_connect(":/tmp/mysql.sock", "root", ""); -if (!$conn) { - die("MySQL connection error: " . mysql_error()); -} -mysql_select_db("mileslinden", $conn); +$conn = new mysqli("localhost", "mileslinden", "Daiso@6969", "mileslinden"); -$query = sprintf( - "INSERT INTO subscribers (`email`, `full_name`, `phone`, `gender`, `join_date`) ". - "VALUES ('%s', '%s', '%s', '%s', '%s')", - mysql_real_escape_string($email), - mysql_real_escape_string($fname), - mysql_real_escape_string($phone), - mysql_real_escape_string($gender), +$query = $conn->prepare( + "INSERT INTO subscribers (`email`, `full_name`, `phone`, `gender`, `join_date`) VALUES (?, ?, ?, ?, ?)" +); +if (!$query) { + http_response_code(500); + die(json_encode(['message' => $conn->error])); +} +$query->bind_param( + "sssss", + $email, $fname, $phone_num, $gender, date("Y-m-d H:i:s") ); -$res = mysql_query($query); - -if (!$res) { - die("MySQL query error: " . mysql_error()); -} - -mysql_close($conn); +$query->execute(); ?> @@ -52,6 +54,6 @@ mysql_close($conn); Miles Linden for San Jose City Council -

You have subscribed successfully!

+

You have subscribed successfully.